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

聚类算法中 K均值聚类(KMeans)的python实现

程序员文章站 2022-07-14 20:29:55
...

**

聚类算法中 K均值聚类(KMeans)的python实现

**

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn import cluster
from sklearn.metrics import adjusted_rand_score
from sklearn import mixture

"""""产生数据"""
def creat_data(centers,num,std):#center聚类中心数组,std,每个族中的标准差
    x,labels_true=make_blobs(n_samples=num,centers=centers,cluster_std=std)
    return x,labels_true  #x为样本,labes为样本点的真实族分类标记

"""""先观察一下生成的样本点"""
def plot_data(*data):
    x,labels_true=data
    labels=np.unique(labels_true)
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    colors="rgbyckm"
    for i,label in enumerate(labels):
        position=labels_true==label#这儿出了问题,是什么原因
        ax.scatter(x[position,0],x[position,1],label="cluster %d"%label,color=colors[i%len(colors)])#前面两个数是坐标
    ax.legend(loc="best",framealpha=0.5)
    ax.set_xlabel("x[0]")
    ax.set_ylabel("y[1]")
    ax.set_title("data")
    plt.show()
x,labels_true=creat_data([[1,1],[2,2],[1,2],[10,20]],1000,0.5)
plot_data(x,labels_true)

"""""调用KMeans聚类,来检测聚类的结果"""
def test_KMeans(*data):
    x,labels_true=data
    clst=cluster.KMeans()
    clst.fit(x)
    predicted_labels=clst.predict(x)
    print("ARI:%s"%adjusted_rand_score(labels_true,predicted_labels))#外部指标性能度量指数,值越大说明性能越好
    print("sum center %s"%clst.inertia_)#输出每个样本距离他们各自最近簇中心的距离之和

centers=[[1,1],[2,2],[1,2],[10,20]]
x,label_values=creat_data(centers,1000,0.5)
test_KMeans(x,label_values)


在这里,基本的KMeans聚类算法 python实现就基本完成了,下面,我们测试一下,不同簇数对聚类效果的影响:

def test_KMeans_nclusters(*data):#考察簇数量对系统聚类效果的影响
    x,label_values=data
    nums=range(1,50)
    ARIs=[]
    distances=[]
    for num in nums:
        clst=cluster.KMeans(n_clusters=num)
        clst.fit(x)
        predicted_labels=clst.predict(x)
        ARIs.append(adjusted_rand_score(label_values,predicted_labels))
        distances.append(clst.inertia_)
    fig=plt.figure()
    ax=fig.add_subplot(1,2,1)
    ax.plot(nums,ARIs,marker="+")
    ax.set_xlabel("n_clusters")
    ax.set_ylabel("ARI")

    ax=fig.add_subplot(1,2,2)
    ax.plot(nums,distances,marker="o")
    ax.set_xlabel("n_clusters")
    ax.set_ylabel("intertia_")
    fig.suptitle('KMeans')
    plt.show()

centers=[[1,1],[2,2],[1,2],[10,20]]
x,label_values=creat_data(centers,1000,0.5)
test_KMeans_nclusters(x,label_values)

结果运行程序之后可以看到结果,
最后,还需要考察一下算法的运行次数和初始中心向量策略的影响

   """考察K均值算法运行次数和选择初始中心向量策略的影响,random,KMeans,为初始中心化策略,n_init为算法运行的次数"""

def test_KMeans_n_init(*data):
    x,label_values=data
    nums=range(1,50)
    fig=plt.figure()#绘图
    ARIs_k=[]
    Distances_k=[]
    ARIs_r=[]
    Distances_r=[]
    for num in nums:
        clst=cluster.KMeans(n_init=num,init="k-means++")
        clst.fit(x)
        predicted_labels=clst.predict(x)
        ARIs_k.append(adjusted_rand_score(label_values,predicted_labels))
        Distances_k.append(clst.inertia_)

        clst=cluster.KMeans(n_init=num,init="random")
        clst.fit(x)
        predicted_labels=clst.predict(x)
        ARIs_r.append(adjusted_rand_score(label_values,predicted_labels))
        Distances_r.append(clst.inertia_)


    ax=fig.add_subplot(1,2,1)
    ax.plot(nums,ARIs_k,marker="+",label="K-means")
    ax.plot(nums,ARIs_r,marker=".",label="random")
    ax.set_xlabel("n_init")
    ax.set_ylabel("ARI")
    ax.set_ylim(0,1)
    ax.legend(loc="best")

    ax = fig.add_subplot(1, 2, 2)
    ax.plot(nums, Distances_k, marker="+", label="K-means",color="red")
    ax.plot(nums, Distances_r, marker="o", label="random",color="green")
    ax.set_xlabel("n_init")
    ax.set_ylabel("inertia_")
    ax.legend(loc="best")


    fig.suptitle("KMeans")
    print(Distances_k)
    plt.show()

结果如图:聚类算法中 K均值聚类(KMeans)的python实现
可以看到,随着运行次数和初始中心向量策略的改变,结果是震荡的,五规律可言,因此,它们对聚类的影响并不算太大。

学算法的小白,写博客就是为了监督自己,也是一个自己学习和反省,检测自己一天的成果,这里面很多是别人的代码,学着别人的方法,做了一遍。