基于R语言的Kmeans聚类算法
题记:本文是个人的读书笔记,仅用于学习交流使用。
01
解决什么问题
本节介绍一下Kmeans聚类,也叫K均值聚类或者是动态聚类法。k-means算法也属于无监督学习的一种聚类算法。采用R语言详细描述Kmeans实现过程。
这种聚类方法的优势在于,对于大样本的聚类,具有计算量小,占用计算机内存较少和方法简单的优点。
02
算法思想
4.重复以上2~3步,直到类心的位置不再发生变化或者达到设定的迭代次数。
其中第三步是:类心的计算公式如下,其中表示第k类,表示第k类中数据对象的个数:
下面我们通过一个具体的例子来理解这个算法,假设我们首先拿到了这样一个数据,要把它分成两类:
2.首先我们随机选取样本中任意两个点作为聚类中心。根据选取的两点,通过第一次迭代,将图中黑色的点归为一类,蓝色的点归为另一类。
3.根据第一次迭代将生成的两类数据,分别求出每个簇的类心。相当于原理第三步。并再次计算每个点与新的类心距离,将点分到最近的类心。
由图可以看到经过第二次迭代,数据正确分成2簇。
采用R代码将上述算法原理详细实现一遍,更多采用python写,清楚了原理,用哪种语言写,都是很随意的。当然R里面有封装的好的Kmeans函数,一句代码就做完所有的事,但还是建议大家,自己写一遍算法,有助于理解。
### Kmeans 均值聚类#为给定数据集构建一个包含K个随机质心的集合randcent <- function(dt,k){centroids <- as.data.frame(matrix(0,nrow = k,ncol=ncol(dt)))colnames(centroids) <- colnames(dt)for(i in 1:k){index <- sample(1:nrow(dt),1,replace =T)centroids[i,] <- dt[index,]}return(centroids)}
建立一个对象,存放样本点所属簇和每个样本点与类心的距离。
clusterAssment = data.frame(class = rep(0,nrow(dt)),error = rep(0,nrow(dt)))
编写Kmeans算法:
kmeans_fit <- function(dt,k){clusterAssment = data.frame(class = rep(0,nrow(dt)),error = rep(0,nrow(dt)))clusterChange = T# 第1步 初始化centroidscentroids = randcent(dt,k=2)step=1while(clusterChange){clusterChange = F# 遍历所有的样本(行数)in 1:nrow(dt)){minDist = 100000.0= -1# 遍历所有的质心#第2步 找出最近的质心in 1:k){dt_ <- rbind(dt[i,],centroids[j,])d <- dist(dt_)< minDist){minDist <- d;j}}# 第 3 步:更新每一行样本所属的簇= minIndex){clusterChange = T<- minIndex<- minDist}}#第 4 步:更新质心in 1:k){loc <- which(clusterAssment[,1]==i)pointsIncluster <- dt[loc,] # 获取簇类所有的点<- apply(pointsIncluster,2,mean) ##对数据集的列就均值}step=step+1 ##观察迭代次数print(step)}complete!")re <- list(centroids=centroids,clusterAssment=clusterAssment)return(re)}
运行这个简易的算法模型
dt <- data.frame(x1 = c(5,6,4.5,0.5,2,-3,-2.5,-2,0,-4,3,-1),x2=c(5,2,2,2.1,1,0,-1,-2,-4,-3.5,3,-1.75))re <- kmeans_fit(dt,2)###查看运行完的结果re$centroids;re$clusterAssment ## 可查看所属簇和类心library(ggplot2)qplot(dt$x1,dt$x2,color=clusterAssment$class) ###画图
04
案例实战
library(HDclassif) #contains the dataset ##葡萄酒数据集data(wine)names(wine) <- c("Class", "Alcohol", "MalicAcid", "Ash","Alk_ash", "magnesium", "T_phenols", "Flavanoids", "Non_flav","Proantho", "C_Intensity", "Hue", "OD280_315", "Proline")df <- as.data.frame(scale(wine[, -1]))re <- kmeans_fit(df,3)table(re$clusterAssment[,1],wine$Class) ###匹配度达95%
05
Kmeans()函数详解
kmeans(x, centers, iter.max = 10, nstart = 1,algorithm = c("Hartigan-Wong", "Lloyd","Forgy", "MacQueen"))
1.待聚类样本组织在x指定的矩阵或数据框中。
2.参数centers:若为一个整数,则表示聚类数目K;若为一个矩阵(行数等于聚类数目K,列数等于聚类变量个数),则表示初始类质心,每一行表示一个初始类质心。
3.参数iter.max用于指定最大迭代次数,默认为10次。R中仅以最大迭代次数作为终止迭代条件。
4.当参数为centers为一个整数时,R将采用随机选择法从数据中抽取K个观测值作为初始类质心。我们,不同的初始类质心对最终的聚类结果是存在影响的。所以,R为克服大数据集下终止迭代次数不充分大时,初始类质心抽取的随机性对聚类结果的影响,可指定参数nstar为一个大于1的值(默认为1),表示重复多次抽取质心。
5.参数algorithm,用于指定迭代算法,其中"Lloyd"是经典的算法,就是上面自己编写代码的实现过程,但这种算法针对不平衡数据效果不太好,而"Hartigan-Wong"则是改进的针对不平衡数据的算法,作为默认算法。每一种算法的实现过程,有兴趣的朋友可以参看参考文献3。
Kmeans函数的返回结果是一个列表,包括如下成分:
1.cluster:存储各观测所属的类别编号,也称聚类解。
2.centers:存储各个类的最终类质心。
3.totss:所有聚类变量的离差平方和之和,是对类内部观测数据点离散程度的测度。
6.size:各类的样本量。
Kmeans聚类
现在选择3个簇进行Kmeans聚类,现在计算距离矩阵,并建立层次聚类模型。如下所示:
set.seed(1234) ##设定随机数种子km <- kmeans(scale(df), 3, nstart = 25) #设置随机分配的参数nstart
对比K均值聚类结果和品种等级:
cluster, wine$Class)
这个表中,聚类结果匹配了96%的品种等级。与层次聚类的ward.D2相比,这两种方法效果相似,因此可以将任意一种作为最优的聚类方法。
06
总结
参考文献
薛毅等.统计建模与R软件.清华大学出版社
Cory Leismester.精通机器学习.基于R.人民邮电出版社
https://blog.csdn.net/joeland209/article/details/72147763
作介绍:医疗大数据统计分析师,擅长R语言。
欢迎各位在后台留言,恳请斧正!
更多阅读
长按二维码
易学统计
