kmeans背景原理以及工作流程介绍:
源代码:
https://github.com/apachecn/AiLearning/blob/master/src/py3.x/ml/10.kmeans/kMeans.py
样本数据:
https://github.com/apachecn/AiLearning/tree/master/db/10.KMeans
代码解析:(比上面的更详细、细致)
上述是资料和代码来源,这里说一下重点的内容:
k-means特征:
聚类、无监督学习、无需划分样本数据和实验数据、分类算法
k-means的缺陷和解决办法:
kMeans 可能偶尔会陷入局部最小值(局部最优的结果,但不是全局最优的结果),即并不能准确的将数据划分成k个簇,出现这种情况的原因有很多,例如:距离算法选的不好、初始质心选的不好、数据本身存在较多异常数据等等。
解决方法:直接的思路就是将sse较大的簇进行再切分、然后对所有簇的数目进行把控,思路简单、但是实现起来比较麻烦,有一种可行的方法是利用二分k-means法,该算法首先将所有点作为一个簇,然后将该簇一分为二。之后选择其中一个簇继续进行划分,选择哪一个簇进行划分取决于对其划分时候可以最大程度降低 SSE(平方和误差)的值。上述基于 SSE 的划分过程不断重复,直到得到用户指定的簇数目为止。
下面对二分法k-means的代码进行详细的解释:
# 二分 KMeans 聚类算法, 基于 kMeans 基础之上的优化,以避免陷入局部最小值
def biKMeans(dataMat, k, distMeas=distEclud):
m = shape(dataMat)[0] #获取数据矩阵的行数、每一行即一个样本、每一列即一个样本特征(维度)
clusterAssment = mat(zeros((m, 2))) # 保存每个数据点的簇分配结果和平方误差
centroid0 = mean(dataMat, axis=0).tolist()[0] # 质心初始化为所有数据点的均值、按列取
centList = [centroid0] # 初始化只有 1 个质心的 list
for j in range(m): # 计算所有数据点到初始质心的距离平方误差,质心索引均为0.0
clusterAssment[j, 1] = distMeas(mat(centroid0), dataMat[j, :])**2
while (len(centList) < k): # 当质心数量小于 k 时
lowestSSE = inf #无穷大
for i in range(len(centList)): #