机器学习实战之K-means
来源:互联网 发布:七天网络查分怎么登录 编辑:程序博客网 时间:2024/06/03 15:16
1 算法思想
聚类的基本思想是将数据集中的样本划分为若干个通常是不相交的子集,每个子集称为一个”簇”(cluster)。划分后,每个簇可能有相同对应的概念(性质)。K-均值算法就是一个使用很广泛的聚类算法,其中的K就表示簇的数量,K-means简单的说就是通过质心来将样本划分成K个不同的簇。
伪代码为:
工作流程:
(1)事先选定K个聚类中心
(2)计算待测样本a到每个聚类中心的距离,然后将样本a分配到距离最近的聚类中
(3)计算每个聚类样本的均值来动态更新原聚类质心
(4)不断迭代(2),(3),直到簇质心不再改变。
2 实现
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent): m = shape(dataSet)[0] #m=80L clusterAssment = mat(zeros((m,2))) #创造一个m个列表,每个列表中2个元素的全零变量 #在matlab中相当于创建一个m行2列的矩阵 #第一列存簇索引值,第二列存当前点到簇质心的距离 centroids = createCent(dataSet, k) #随机创建k个簇心 clusterChanged = True #创建标注标量,用来达到条件就终止循环 while clusterChanged: clusterChanged = False for i in range(m):#遍历每个样本 minDist = inf #初始样本到簇质心的距离 nif 表示正无穷;-nif表示负无穷 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,结束while循环 clusterAssment[i,:] = minIndex,minDist**2 print centroids for cent in range(k):#遍历每个簇质心 #找到每个簇质心对应的样本 ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get all the point in this cluster centroids[cent,:] = mean(ptsInClust, axis=0) #计算这些样本的均值,作为该簇的新质心 return centroids, clusterAssment
3 二分K-均值算法
K-means虽然实现很容易,但却很容易收敛到局部最小,达不到全局最小,所以有人提出二分K-均值。二分K-均值简单来说就是将所有数据集分成两簇,然后再选择误差最小的那个簇再进行二分K-均值划分。
二分K-均值伪代码:
3.1 实现
def biKmeans(dataSet, k, distMeas=distEclud): m = shape(dataSet)[0] #60L clusterAssment = mat(zeros((m,2))) centroid0 = mean(dataSet, axis=0).tolist()[0] #计算每维的均值 如果axis=1,就是计算每个列表元素的均值 centList =[centroid0] #用每维均值创建初始簇质心,也就是说,将整个数据集当成一簇 for j in range(m):#遍历每个样本 #保存样本到每个簇质心的距离 #所以此处shape(clusterAssment)=(60L,2L) clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2 while (len(centList) < k): #如果初始的簇个数小于k lowestSSE = inf for i in range(len(centList)): #遍历初始的那簇 #提取当前簇中的所有样本点 ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:] #将这些样本点进行kmeans操作,其中K设为2. # 也就是说,把之前那簇数据集分成两簇,分别计为:0簇和1簇,同时返回新分成的两簇中的每簇的质心和误差 #shape(centroidMat)=(2L,2L) shape(splitClustAss)=(60L,2L) centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas) sseSplit = sum(splitClustAss[:,1])# 所有误差相加 sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1]) print "sseSplit, and notSplit: ",sseSplit,sseNotSplit #选择误差小的簇继续二分K-均值划分 if (sseSplit + sseNotSplit) < lowestSSE: bestCentToSplit = i bestNewCents = centroidMat bestClustAss = splitClustAss.copy() lowestSSE = sseSplit + sseNotSplit #将簇编号(0,1)修改成划分簇及新加簇的编号 bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList) #change 1 to 3,4, or whatever bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit print 'the bestCentToSplit is: ',bestCentToSplit print 'the len of bestClustAss is: ', len(bestClustAss) #新划分的质点更新到centList中 centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]#replace a centroid with two best centroids centList.append(bestNewCents[1,:].tolist()[0]) #新划分的结果更新到clusterAssment中 clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss#reassign new clusters, and SSE return mat(centList), clusterAssment
0 0
- 机器学习实战之k-means
- 机器学习实战之K-means
- 机器学习实战K-means
- 机器学习实战-10k-means聚类
- 机器学习之K-means算法:深入浅出K-Means算法
- 【机器学习实战之三】:C++实现K-均值(K-Means)聚类算法
- 机器学习实战之 第10章 K-Means(K-均值)聚类算法
- 机器学习算法 之 K-Means聚类
- 机器学习之K-means算法
- 【机器学习算法】之K-means聚类
- 机器学习之k-means算法
- 机器学习----聚类之k-means
- 机器学习算法之K-means-spark
- k-means 机器学习
- 机器学习(26)之K-Means实战与调优详解
- 机器学习实战ByMatlab(三)K-means算法
- 机器学习实战ByMatlab(四)二分K-means算法
- 机器学习实战ByMatlab(三)K-means算法
- 转载博客文章技巧
- 应用程序写Xml文档
- 慕课网c语言学习记录(递归,局部与全局,变量存储类别,内外部函数)
- Ubuntu环境下安装jdk1.8
- the diary of pipe in linux
- 机器学习实战之K-means
- Java基础之容器
- 二叉树--TreeSet数据结构
- nginx 405 not allowed问题的解决
- 在一个循环中break,continue和return有什么不同?
- 在应用程序中使用Xml文件
- 信息资源管理
- Socket长连接和短连接
- NYOJ--1058--dfs--部分和问题