聚类分析2

1.基于分层的分类(matlab)实现

基本套路:

a=[1,0;1,1;3,2;4,3;2,5];
Y=pdist(a,'cityblock');%求距离矩阵
yc=squareform(Y)%将距离矩阵以简明的方式表现出来
z=linkage(Y)%利用不同算法进行聚类,生成聚类树
[h,t]=dendrogram(z)%根据z生成简明聚类树
T=cluster(z,'maxclust',3)%指定阈值,进行分类
for i=1:3
    tm=find(T==i);
    tm=reshape(tm,1,length(tm));
    fprintf('第%d类的有%s\n',i,int2str(tm));
end

Q型聚类分析:

load gj.txt;
r=corrcoef(gj);%计算相关矩阵
d=1-r;%把相关系数转化为距离
d=tril(d);%取下三角元素
d=nonzeros(d);%取非零元素
y=linkage(d,'average');%聚类
[h,t]=dendrogram(y);%画图
T=cluster(y,'maxclust',6);%取阈值
for i=1:6
    tm=find(T==i);
    tm=reshape(tm,1,length(tm));
    fprintf('第%d类的有%s\n',i,int2str(tm));
end


R型聚类分析:

clear
load gj.txt
gj(:,3:6)=[];
gj=zscore(gj);
y=pdist(gj);
z=linkage(y,'average');
dendrogram(z);
for k=3:5
    fprintf('划分成%d类的结果如下:\n',k)
    T=cluster(z,'maxclust',k);
    for i=1:k
        tm=find(T==i);
        tm=reshape(tm,1,length(tm));
        fprintf('第%d类的有%s\n',i,int2str(tm));
    end
    if k==5
        break;
    end
    fprintf('---------------');
end

相关具体信息详见《数学建模算法与应用》p597

2.基于划分的聚类

k-means

main.m:

clear all;
close all;
clc;

%第一类数据
mu1=[0 0 0];  %均值
S1=[0.3 0 0;0 0.35 0;0 0 0.3];  %协方差
data1=mvnrnd(mu1,S1,100);   %产生高斯分布数据

%%第二类数据
mu2=[1.25 1.25 1.25];
S2=[0.3 0 0;0 0.35 0;0 0 0.3];
data2=mvnrnd(mu2,S2,100);

%第三个类数据
mu3=[-1.25 1.25 -1.25];
S3=[0.3 0 0;0 0.35 0;0 0 0.3];
data3=mvnrnd(mu3,S3,100);

%显示数据
plot3(data1(:,1),data1(:,2),data1(:,3),'+');
hold on;
plot3(data2(:,1),data2(:,2),data2(:,3),'r+');
plot3(data3(:,1),data3(:,2),data3(:,3),'g+');
grid on;

%三类数据合成一个不带标号的数据类
data=[data1;data2;data3];   %这里的data是不带标号的

%k-means聚类
[u re]=KMeans(data,3);  %最后产生带标号的数据,标号在所有数据的最后,意思就是数据再加一维度
[m n]=size(re);

%最后显示聚类后的数据
figure;
hold on;
for i=1:m 
    if re(i,4)==1   
         plot3(re(i,1),re(i,2),re(i,3),'ro'); 
    elseif re(i,4)==2
         plot3(re(i,1),re(i,2),re(i,3),'go'); 
    else 
         plot3(re(i,1),re(i,2),re(i,3),'bo'); 
    end
end
grid on;

KMeans.m:

%N是数据一共分多少类
%data是输入的不带分类标号的数据
%u是每一类的中心
%re是返回的带分类标号的数据
function [u re]=KMeans(data,N)   
    [m n]=size(data);   %m是数据个数,n是数据维数
    ma=zeros(n);        %每一维最大的数
    mi=zeros(n);        %每一维最小的数
    u=zeros(N,n);       %随机初始化,最终迭代到每一类的中心位置
    for i=1:n
       ma(i)=max(data(:,i));    %每一维最大的数
       mi(i)=min(data(:,i));    %每一维最小的数
       for j=1:N
            u(j,i)=ma(i)+(mi(i)-ma(i))*rand();  %随机初始化,不过还是在每一维[min max]中初始化好些
       end      
    end
   
    while 1
        pre_u=u;            %上一次求得的中心位置
        for i=1:N
            tmp{i}=[];      % 公式一中的x(i)-uj,为公式一实现做准备
            for j=1:m
                tmp{i}=[tmp{i};data(j,:)-u(i,:)];
            end
        end
        
        quan=zeros(m,N);
        for i=1:m        %公式一的实现
            c=[];
            for j=1:N
                c=[c norm(tmp{j}(i,:))];
            end
            [junk index]=min(c);
            quan(i,index)=norm(tmp{index}(i,:));           
        end
        
        for i=1:N            %公式二的实现
           for j=1:n
                u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));
           end           
        end
        
        if norm(pre_u-u)<0.1  %不断迭代直到位置不再变化
            break;
        end
    end
    
    re=[];
    for i=1:m
        tmp=[];
        for j=1:N
            tmp=[tmp norm(data(i,:)-u(j,:))];
        end
        [junk index]=min(tmp);
        re=[re;data(i,:) index];
    end
    
