Kmeans算法是机器学习里面用的相当多的一种聚类算法,属于半监督学习的范畴,如果你对数据科学很熟悉的话,R和Python都有相应的封装函数,这篇文章带你从R自带函数中解脱出来,进一步探索kmeans算法的内部并用R原生代码进行实现!
Kmeans算法分为如下几个步骤:
1.确定中心点的数量k,随即从数据中选取k个数据
2.计算数据点到每个中心点的距离(一般为欧式距离),确定每个点归类到最近点的类当中
去
3.每一个类的数据均值作为新的中心质心,再次计算数据到中心点的位置
4.循环2,3步骤,直到中心点坐标不再变化或者变化很小
R语言的自带函数为kmeans(),输入参数为数据和质心数量和最大迭代次数,默认为10次,具体可参考R语言的kmeans文档,我们在这里不多做赘述,接下来我们根据上面的算法核心来编写R语言代码:
customKmeans<-function(dataset=NA,k=NA){
if(is.na(dataset) || is.na(k)){
stop("You must input valid parameters!!")
}
#计算两点之间欧式距离的函数
Eudist<-function(x,y){
distance<-sqrt(sum((x-y)^2))
return (distance)
}
rows.dataset<-nrow(dataset)
continue.change=TRUE
initPoint<-dataset[sample.int(rows.dataset,size = k),]
formerPoint<-initPoint
iterPoint<-matrix(0,nrow = k,ncol = ncol(dataset))
#记录每一个点到每一个类的距离
error.matrix<-matrix(0,nrow=rows.dataset,ncol=k)
while(continue.change){
#记录每个点所属的类是哪一个
cluster.matrix<-matrix(0,nrow=rows.dataset,ncol=k)
for(i in 1:rows.dataset){#计算每个点到三个初始中心点的距离
for(j in 1:k){
error.matrix[i,j]<-Eudist(dataset[i,],formerPoint[j,])
}
}
#将每一个点所属的类计算出来
for(i in 1:rows.dataset){
cluster.matrix[i,which.min(error.matrix[i,])]<-1
}
#更新新的质心位置
for(i in 1:k){
iterPoint[i,]<-apply(dataset[which(cluster.matrix[,i] == 1),],2,"mean")
}
all.true<-c()
#判断中心点是否已经保持不变
for(i in 1:k){
if(all(formerPoint[i,] == iterPoint[i,]) == T){
all.true[i]<-TRUE
}
}
formerPoint = iterPoint
continue.change=ifelse(all(all.true) == T,F,T)
}
colnames(iterPoint)<-colnames(dataset)
out=list()
out[["centers"]]<-iterPoint
out[["distance"]]<-error.matrix
out[["cluster"]]<-rep(1,rows.dataset)
for(i in 1:rows.dataset){
out[["cluster"]][i]<-which(cluster.matrix[i,] == 1)
}
#返回结果,包括中心点坐标,每个点离每一个中心点的位置以及每个数据点所属的聚类名称
return(out)
}
每一步的注释已经在代码之中,代码细节可能不如自带函数那么详细,这也是我自己为了更加深入了解算法做的校工作,大家可以使用R中自带的iris数据集进行测验。
最后推广一下自己的R语言资料集合的GitHub库,总结了一下R常用的数据包和一些文档,希望大家可以pull requests自己的认为好的R语言材料,供大家分享:
https://github.com/Ronlee12355/Road2Rgithub.com