版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mr_muli/article/details/84590277
- 机器学习之kMeans聚类
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 28 16:23:36 2018
@author: muli
"""
from sklearn.datasets.samples_generator import make_blobs
from sklearn import cluster
from sklearn.metrics import adjusted_rand_score
import matplotlib.pyplot as plt
def create_data(centers,num=100,std=0.7):
'''
生成用于聚类的数据集
:param centers: 聚类的中心点组成的数组。如果中心点是二维的,则产生的每个样本都是二维的。
:param num: 样本数
:param std: 每个簇中样本的标准差
:return: 用于聚类的数据集。是一个元组,第一个元素为样本集,第二个元素为样本集的真实簇分类标记
'''
X, labels_true = make_blobs(n_samples=num, centers=centers, cluster_std=std)
return X,labels_true
def test_Kmeans(*data):
'''
测试 KMeans 的用法
:param data: 可变参数。它是一个元组。元组元素依次为:第一个元素为样本集,第二个元素为样本集的真实簇分类标记
:return: None
'''
X,labels_true=data
clst=cluster.KMeans()
# 训练模型
clst.fit(X)
predicted_labels=clst.predict(X)
# ARI指数
print("ARI:%s"% adjusted_rand_score(labels_true,predicted_labels))
# 所有样本距离各簇中心点的距离之后
print("Sum center distance %s"%clst.inertia_)
def test_Kmeans_nclusters(*data):
'''
测试 KMeans 的聚类结果随 n_clusters 参数的影响
:param data: 可变参数。它是一个元组。元组元素依次为:第一个元素为样本集,第二个元素为样本集的真实簇分类标记
:return: None
'''
X,labels_true=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(labels_true,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("inertia_")
fig.suptitle("KMeans")
plt.show()
def test_Kmeans_n_init(*data):
'''
测试 KMeans 的聚类结果随 n_init 和 init 参数的影响
:param data: 可变参数。它是一个元组。元组元素依次为:第一个元素为样本集,第二个元素为样本集的真实簇分类标记
:return: None
'''
X,labels_true=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(labels_true,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(labels_true,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='o',label="k-means++")
ax.plot(nums,Distances_r,marker='o',label="random")
ax.set_xlabel("n_init")
ax.set_ylabel("inertia_")
ax.legend(loc='best')
fig.suptitle("KMeans")
plt.show()
if __name__=='__main__':
# 用于产生聚类的中心点
# 聚类中心是几维,则特征向量是几维的
centers=[[1,1],[2,2],[1,2],[10,20]]
# 产生用于聚类的数据集
X,labels_true=create_data(centers,1000,0.5)
# plot_data(X,labels_true) # 绘制用于聚类的数据集
# test_Kmeans(X,labels_true) # 调用 test_Kmeans 函数
# test_Kmeans_nclusters(X,labels_true) # 调用 test_Kmeans_nclusters 函数
test_Kmeans_n_init(X,labels_true) # 调用 test_Kmeans_n_init 函数