概要
t-SNEとPCAでMNISTの手書き文字やファッション画像を2〜3次元に圧縮して可視化してみる。
バージョン情報
- scikit-learn==0.21.2
- Keras==2.2.4 (fashion_mnistのデータセットで利用)
手書き文字 - t-SNE - 2次元
sklearn.datasetsのdigitsを使って2次元にしてみる。
データのロード。
import sklearn.datasets digits, label = sklearn.datasets.load_digits(return_X_y=True) digits = digits / 255
sklearnに入っている手書き文字データは8x8の64次元。
digits.shape
#=> (1797, 64)
これをt-SNEで二次元に変換する。
from sklearn.manifold import TSNE digits2d = TSNE(n_components=2).fit_transform(digits)
可視化してみる。
from matplotlib import pylab as plt f, ax = plt.subplots(1, 1, figsize=(10, 10)) for i in range(10): target = digits2d[label == i] ax.scatter(x=target[:, 0], y=target[:, 1], label=str(i), alpha=0.5) plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
なかなかキレイに分かれた。
手書き文字 - PCA - 2次元
同じ処理をPCAでもやってみる。
from sklearn.decomposition import TruncatedSVD pca = TruncatedSVD(n_components=2) digits2d = pca.fit_transform(digits) f, ax = plt.subplots(1, 1, figsize=(10, 10)) for i in range(10): target = digits2d[label == i] ax.scatter(x=target[:, 0], y=target[:, 1], label=str(i), alpha=0.5) plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
なんとなく傾向は取れてはいる。
手書き文字 - 3次元
3次元で可視化してみる。
まずはt-SNE
digits3d = TSNE(n_components=3).fit_transform(digits) from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize=(10, 10)).gca(projection='3d') for i in range(10): target = digits3d[label == i] fig.scatter(target[:, 0], target[:, 1], target[:, 2], label=str(i), alpha=0.5) fig.legend(bbox_to_anchor=(1.02, 0.7), loc='upper left')
PCA。
pca = TruncatedSVD(n_components=3) digits3d = pca.fit_transform(digits) fig = plt.figure(figsize=(10, 10)).gca(projection='3d') for i in range(10): target = digits3d[label == i] fig.scatter(target[:, 0], target[:, 1], target[:, 2], label=str(i), alpha=0.5) fig.legend(bbox_to_anchor=(1.02, 0.7), loc='upper left')
ファッション - t-SNE - 2次元
kerasのdatasetsを使ってファッション画像のダウンロード。
60,000 x 28 x 28でデータが返るので、reshapeして60,000 x 784にしておく。
import keras (train_images, train_labels), (test_images, test_labels) = keras.datasets.fashion_mnist.load_data() train_images = train_images.reshape(60000, 28*28)
t-SNEの実行。この処理はうちの環境では1時間以上かかった。scikit-learnのTSNEはシングルスレッドで動くのである程度の大きさのデータを扱う場合は実行速度の速い他の実装を検討する必要がある。
from sklearn.manifold import TSNE from matplotlib import pylab as plt fashion2d = TSNE(n_components=2).fit_transform(train_images) labels = [ 'T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot', ] f, ax = plt.subplots(1, 1, figsize=(10, 10)) for i in range(10): target = fashion2d[train_labels == i] ax.scatter(x=target[:500, 0], y=target[:500, 1], label=labels[i], alpha=0.5) plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
各ラベル500件ずつ表示。
Bag(カバン)やTrouser(ズボーン・ドカーン・バキューン)は独立しており、Sandal(サンダル)、Sneaker(スニーカー)、Ankle Boot(アンクルブーツ)が固まっている。
ファッション - PCA - 2次元
PCAは数秒で実行が終わる。
fashion2d = pca.fit_transform(train_images) f, ax = plt.subplots(1, 1, figsize=(10, 10)) for i in range(10): target = fashion2d[train_labels == i] ax.scatter(x=target[:500, 0], y=target[:500, 1], label=labels[i], alpha=0.5) plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
ファッション - 3次元
t-SNE。見づらかったので各ラベル300件ずつ表示。
fashion3d = TSNE(n_components=3).fit_transform(train_images) fig = plt.figure(figsize=(10, 10)).gca(projection='3d') for i in range(10): target = fashion3d[train_labels == i] fig.scatter(target[:300, 0], target[:300, 1], target[:300, 2], label=labels[i], alpha=0.5) fig.legend(bbox_to_anchor=(1.02, 0.7), loc='upper left')
PCA。
pca = TruncatedSVD(n_components=3) fashion3d = pca.fit_transform(train_images) fig = plt.figure(figsize=(10, 10)).gca(projection='3d') for i in range(10): target = fashion3d[train_labels == i] fig.scatter(target[:300, 0], target[:300, 1], target[:300, 2], label=labels[i], alpha=0.5) fig.legend(bbox_to_anchor=(1.02, 0.7), loc='upper left')
改定履歴
Author: Masato Watanabe, Date: 2019-06-25, 記事投稿