日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

matlab编程实现基于密度的聚类(DBSCAN)

發布時間:2023/11/27 生活经验 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 matlab编程实现基于密度的聚类(DBSCAN) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. DBSCAN聚類的基本原理

詳細原理可以參考鏈接:
https://www.cnblogs.com/pinard/p/6208966.html
這是找到的相對很詳細的介紹了,此鏈接基本仍是周志華《機器學習》中的內容,不過這個鏈接更通俗一點,且算法流程感覺比《機器學習》書中的偽代碼形式算法流程更清晰。

2. matlab實現DBSCAN聚類

參考《機器學習》中的偽代碼編寫的算法,具體代碼如下:

function [clusterIndex, dataType] = DBSCAN(data, r, minPts)
% 本函數用于基于密度的聚類(DBSCAN)
% 輸入data為聚類數據,每行一個數據點
% 輸入r為密度聚類的滑動窗口半徑參數
% 輸入minPts為滑動窗口內數據量閾值參數
% 輸出clusterIndex為數據對應的類別號組成的序列
% 輸出objType為數據樣本類型,0表示噪聲樣本,1表示邊緣對象,2表示核心對象% 數據量大小
dataSize = length(data(:, 1));
% 預分配輸出的內存
clusterIndex = zeros(dataSize, 1);
dataType = zeros(dataSize, 1);
% 獲得距離方陣
distanceMatrix = squareform(pdist(data));% 標記核心對象集合
% 這里直接用距離矩陣判斷,相當于把自己到自己的距離0也算進去
for i = 1 : dataSizeif sum(distanceMatrix(:, i) < r) >= minPtsdataType(i) = 2;end
end
% 保存核心對象
coreObj = data(dataType == 2, :);% 初始化聚類簇的標記
k = 0;
% 初始化未被訪問的樣本集合
noData = data;% 進入迭代,如果核心對象集合非空,則進入迭代過程
while ~isempty(coreObj)% 記錄當前未被訪問樣本集合,noData數據每次迭代會更新noDataOld = noData;% 隨機選擇一個核心對象作為初始迭代對象randCoreIndex = randperm(length(coreObj(:, 1)), 1);initCoreObj = coreObj(randCoreIndex, :);% 初始化隊列,最初Q只有一個初始核心對象Q = initCoreObj;% 注:集合運算后默認是將集合排序過的,需要加stable參數來保持原來的順序% 從未訪問樣本中刪去隨機選擇的這個核心對象,只刪除這一個,不刪除它密度直達的對象noData = setdiff(noData, initCoreObj, 'stable', 'rows');% 進入循環,找到Q的所有密度可達對象,并放入隊列Q中while ~isempty(Q)% 取出Q中的第一個元素q = Q(1, :);Q(1, :) = [];% 再次距離計算,找到點q鄰域內的數據個數qSizeqIndex = ismember(data, q, 'rows') == 1;qSize = sum(distanceMatrix(qIndex, :) <= r);% q鄰域內的數據qAeraData = data(distanceMatrix(qIndex, :) <= r, :);% 如果數量超過閾值,則將鄰域內的的未訪問的數據賦給隊列Q        if qSize >= minPts% 求交集D = qAereData∩noDataD = intersect(qAeraData, noData, 'stable', 'rows');% 將D中的元素加入隊列QQ = union(Q, D, 'stable', 'rows');% 再將這些數據從未訪問數據noData中刪除掉noData = setdiff(noData, D, 'stable', 'rows'); endendk = k + 1;% 生成聚類簇kCluster = setdiff(noDataOld, noData, 'stable', 'rows');coreObj = setdiff(coreObj, kCluster, 'stable', 'rows');% 記錄類編號clusterIndex(ismember(data, kCluster, 'rows')) = k;
end% 遍歷得到邊緣對象(非核心對象,但在類中)
for i = 1 : dataSizeif (dataType(i) ~= 2) && (clusterIndex(i) ~= 0)dataType(i) = 1;end
end% 函數結束
end

主函數調用:

clear all; close all;
model_class = 3;
dim = 2;
% 期望值
m = [0, 0;2, 2;-2, -2];
% 協方差陣
s(:, :, 1) = [0.1, 0;0, 0.1];
s(:, :, 2) = [0.5, 0.3;0.3, 0.5];
s(:, :, 3) = [1, -0.5;-0.5, 1];num = [500, 500, 500];
data = generate_data_GMM(dim, model_class, m, s, num);
data = data(:, (1:2));[T, N] = DBSCAN(data, 0.27, 9);figure(1)
for i = 1 : length(T)if N(i) == 0plot(data(i, 1), data(i, 2), '*k');hold on;% 邊緣對象elseif N(i) == 1if T(i) == 1plot(data(i, 1), data(i, 2), 'or');hold on;elseif T(i) == 2plot(data(i, 1), data(i, 2), 'og');hold on;elseif T(i) == 3plot(data(i, 1), data(i, 2), 'ob');hold on;else plot(data(i, 1), data(i, 2), 'oy');hold on;endelse % 核心對象if T(i) == 1plot(data(i, 1), data(i, 2), '.r');hold on;elseif T(i) == 2plot(data(i, 1), data(i, 2), '.g');hold on;elseif T(i) == 3plot(data(i, 1), data(i, 2), '.b');hold on;else plot(data(i, 1), data(i, 2), '.y');hold on;endendgrid on;
end% watermelon4_0 = load('watermelon4.0.txt');
% data = watermelon4_0;

聚類結果如下:

注:主函數給了兩個例子,一個是基于高斯分布數據,一個是基于《機器學習》書籍上的西瓜數據集4.0。這里高斯分布數據用到了筆者自編寫的generate_data_GMM函數,這個函數詳細說明及代碼請查看:
https://blog.csdn.net/sangnanpo/article/details/104222339

3. 其他說明

DBSCAN的主要優點有:

  1. 不需要輸入簇的數量
  2. 可以對任意形狀的稠密數據集進行聚類,相對的,K-Means之類的聚類算法一般只適用于凸數據集。
  3. 可以在聚類的同時發現噪聲點,對數據集中的噪聲點不敏感。
  4. 聚類結果沒有偏倚,相對的,K-Means之類的聚類算法初始值對聚類結果有很大影響。

DBSCAN的主要缺點有:

  1. 如果樣本集的密度不均勻、聚類間距差相差很大時,聚類質量較差,這時用DBSCAN聚類一般不適合。
  2. 如果樣本集較大時,聚類收斂時間較長,此時可以對搜索最近鄰時建立的KD樹或者球樹進行規模限制來改進。
  3. 需要調參數,調參相對于傳統的K-Means之類的聚類算法稍復雜,主要需要對距離閾值?,鄰域樣本數閾值MinPts聯合調參,不同的參數組合對最后的聚類效果有較大影響。這一點在具體實現時即可發現。

附:西瓜數據集4.0
0.697 0.460
0.774 0.376
0.634 0.264
0.608 0.318
0.556 0.215
0.403 0.237
0.481 0.149
0.437 0.211
0.666 0.091
0.243 0.267
0.245 0.057
0.343 0.099
0.639 0.161
0.657 0.198
0.360 0.370
0.593 0.042
0.719 0.103
0.359 0.188
0.339 0.241
0.282 0.257
0.748 0.232
0.714 0.346
0.483 0.312
0.478 0.437
0.525 0.369
0.751 0.489
0.532 0.472
0.473 0.376
0.725 0.445
0.446 0.459

總結

以上是生活随笔為你收集整理的matlab编程实现基于密度的聚类(DBSCAN)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。