Pythonによる4種の次元削減と可視化

以下4つの次元削減アルゴリズムをPythonで実行し、それぞれで2次元のグラフを作成してみます。

  • PCA(Principal Component Analysis:主成分分析)
  • SVD(Singular Value Decomposition:特異値分解)
  • t-SNE(t-distributed Stochastic Neighbor Embedding)
  • UMAP(Uniform Manifold Approximation and Projection)

次元削減についての説明やこれらの使い分けについてはこちらの記事に纏めています。

「次元削減」の意味と活用方法

ファイルの読み込み

今回は、以下のような15名のエンジニアのスキルレベルを10段階で評価したデータを仮定します。

まずはこのCSVを以下のようにデータフレームに読み込みます。

さて、それでは全社員のスキルの傾向や分布はどうなっているのか。
どの社員とどの社員が近いのか。
そういった事をパッと視覚的に分かりやすくするために、次元削減で可視化してみましょう。

Pythonによる次元削減の実行

PCA

scikit-learnのPCAクラスを使います。

vecs_listに、2次元に圧縮された15名のデータが格納されています。
なので、最終的にはこの圧縮された15個の点を座標状にプロットしてあげればOKです。
(この散布図の書き方は次の章で記します。)

また、PCAではどれほど元の情報が残ったかの「寄与度」を簡単に計算する事ができます。

第1主成分だけで約71%、第2主成分だけで約21%です。
累積寄与率は約93%という高い値なので、次元を2にしても、元の情報は殆ど保持されていると考えて良いでしょう。

SVD

scikit-learnのTruncatedSVDクラスを使います。


結果を見ると、ほぼPCAが左右反転しただけのようです。
細かい計算の理論は違うのですが、このようにほぼPCAとSVDは同じ結果が得られます。

t-SNE

scikit-learnのTSNEクラスを使用します。
bhtsneライブラリを使用する方法もあります。)



PCAやSVDよりも綺麗にクラスタが出来ているのが分かるかと思います。
一般的に、PCA/SVDよりもt-SNEを用いた方が明確にクラスタが見て取れるような結果が得られます。
しかし、その分、「データ間の距離」にはあまり意味がなくなっていますのでご注意ください。

また、t-SNEは、パラメータ調整で結果が大きく変わります。
パラメータにも色々ありますが、とりわけ重要なのはperplexityという引数です。
この値によって結果は大きく変わります。
データによってどの値が優れるかは変わりますので、幾つか実験してみる必要があります。
例えば2,5,10,50,100あたりにひとまず設定してみるのが良いかと思います。

ちなみに、今回のデータでperplexity=100とすると、以下の結果が得られます。

綺麗ですが、特に何の特徴も読み取れない結果となってしまいました。このように、perplexityの値で結果が大きく変わるので注意が必要です。

UMAP

umapライブラリのUMAPクラスを使います。

こちらも、綺麗にクラスタができています。
UMAPもt-SNE同様パラメータ調整が必要で、特に重要なのがn_neighborsです。

今回のデータでは3にしましたが、適切な値はデータによって異なりますので、t-SNE同様に幾つか数値を入れてみて、上手く次元削減できていそうなところをご自身で選ぶようにしてください。

グラフの描画ソース

seabornライブラリのscatterplotを用いて、上記の散布図を作成するソースです。

vecs_listに圧縮された値が入っているので、そのXとYを与えてやるだけです。
plt.annotateで、点の上にデータ名を付与しています。

以上、Pythonによる次元削減でした。