接下来就要说下无监督机器学习方法,所谓无监督机器学习前面也说过,就是没有标签的情况,对样本数据进行聚类分析、关联性分析等。主要包括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. Java was started but returned exit code=13

    安装Eclipse(32位)后打开报错:Java was started but returned exit code=13 解决方法: 1,首先我查看了我当前安装的JDK版本,发现是64位的: 2, ...

  2. Linux中判断大小端的一种方法

    大小端的定义无需赘言,常用的方法有使用联合体和指针法,如: int checkCPU() { union w { int a; char b; }c; c.a = 1; return (c.b == ...

  3. Unity中的各种寻找GameObject方法

    1.GameObject.Find():寻找Hierarchy面板中的activie 不为false的游戏对象: 路径如官方事例写法: public class ExampleClass : Mono ...

  4. 专门讲讲这个MYSQL授权当中的with grant option的作用

    对象的owner将权限赋予某个用户(如:testuser1) grant select ,update on bd_corp to testuser1 [with grant option ]1.如果 ...

  5. LED限流电阻的大小计算

    很多时候电路中都用LED做指示,这就涉及到限流电阻,这个怎么选取呢? 可以举个例子,贴片蓝色LED datasheet上参数如下 要注意理解LED Datasheet上的参数.最重要的三个参数如下: ...

  6. reg51.h 详解

    /* BYTE Register */ sfr P0 = 0x80; //P0口 sfr P1 = 0x90; //P1口 sfr P2 = 0xA0; //P2口 sfr P3 = 0xB0; // ...

  7. MongoDB开发学习(1)开天辟地,经典入门

    原文地址:http://www.cnblogs.com/xumingxiang/archive/2012/04/08/2437468.html 如果你从来没有接触MongoDB或对MongoDB有一点 ...

  8. HDU_2039——判断三条边是否能组成三角形

    Problem Description 给定三条边,请你判断一下能不能组成一个三角形.   Input 输入数据第一行包含一个数M,接下有M行,每行一个实例,包含三个正数A,B,C.其中A,B,C & ...

  9. [转]10款 Web 开发常备工具

    文章地址:https://my.oschina.net/u/2903254/blog/798135 工欲善其事,必先利其器.如今 Web 开发标准越来越高,Web 开发者也在不断寻找途径提升自己的技能 ...

  10. hdu5136:组合计数、dp

    题目大意: 求直径长度为N的无根二叉树的个数(同构的只算一种) 分析: 分析发现直径长度不好处理!因此考虑把问题转化一下: 假设要求直径为N的二叉树 (1) 若N为偶数,将树从直径中点的边断开,则分成 ...