2016-12-05 8 views
2

все! Меня попросили создать алгоритм К-мер на R, но я действительно не знаю языка, поэтому я нашел примерный код в Интернете и решил использовать. Я изучил его, изучил функции, которые используются в нем, и немного исправил его, потому что он не очень хорошо работал. Вот код:K-алгоритм, R

# Creating a sample of data 
y=rnorm(500,1.65) 
x=rnorm(500,1.15) 
x=cbind(x,y) 
centers <- x[sample(nrow(x),5),] 

# A function for calculating the distance between centers and the rest of the dots 
euclid <- function(points1, points2) { 
    distanceMatrix <- matrix(NA, nrow=dim(points1)[1], ncol=dim(points2)[1]) 
    for(i in 1:nrow(points2)) { 
    distanceMatrix[,i] <- sqrt(rowSums(t(t(points1)-points2[i,])^2)) 
    } 
    distanceMatrix 
} 


# A method function 
K_means <- function(x, centers, euclid, nItter) { 
    clusterHistory <- vector(nItter, mode="list") 
    centerHistory <- vector(nItter, mode="list") 

    for(i in 1:nItter) { 
    distsToCenters <- euclid(x, centers) 
    clusters <- apply(distsToCenters, 1, which.min) 
    centers <- apply(x, 2, tapply, clusters, mean) 
    # Saving history 
    clusterHistory[[i]] <- clusters 
    centerHistory[[i]] <- centers 
    } 

    structure(list(clusters = clusterHistory, centers = centerHistory)) 

} 


res <- K_means(x, centers, euclid, 5) 
#To use the same plot operations I had to use unlist, since the resulting object in my function is a list of lists, 
#and default object is just a list. And also i store the history of each iteration in that object. 
res <- unlist(res, recursive = FALSE) 
plot(x, col = res$clusters5) 
points(res$centers5, col = 1:5, pch = 8, cex = 2) 

Он отлично работает на этой простой матрице. Но меня попросили использовать его на радужной оболочке:

head(iris) 
a <-data.frame(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length, iris$Petal.Width) 
centers <- a[sample(nrow(a),3),] 
iris_clusters <- K_means(a, centers, euclid, 3) 
iris_clusters <- unlist(iris_clusters, recursive = FALSE) 
head(iris_clusters) 

И проблема в том, что он не работает. Ошибка:

Error in distanceMatrix[, i] <- sqrt(rowSums(t(t(points1) - points2[i, : 
    number of items to replace is not a multiple of replacement length 

Я понимаю, что размеры объектов не совпадают, но я не понимаю, почему. Вот почему я прошу о помощи. Прошу прощения за всю тупость, которая может быть в этом коде заранее, но я пока не очень хорошо знаком с языком, поэтому не судите меня слишком жестко. Спасибо!

+0

Это может быть потому, что в вашем примере 'centers' является матрицей и с«радужки»представляет собой кадр данных. попробуйте 'центры <- unlist (a [sample (nrow (a), 3),])' –

+0

Вам нужно написать свой собственный или просто создать выход 'kmeans'? Если это последний, 'kmeans' встроен. Рассмотрим' kmeans (iris [, -5], 3) '. –

+0

Это было быстро! Спасибо за ответ @PierreLafortune, но теперь он дает еще одну ошибку: Ошибка в матрице (NA, nrow = dim (points1) [1], ncol = dim (points2) [1]): код нечисловой матрицы ' –

ответ

0

Ваша реализация должна работать с простыми

приведения типов
iris_clusters <- K_means(as.matrix(a), as.matrix(centers), euclid, 3) # 3 iterations 

iris_clusters <- unlist(iris_clusters, recursive = FALSE) 

# plotting the clusters obtained on the first two dimensions at the end of 3rd iteration 

plot(a[,1:2], col = iris_clusters$clusters3, pch=19) 
points(iris_clusters$centers3, col = 1:5, pch = 8, cex = 2) 

enter image description here

head(iris_clusters) 

# cluster assignments and centroids computed at different iterations 

$clusters1 
    [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 3 2 3 2 3 2 3 3 3 3 2 3 3 3 3 3 3 2 3 2 2 3 3 
[77] 2 2 3 3 3 3 3 2 3 3 2 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 1 2 1 1 3 1 1 1 2 2 2 2 2 2 2 1 1 2 1 2 1 2 1 1 2 2 2 1 1 1 2 2 2 1 2 2 2 2 1 2 2 1 1 2 2 2 2 2 

$clusters2 
    [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 3 2 3 3 2 2 2 3 2 2 2 2 3 2 2 2 2 2 2 
[77] 2 2 2 3 3 3 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 3 2 1 2 1 2 1 1 2 1 1 1 2 2 1 2 2 2 2 1 1 2 1 2 1 2 1 1 2 2 2 1 1 1 2 2 2 1 2 2 2 1 1 2 2 1 1 2 2 2 2 2 

$clusters3 
    [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 
[77] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 3 2 1 2 1 2 1 1 2 1 1 1 2 2 1 2 2 2 2 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 2 1 1 2 2 1 1 1 2 1 1 1 2 2 2 2 

$centers1 
    iris.Sepal.Length iris.Sepal.Width iris.Petal.Length iris.Petal.Width 
1   7.150000   3.120000   6.090000  2.1350000 
2   6.315909   2.915909   5.059091  1.8000000 
3   5.297674   3.115116   2.550000  0.6744186 

$centers2 
    iris.Sepal.Length iris.Sepal.Width iris.Petal.Length iris.Petal.Width 
1   7.122727   3.113636   6.031818  2.1318182 
2   6.123529   2.852941   4.741176  1.6132353 
3   5.056667   3.268333   1.810000  0.3883333 

$centers3 
    iris.Sepal.Length iris.Sepal.Width iris.Petal.Length iris.Petal.Width 
1   7.014815   3.096296   5.918519   2.155556 
2   6.025714   2.805714   4.588571   1.518571 
3   5.005660   3.369811   1.560377   0.290566 
+0

О, большое спасибо, @sandipan. Результат не идеальный, из-за алгоритма, я полагаю, но он работает! –

+0

@ John Dirak Я думаю, что он еще не сходился с 3 итерациями, мы можем попробовать больше итераций (например, 6), чтобы получить его сближение. Кроме того, мы проектируем его только в первых двух измерениях, игнорируя последние два, но kmeans использовали все 4, поэтому ожидается некоторое несоответствие с идеальным. –

+0

Я добавил много итераций, но он все еще не сходится хорошо. Проецирование также бесполезно, да, спасибо. –

 Смежные вопросы

  • Нет связанных вопросов^_^