问题描述
- 现在有一组数据,需要通过聚类方法发掘其内在结构
目标
- 对数据进行聚类分析,将数据分为四类(k=4)
数据集
- clusterdata.txt存储待聚类数据;共包含400个数据点;数据维度(400,3)
分析
- 根据以上问题,进行分析。已知训练集,需要将训练集分为4类,同时输出每一类的中心点坐标。
- 分析可得,使用K-Means算法实现此要求。K-Means算法是一个聚类算法,它接受输入参数k,在此实验中k取值为4类,然后将400个数据对象划分为4个聚类,使所获得的聚类满足以下两个条件。
(1) 同一聚类中的对象之间的相似度较高。
(2) 不同聚类中的对象之间的相似度较小。 - 其中,“聚类相似度”是利用各聚类中对象的均值所获得的一个“中心对象”的方式计算
算法阐述
- 设置k的取值,并在原始数据集中随机选择k个对象,将这些结点作为聚类中心对象。K=4。
- 计算其他对象与这些聚类中心对象之间的距离,并根据最小距离,将其他结点合并入对应的聚类中心点所属聚类,形成k=4个初始聚类。
- 计算每个中间聚类结果的均值,在k中间聚类中找出k=4个新的“聚类中心对象”。
- 重新计算每个对象与这些新的类中心对象之间的距离,并据最小距离,重新分类,形成k=4个中间聚类结果。
- 重复执行(3)、(4)。当所有对象的聚类情况不再变化或已达到规定的循环次数时,结束执行,并得到最终聚类结果。
代码实现
from matplotlib import pyplot as plt
import numpy as np
from sklearn import cluster
from sklearn.cluster import KMeans
import pandas as pd
#提取训练集
data = np.loadtxt('clusterdata.txt')
print('数据集的形状为:',np.shape(data))#data数据集的形状
print('------------------------------------------------------------------------------')
n_clusters = 4 #分四类
#将data数据集分为四类
#init初始化质心
cluster = KMeans(n_clusters = n_clusters,init='k-means++',random_state = 0)
#开始聚类
cluster.fit(data)
#简单打印结果
y_pred = cluster.labels_#每个样本对应的簇类别标签
print('数据集的分类结果:')
print(y_pred)
print('------------------------------------------------------------------------------')
r1 = pd.Series(y_pred).value_counts()#统计各类别的数目
centroid = cluster.cluster_centers_#聚类中心,质心
r2=pd.DataFrame(centroid,columns=list('xyz'))#找出聚类中心
r = pd.concat([r2,r1],axis = 1)#横向连接(0是纵向),得到聚类中心对应的类别下的数目
print(r)
print('------------------------------------------------------------------------------')
print('各类别对应的数据数目:')
print(r1)
print('------------------------------------------------------------------------------')
print('质心为\n',centroid)
print('------------------------------------------------------------------------------')
print('质心的数据形状',centroid.shape)
#数据可视化
fig=plt.figure#创建绘图窗口
ax=plt.axes(projection='3d')#创建坐标轴对象
#数据集进行分类
j=0
for i in y_pred:
if i==0:
ax.scatter(data[j,0],data[j,1],data[j,2],c='limegreen',s=8)
elif i==1:
ax.scatter(data[j,0],data[j,1],data[j,2],c='red',s=8)
elif i==2:
ax.scatter(data[j,0],data[j,1],data[j,2],c='royalblue',s=8)
else:
ax.scatter(data[j,0],data[j,1],data[j,2],c='orange',s=8)
j+=1
#显示质心
for k in range(n_clusters):
ax.scatter(centroid[k,0],centroid[k,1],centroid[k,2],c='black',s=25)
plt.show()
结果