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实现
点击打开链接