《机器学习实战》代码片段学习6 k均值聚类与二分k均值聚类
2017-09-11 09:23
501 查看
概述:
本章开始进入无监督学习的内容。聚类方法将相似的对象分到同一个簇中。簇识别:“簇识别给出聚类结果的含义。假定有一些数据,现在将相似数据归到一起,簇识别会告诉我们这些簇到底都是些什么。聚类与分类的最大不同在于,分类的目标事先已知,而聚类则不一样。因为其产生的结果与分类相同,而只是类别没有预先定义,聚类有时也被称为无监督分类(unsupervised classification)。”
K均值聚类:“k均值是发现给定数据集的k个簇的算法。簇个数k是用户给定的,每一个簇通过其质心(centroid),即簇中所有点的中心来描述。”
优缺点:
优点:容易实现。
缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢。
适用数据类型:数值型数据。
二分k均值算法:
使用SSE(误差平方和)来评估聚类效果。首先将所有的点视为一个簇,然后将簇一分为二,选择其中一个簇继续划分,选择簇的标准为对其进行划分能否在最大程度上降低SSE的值。如此重复下去,直到簇的数目达到用户指定的数目为止。
另一种做法是选择SSE最大的组进行划分,直到簇的数目达到用户指定的数目为止。示例代码实现的是第二种做法。
代码学习:
K均值聚类伪代码:创建k个点作为起始质心(经常是随机选择) 当任意一个点的簇分配结果发生改变时 对数据集中的每个数据点 对每个质心 计算质心与数据点之间的距离 将数据点分配到距其最近的簇 对每一个簇,计算簇中所有点的均值并将均值作为质心
加载数据函数:
def loadDataSet(fileName): dataMat = [] fr = open(fileName) for line in fr.readlines(): curLine = line.strip().split('\t') #map()此处意为用float()作用于curLine每一个元素 fltLine = map(float,curLine) #map all elements to float() dataMat.append(fltLine) return dataMat #计算两个向量的欧氏距离 def distEclud(vecA, vecB): #power()此处意为对(vecA-vecB)的每个值求2次方 return sqrt(sum(power(vecA - vecB, 2))) #构建包含随机k个质心的集合,参数k为包含随机质心的个数 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) #random.rand()生成k*1个在(0,1)之间的数 centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1)) return centroids
k均值算法
#输入参数dataSet数据集,k簇的数目,distMeas距离计算函数可选,createCent创建初始质心函数可选 def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent): m = shape(dataSet)[0] #clusterAssment用于记录每条数据所属簇的索引与到其的距离的平方 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): #获取被分配到该簇中的所有点,nonzero()返回不为0的值的索引,.A将矩阵转为数组 ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]] #mean()返回平均值,更新簇的质心 centroids[cent,:] = mean(ptsInClust, axis=0) return centroids, clusterAssment
二分k均值聚类算法:
伪代码:
将所有点看成一个簇 当簇数目小于k时 对于每一个簇 计算总误差 在给定的簇上面进行K均值聚类(K=2) 计算将该簇一分为二之后的总误差 选择使得误差最小的那个簇进行划分操作
以下二分k均值聚类算法是以每次SSE最大的簇进行划分,直到达到用户给定的划分次数k的算法:
#输入参数dataSet数据集,k最大划分的簇个数,distMeans距离计算函数可选 def biKmeans(dataSet, k, distMeas=distEclud): m = shape(dataSet)[0] clusterAssment = mat(zeros((m,2))) #用matrix.mean求每一列特征的平均值,用ndarray.tolist将数组转为列表 centroid0 = mean(dataSet, axis=0).tolist()[0] centList =[centroid0] #新建记录簇情况的列表 for j in range(m): clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2 while (len(centList) < k): lowestSSE = inf for i in range(len(centList)): #获取在当前簇里的点 ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:] #以kMeans(,2,)进行二分划分,返回两个新的质心与点到质心误差 centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas) sseSplit = sum(splitClustAss[:,1]) #划分后的sse sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1]) ##划分前的sse print "sseSplit, and notSplit: ",sseSplit,sseNotSplit if (sseSplit + sseNotSplit) < lowestSSE: bestCentToSplit = i bestNewCents = centroidMat bestClustAss = splitClustAss.copy() lowestSSE = sseSplit + sseNotSplit #更新簇的划分结果 bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList) bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit print 'the bestCentToSplit is: ',bestCentToSplit print 'the len of bestClustAss is: ', len(bestClustAss) #将一个簇以决定划分的两个新簇代替 centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0] centList.append(bestNewCents[1,:].tolist()[0]) #再分配新簇与sse clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss return mat(centList), clusterAssment
小结
同为无监督的学习方法,,二分k均值聚类算法作为k均值聚类算法的改进,克服了k均值聚类算法诸如结果易受初始选择质心的影响的缺点,聚类效果也好于后者。除了k均值聚类算法,另外被称为层次聚类的算法也被广泛使用。相关文章推荐
- 《机器学习实战》学习笔记-[14]-无监督学习-利用二分K-均值聚类对未标注数据分组
- 《机器学习实战》代码片段学习3 朴素贝叶斯
- 《机器学习实战》代码片段学习2 决策树
- 《机器学习实战》学习笔记-[13]-无监督学习-利用K-均值聚类对未标注数据分组
- 《机器学习实战》代码片段学习1 k-近邻算法
- 《机器学习实战》代码片段学习4 Logistic回归
- 《机器学习实战》代码片段学习5 AdaBoost元算法
- [置顶] 【二分-kMeans算法】二分K均值聚类分析与Python代码实现
- 《机器学习实战》二分-kMeans算法(二分K均值聚类)
- 机器学习小组知识点35:二分K-means聚类
- 数据挖掘学习笔记1——系统聚类与K-均值聚类
- 【OpenCV学习】Kmean均值聚类对图片进行减色处理
- 【JQuery学习总结1 】 一些实用的JQuery代码片段收集(筛选,搜索,样式,清除默认值,多选等)
- java学习_有趣代码片段(一)
- java例题学习:简单的继承代码小片段
- 机器学习算法与Python实践之(六)二分k均值聚类
- 常用js/jquery代码片段(学习更新)
- k-means k均值聚类 及二分k均值聚类
- 【OpenCV学习】Kmean均值聚类对图片进行减色处理
- Jquery学习总结(4)——高效Web开发的10个jQuery代码片段