Python
機械学習
scikit-learn

scikit-learnによる次元圧縮とクラスタリング

More than 1 year has passed since last update.


目標

クラスタリングはどのように行うかを全体的に実験し、可視化するまで。


事前知識

クラスタリング

次元圧縮


使用するデータ

今回はscikit-learnのdigitsデータを用いて実験を行う。


データ読み込み

from sklearn.datasets import load_digits

digits = load_digits()
x = digits.data
y = digits.target

x.shape

> (1797, 64) # サンプル数1797, 特徴次元64(8x8)
np.max(x)
> 16
np.min(x)
> 0 # xは0~16の値をとる。


次元圧縮して可視化

xの特徴が64次元もあると可視化できないので、2次元まで次元を圧縮する。

ここで、次元圧縮のアルゴリズムを使用する。

今回使用するのは、

・PCA (線形アルゴリズム)

・NMF

・KernelPCA (非線形アルゴリズム)

・Isomap(非線形アルゴリズム)


PCA


PCA

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
x_pca = pca.fit_transform(x)
#################### 可視化 ####################
for label in labels:
plt.scatter(x_pca[digits.target == label, 0], x_pca[digits.target == label, 1])

スクリーンショット 2018-01-24 16.21.21.png


NMF


NMF

from sklearn.decomposition import NMF

nmf = NMF(n_components=2)
x_nmf = nmf.fit_transform(x)
#################### 可視化 ####################
for label in labels:
plt.scatter(x_nmf[digits.target == label, 0], x_nmf[digits.target == label, 1])

スクリーンショット 2018-01-24 16.23.17.png


KernelPCA


KernelPCA

from sklearn.decomposition import KernelPCA

kernel_pca = KernelPCA(n_components=2, kernel='rbf', gamma=10)
# 以下省略

スクリーンショット 2018-01-24 16.26.09.png


Isomap


Isomap

from sklearn.manifold import Isomap

isomap = Isomap(n_neighbors=8, n_components=2)
# 以下省略

スクリーンショット 2018-01-24 16.27.09.png


次元圧縮まとめ

一番まとまって可視化できている、線形アルゴリズムのPCAが最もよく次元圧縮できてそうです。

ついでIsomapですかね。

なんでこのような結果になったのかを理解するには数式を追わなきゃダメそうですね。今後時間ができたらやりたいです。

でも、ここでは可視化するために次元圧縮しているので、そこまで深く追わなくても良いですね。


クラスタリング

クラスタリングとは特徴ベクトルだけを見て(教師なし学習)、グループごとに分ける機械学習アルゴリズムです。今回のdigitsは教師ありデータですが、これを教師なしデータとみなしてクラスタリングします。クラスタリングのデータを可視化して、教師データと比べて見て、一番よくクラス分けできているものを最も良いアルゴリズムとします。

今回使用するアルゴリズムは、以下の通りです。

・K-means

・LDA

・GMM

・HAC

また、教師データとの比較にはPCAの次元圧縮アルゴリズムを使用します。(以下の図)

スクリーンショット 2018-01-24 16.21.21.png


K-means


k-means

from sklearn.cluster import KMeans

n_cluster = len(digits.target_names)
x_kmeans = KMeans(n_cluster, random_state=0, verbose=1).fit_transform(x)
labels_kmeans = [np.argmax(_) for _ in x_kmeans]
###################### 可視化 ################################
for label in np.arange(0, n_cluster):
plt.scatter(x_pca[labels_kmeans == label, 0], x_pca[labels_kmeans == label, 1]) # x_pca : 上で、xを二次元に圧縮したデータ

スクリーンショット 2018-01-24 16.38.05.png


LDA


lda

from sklearn.decomposition import LatentDirichletAllocation

lda_model = LatentDirichletAllocation(n_components=n_cluster, random_state=0, verbose=1)
#以下略

スクリーンショット 2018-01-24 16.40.39.png


混合ガウスモデル


gmm

from sklearn.mixture import GMM

gmm_model = GMM(n_components=n_cluster, verbose=1, random_state=0)

スクリーンショット 2018-01-24 16.41.19.png


HAC


HAC

from sklearn.cluster import AgglomerativeClustering

hac_model = AgglomerativeClustering(n_clusters=n_cluster)

スクリーンショット 2018-01-24 16.42.14.png


クラスタリングまとめ

今回教師データと、最もよく似ていたのはLDAかHACだと思います。K-meansはあまりうまくラベルづけできていなかったですね。


まとめ

本来は文書データでクラスタリングを行いたかったのですが、あまり良い実験データが見つからなくて、sklearnのdigitsデータで試しました。digitsは特徴量が直接的に現れているデータだと思うので、複雑な処理をしなくてもうまくクラスタリングできました。

文書データになった場合は、スパース問題や、トピック推定問題など、もっと複雑になると思います。教師ありデータを用いてクラスタリングすることで、どのクラスタリング手法が良いか調べられるのは良いと思います。

今回は見た目で、どのクラス分類が効果的かを見ましたが、実際にはエントロピーなどを使って調べるべきだと思います(特に文書データは可視化することが不可能に近いため。)。


今後の課題

・次元圧縮アルゴリズムの数式的理解

・文書データに適した次元圧縮アルゴリズムの選択

・クラスタリング手法のスコア計算(情報エントロピーなど)