从零开始的数模(九)聚类分析

一、概念

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的输出转换为方阵。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟雨平生9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值