python机器学习之--用凝聚层次聚类进行数据分组
程序员文章站
2022-07-14 11:40:40
...
1.什么是层次聚类
def perfrom_clustering(X,connectivity,title,num_clusters=3,linkage='ward'):
plt.figure()
model = AgglomerativeClustering(linkage=linkage,
connectivity=connectivity,n_clusters=num_clusters)
model.fit(X)
层次聚类是一组聚类算法,通过不断分接或合并集群来构建树状集群,层次聚类可以用一棵树来表示。
层次聚类算法可以自下而上和自上而下。在自下而上算法中,每个数据点都被看做是一个单独的集群,这些集群不断合并,知道所有的集群合并成一个举行集群,这被称为凝聚层次聚类。与之相反,自上而下层次的算法是从一个巨大的集群开始,不断的分接,直到所有的集群变为一个个单独的数据点。
本片博客主要参考了:http://nlp.stanford.edu/IR-book/html/htmledition/hierarchical-agglomerative-clustering-1.html
2.详细步骤
首先导入需要的程序包:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from sklearn.neighbors import kneighbors_graph
定义一个实现凝聚层次聚类的函数
def perfrom_clustering(X,connectivity,title,num_clusters=3,linkage='ward'):
plt.figure()
model = AgglomerativeClustering(linkage=linkage,
connectivity=connectivity,n_clusters=num_clusters)
model.fit(X)
提取标记,然后指定不同聚类在图形中的标记
迭代数据,用不同的标记把聚类的点画在图形中
labels = model.labels_
markers = '.vx'
#迭代数据,用不同的标记把聚类的点画在图形上
for i, marker in zip(range(num_clusters),markers):
#画出属于某个集群中心的数据点
plt.scatter(X[labels == i, 0], X[labels == i, 1], s=50,
marker=marker, color='k', facecolor='none')
plt.title(title)
为了掩饰凝聚层次聚类的优势,需要用它对一些在空间中是链接在一起,但批次却非常接近的数据进行聚类,我们希望链接在一起的数据可以聚成一类,而不是在空间上非常接近的点聚成一类,下面定义一个人函数来获取一组呈螺旋状的数据点
def get_spiral(t,noise_amplitude=0.5):
r=t
x=r*np.cos(t)
y=r*np.sin(t)
return add_noise(x,y,noise_amplitude)
在上面的函数中,我们增加了一些噪声,因为这样做可以增加一些不确定性,下面定义一些噪声函数
def add_noise(x,y,amplitude):
X = np.concatenate((x,y))
X+= amplitude *np.random.randn(2,X.shape[1])
return X.T
我们再定义一个函数来获取位于玫瑰曲线上的数据点def get_rose(t,noise_amplitude=0.02):
#设置玫瑰曲线方程,如果变量k是奇数,那么曲线有k花瓣,如果是偶数,则是2k
k =5
r =np.cos(k*t) +0.25
x = r *np.cos(t)
y = r *np.sin(t)
return add_noise(x,y,noise_amplitude)
为了增加多样性,在定义一个函数
def get_hypotrochoid(t,noise_amplitude=0):
a,b,h=10.0,2.0,4.0
x = (a-b)*np.cos(t)+h*np.cos((a-b)/b*t)
y = (a-b)*np.sin(t)-h*np.sin((a-b)/b*t)
return add_noise(x,y,0)
接下来定义主函数,主要是
生成样本数据、不考虑螺旋状的数据连接性、根据数据连接线创建k个临近点的图形
if __name__ == '__main__':
#生成样本数据
n_samples = 500
np.random.seed(2)
t = 2.5*np.pi*(1+2*np.random.rand(1,n_samples))
X=get_spiral(t)
connectivity = None
perfrom_clustering(X,connectivity,'No connectivity')
connectivity = kneighbors_graph(X,10,include_self=False)
perfrom_clustering(X,connectivity,'K-Neighbora connectivity')
plt.show()
运行代码
由结果我们可以看出,使用连接特征可以让我们把连接在一起的数据和在一组,而不是按照它们在螺旋线上的位置进行聚类。
上一篇: MarkDown基本操作