とある技術者の徒然草

生産技術者の適当な日記(統計言語Rに関するメモがメイン)

【R言語】t-sneで次元削減 -Rtsneパッケージ-→DBSCANクラスタリング

t-sneで次元削減 -Rtsneパッケージ-


大量の不良画像データをモード分けしたいことが多い。
いきなりkmeans法でクラスタリングしてもよいが、
tsneで2次元に落とし込んみ可視化すると、
意外な関係性が読み取れて面白かったのでメモする。

t-sneとは?

tsneとは次元を圧縮するアルゴリズムであり、特に高次元データを可視化する手法です。
2 点間の「近さ」を距離ではなく確率分布に基づいて表現するのがポイント。
アルゴリズムの詳細は下記が詳しい。

blog.albert2005.co.jp
使用するパッケージはRtsneである。
主成分分析(PCA)を事前に使用しており、
tsneパッケージを比べてかなり高速?とのこと。
また、perplexity = 18としているがこちらはハイパーパラメータで、
経験的に10-50くらいがよいらしい。

rm(df_temp)
#install.packages("Rtsne")
library(Rtsne)

tsne_out <- Rtsne(kmdf, perplexity = 18, check_duplicates = FALSE)

#結果をプロット
tsne_plot <- data.frame(x = tsne_out$Y[,1], y = tsne_out$Y[,2])
ggplot(tsne_plot) + geom_point(aes(x=x, y=y))


そして二次元に落とした結果がこちら。

f:id:M_taka072:20190210130801p:plain
tsneプロット

群ごとに分けたいため、k-means法でクラスタリングしてみよう。

#kmeans方は初期値に依存するのでset.seed(123)で乱数を固定した方がよい
km_tsne <- kmeans(tsne_plot,6)

#結果を確認
tsne_plot2 <- cbind(tsne_plot,km_tsne$cluster)
library(dplyr)
#列名を変える
tsne_plot2 <- rename(tsne_plot2,"class"="km_tsne$cluster")
tsne_plot2$class <- as.factor(tsne_plot2$class)

km_tsneplot <- ggplot(tsne_plot2) + geom_point(aes(x=x, y=y,col=class))

f:id:M_taka072:20190210131352p:plain
tsne_kmeans

DBSCANクラスタリング

外れ値がうまく分かれていない。
k-meansではなく、密度に基づいたクラスタリングであるDBSCAN を使う。

#DBSCAN (Density-based spatial clustering of applications with noise)でクラスタリング
install.packages("fpc")
library(fpc)

df_dbscan <- fpc::dbscan(tsne_plot, eps = 2.3, MinPts = 5)
#結果をプロット
plot(df_dbscan, tsne_plot, main = "DBSCAN", frame = FALSE)

#結果をプロット
library("factoextra")
fviz_cluster(df_dbscan, tsne_plot, stand = FALSE, frame = FALSE, geom = "point")

tsne_dbscan_plot <- cbind(tsne_plot,df_dbscan$cluster)


f:id:M_taka072:20190210131530p:plain
tsne_DBSCAN

このクラスタリング結果を元のデータフレームに戻し
①教師データとして決定木分析をする
②または層別分析をすると意外な結果が分かることもある。