欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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()

运行代码

python机器学习之--用凝聚层次聚类进行数据分组

python机器学习之--用凝聚层次聚类进行数据分组

由结果我们可以看出,使用连接特征可以让我们把连接在一起的数据和在一组,而不是按照它们在螺旋线上的位置进行聚类。