Python

【Pythonデータ分析】 t-SNEをPCAと比較

Python

はじめに

Pythonで機会学習や深層学習していて、多次元データを可視化したいけど、やり方がわからずお悩みの方は、多いのではないでしょうか?今回の記事は、そのようなお悩みを解決するための記事になります。
多次元データを可視化するには、人間が認識できる次元まで削減する必要があります。そこで、用いる方法としてt-SNEがあります。

t-SNEとは?

t-SNEとは、次元削減アルゴリズムの一つです。深層学習において、中間層の出力がどのようになっているかなどを知りたい状況が、頻繁にあります。なぜなら、学習がうまく進行しているのかどうかという中間特性値をt-SNE分析によって、人間にとってわかりやすい二or三次元マップとして可視化できるためです。

以下の二次元プロットしたグラフが、t-SNEによる分析結果です。このように、人間が認識できなかった多次元データを以下のような認識できるグラフに変換するということです。

詳細はこちらの論文を参照ください。

従来技術PCAとは?

従来、次元削減の分析方法で主流であったPCA分析が主流でした。PCA分析とは、主成分分析と呼ばれるものです。主成分分析とは、データのばらつきに注目して、ばらつきが大きい方向に直行する方向に軸を設定することで、人間が認識できる次元まで、次元削減を行う手法です。

PCA分析

次元削減には様々なPCA意外にも方法があります。 例えば、Isomap や LLEです。ただし、 t-SNE 以外はうまく可視化できていないことがこちらの論文では述べられています。

なので、 初心者の我々は、とりあえず迷ったら「t-SNE分析」をやってみるというスタイルで構わないと思います。使いながらその他の手法も勉強し、まずは直感的に使ってみて、理解していくことが大切だと筆者は考えます。

t-SNEとPCAの比較

では、t-SNEとPCA分析を比較するために人の認識するデータ(今回は、2次元)まで次元削減し、直感的に理解していきましょう。

データ|MNISTについて

データには、MINSTを使用します。MNIST(Mixed National Institute of Standards and Technology database)とは、手書き数字画像60,000枚、テスト画像10,000枚を集めた画像データセットです。さらに、手書きの数字「0〜9」に正解ラベルが与えられるデータセットでもあり、画像分類問題で人気の高いデータセットです。

MNIST

コード全文

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, InputLayer
from keras.optimizers import RMSprop

# MNISTデータを読込む
(x_train, y_train), (x_test, y_test) = mnist.load_data()

import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
from mpl_toolkits.mplot3d import axes3d
#%matplotlib notebook


def show_2D_tSNE(latent_vecs, target, title='t-SNE viz'):
    latent_vecs = latent_vecs
    latent_vecs_reduced = TSNE(n_components=2, random_state=0).fit_transform(latent_vecs)
    plt.scatter(latent_vecs_reduced[:, 0], latent_vecs_reduced[:, 1],
                c=target, cmap='jet')
    plt.colorbar()
    plt.show()

def show_as_PCA(latent_vecs, target, title='PCA viz'):
    latent_vecs = latent_vecs
    #latent_vecs_reduced = TSNE(n_components=2, random_state=0).fit_transform(latent_vecs)
    latent_vecs_reduced = PCA(n_components=2).fit_transform(latent_vecs)
    plt.scatter(latent_vecs_reduced[:, 0], latent_vecs_reduced[:, 1],
                c=target, cmap='jet')
    plt.colorbar()
    plt.show()

import numpy as np

raw_x = np.array([a for a in x_train])
raw_y = np.array([y for y in y_train])
raw_x = raw_x.reshape((len(raw_x), -1))

if True: # for saving time
    LIMIT = 1000
    chosen_idxes = np.random.choice(list(range(len(raw_x))), LIMIT)
    raw_x = raw_x[chosen_idxes]
    raw_y = raw_y[chosen_idxes]

show_2D_tSNE(raw_x, raw_y, 'Raw sample distributions (t-SNE)')
show_as_PCA(raw_x, raw_y, 'Raw sample distributions (PCA)')

t-SNEとPCAの比較結果

t-SNEの方がラベルごとに分離できていることがわかると思います。

t-SNEの分析結果
PCA分析結果

まとめ

  • MNISTデータの分離には、「t-SNE」の方が良い

多次元のデータ分析で、分析方法で迷ったらまずは、「t-SNE分析」をやってみるで分析してみましょう。

その他の次元削減手法やデータ別の比較結果は、こちらの記事を参考にしてみてください。

Pythonによるデータ分析方法を学びたい方、もっと知りたい方はこちらの記事も参考にしてみてください。

今回の記事は、以上です。

最後までお読み頂きありがとうございました。

コメント

  1. […] 【Pythonデータ分析】 t-SNEをPCAと比較はじめにPythonで機会学習や深層学習していて、多次元データを可視化したいけど、やり方がわからずお悩みの方は、多いのではないでしょうか?今回 […]

タイトルとURLをコピーしました