k-平均算法源于信号处理中的一种向量量化方法,现在更多作为一种聚类分析方法流行于数据挖掘领域。
聚类是一种无监督学习,它将相似的对象归到同一个簇中。簇内的对象越相似,聚类的效果越好。聚类与分类最大的不同在于,分类的目标事先已知,聚类则不一样。
k-均值是发现给定数据集的k个簇的算法。簇个数k是用户给定的,每个簇通过其质心,即簇中所有点的中心来描述。
把n个点划分到k个聚类中,使得每个点都属于离他最近的均值(即聚类中心)对应的聚类,以此作为聚类的标准。
数据预处理,导入数据做成矩阵。distEclud方法计算两个向量之间的距离。
from numpy import *
def loadDataSet(fileName):
dataMat = []
fr = open(fileName)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = map(float, curLine)
dataMat.append(fltLine)
return dataMat
def distEclud(vecA, vecB):
return sqrt(sum(power(vecA - vecB, 2)))
def randCent(dataSet, k):
n = shape(dataSet)[1]
centroids = mat(zeros((k, n)))
for j in range(n):
minJ = min(dataSet[:,j])
rangeJ = float(max(dataSet[:,j]) - minJ)
centroids[:, j] = minJ + rangeJ * random.rand(k, 1)
return centroids
创建k个质心,然后将每个点分配到最近的质心,然后重新计算质心。这个过程反复迭代,直到数据点的簇分配结果不再改变为止。
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0]
clusterAssment = mat(zeros((m, 2)))
centroids = createCent(dataSet, k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m):
minDist = inf
minIndex = -1
for j in range(k):
distJI = distMeas(centroids[j, :], dataSet[i, :])
if distJI < minDist:
minDist = distJI
minIndex = j
if clusterAssment[i, 0] != minIndex:
clusterChanged = True
clusterAssment[i, :] = minIndex, minDist ** 2
print centroids
for cent in range(k):
ptsInClust = dataSet[nonzero(clusterAssment[:0].A == cent)[0]]
centroids[cent,:] = mean(ptsInClust, axis=0)
return centroids, clusterAssment
聚类的簇的数目k是一个用户预先定义的参数,那么用户如何才能直到k的选择是正确的那?在包含簇分配结果的矩阵中保存着每个点的误差,即该点到簇质心的距离平方值。下面讨论利用误差来评价聚类质量。
SSE(Sum of Squared Error, 误差平方和)
SSE值越小,表示数据点越接近它们的质心,聚类的效果也就越好。降低SSE值的方法就是增加簇的个数,但聚类的目标就是在保持簇数目不变的情况下提高簇的质量。应该如何去做?
二分k-均值算法是为了克服k-均值算法收敛于局部最小值的问题提出的。该算法首先将所有点作为一个簇,然后将簇一分为二,选择最有可能降低SSE值的簇继续进行划分,继续迭代上述的过程,直至划分到用户指定的簇数目为止。另一种做法是选择SSE最大的簇进行划分,直到簇数目达到用户指定的数目为止。
sklearn.cluster.KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm='auto')
详细API介绍
使用方法
from sklearn.cluster import KMeans
import numpy as np
X = np.array([[1, 2], [1, 4], [1, 0],
[4, 2], [4, 4], [4, 0]])
kmeans = KMeans(n_clusters = 2, random_state = 0).fit(X)
print kmeans.labels_
print kmeans.predict([[0, 0], [4, 4]])
print kmeans.cluster_centers_
得到结果
python kMeansAPI.py
[0 0 0 1 1 1]
[0 1]
[[ 1. 2.]
[ 4. 2.]]
还有其他很多方法,详细的要阅读文档API。