
「t-SNE」を用いて高次元データを可視化する
2020.08.13
t-SNE(ティースニー)を使い高次元データを可視化してみる
高次元のデータを可視化するには、高次元のデータを2〜3次元のデータに変換する必要があります。
有名な手法としては、例えば、以下のようなものがあります。
- 主成分分析
- 多次元尺度構成法
- Isomap
- LLE(Locally Linear Embedding)
これらの方法を用いれば、高次元のデータを低次元のデータに変換し、2〜3次元のデータとして可視化することができます。
変換にも限界がある
しかし、これらの方法には限界があります。
まず、「主成分分析」や「多次元尺度構成法」は線形変換を前提としているため、非線形な高次元データを低次元データに上手く落とし込むことができません。
また、「Isomap」や「LLE」は、データの局所的な構造と大局的な構造を、同時に低次元データへと表現することが難しいことが知られています。
問題点を解消する分析手法「t-SNE」の提案
そこで、これらの問題点を乗り越える、「t-SNE(ティースニー)」と呼ばれる分析手法が2008年に提案されました。
2008年の提案論文の詳細は、以下の論文を参照してください。
「Maaten Laurens van der., and Hinton Geoffrey., 2008, "Visualizing Data using t-SNE," Journal of Machine Learning Research 9: 2579-2605.」
それでは、「t-SNE」について解説し、「MNIST」を使った分析例を見ていきたいと思います!
こちらの記事もオススメ!
「t-SNE」の概要
「SNE」とは?
「t-SNE」は、「SNE(Stochastic Neighbor Embedding)」をベースとしています。
そこで、まずは「SNE」について見ていきます。
「SNE」のポイントは、「2つ」です!
「SNE」のポイント1
1つ目のポイントは、高次元でのデータポイント間の距離を条件付き確率に変換することです。
高次元において、「データポイント\(x_i\)」から見た場合の「データポイント\(x_j\)との距離\(p_{i|j}\)」を、「データポイント\(x_i\)」を平均とした正規分布に従っていると仮定して、その距離(条件付き確率)を計算します。
具体的には以下のように計算します。
$$p_{i|j} = \frac{exp(-||x_i - x_j||^2 / 2 \sigma_i^2)}{\sum_{i≠k} exp(-||x_i - x_k||^2 / 2 \sigma_i^2)}$$
なお、正規分布の確率密度関数の\(\frac{1}{\sqrt{2 \pi \sigma_i ^ 2}}\)部分は、分母と分子でうち消され合っていることに注意してください。
「SNE」のポイント2
2つ目のポイントは、上記で計算した高次元でのデータポイント間の距離(条件付き確率)と、できるだけ近い低次元でのデータポイント間の距離(条件付き確率)をとる点を見つけることです。
まず、低次元での「データポイント\(y_i\)」から見た場合の「データポイント\(y_j\)との距離\(q_{i|j}\)」を、\(p_{i|j}\)同様に以下のように表現します。
ただし、標準偏差は\(\frac{1}{\sqrt{2}}\)に固定しておきます。
$$q_{i|j} = \frac{exp(-||y_i - y_j||^2)}{\sum_{i≠k} exp(-||y_i - y_k||^2)}$$
このように計算された\(q_{i|j}\)と、上記の\(p_{i|j}\)を出来る限り同じにします。
カルバック・ライブラー情報量
両者はどちらも確率分布なので、「異なる確率分布間の距離の指標」である「カルバック・ライブラー情報量」と呼ばれる指標を用います。
このカルバック・ライブラー情報量をコスト関数として、それを最小化する「 \(y\) 」 を見つけます。
こうして見つけられた「 \(y\) 」が、高次元データ\(x\)の低次元データ変換後のデータポイントとして解釈できます。
「t-SNE」とは「SNE」から2つのポイントを改善した分析手法
以上が「SNE」のアイディアです。
「t-SNE」は SNE から2つのポイントを改善した分析手法なのです!
「t-SNE」のポイント1
最初のポイントは、距離に対称性を持たせることです。
SNE では\(p_{i|j}\)と\(p_{j|i}\)が、その定義から同じではありませんでした。
そこで、高次元データ上での「データポイント\(x_i\)」と、「データポイント\(x_j\)間の距離\(p_{ij}\)」を以下のように定義することで、その対称性を担保します。
$$p_{ij} = \frac{p_{i|j} + p_{j|i}}{2n}$$
「t-SNE」のポイント2
2つ目のポイントは、\(q_{ij}\)を表現する際に、正規分布ではなく自由度1の t 分布を使用することです。
すなわち、以下のように表現します。
$$q_{ij} = \frac{(1 + ||y_i - y_j||^2)^{-1}}{\sum_{k≠l}(1 + ||y_k - y_l||^2)^{-1}}$$
なぜ t 分布を用いるのか?
なぜ正規分布ではなく t 分布を用いるかというと、t 分布は正規分布に比べて裾が長いため、近いデータはより近くに、遠いデータはより遠くに表現できるためです。
t-SNE の「t」は、t 分布の「t」だったんですね!
以上、2つのポイントを SNE から変更したのが「t-SNE」です。
「t-SNE」を MNIST に適用
それでは、「t-SNE」を実際のデータに適用して分析してみましょう!
MNIST データの準備・確認
今回利用するデータは、おなじみの「MNIST」です。
「MNIST」には、訓練データが60,000枚、テストデータが10,000枚あり、1つ1つの画像には784(28×28)のデータが含まれています。
データ量が多いと計算に時間がかかってしまいます。
そのため、今回はテストデータ10,000枚を使用します。
ちなみに、別の話ですが、弊社ブロブでは、こんな「MNIST」記事も書いてます。
中身の確認
まずは、中身を確認しましょう。
テストデータとそのラベルはすでに X_test 、 y_test に格納されているとします。
1 2 3 4 5 | # dataの確認 print(X_test.shape) print(y_test.shape) print(type(X_test)) print(type(y_test)) |
出力結果
出力結果は、こちらです。
1 2 3 4 | (10000, 784) (10000,) <class 'numpy.ndarray'> <class 'numpy.ndarray'> |
画像の確認
では、先頭のデータは、どのような画像になっているのか確認してみましょう。
1 2 3 | # dataの確認 import matplotlib.pyplot as plt plt.imshow(X_test[0].reshape(28, 28)) |
出力結果は、こうなりました。

