一、 实验目的:
- 了解Kmeans算法基本原理;
- 编写代码并实现Kmeans算法对数据的聚簇
二、 实验软件
Rstudio
三、 实验内容
(1)K-Means算法
K-Means算法是最为经典的基于划分的聚簇方法,是十大经典数据挖掘算法之一。简单的说K-Means就是在没有任何监督信号的情况下将数据分为K份的一种方法。聚类算法就是无监督学习中最常见的一种,给定一组数据,需要聚类算法去挖掘数据中的隐含信息。
K值是聚类结果中类别的数量。简单的说就是我们希望将数据划分的类别数
(2)K-Means算法基本思想
在数据集中根据一定策略选择K个点作为每个簇的初始中心,然后观察剩余的数据,将数据划分到距离这K个点最近的簇中,也就是说将数据划分成K个簇完成一次划分,但形成的新簇并不一定是最好的划分,因此生成的新簇中,重新计算每个簇的中心点,然后在重新进行划分,直到每次划分的结果保持不变。在实际应用中往往经过很多次迭代仍然达不到每次划分结果保持不变,甚至因为数据的关系,根本就达不到这个终止条件,实际应用中往往采用变通的方法设置一个最大迭代次数,当达到最大迭代次数时,终止计算。
四、 实验步骤
1、在总体中随机选择k个值作为初始质心。
2、计算每个样本点到每个质心的距离(欧式距离),将每个点指派到最近的质心点,形成K个聚类。
3、重新这个簇的样本点的平均值,作为簇的新质心。
4、重复2-3直至质心不再发生变化,或者只发生很微小的变化。
五、 实验代码
#Kmeans主函数
Kmeans = function(dataset,k){
#计算两点之间欧式距离的函数
Eudist<-function(x,y){
distance<-sqrt(sum((x-y)^2))
return (distance)
}
rows<-nrow(dataset) #行数
changed=TRUE #判断循环
firstPoint<-dataset[sample.int(rows,size = k),] #在总体中随机选择k个值作为初始质心。
tempPoint<-firstPoint #中转质心
newPoint<-matrix(0,nrow = k,ncol = ncol(dataset)) #更新的质心
#记录每一个点到每一个类的距离
disMatrix<-matrix(0,nrow=rows,ncol=k)
while(changed){
#记录每个点所属的类是哪一个
cluster<-matrix(0,nrow=rows,ncol=k)
for(i in 1:rows){
#计算每个点到初始中心点的距离
for(j in 1:k){
disMatrix[i,j] <- Eudist(dataset[i,],tempPoint[j,])
}
}
#将每一个点所属的类计算出来
for(i in 1:rows){
cluster[i,which.min(disMatrix[i,])] <- 1 #which.min(x)是确定最小值(最小距离)的位置(索引)
}
#更新质心
for(i in 1:k){
newPoint[i,]<-apply(dataset[which(cluster[,i] == 1),] ,2,"mean")
}
#apply(x,1,Fun) 1表示按行计算,2表示按列计算
#判断中心点是否已经保持不变
judge<-c()
for(i in 1:k){
if(all(tempPoint[i,] == newPoint[i,]) == T){
judge[i]<-TRUE
}
}
#中心点改变则质心更新
tempPoint = newPoint
changed=ifelse(all(judge) == T,F,T) #judge的所有值为T时,changed = F,不再循环;否则为T,继续循环
}
colnames(newPoint) <- colnames(dataset)
result=list()
result[["centers"]]<-newPoint #质心
result[["distance"]]<-disMatrix #距离
result[["cluster"]]<-rep(1,rows) #簇
for(i in 1:rows){
result[["cluster"]][i]<-which