一、概念
1.1相关概念
1.2基本思想
1.3聚类对象
聚类分析根据分类对象的不同可分为Q型和R型两大类
1.4相似性度量
对样品聚类时相似性通常用某种距离来表征,对于间隔尺度的变量,可以采用欧氏距离或者马氏距离(马氏距离不受指标量纲的影响,但某些情况下的值难以计算,故虽然欧氏距离表征效果没有马氏距离好,但在实际应用中仍多采用欧氏距离)。如果指标是有序尺度或者名义尺度,常用相似系数量化不同指标之间的相似程度,常用的相似系数包括夹角余弦(不重视长度)和相关系数(数据标准化后的夹角余弦)。
二、聚类分析的一般步骤
三、聚类实操——python实现
① 导入相关库
import numpy as np
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram,linkage
import xlrd as xr
import pandas as pd
from sklearn import preprocessing
from sklearn.cluster import AgglomerativeClustering
② 读取excel文件数据
file_location="/Users/lifangjian/Desktop/聚类数据.xls"
data=xr.open_workbook(file_location)
sheet = data.sheet_by_index(0)
lie=sheet.ncols
hang=sheet.nrows
③ 形成数据矩阵,这里有很多处理方式,一种是常规的遍历法,另一种是列表推导式。默认第一行是变量名,比如指标A,指标B,第一列是样品名,比如工厂1,工厂2。
#如果第一行是变量名,第一列是不同样本_遍历法
datam=[]
for i in range(1,hang):
hanglie=[]
for j in range(1,lie):
hanglie.append(sheet.cell_value(i,j))
datam.append(hanglie)
print(datam)
#列表推导式法_得到所有的值,按照行列排列,第一行j个数,第2行j个数。
hanglie=[sheet.cell_value(i,j) for i in range(1,hang) for j in range(1,lie)] #得到所有ij的值
stats = [[sheet.cell_value(r,c) for c in range(1,sheet.ncols)] for r in range(1,sheet.nrows)]#得到所有行列值
print(stats)
stats = pd.DataFrame(stats)
print(stats)
#如果第一行不同的变量,第一行是不同样本_遍历法,如果不是,建议在excel文件中使用=transpose命令
lie=sheet.nrows
hang=sheet.ncols
sheet= data.sheet_by_index(1)
datam=[]
for j in range(1,lie):
liehang=[]
for i in range(1,hang):
liehang.append(sheet.cell_value(i,j))
datam.append(liehang)
print(datam)
输出数据矩阵结果
如果需要标准化,就按照以下的代码实现就可以,上面是Z分数标准化法
stats_frame=pd.DataFrame(stats)
normalizer=preprocessing.scale(stats_frame)
stats_frame_nomalized=pd.DataFrame(normalizer)
print(stats_frame)
print(stats_frame_nomalized)
④ 输出聚类过程
z=linkage(stats,"average",metric='euclidean',optimal_ordering=True)
print(z)
# average=类平均法,ward=离差平方和法,sin=最短距离法,com=最长距离法,med=中间距离法,cen=重心法,fle=可变类平均法
第一列表示聚类类别,第二列表示和哪一类聚类,第三列是类之间的距离,第四列是簇中含有的类别的个数
这里对于各种方式的选取建议在IDLE中输入:
⑤ 画出动态聚类图
fig, ax = plt.subplots(figsize=(10,9))
dendrogram(z, leaf_font_size=14) #画图
plt.title("Hierachial Clustering Dendrogram")
plt.xlabel("Cluster label")
plt.ylabel("Distance")
plt.axhline(y=4) #画一条分类线
plt.show()
⑤ 画出聚类散点图,以2簇为例
cluster = AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage='average')
#linkage模式可以调整,n_cluser可以调整
print(cluster.fit_predict(stats))
plt.figure(figsize=(10, 7))
plt.scatter(stats_frame[0],stats_frame[1], c=cluster.labels_)
plt.show()
代码总结
import numpy as np
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram,linkage
import xlrd as xr
import pandas as pd
from sklearn import preprocessing
from sklearn.cluster import AgglomerativeClustering
file_location="/Users/lifangjian/Desktop/聚类数据.xls"
data=xr.open_workbook(file_location)
sheet = data.sheet_by_index(0)
lie=sheet.ncols
hang=sheet.nrows
#如果第一行是变量名,第一列是不同样本_遍历法
datam=[]
for i in range(1,hang):
hanglie=[]
for j in range(1,lie):
hanglie.append(sheet.cell_value(i,j))
datam.append(hanglie)
print(datam)
#列表推导式法_得到所有的值,按照行列排列,第一行j个数,第2行j个数。
hanglie=[sheet.cell_value(i,j) for i in range(1,hang) for j in range(1,lie)] #得到所有ij的值
stats = [[sheet.cell_value(r,c) for c in range(1,sheet.ncols)] for r in range(1,sheet.nrows)]#得到所有行列值
stats_frame=pd.DataFrame(stats)
normalizer=preprocessing.scale(stats_frame)
stats_frame_nomalized=pd.DataFrame(normalizer)
print(stats_frame)
print(stats_frame_nomalized)
z=linkage(stats,"average",metric='euclidean',optimal_ordering=True)
print(z)
# average=类平均法,ward=离差平方和法,sin=最短距离法,com=最长距离法,med=中间距离法,cen=重心法,fle=可变类平均法
fig, ax = plt.subplots(figsize=(10,9))
dendrogram(z, leaf_font_size=14) #画图
plt.title("Hierachial Clustering Dendrogram")
plt.xlabel("Cluster label")
plt.ylabel("Distance")
plt.axhline(y=4) #画一条分类线
plt.show()
cluster = AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage='average')
#linkage模式可以调整,n_cluser可以调整
print(cluster.fit_predict(stats))
plt.figure(figsize=(10, 7))
plt.scatter(stats_frame[0],stats_frame[1], c=cluster.labels_)
plt.show()
四、聚类实操——MATLAB实现
最短距离法的聚类举例--Q型聚类问题
clc,clear
a=[1,0;1,1;3,2;4,3;2,5];
[m,n]=size(a);
d=zeros(m);
for i=1:m
for j=i+1:m
d(i,j)=mandist(a(i,:),a(j,:)');
%求第一个矩阵的行向量与第二个矩阵的列向量之间对应的绝对值距离
end
end
d
nd=nonzeros(d); %去掉d中的零元素,非零元素按列排列
nd=union(nd,nd) %去掉重复的非零元素
for i=1:m-1
nd_min=min(nd);
[row,col]=find(d==nd_min);tm=union(row,col); %row和col归为一类
tm=reshape(tm,1,length(tm)); %把数组tm变成行向量
fprintf('第%d次合成,平台高度为%d时的分类结果为:%s\n',...
i,nd_min,int2str(tm));
nd(find(nd==nd_min))=[]; %删除已经归类的元素
if length(nd)==0
break
end
end
或者使用MATLAB统计工具箱的相关命令,编写如下程序:
clc,clear
a=[1,0;1,1;3,2;4,3;2,5];
y=pdist(a,'cityblock'); %求a的两两行向量间的绝对值距离
yc=squareform(y) %变换成距离方阵
z=linkage(y) %产生等级聚类树
[h,t]=dendrogram(z) %画聚类图
T=cluster(z,'maxclust',3) %把对象划分成3类
for i=1:3
tm=find(T==i); %求第i类的对象
tm=reshape(tm,1,length(tm)); %变成行向量
fprintf('第%d类的有%s\n',i,int2str(tm)); %显示分类结果
end
Matlab 聚类分析的相关命令
pdist
Y=pdist(X)计算 m× n 矩阵X(看作m 个 n 维行向量)中两两对象间的欧氏距离。
对于有m 个对象组成的数据集,共有(m −1)⋅ m / 2个两两对象组合。linkage
Z=linkage(Y)使用最短距离算法生成具层次结构的聚类树。输入矩阵Y为pdist函数输出的(m −1)⋅ m / 2维距离行向量。cluster
T=cluster(Z,cutoff)从连接输出(linkage)中创建聚类。cutoff为定义cluster函数如何生成聚类的阈值zsore(X)
H=dendrogram(Z,P)
由linkage产生的数据矩阵Z画聚类树状图。P是结点数,默认值是30。T=clusterdata(X,cutoff)
squareform
将pdist的输出转换为方阵。