接下来就要说下无监督机器学习方法,所谓无监督机器学习前面也说过,就是没有标签的情况,对样本数据进行聚类分析、关联性分析等。主要包括K均值聚类(K-means clustering)和关联分析,这两大类都可以说的很简单也可以说的很复杂,学术的东西本身就一直在更新着。比如K均值聚类可以扩展一下形成层次聚类(Hierarchical Clustering),也可以进入概率分布的空间进行聚类,就像前段时间很火的LDA聚类,虽然最近深度玻尔兹曼机(DBM)打败了它,但它也是自然语言处理领域(NLP:Natural Language Processing)的一个有力工具,有过辉煌的一段故事。而关联性分析又是另外一个比较有力的工具,它又称购物篮分析,我们可以大概可以体会到它的用途,挖掘目标之间的关联性,经典的故事就是啤酒和尿布的关联。另外多说一下,google最近的两大核心技术:深度学习和知识图,深度学习就不说了,而知识图就是挖掘关系的。找到了关系就找到了金矿,关系也可以用复杂网络(complex network)来建模。这些话题就打住吧,今天就来说下K均值聚类和二分K均值聚类。

K均值聚类比较简单,再说原理之前,先来看个样本图,如(图一)所示:

(图一)

假如(图一)中是我们的样本数据,每个样本都没有类别,我们想对他们简单的划下类,在(图一)中明显的有四“堆”数据,我们用什么方法能把他们分成四类呢?K均值聚类就是解决这种问题的(好腻 = =!),K均值聚类的原理如下:

随机的分配K个质心(上图中K为4)

如果样本中任意一个数据点归属的簇号(堆类别)发生改变

遍历每一个样本点

遍历每一个质心

计算数据点到质心的距离

把数据点分配到距其最近的簇

对每一个簇,重新计算簇中所有样本点的均值作为质心

K均值简单的一句话总结就是:更新质心,更新每个样本的所属的类别。按照上述更新规则,当没有样本的簇号发生改变了,迭代也就终止咯。下面就来看看代码吧:

from numpy import *

def loadDataSet(fileName):      #general function to parse tab -delimited floats
dataMat = [] #assume last column is target value
fr = open(fileName)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = map(float,curLine) #map all elements to float()
dataMat.append(fltLine)
return dataMat def distEclud(vecA, vecB):
return sqrt(sum(power(vecA - vecB, 2))) #la.norm(vecA-vecB) def randCent(dataSet, k):
n = shape(dataSet)[1]
centroids = mat(zeros((k,n)))#create centroid mat
for j in range(n):#create random cluster centers, within bounds of each dimension
minJ = min(dataSet[:,j])
rangeJ = float(max(dataSet[:,j]) - minJ)
centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))
return centroids def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0]
clusterAssment = mat(zeros((m,2)))#create mat to assign data points
#to a centroid, also holds SE of each point
centroids = createCent(dataSet, k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m):#for each data point assign it to the closest centroid
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):#recalculate centroids
ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get all the point in this cluster
centroids[cent,:] = mean(ptsInClust, axis=0) #assign centroid to mean
return centroids, clusterAssment

代码也很简单,其中函数loadDataSet用来加载数据集,函数distEclud用来计算两个样本的距离,函数randCent为样本随机的分配K个质心(centroid),另外注意一下样本的质心维度和样本维度是一样的,这个应该没有异议,高维空间中的坐标,最后函数kMeans则是k均值聚类算法的核心步骤,和原理都是一一对应的。下面是运行结果:

(图二)

从(图二)可以看出质心的更新,不过按照k-means的聚类规则很容易陷入局部最小,陷入局部最小说简单的就是随机初始的质心分布的不是太好,最后迭代终止后,两个质心有可能在同一堆数据上,而另外一个质心成了另外两堆离的近样本的唯一质心(如下面图三所示)。说的复杂一些就是马尔科夫岁机场中配置的代价函数不是好的目标函数(虽然这里没写出这个函数)。为了解决这个问题,有人提出了二分K均值聚类算法,该算法也比较简单,首先把所有样本作为一个簇,然后二分该簇,接着选择其中一个簇进行继续进行二分。选择哪一个簇二分的原则就是能否使得误差平方和(SSE: Sum of Squared Error)进可能的小。也就是说该算法有了个好的目标函数,SSE的计算其实就是距离和。下面来看看二分K均值聚类算法的代码:

def biKmeans(dataSet, k, distMeas=distEclud):
m = shape(dataSet)[0]
clusterAssment = mat(zeros((m,2)))
centroid0 = mean(dataSet, axis=0).tolist()[0]
centList =[centroid0] #create a list with one centroid
for j in range(m):#calc initial Error
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],:]#get the data points currently in cluster i
centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas)
sseSplit = sum(splitClustAss[:,1])#compare the SSE to the currrent minimum
sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1])
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) #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[bestCentToSplit] = bestNewCents[0,:].tolist()[0]#replace a centroid with two best centroids
centList.append(bestNewCents[1,:].tolist()[0])
clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss#reassign new clusters, and SSE
return mat(centList), clusterAssment

这个算法比K均值聚类算法效果好一些,比如(图三)是K均值算法在随机初始化不好的情况下聚类的效果示意图:

(图三)

而用二分K均值聚类跑出的效果图如(图四)所示:

(图四)