「7」という手書き文字であることが確認できます。
print(y_test[0]) を実行し、ラベルデータで確認しておきましょう。
予想通り、出力結果は 7 となるはずです。
「t-SNE」の適用・可視化
それでは、「t-SNE」を適用してみましょう!
今回は、2次元のデータに落とし込みます。
また、それ以外のハイパーパラメータは、ライブラリのデフォルトのままにしておきます。
下記の通りに実行すると、 X_test に t-SNE を適用でき、得られた低次元データを X_tsne に格納できます。
1 2 3 4 | # t-SNEの適用 from sklearn.manifold import TSNE tsne = TSNE(n_components = 2) # n_componentsは低次元データの次元数 X_tsne = tsne.fit_transform(X_test) |
結果の可視化
結果を可視化してみます!
可視化のためのコードは、下記の通りです。
2次元の散布図上に、文字を色分けしてプロットしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 結果の可視化 import matplotlib.pyplot as plt colors = ['red', 'blue', 'green', 'pink', 'tomato', 'purple', 'black', 'olive', 'lightblue', 'lime'] plt.xlim(X_tsne[:, 0].min(), X_tsne[:, 0].max() + 1) plt.ylim(X_tsne[:, 1].min(), X_tsne[:, 1].max() + 1) for i in range(len(X_test)): plt.text( X_tsne[i, 0], X_tsne[i, 1], str(y_test[i]), color = colors[y_test[i]] ) plt.xlabel('t-SNE Feature1') plt.ylabel('t-SNE Feature2') |
出力結果
出力結果です。

これを見ると、高次元データが低次元データへと綺麗にプロットされている様子がうかがえます。
t-SNE で出力された、この2つの特徴量を用いれば、画像分類のアルゴリズムを比較的簡単に実装できそうです。
さらに、出力結果を確認すると互いの関係がよく分かるようになります。
例えば、「7」(深緑色:左上)と「9」(黄緑色:左上)は互いに近くに分布しています。
一方で、「7」(深緑色:左上)と「0」(赤色:右下)は互いに遠く分布しています。
ここから「7」と「9」は同じような特徴があり、「7」と「0」は異なる特徴を有していることが示唆されます。
さいごに
今回は「t-SNE」について解説し、MNIST データに適用してみました!
「t-SNE」は、高次元データを低次元データへと変換する比較的新しい分析手法です。
「t-SNE」のアイディアの核は、高次元データ上でのデータ間の距離を確率として表現し、それとできるだけ同じような、低次元データ上でのデータ間の距離(確率)をとる点を探すことです。
「t-SNE」を用いると、高次元データを低次元データへと簡単に可視化できます。
ぜひ、「t-SNE」をご自身のデータにも適用してみてください!
(株)ライトコードは、WEB・アプリ・ゲーム開発に強い、「好きを仕事にするエンジニア集団」です。
機械学習でのシステム開発依頼・お見積もりはこちらまでお願いします。
また、機械学習系エンジニアを積極採用中です!詳しくはこちらをご覧ください。
※現在、多数のお問合せを頂いており、返信に、多少お時間を頂く場合がございます。
こちらの記事もオススメ!
ライトコードよりお知らせ






一緒に働いてくれる仲間を募集しております!
ライトコードでは、仲間を募集しております!
当社のモットーは「好きなことを仕事にするエンジニア集団」「エンジニアによるエンジニアのための会社」。エンジニアであるあなたの「やってみたいこと」を全力で応援する会社です。
また、ライトコードは現在、急成長中!だからこそ、あなたにお任せしたいやりがいのあるお仕事は沢山あります。「コアメンバー」として活躍してくれる、あなたからのご応募をお待ちしております!
なお、ご応募の前に、「話しだけ聞いてみたい」「社内の雰囲気を知りたい」という方はこちらをご覧ください。
ライトコードでは一緒に働いていただける方を募集しております!
採用情報はこちら書いた人はこんな人

IT技術2021.03.02TypeScriptの型を問題形式で学べる「type-challenges」とは?
IT技術2021.03.01シスコルータのコンフィグ作成をPythonで自動化してみた!
IT技術2021.02.23【Unity】ARFoundation入門~機能解説から平面検知の実装まで~
IT技術2021.02.22Swiftでguardを使うメリットと使い方をご紹介!