1.层次聚类
简介
别称:系统聚类
英文名:Hierarchical Clustering
基本原理:假设数据类别之间存在层次结构,通过对数据集在不同层次的划分,构造出树状结构的聚类结果
实现方法:聚合方法、分裂方法
实现方法 方向 步骤描述 经典算法 聚合方法 自底向上
- 首先,每个样本自成一簇;
- 然后,开始迭代,每一次迭代把距离相近的两个簇合并为1个簇;
- 直至,簇的数量达到预设值;
- 若无预设值,则最后把所有样本合并为1个簇
AGNES
(Agglomerative Nesting)
分裂方法 自顶向下
- 起初,只有1个簇,即所有样本构成的簇;
- 使用聚合方法的逆过程;
- 最终,每个样本自成一簇。
未知
2. AGNES算法
AGNES算法,是一种聚合层次聚类算法
2.1 算法步骤
为了便于理解,下面举一个例子:
图11.1
2.2 Python实现
方法一:使用 sklearn.cluster中的AgglomerativeClustering
缺点:只会画聚类散点图,不知道怎么画聚类树状图
需要导入的库:sklearn,matplotlib
from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
关键代码介绍
函数AgglomerativeClustering(n_clusters,linkage)
参数解读:
n_clusters:聚类数 linkage簇间距离计算方式 层次聚类法的关键就是选择合适的linkage!!! single:最小距离 complete:最大距离 average:平均距离 ward:离差平方和- return返回值:返回一个聚类模型
model=AgglomerativeClustering(n_clusters,linkage).fit(x)
代码解读:
在AgglomerativeClustering(n_clusters,linkage)后面加上了.fit(x),
表示将聚类模型应用于数据集x
- x:数据集
- 得到的是拟合于数据集x的聚类模型
plt.scatter(x[:,0],x[:,1],c=model.labels_)
代码解读:
画散点图
- x[:,0],x[:,1]:分别是横、纵坐标
- model.labels_:聚类后,用于表示各个样本属于哪个类别的标签
- c=model.labels_:用聚类后的标签来区分不同颜色
例一:同心圆数据集、半月数据集
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei'] # 散点图标签可以显示中文
plt.rcParams['axes.unicode_minus'] =False
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_moons,make_circles # 导入半月数据集、同心圆数据集
# 构造数据集
circle_x,circle_y=make_circles(n_samples=500,factor=0.5,noise=0.05)
print("circle_x:\n",circle_x)
moon_x,moon_y=make_moons(n_samples=500,noise=0.05,random_state=0)
print("moon_x:\n",moon_x)
circle_model=AgglomerativeClustering(n_clusters=2,linkage="single").fit(circle_x)
moon_model=AgglomerativeClustering(n_clusters=2,linkage="single").fit(moon_x)
'''AgglomerativeClustering
参数解读:
linkage簇间距离计算方式,共有3种选择:
single:最小距离
complete:最大距离
average:平均距离'''
# 绘图
plt.figure(figsize=(12,5)) # 设置画布大小
plt.subplot(121)
plt.title("AGENS on circle dataset",y=-0.15)
plt.scatter(circle_x[:,0],circle_x[:,1],
c=circle_model.labels_) # circle_model.labels_得到各类的标签
plt.subplot(122)
plt.title("AGENS on moon dataset",y=-0.15)
plt.scatter(moon_x[:,0],moon_x[:,1],c=moon_model.labels_)
plt.show()
结果如下:
例二:采用多种linkage聚类
例一只采用了linkage="single"的簇间距离计算方式,下面采用多种linkage分别对多个数据集进行聚类
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei'] # 散点图标签可以显示中文
plt.rcParams['axes.unicode_minus'] =False
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_moons,make_circles,make_blobs,make_s_curve
# 构造数据集
circle_x,circle_y=make_circles(n_samples=500,factor=0.5,noise=0.05)
print("circle_x:\n",circle_x)
moon_x,moon_y=make_moons(n_samples=500,noise=0.05,random_state=0)
print("moon_x:\n",moon_x)
blobs_x,blobs_y=make_blobs(n_samples=200,random_state=0)
print("blobs_x:\n",blobs_x)
curve_x,curve_y=make_s_curve(n_samples=100,noise=0.05,random_state=5)
print("curve_x:\n",curve_x)
'''下面以不同的linkage方式,对不同数据集 进行聚类'''
plt.figure(figsize=(12,12)) # 设置画布大小
i=1
for x in [circle_x,moon_x,blobs_x,curve_x]:
for link in ["single","complete","average","ward"]:
# 得到聚类数据集
model=AgglomerativeClustering(n_clusters=2,linkage=link).fit(x)
plt.subplot(4,4,i)
plt.scatter(x[:, 0], x[:, 1], c=model.labels_)
i+=1
plt.show()
结果如下:
不难发现,对于不同的数据集,选择不同的linkage会有不同的聚类效果。
因此,层次聚类法的关键就是选择合适的linkage!!!
方法二:使用scipy.cluster.hierarchy 中的linkage、fcluster、dendrogram
优点:既可以画聚类树状图、又可以画聚类散点图
需要导入的库:scipy、matplotlib
import scipy.cluster.hierarchy as sch
import matplotlib.pyplot as plt
关键代码介绍
Z=sch.linkage(x,method,metric)
作用:根据method和metric,利用数据集x,生成聚类树的数据矩阵Z
参数解读:
- x:数据集
- method:簇间距离计算方式(与方法一中的linkage是指同一个东西)
- 层次聚类法的关键就是选择合适的簇间距离计算方式,即:method!!!
method取值及其含义 字符串 含义 "single" 最短距离(默认值) "complete" 最大距离 "average" (不加权)平均距离 "ward" 离差平方和方法 "centroid" 重心距离 "weighted" 加权分组平均- metric:距离度量
metric取值及其含义 字符串 含义 "euclidean" 欧几里德距离 "seuclidean" 标准欧几里德距离 "minkowski" 闵氏距离 "cityblock" 绝对值距离 "mahalanobis" 马氏距离 "cosine" 两个向量夹角的余弦 "correlation" 样本相关系数 "hamming" 汉明距离 "jaccard" Jaccard系数 "chebyshev" 切比雪夫距离- return 返回值:数据矩阵Z
T=sch.fcluster(Z,criterion,t)
作用:根据criterion和t,从Z中获取聚类结果T
参数解读:
- Z : 从Z=sch.linkage(x,method,metric)得到的数据矩阵
- criterion:聚类准则(要结合t一起用)
- t
- return 返回值:聚类结果
不同criterion下t的含义 criterion的取值 t的含义 "inconsistent"t值应该在0-1之间波动,
t越接近1代表两个数据之间的相关性越大;
t越趋于0表明两个数据的相关性越小。
这种相关性可以用来比较两个向量之间的相关性,可用于高维空间的聚类
"distance" 簇的最大距离为t "maxclust" 最大分类簇数为t "monocrit"t的选择不是固定的,而是根据一个函数monocrit[j]来确定。 "maxclust_monocrit"在最大聚类数量为t的同时,将阈值t减小到最小的不一致性 criterion的取值中,较常用的是:"distance","maxclust"
sch.dendrogram(Z)
作用:根据聚类树的数据矩阵Z,画出聚类树状图
然后直接plt.show()即可
参数解读:
- Z : 从Z=sch.linkage(x,method,metric)得到的数据矩阵
plt.scatter(x[:,0],x[:,1],c=T)
作用:画出聚类后的散点图
参数解读:
- x[:,0],x[:,1]:数据集的横、纵坐标
- T:从T=sch.fcluster(Z,criterion,t)得到的聚类结果
- c=T:用聚类后的标签来区分不同颜色
例子:同心圆数据集
import scipy.cluster.hierarchy as sch
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_circles # 导入同心圆数据集
# 构造数据集
circle_x,circle_y=make_circles(n_samples=500,factor=0.5,noise=0.05)
print("circle_x:\n",circle_x)
# 计算数据矩阵Z
Z=sch.linkage(circle_x, # 数据
method="single",
metric="euclidean")
print("数据矩阵Z:\n",Z)
'''linkage
参数解读:
method 簇间距离计算方式:
"single"最短距离、"complete"最大距离、"average"(不加权)平均距离、"ward"离差平方和方法、"centroid"重心距离、"weighted"加权分组平均
metric 距离度量:
"euclidean"欧几里德距离、"seuclidean"标准欧几里德距离、"minkowski"闵氏距离、"cityblock"绝对值距离、"mahalanobis"马氏距离、
"cosine"两个向量夹角的余弦、"correlation"样本相关系数、"hamming"汉明距离、"jaccard"Jaccard系数、"chebyshev"切比雪夫距离
'''
# 得到分类结果
T=sch.fcluster(Z,criterion="maxclust",t=2) # 根据给定的类数t,创建Z的聚类
print(T)
'''sch.fcluster
参数解读:
criterion聚类准则(要结合t一起用):
"inconsistent"、"distance"簇的距离不超过t、"maxclust"最大分类簇数为t、"monocrit"、"maxclust_monocrit"
其中"distance""maxclust"较为常用
'''
# 用数据矩阵Z画出聚类树状图
sch.dendrogram(Z)
plt.show()
# 画出聚类散点图
plt.scatter(circle_x[:,0],circle_x[:,1],c=T)
plt.show()
聚类树状图如下:
由此可见,当样本点很多时,聚类树状图非常密集,因此样本点很多时,不太适合画聚类树状图,画聚类散点图更合适、更美观。
聚类散点图如下:
3.变量聚类
简介
- 基本原理:根据变量的相似关系来聚类
- 步骤:
1.先计算变量之间的相似关系
2.计算两变量之间的距离
3.用层次聚类的方法对变量进行聚类- 与其他聚类方法的区别:其他聚类方法聚类的对象都是“样本点”,而变量聚类的对象是“变量”
- 本质:用层次聚类的方法,对变量进行聚类
3.1 算法描述
3.2 Python实现
需要导入的库:scipy,matplotlib
import scipy.cluster.hierarchy as sch
import matplotlib.pyplot as plt
步骤:
- 先求出相似关系r
- 再求变量间的距离d:d=1-abs(r)
- 用层次聚类的方法进行聚类
例子:
(注:数据文件data11_8.xlsx在本文开头)
import scipy.cluster.hierarchy as sch
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data=pd.read_excel("data11_8.xlsx",header=None)
print("各因素之间的相关系数表:\n",data)
# 取出非nan的元素,即data中对角线下方的元素
b=np.triu(data.values.T,k=1)
print(b)
r=b[np.nonzero(b)] # 得到全部相关系数
d=1-abs(r) # 计算两类变量之间的距离
# 用系统聚类的方法对变量进行聚类
Z=sch.linkage(d,"complete")
sch.dendrogram(Z,labels=range(1,15))
plt.show()
结果如下:
参考文献
[1]司守奎,孙玺.Python数学建模算法与应用
[2]左飞.Python机器学习中的数学修炼
[3]python的scipy层次聚类参数详解https://blog.csdn.net/enigma_tong/article/details/79081449
标签:Clustering,plt,Python,距离,聚类,import,circle,linkage From: https://blog.csdn.net/Yhw20040823/article/details/141291710