到此为止,关于K均值的聚类算法也就说完了,虽然有二分K均值聚类算法改进了K均值聚类算法的不足,但也不是没缺点,它们的共同的缺点就是必须事先确定K的值,现实中的数据我们有可能不知道K的值,如何确定K的值也是学术界一直在研究的问题,现在常用的解决办法是用层次聚类(Hierarchical Clustering),或者借鉴下LDA中的话题聚类分析。最后多说一句:谱聚类也是图像中的一个大成员,用途很广,典型的就是图像分割。

转载请注明来源:http://blog.csdn.net/marvin521/article/details/9674075

参考文献:

[1] machine learning in action.Peter Harrington

[2] SpectralMatting.Anat Levin

机器学习理论与实战(十)K均值聚类和二分K均值聚类的更多相关文章

  1. 机器学习实战5:k-means聚类:二分k均值聚类+地理位置聚簇实例

    k-均值聚类是非监督学习的一种,输入必须指定聚簇中心个数k.k均值是基于相似度的聚类,为没有标签的一簇实例分为一类. 一 经典的k-均值聚类 思路: 1 随机创建k个质心(k必须指定,二维的很容易确定 ...

  2. 机器学习理论与实战(十一)关联规则分析Apriori

    <机器学习实战>的最后的两个算法对我来说有点陌生,但学过后感觉蛮好玩,了解了一般的商品数据关联分析和搜索引擎智能提示的工作原理.先来看看关联分析(association analysis) ...

  3. spark Bisecting k-means(二分K均值算法)

    Bisecting k-means(二分K均值算法) 二分k均值(bisecting k-means)是一种层次聚类方法,算法的主要思想是:首先将所有点作为一个簇,然后将该簇一分为二.之后选择能最大程 ...

  4. 机器学习算法与Python实践之(六)二分k均值聚类

    http://blog.csdn.net/zouxy09/article/details/17590137 机器学习算法与Python实践之(六)二分k均值聚类 zouxy09@qq.com http ...

  5. 机器学习理论提升方法AdaBoost算法第一卷

    AdaBoost算法内容来自<统计学习与方法>李航,<机器学习>周志华,以及<机器学习实战>Peter HarringTon,相互学习,不足之处请大家多多指教! 提 ...

  6. Bisecting KMeans (二分K均值)算法讲解及实现

    算法原理 由于传统的KMeans算法的聚类结果易受到初始聚类中心点选择的影响,因此在传统的KMeans算法的基础上进行算法改进,对初始中心点选取比较严格,各中心点的距离较远,这就避免了初始聚类中心会选 ...

  7. 【十大经典数据挖掘算法】k

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 引言 k-means与kNN虽 ...

  8. 应用程序框架实战十五:DDD分层架构之领域实体(验证篇)

    在应用程序框架实战十四:DDD分层架构之领域实体(基础篇)一文中,我介绍了领域实体的基础,包括标识.相等性比较.输出实体状态等.本文将介绍领域实体的一个核心内容——验证,它是应用程序健壮性的基石.为了 ...

  9. R语言中聚类确定最佳K值之Calinsky criterion

    Calinski-Harabasz准则有时称为方差比准则 (VRC),它可以用来确定聚类的最佳K值.Calinski Harabasz 指数定义为: 其中,K是聚类数,N是样本数,SSB是组与组之间的 ...

随机推荐

  1. 利用shell脚本函数实现网络连通性的检测

    通常情况下,linux系统网络连通性的检测有两种方法: 1.通过“ping指令 + 目标IP” 或者 “ping指令 + 目标IP域名” 注意针对IPv6地址的IP网络检测需要试用ping6,同时pi ...

  2. UCOS 请求任务删除函数 及其应用

    有时候,如果任务A拥有内存缓冲区或信号量之类的资源,而任务B想删除该任务,这些资源就可能由于没被释放而丢失.在这种情况下,用户可以想法子让拥有这些资源的任务在使用完资源后,先释放资源,再删除自己.用户 ...

  3. ASP.NET Email + WebConfig

    这里演示如果把 Email provider 的资料写在 WebConfig 里和调用它. 如果整个项目只需要使用一个 Email, 可以写入system.net里, 微软已经帮我们设计好了 < ...

  4. Entity Framewor 学习笔记 (Enum)

    EF 6 支持Enum 的处理 首先说一下 mysql 和 sql server 的区别 mysql 是有 Enum 这个类型的 , insert 时是放入 int , 出来的时候它会是 string ...

  5. Qt之QTableView显示富文本(使用了QAbstractTextDocumentLayout和QTextDocument)

    http://blog.csdn.net/liang19890820/article/details/50973099

  6. mongodb sort limit和skip用法

    > db.mediaCollection.find().skip().toArray() [ { "_id" : ObjectId("5353463193efef0 ...

  7. 如何在Windows服务程序中读写HKEY_CURRENT_USER注册表

    在服务程序中想要对注册表HKEY_CURRENT_USER下的内容进行读写,不会返回失败,但是始终无效.原因是: 1.服务运行在系统权限之下,而不是任何一个用户 2.HKEY_CURRENT_USER ...

  8. [LeetCode] 45. Jump Game II 解题思路

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  9. hdu-3790最短路径问题

    Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的.   Inp ...

  10. A - Network of Schools - poj 1236(求连通分量)

    题意:学校有一些单向网络,现在需要传一些文件,1,求最少需要向几个学校分发文件才能让每个学校都收到,2,需要添加几条网络才能在任意一个学校分发都可以传遍所有学校. 分析:首先应该求出来连通分量,进行缩 ...