gepuro.net
gepulog

データ分析エンジニアによる備忘録的ブログ

kmeansとkmedoidsを比較してみる

やったこと

kmeansとkmedoidsの比較をしてみました。 アルゴリズムの詳細は下の参考文献を見てください。

ざっくりとした説明をすると、 kmeansはクラスタの中心を重心として距離を2乗で評価するのに対して、 kmedoidsはクラスタの中心をデータ点として距離を1乗で評価します。

パッケージの読み込み

library("ggplot2")
library("cluster")

サンプルデータ作成、可視化用関数

makeSampleData <- function(sd){
  df1 <- data.frame(x = rnorm(20, mean=1, sd=sd),
                    y = rnorm(20, mean=1, sd=sd),
                    cluster = rep(1, 20))

  df2 <- data.frame(x = rnorm(20, mean=1, sd=sd),
                    y = rnorm(20, mean=3, sd=sd),
                    cluster = rep(2, 20))

  df3 <- data.frame(x = rnorm(20, mean=3, sd=sd),
                    y = rnorm(20, mean=1, sd=sd),
                    cluster = rep(3, 20))

  df4 <- data.frame(x = rnorm(20, mean=3, sd=sd),
                    y = rnorm(20, mean=3, sd=sd),
                    cluster = rep(4, 20))

  df5 <- data.frame(x = c(-2),
                    y = c(-2),
                    cluster = rep(1, 1))
  sample.df <- dplyr::bind_rows(df1, df2, df3, df4, df5)
  sample.df  
}

plot_clustering <- function(result){
  g <- ggplot2::ggplot(data = result,
                       ggplot2::aes(x = x,
                                    y = y,
                                    group = as.factor(cluster_forecast),
                                    col = as.factor(cluster_forecast))) +
    ggplot2::geom_point(
      ggplot2::aes(shape = factor(cluster))
    )
  print(g)
}

サンプルデータのプロット

sample.df <- makeSampleData(sd=0.3)

sample.df$cluster_forecast <- sample.df$cluster
plot_clustering(sample.df)

kmeansを何度か実行

for( i in 1:5){
  sample_kmeans <- kmeans(sample.df[,-c(3,4)], 4)
  sample_kmeans$centers
  sample.df$cluster_forecast <- sample_kmeans$cluster
  plot_clustering(sample.df)
}

たまに上手くクラスタリングしてくれない。

kmedoidsを何度か実行

for( i in 1:5){
  p2m <- pam(sample.df[,-c(3,4)], 4)
  p2m$medoids
  sample.df$cluster_forecast <- p2m$clustering
  plot_clustering(sample.df)
}