LoginSignup
6
12

More than 3 years have passed since last update.

言語処理100本ノック-99(pandas使用):t-SNEによる可視化

Last updated at Posted at 2020-02-03

言語処理100本ノック 2015の99本目「t-SNEによる可視化」の記録です。
t-SNE(t-distributed Stochastic Neighbor Embedding)で2次元に削減をして単語ベクトルを下図のように可視化します。2次元や3次元なら人間が見てわかりますね。
image.png

参考リンク

リンク 備考
099.t-SNEによる可視化.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:99 言語処理100本ノックで常にお世話になっています
早く知っておきたかったmatplotlibの基礎知識、あるいは見た目の調整が捗るArtistの話 今更ながらにMatplotlibの基本を少し覚えました
color example code: colormaps_reference.py MatplotlibのColor Map

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.15 複数Python環境を使うことがあるのでpyenv使っています
Python 3.6.9 pyenv上でpython3.6.9を使っています
3.7や3.8系を使っていないことに深い理由はありません
パッケージはvenvを使って管理しています

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

種類 バージョン
matplotlib 3.1.1
pandas 0.25.3
scikit-learn 0.21.3

課題

第10章: ベクトル空間法 (II)

第10章では,前章に引き続き単語ベクトルの学習に取り組む.

99. t-SNEによる可視化

96の単語ベクトルに対して,ベクトル空間をt-SNEで可視化せよ.

課題補足(t-SNE)

t-SNE(t-distributed Stochastic Neighbor Embedding)は次元を2または3に削減します。次元削減という意味では、PCA(主成分分析)と同じです。ただ、PCAでできない非線形構造をもつデータにも対応可能です。偉そうに書いていますが、数式を理解しておらず記事「t-SNEによるイケてる次元圧縮&可視化」の受け売りです。

回答

回答プログラム 099.t-SNEによる可視化.ipynb

import matplotlib.pyplot as plt
import pandas as pd
from sklearn.manifold import TSNE
from sklearn.cluster import KMeans

country_vec = pd.read_pickle('./096.country_vector.zip')
print(country_vec.info())

# t-SNE
t_sne = TSNE().fit_transform(country_vec)
print('t_sne shape:', t_sne.shape)

# KMeansクラスタリング
clustered = KMeans(n_clusters=5).fit_predict(country_vec)

fig, ax = plt.subplots(figsize=(22, 22))

# Set Color map
cmap = plt.get_cmap('Dark2')

for i in range(t_sne.shape[0]):
    cval = cmap(clustered[i] / 4)
    ax.scatter(t_sne[i][0], t_sne[i][1], marker='.', color=cval)
    ax.annotate(country_vec.index[i], xy=(t_sne[i][0], t_sne[i][1]), color=cval)
plt.show()

回答解説

全体の8割近くは記事「素人の言語処理100本ノック:99」のコピペです。

ここが、今回のメインのコードです。scikt-learnのTSNEはいくつかパラメータがあるのですが、デフォルトのままで実行しました。scikt-learnのTSNEはあまりよくないと言及しているブログもありましたが、とりあえず気にせず行きます。

t_sne = TSNE().fit_transform(country_vec)

あと、散布図で表示する色としてK-Meanで非階層クラスタリングをしています。

clustered = KMeans(n_clusters=5).fit_predict(country_vec)

最後にmatplotlibで散布図表示です。plt.get_cmapを使って表示色定義をしていて、どんな色かはcolor example code: colormaps_reference.pyに情報があります。
scatterで点を表示し、annotateでラベル(国名)を表示しています。
※今更恥ずかしながらmatplotlibの基本を、少しだけ記事「早く知っておきたかったmatplotlibの基礎知識、あるいは見た目の調整が捗るArtistの話」で理解しました。

fig, ax = plt.subplots(figsize=(22, 22))

# Set Color map
cmap = plt.get_cmap('Dark2')

for i in range(t_sne.shape[0]):
    cval = cmap(clustered[i] / 4)
    ax.scatter(t_sne[i][0], t_sne[i][1], marker='.', color=cval)
    ax.annotate(country_vec.index[i], xy=(t_sne[i][0], t_sne[i][1]), color=cval)
plt.show()

日本のあたりを拡大して見るとこんな感じです。前回ノックでやった階層的クラスタリングより、わかりやすいです。
image.png

6
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
12