R語言實現K-Means演算法資料集iris

亓了個葩發表於2015-12-09

博主程式碼根據機器挖掘實戰編寫的.那本書用的是Python.Step By Step. R語言有函式包實現
也可以呼叫,裡面的四個algorithm我怎麼看著都差不多,所以我決定寫一下,明天仔細看一下
kmeans(x, centers, iter.max = 10, nstart = 1,
algorithm = c(“Hartigan-Wong”, “Lloyd”, “Forgy”,
“MacQueen”))

程式碼
#載入iris函式
loadData <- function(){
  data(iris)
  #要把Species列去掉
  dataSet =  iris[,-ncol(iris)]
  return (dataSet)
  }
 #計算歐幾里得距離
 distEnclud <- function(vecA,vecB){
   distEnclud = sqrt(apply((vecA-vecB)^2,1,sum))
   return (distEnclud)
 }
 #設定初始族
 randCent <- function(dataSet,k){
   n = ncol(dataSet)
   #建立一個空矩陣
   centroids = matrix(data = NA, nrow = k, ncol = n, byrow = FALSE,dimnames = NULL)
   #隨機設定初始族
   for(j in 1:n){
     minJ = min(dataSet[,j])
     rangeJ = max(dataSet[,j]) - minJ
     #隨機生成每一列的初始簇
     centroids[,j] = minJ + rangeJ *runif(k)
   }
   return (centroids)
 } 
 kMeans <- function(dataSet,k,distEnclud, randCent){
   m = nrow(dataSet)
   #記錄矩陣,一列記錄簇索引值,即類別,第二列記錄誤差
   clusterAssment = matrix(data = 0,  nrow = m , ncol = 2,byrow = FALSE,dimnames = NULL)
   #初始族
   centroids = randCent(dataSet,k)
   #初始簇列名和資料集列名相同
   colnames(centroids) = colnames(dataSet)


   clusterChanged = TRUE
    #設定結束變數,如果為TRUE 說明族中心點和分類結果還有變化,所以要繼續分類,若沒有改變則設定為FALSE 跳出迴圈
   while (clusterChanged) {
     clusterChanged = FALSE
     for(i in 1: m){
       minDist = Inf
       minIndex = -1
       for(j in 1:k){
         distJI = distEnclud(dataSet[i,],centroids[j,])
         if(is.na(distJI)) distJI = Inf
         if(distJI < minDist){
           minDist = distJI
           minIndex = j
         }
       }
       if(clusterAssment[i,1] != minIndex){
         clusterChanged = TRUE
         clusterAssment[i,1] = minIndex 
       } 
       clusterAssment[i,2] = minDist^2
     }

     #每計算一遍 都要 updata center 
     for(cent in 1:k){
       ptsCluster = dataSet[which(clusterAssment[,1] == cent),]
       centroids[cent,] = apply(ptsCluster,2,mean)
     }
   }
   #小技巧 R語言返回幾個矩陣時 可用list將其組合,返回後再如取list元素一邊取出就好
   out = list(clusterAssment = clusterAssment ,centroids = centroids)
   return (out)
 }
###########呼叫函式程式碼,只需3行,簡單吧
#dataSet = loadData()
#head(dataSet)
#output = kMeans(dataSet,2,distEnclud,randCent)

#繪製Sepal.Length,Sepal.Width 兩列
plot(dataSet[c("Sepal.Length","Sepal.Width")],col = output$clusterAssment[,1]) 
points(output$centroids[,1],output$centroids[,2],col = 1:2,pch = 8,cex = 2)
#繪製Petal.Length,Petal.Width 兩列
plot(dataSet[c("Petal.Length","Petal.Width")],col = output$clusterAssment[,1]) 
points(output$centroids[,3],output$centroids[,4],col = 1:2,pch = 8,cex = 2)
table(iris$Species, output$clusterAssment[,1])

根據Sepal.Length,Sepal.Width 兩列兩列畫出的圖形
根據iris前兩列畫出的圖形
根據Petal.Length,Petal.Width 兩列畫出的圖形
根據後兩列畫出的圖形

相關文章