やったこと
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)
}
いつも上手くクラスタリングしてくれる。
まとめ
外れ値が気になる時はkmedoidsを検討すると良いかもしれない