(1)K-means简介
k-meansalgorithm算法是一个聚类算法,把n的对象根据他们的属性分为k个分割,k < n。假设对象属性来自于空间向量,并且目标是使各个群组内部的均方误差总和最小。
假设有k个群组Si, i=1,2,…,k。μi是群组Si内所有元素xj的质心,或叫中心点。
k平均聚类发明于1956年, 该算法最常见的形式是采用被称为劳埃德算法(Lloydalgorithm)的迭代式改进探索法。劳埃德算法首先把输入点分成k个初始化分组,可以是随机的或者使用一些启发式数据。然后计算每组的中心点,根据中心点的位置把对象分到离它最近的中心,重新确定分组。继续重复不断地计算中心并重新分组,直到收敛,即对象不再改变分组(中心点位置不再改变)。
劳埃德算法和k平均通常是紧密联系的,但是在实际应用中,劳埃德算法是解决k平均问题的启发式法则,对于某些起始点和重心的组合,劳埃德算法可能实际上收敛于错误的结果。虽然存在变异,但是劳埃德算法仍旧保持流行,因为它在实际中收敛非常快。实际上,观察发现迭代次数远远少于点的数量。然而最近,David Arthur和Sergei Vassilvitskii提出存在特定的点集使得k平均算法花费超多项式时间达到收敛。近似的k平均算法已经被设计用于原始数据子集的计算。
从算法的表现上来说,它并不保证一定得到全局最优解,最终解的质量很大程度上取决于初始化的分组。由于该算法的速度很快,因此常用的一种方法是多次运行k平均算法,选择最优解。
k平均算法的一个缺点是,分组的数目k是一个输入参数,不合适的k可能返回较差的结果。另外,算法还假设均方误差是计算群组分散度的最佳参数。
(2)基本方法:
一、从数据中随机抽取k个点作为初始聚类的中心,由这个中心代表各个聚类。
二、计算数据中所有的样本点到这k个点的距离,将每个样本点都归到最近的聚类里。
三、重新计算聚类中心点,方法就是将第二步中的中心移动到聚类的几何中心(即平均值)处。
四、重复第2步直到聚类的中心不再移动,此时算法收敛。
(3)sklearn中基本步骤。
读入数据、可以绘制出数据的样子、训练模型、绘制边界(观察效果)、中心点绘制。
代码参考如下:
from numpy import *
import numpy as np
from math import *
import matplotlib.pyplot as plt
import matplotlib
#————————————–输入信息
#输入:文件名;
#输出:list(dataMat),数据集为所有特征(无监督学习)
def loadDataSet(fileName):
numFeat=len(open(fileName).readline().split(‘\t’))
dataMat=[];labelArr=[]
fr=open(fileName)
for line infr.readlines():
lineArr=[]
curLine=line.strip().split(‘\t’)
for i inrange(numFeat):
lineArr.append(float(curLine[i]))
dataMat.append(lineArr)
return dataMat #返回的是array类型。
#————————————————————-————————
def plotxy(x,y):#x,y具有相同数组序列;只要长度一致即可。
#x=[[2,3,4,5,6,7,8]]
#y=[[1],[2],[3],[4],[5],[6],[7]]
fig=plt.figure()
ax1=fig.add_subplot(221)
ax1.set_title(‘clustering:’)
ax1.scatter(x,y,s=20,c=’r’,marker=’o’)#s代表大小,可以是数组,和前面对应。
x_min, x_max = min(x) – 1,max(x) + 1
y_min, y_max = min(y) – 1, max(y) + 1
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
# Train the model
kmeans = KMeans(init=’k-means++’,n_clusters=num_clusters, n_init=10)
kmeans.fit(data)
# Step size of the mesh
step = 0.05
# Plot the boundaries
x_min, x_max = min(data[:, 0]) – 1,max(data[:, 0]) + 1
y_min, y_max = min(data[:, 1]) – 1,max(data[:, 1]) + 1
x_values, y_values =np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step))
predicted_labels =predicted_labels.reshape(x_values.shape)
plt.figure()
plt.clf()
plt.imshow(predicted_labels,interpolation=’nearest’,
extent=(x_values.min(), x_values.max(), y_values.min(), y_values.max()),
cmap=plt.cm.Paired,aspect=’auto’, origin=’lower’)
plt.scatter(data[:,0], data[:,1],marker=’o’, facecolors=’none’, edgecolors=’k’, s=30)
centroids = kmeans.cluster_centers_
plt.scatter(centroids[:,0], centroids[:,1],marker=’o’, s=200, linewidths=3,color=’k’, zorder=10, facecolors=’black’)
x_min, x_max = min(data[:, 0]) – 1,max(data[:, 0]) + 1
y_min, y_max = min(data[:, 1]) – 1,max(data[:, 1]) + 1
plt.title(‘Centoids and boundaries obtainedusing KMeans’)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()