俗话说"物以类聚,人以群分"算法
聚类(Clustering)是一种无监督学习(unsupervised learning),简单地说就是把类似的对象归到同一簇中。簇内的对象越类似,聚类的效果越好。bash
定义:给定一个有个对象的数据集,聚类将数据划分为个簇,并且这个划分知足两个条件:(1)每一个簇至少包含一个对象;(2)每一个对象属于且仅属于一个簇。网络
基本思想:对给定的,算法首先给出一个初始的划分方法,之后经过反复迭代的方法改变划分,使得每一次改进以后的划分方案都较前一次更好。机器学习
监督学习(supervised learning):是对具备概念标记(分类)的训练样本进行学习,以尽量对训练样本集外的数据进行标记(分类)预测。【神经网络和决策树】ide
无监督学习(unsupervised learning):是对没有概念标记(分类)的训练样本进行学习,以发现训练样本集中的结构性知识。【聚类】函数
K-均值(K-means)聚类算法学习
聚类分析(cluster analysis)试图将类似对象纳入同一簇,将不类似对象归到不一样簇。大数据
K-Means: K-均值聚类也称为快速聚类法,在最小化偏差函数的基础上将数据划分为预约的类数K。该算法原理简单并便于处理大量数据。优化
K-中心点:K-均值算法对孤立点的敏感性,K-中心点算法不采用簇中对象的平均值做为簇中心,而选用簇中离平均值最近的对象做为簇中心。google
系统聚类:也称为层次聚类,分类的单位由高到低呈树形结构,且所处的位置越低,其所包含的对象就越少,但这些对象间的共同特征越多。该聚类方法只适合在小数据量的时候使用,数据量大的时候速度会很是慢。
K-Means算法是最为经典的基于划分的聚簇方法,是十大经典数据挖掘算法之一。简单的说K-Means就是在没有任何监督信号的状况下将数据分为K份的一种方法。聚类算法就是无监督学习中最多见的一种,给定一组数据,须要聚类算法去挖掘数据中的隐含信息。聚类算法的应用很广:顾客行为聚类,google新闻聚类等。
K值是聚类结果中类别的数量。简单的说就是咱们但愿将数据划分的类别数
在数据集中根据必定策略选择K个点做为每一个簇的初始中心,而后观察剩余的数据,将数据划分到距离这K个点最近的簇中,也就是说将数据划分红K个簇完成一次划分,但造成的新簇并不必定是最好的划分,所以生成的新簇中,从新计算每一个簇的中心点,而后在从新进行划分,直到每次划分的结果保持不变。在实际应用中每每通过不少次迭代仍然达不到每次划分结果保持不变,甚至由于数据的关系,根本就达不到这个终止条件,实际应用中每每采用变通的方法设置一个最大迭代次数,当达到最大迭代次数时,终止计算。
具体的算法步骤以下:
K-means聚类能处理比层次聚类更大的数据集。另外,观测值不会永远被分到一类中,当咱们提升总体解决方案时,聚类方案也会改动。不过不一样于层次聚类的是,K-means会要求咱们事先肯定要提取的聚类个数
适用范围及缺陷
K-Menas算法试图找到使平方偏差准则函数最小的簇。当潜在的簇形状是凸面的,簇与簇之间区别较明显,且簇大小相近时,其聚类结果较理想。对于处理大数据集合,该算法很是高效,且伸缩性较好。
但该算法除了要事先肯定簇数K和对初始聚类中心敏感外,常常以局部最优结束,同时对“噪声”和孤立点敏感,而且该方法不适于发现非凸面形状的簇或大小差异很大的簇。
克服缺点的方法:使用尽可能多的数据;使用中位数代替均值来克服outlier的问题。
通常状况下,没有必要本身实现K-Means算法,有不少成熟的软件包实现了K-Means算法,R语言提供了kmeans方法进行聚类分析。
kmeans(x, centers, iter.max = 10, nstart = 1, algorithm = c("Hartigan-Wong", "Lloyd", "Forgy", "MacQueen"), trace=FALSE)
# centers为提取的聚类数目
进行K-Means划分时,首先要肯定划分簇数K,若是对数据有先验性认知可根据对数据的认知肯定K,在对数据没有先验性认知的状况下,一般经过数据可视化方法肯定K值。咱们以机器学习中经常使用的iris数据集为例演示如何进行K-Means聚类分析。首先使用主成分分析(PCA)等降维方法将数据将降维投影到二维平面上,经过人工观察肯定划分数。
library(ggplot2) library(ggfortify) #使用ggfortify包进行聚类结果的可视化展现 newiris <- iris; newiris$Species <- NULL; autoplot(prcomp(newiris))
经过上面的图形可清晰的看到,数据被划分红两部分,因此K至少大于2,尽管左右两边的数据被清晰的分开,但每部分数据是否还能够进一步划分红小聚簇呢,从图上看不出来。回顾一下K-Means的思想,每一个簇内间距尽量小,咱们尝试使用不一样划分数K进行K-Means聚类,看看不一样划分的簇内间距变化状况。
wss <- c(1:15) for(i in 1:15) wss[i] <- sum(kmeans(newiris,i)$withinss) plot(wss)
从图中可见,划分数在4-15之间,簇内间距变化很小,基本上是水平直线,所以能够选择K=4(拐点附近位置)做为划分数。聚类计算完成后,咱们使用mds方法观察一下聚类结果。
newiris <- iris; newiris$Species <- NULL; dist.e <- dist(newiris,method='euclidean') #计算各观测值之间的欧式距离
mds <- cmdscale(dist.e, k=2, eig=T) #cmdscale()
计算MDS,为可视化,取前两个主坐标
x <- mds$points[,1]
y <- mds$points[,2]
k <- kmeans(newiris, 4)
ggplot(data.frame(x,y), aes(x,y)) + geom_point(aes(colour = factor(k$cluster))) cmdscale()
从图中能够观察到,数据被清晰的划分为4个不一样的区域。
r语言中使用dist(x, method = "euclidean",diag = FALSE, upper = FALSE, p = 2) 来计算距离。其中x是样本矩阵或者数据框。method表示计算哪一种距离。method的取值有:
euclidean 欧几里德距离,就是平方再开方。
maximum 切比雪夫距离
manhattan 绝对值距离
canberra Lance 距离
minkowski 明科夫斯基距离,使用时要指定p值
binary 定性变量距离.
定性变量距离: 记m个项目里面的 0:0配对数为m0 ,1:1配对数为m1,不能配对数为m2,距离=m1/(m1+m2);
diag 为TRUE的时候给出对角线上的距离。upper为TURE的时候给出上三角矩阵上的值。
从上面的内容中,咱们知道K-Means经过数据间距远近来进行划分操做,对于数值型数据而言,很容易经过欧几里得距离计算数据间的距离,对于分类等类型的数据则没法经过欧几里得距离计算数据的距离。韩家炜教授所著的《数据挖掘 概念与技术》2.4 度量数据的类似性和相异性章节中给出了计算数据间距的具体方法,须要时可按照书中方法进行数据间距计算。
须要说明的是,R语言中的kmeans函数只能接受数值型数据,若是须要对分类等类型的数据进行聚类计算,只能本身实现K-Means算法了,先计算数据距离,而后在编写K-Means算法进行聚类计算。值得一提的是在R语言中使用edit(kmeans)能够查看kmeans方法的源代码,能够参照源代码实现定制的K-Means算法。
K值怎么定?我怎么知道应该几类?
答:这个真的没有肯定的作法,分几类主要取决于我的的经验与感受,一般的作法是多尝试几个K值,看分红几类的结果更好解释,更符合分析目的等。或者能够把各类K值算出的SSE作比较,取最小的SSE的K值。
初始的K个质心怎么选?
答:最经常使用的方法是随机选,初始质心的选取对最终聚类结果有影响,所以算法必定要多执行几回,哪一个结果更reasonable,就用哪一个结果。 固然也有一些优化的方法,第一种是选择彼此距离最远的点,具体来讲就是先选第一个点,而后选离第一个点最远的当第二个点,而后选第三个点,第三个点到第1、第二两点的距离之和最小,以此类推。第二种是先根据其余聚类算法(如层次聚类)获得聚类结果,从结果中每一个分类选一个点。
K-Means会不会陷入一直选质心的过程,永远停不下来?
答:不会,有数学证实K-Means必定会收敛,大体思路是利用SSE的概念(也就是偏差平方和),即每一个点到自身所归属质心的距离的平方和,这个平方和是一个函数,而后可以证实这个函数是能够最终收敛的函数。
判断每一个点归属哪一个质心的距离怎么算?
答:这个问题必须不得不提一下数学了……
第一种,欧几里德距离(欧几里德这位爷仍是很厉害的,《几何本来》被称为古希腊数学的高峰,就是用5个公理推导出了整个平面几何的结论),这个距离就是平时咱们理解的距离,若是是两个平面上的点,也就是(X1,Y1),和(X2,Y2),那这俩点距离是多少初中生都会,就是√( (x1-x2)^2+(y1-y2)^2) ,若是是三维空间中呢?√( (x1-x2)^2+(y1-y2)^2+(z1-z2)^2 ;推广到高维空间公式就以此类推。能够看出,欧几里德距离真的是数学加减乘除算出来的距离,所以这就是只能用于连续型变量的缘由。
第二种,余弦类似度,余弦类似度用向量空间中两个向量夹角的余弦值做为衡量两个个体间差别的大小。相比距离度量,余弦类似度更加注重两个向量在方向上的差别,而非距离或长度上。下图表示余弦类似度的余弦是哪一个角的余弦,A,B是三维空间中的两个向量,这两个点与三维空间原点连线造成的角,若是角度越小,说明这两个向量在方向上越接近,在聚类时就归成一类:
看一个例子(也许不太恰当):歌手大赛,三个评委给三个歌手打分,第一个评委的打分(10,8,9) 第二个评委的打分(4,3,2),第三个评委的打分(8,9,10)
若是采用余弦类似度来看每一个评委的差别,虽然每一个评委对同一个选手的评分不同,但第1、第二两个评委对这四位歌手实力的排序是同样的,只是第二个评委对满分有更高的评判标准,说明第1、第二个评委对音乐的品味上是一致的。
所以,用余弦类似度来看,第1、第二个评委为一类人,第三个评委为另一类。
若是采用欧氏距离, 第一和第三个评委的欧氏距离更近,就分红一类人了,但其实不太合理,由于他们对于四位选手的排名都是彻底颠倒的。
总之,若是注重数值自己的差别,就应该用欧氏距离,若是注重的是上例中的这种的差别(我归纳不出来究竟是一种什么差别……),就要用余弦类似度来计算。
还有其余的一些计算距离的方法,可是都是欧氏距离和余弦类似度的衍生,简单罗列以下:明可夫斯基距离、切比雪夫距离、曼哈顿距离、马哈拉诺比斯距离、调整后的余弦类似度、Jaccard类似系数……
还有一个重要的问题是,你们的单位要一致!
好比X的单位是米,Y也是米,那么距离算出来的单位仍是米,是有意义的
可是若是X是米,Y是吨,用距离公式计算就会出现“米的平方”加上“吨的平方”再开平方,最后算出的东西没有数学意义,这就有问题了。
还有,即便X和Y单位一致,可是若是数据中X总体都比较小,好比都是1到10之间的数,Y很大,好比都是1000以上的数,那么,在计算距离的时候Y起到的做用就比X大不少,X对于距离的影响几乎能够忽略,这也有问题。
所以,若是K-Means聚类中选择欧几里德距离计算距离,数据集又出现了上面所述的状况,就必定要进行数据的标准化(normalization),即将数据按比例缩放,使之落入一个小的特定区间。去除数据的单位限制,将其转化为无量纲的纯数值,便于不一样单位或量级的指标可以进行计算和比较。
标准化方法最经常使用的有两种:
每一轮迭代如何选出新的质心?
答:各个维度的算术平均,好比(X1,Y1,Z1)、(X2,Y2,Z2)、(X3,Y3,Z3),那就新质心就是【(X1+X2+X3)/3,(Y1+Y2+Y3)/3,(Z1,Z2,Z3)/3】,这里要注意,新质心不必定是实际的一个数据点。
关于离群值?
答:离群值就是远离总体的,很是异常、很是特殊的数据点,在聚类以前应该将这些“极大”“极小”之类的离群数据都去掉,不然会对于聚类的结果有影响。可是,离群值每每自身就颇有分析的价值,能够把离群值单独做为一类来分析。
用SPSS做出的K-Means聚类结果,包含ANOVA(单因素方差分析),是什么意思?
答:答简单说就是判断用于聚类的变量是否对于聚类结果有贡献,方差分析检验结果越显著的变量,说明对聚类结果越有影响。对于不显著的变量,能够考虑从模型中剔除。
参考:https://my.oschina.net/polaris16/blog/801889
http://blog.csdn.net/yucan1001/article/details/23123043
http://www.jianshu.com/p/fc91fed8c77b