end


也可用matlab中自带的kmeans函数,函数介绍如下:

    idx = kmeans(X,k)
    idx = kmeans(X,k,Name,Value)
    [idx,C] = kmeans(___)
    [idx,C,sumd] = kmeans(___)
    [idx,C,sumd,D] = kmeans(___)

3.基于密度的聚类

dbscan

main.m:

A=E;%209个行向量
numData=size(A,1);
kdist=zeros(numData,1);%记录k距离的数组
%先在其他向量中找出距离第一个向量最近的k距离以及该向量的IDX
[IDX1, Dist]=knnsearch(A(2:numData,:),A(1,:));
kdist(1)=Dist;

%依次算出每个向量到其他向量最近的k距离以及该向量的IDX
for i=2:size(A,1)
    [IDX1,Dist]=knnsearch(A([1:i-1,i+1:numData],:),A(i,:));
    kdist(i)=Dist;
end

%将距离矩阵排序并画图,找出剧烈变化的点的纵坐标作为DBSCAN中第一个参数
[sortKdist,sortKdistIsx]=sort(kdist,'descend');
distX=[1:numData];
plot(distX,sortKdist,'r+-','LineWidth',2);
grid on;

epsilon=4;%通过观察上图得到该值
MinPts=9;%未看懂
IDX=DBSCAN(E,epsilon,MinPts);%未看懂该算法,所以不知道返回值是什么,怎么利用这个算法得到每个簇的IDX
PlotClusterinResult(E,IDX);%不知道画图的原理


BDSCAN.m:

%
% Copyright (c) 2015, Yarpiz (www.yarpiz.com)
% All rights reserved. Please read the "license.txt" for license terms.
%
% Project Code: YPML110
% Project Title: Implementation of DBSCAN Clustering in MATLAB
% Publisher: Yarpiz (www.yarpiz.com)
% 
% Developer: S. Mostapha Kalami Heris (Member of Yarpiz Team)
% 
% Contact Info: [email protected], [email protected]
%

function [IDX, isnoise]=DBSCAN(X,epsilon,MinPts)

    C=0;
    
    n=size(X,1);
    IDX=zeros(n,1);
    
    D=pdist2(X,X);
    
    visited=false(n,1);
    isnoise=false(n,1);
    
    for i=1:n
        if ~visited(i)
            visited(i)=true;
            
            Neighbors=RegionQuery(i);
            if numel(Neighbors)=MinPts
                    Neighbors=[Neighbors Neighbors2];   %#ok
                end
            end
            if IDX(j)==0
                IDX(j)=C;
            end
            
            k = k + 1;
            if k > numel(Neighbors)
                break;
            end
        end
    end
    
    function Neighbors=RegionQuery(i)
        Neighbors=find(D(i,:)<=epsilon);
    end

end


PlotClusterinResult.m:

%
% Copyright (c) 2015, Yarpiz (www.yarpiz.com)
% All rights reserved. Please read the "license.txt" for license terms.
%
% Project Code: YPML110
% Project Title: Implementation of DBSCAN Clustering in MATLAB
% Publisher: Yarpiz (www.yarpiz.com)
% 
% Developer: S. Mostapha Kalami Heris (Member of Yarpiz Team)
% 
% Contact Info: [email protected], [email protected]
%

function PlotClusterinResult(X, IDX)

    k=max(IDX);

    Colors=hsv(k);

    Legends = {};
    for i=0:k
        Xi=X(IDX==i,:);
        if i~=0
            Style = 'x';
            MarkerSize = 8;
            Color = Colors(i,:);
            Legends{end+1} = ['Cluster #' num2str(i)];
        else
            Style = 'o';
            MarkerSize = 6;
            Color = [0 0 0];
            if ~isempty(Xi)
                Legends{end+1} = 'Noise';
            end
        end
        if ~isempty(Xi)
            plot(Xi(:,1),Xi(:,2),Style,'MarkerSize',MarkerSize,'Color',Color);
        end
        hold on;
    end
    hold off;
    axis equal;
    grid on;
    legend(Legends);
    legend('Location', 'NorthEastOutside');

end


dbscan算法简介
点击打开链接

dbscan算法参数的确定

点击打开链接
另一种dbscan算法matlab实现

点击打开链接



你可能感兴趣的:(数学建模)