聚类分析 ---- K-Means算法

#K-Means算法# K-Means算法是最为经典的基于划分的聚簇方法,是十大经典数据挖掘算法之一。简单的说K-Means就是在没有任何监督信号的情况下将数据分为K份的一种方法。

##一、K-Means算法基本思想## 在数据集中根据一定策略选择K个点作为每个簇的初始中心,然后观察剩余的数据,将数据划分到距离这K个点最近的簇中,也就是说将数据划分成K个簇完成一次划分,但形成的新簇并不一定是最好的划分,因此生成的新簇中,重新计算每个簇的中心点,然后在重新进行划分,直到每次划分的结果保持不变。在实际应用中往往经过很多次迭代仍然达不到每次划分结果保持不变,甚至因为数据的关系,根本就达不到这个终止条件,实际应用中往往采用变通的方法设置一个最大迭代次数,当达到最大迭代次数时,终止计算。

##二、算法实现## 输入:k, data[n];
(1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 对于data[0]….data[n], 分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i;
(3) 对于所有标记为i点,重新计算c[i]={ 所有标记为i的data[j]之和}/标记为i的个数;
(4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值。

##三、K-Means R语言实战## 一般情况下,没有必要自己实现K-Means算法,有很多成熟的软件包实现了K-Means算法,R语言提供了kmeans方法进行聚类分析。

kmeans(x, centers, iter.max = 10, nstart = 1, algorithm = c("Hartigan-Wong", "Lloyd", "Forgy", "MacQueen"), trace=FALSE)

进行K-Means划分时,首先要确定划分簇数K,如果对数据有先验性认知可根据对数据的认知确定K,在对数据没有先验性认知的情况下,通常通过数据可视化方法确定K值。我们以机器学习中常用的iris数据集为例演示如何进行K-Means聚类分析。首先使用主成分分析(PCA)等降维方法将数据将降维投影到二维平面上,通过人工观察确定划分数。

library(ggplot2)
library(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)
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)))

从图中可以观察到,数据被清晰的划分为4个不同的区域。

##四、更进一步## 从上面的内容中,我们知道K-Means通过数据间距远近来进行划分操作,对于数值型数据而言,很容易通过欧几里得距离计算数据间的距离,对于分类等类型的数据则无法通过欧几里得距离计算数据的距离。韩家炜教授所著的《数据挖掘 概念与技术》2.4 度量数据的相似性和相异性章节中给出了计算数据间距的具体方法,需要时可按照书中方法进行数据间距计算。

需要说明的是,R语言中的kmeans函数只能接受数值型数据,如果需要对分类等类型的数据进行聚类计算,只能自己实现K-Means算法了,先计算数据距离,然后在编写K-Means算法进行聚类计算。值得一提的是在R语言中使用edit(kmeans)可以查看kmeans方法的源代码,可以参照源代码实现定制的K-Means算法。

转载于:https://my.oschina.net/polaris16/blog/801889

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值