PythonとScikit-learnではじめるt-SNE!次元削減の基礎からパラメータ調整まで

Python

「たくさんの特徴量を持つ高次元データを扱っているけど、データ全体がどういう構造になっているのか直感的に理解できない…」

データ分析や機械学習に携わっていると、このような課題に直面することは少なくありません。数十、数百次元にもなるデータを前に、どの特徴が重要で、データがどのようにグループ分けできるのかを把握するのは困難です。

この記事では、そんな高次元データの構造を**人間が直感的に理解できる2次元や3次元のマップに変換してくれる強力な可視化手法「t-SNE」**について、基礎から実践までを丁寧に解説します。

Pythonの定番ライブラリであるScikit-learnを使って、実際に手を動かしながらt-SNEを学ぶことができます。

この記事を読み終える頃には、あなたは以下のことができるようになっています。

  • t-SNEがどのような次元削減手法なのかを理解できる
  • Scikit-learnを使ってPythonでt-SNEを実装し、高次元データを可視化できる
  • perplexityなどの重要なパラメータの意味を理解し、調整できるようになる
  • t-SNEを使う上での注意点を把握し、結果を正しく解釈できるようになる

それでは、さっそく高次元データの世界を探索しにいきましょう。

t-SNEとは?高次元データを可視化する次元削減手法

まずは、t-SNE(ティースニー)がどのような技術なのか、その基本から見ていきましょう。

まずは「次元削減」の基本をおさえよう

結論として、次元削減とはデータの持つ本質的な情報をできるだけ保ちながら、特徴量の数(次元)を減らす技術です。

例えば、100個の特徴量(100次元)を持つデータを、2個の特徴量(2次元)に変換することを次元削減と呼びます。特徴量が多すぎると、計算コストが増大したり、「次元の呪い」と呼ばれる現象によってモデルの予測精度が低下したりすることがあります。

次元削減を行うことで、以下のようなメリットが生まれます。

  • データを可視化できる(2次元 or 3次元)
  • 計算コストを削減できる
  • ノイズを除去し、モデルの性能を向上させられる場合がある

t-SNEは、この中でも特に**「データの可視化」**に非常に優れた能力を発揮する手法です。

t-SNEの直感的な仕組み

結論として、t-SNEは「高次元の世界で近所にいたデータ同士は、次元削減後の低い次元の世界でも近所にいられるように配置し直す」という考え方に基づいています。

t-SNEは “t-distributed Stochastic Neighbor Embedding” の略で、日本語では「t分布型確率的近傍埋め込み法」と訳されます。名前だけ聞くと非常に難しそうですが、やっていることのイメージはシンプルです。

例えるなら、たくさんの生徒がいる学校のクラス(高次元データ)を、狭い教室の座席(低次元空間)に配置し直すようなものです。このとき、t-SNEは**「クラスで仲の良いグループ(高次元で距離が近いデータ点)は、席替え後の教室でも近くの席(低次元で距離が近い位置)に座らせてあげよう」**と頑張ってくれる先生のような役割を果たします。

この「近傍の構造を保持する」という特性のおかげで、高次元空間でデータが形成していたクラスタ構造などを、私たちが視覚的に理解しやすい形で描き出すことができるのです。

t-SNEとPCA(主成分分析)の主な違い

結論として、PCAがデータ全体の広がり(分散)を捉える線形的な手法であるのに対し、t-SNEはデータの局所的な構造を捉える非線形的な手法である、という点が最も大きな違いです。

次元削減の手法として、t-SNEと同じくらい有名なものにPCA(主成分分析)があります。どちらも次元を減らす目的で使われますが、そのアプローチは全く異なります。

項目t-SNE (t-distributed Stochastic Neighbor Embedding)PCA (Principal Component Analysis)
アプローチ非線形線形
主な目的データの可視化次元削減、特徴抽出
重視するものデータの局所的な構造(近いものが近く)データの大域的な構造(全体の分散)
計算コスト高い低い

PCAはデータ全体のばらつきが最も大きくなる方向(主成分)を見つけ出すことで次元削減を行います。そのため、データの全体像を大まかに捉えるのは得意ですが、複雑なクラスタ構造などを可視化するのは苦手な場合があります。

一方で、t-SNEは近くのデータ点を近くに配置することに特化しているため、複雑なマニフォールド構造(曲がった構造)やクラスタの可視化に非常に優れています。

Scikit-learnでt-SNEを使ってみよう【基本編】

それでは、実際にPythonとScikit-learnを使ってt-SNEを動かしてみましょう。理論よりも、まずは手を動かしてみるのが理解への一番の近道です。

環境準備(ライブラリのインストール)

結論として、pipコマンドを使って、分析と可視化に必要なライブラリをインストールします。

ターミナルやコマンドプロンプトで、以下のコマンドを実行してください。Scikit-learnの他に、データ操作のためのnumpyと、可視化のためのmatplotlibが必要です。

pip install scikit-learn numpy matplotlib

すでにインストール済みの方は、このステップは不要です。

Irisデータセットで次元削減を実践

結論として、sklearn.manifold.TSNEをインポートし、fit_transformメソッドを呼び出すだけで簡単にt-SNEを実行できます。

ここでは、機械学習の入門で定番の「Iris(アヤメ)データセット」を使用します。このデータセットには3種類のアヤメ(setosa, versicolor, virginica)について、それぞれ4つの特徴量(がくの長さ・幅、花びらの長さ・幅)が含まれています。

この4次元のデータをt-SNEを使って2次元に削減してみましょう。

import numpy as np
from sklearn.manifold import TSNE
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

# 1. データの準備
iris = load_iris()
X = iris.data # 特徴量 (4次元)
y = iris.target # ラベル (品種)

# 2. t-SNEモデルのインスタンス化
# n_components: 削減後の次元数
# perplexity: 非常に重要なパラメータ(後述)
# random_state: 結果を固定するためのシード値
tsne = TSNE(n_components=2, perplexity=30.0, random_state=42)

# 3. t-SNEの実行(次元削減)
X_tsne = tsne.fit_transform(X)

# 4. 結果の確認
print("元のデータの形状:", X.shape)       # (150, 4)
print("t-SNE後のデータの形状:", X_tsne.shape) # (150, 2)

たったこれだけのコードで、4次元のデータが2次元のデータに変換されました。fit_transformメソッドが、データの学習と変換を一度に行ってくれます。

結果をMatplotlibで可視化する

結論として、matplotlib.pyplot.scatterを使い、次元削減後の2次元データを品種ごとに色分けしてプロットします。

2次元に削減したデータX_tsneを散布図としてプロットし、t-SNEがアヤメの品種をうまく分離できているか確認してみましょう。

# (上記のコードに続けて実行)

# 5. 可視化
plt.figure(figsize=(10, 8))

# 品種ごとに色を分けてプロット
for i, target_name in enumerate(iris.target_names):
    plt.scatter(
        X_tsne[y == i, 0],  # yがi(0, 1, 2)のときのx座標
        X_tsne[y == i, 1],  # yがi(0, 1, 2)のときのy座標
        label=target_name
    )

plt.title('t-SNEによるIrisデータセットの可視化')
plt.xlabel('t-SNE dimension 1')
plt.ylabel('t-SNE dimension 2')
plt.legend()
plt.grid(True)
plt.show()

このコードを実行すると、3種類のアヤメがそれぞれ綺麗にグループ分けされた散布図が表示されるはずです。4次元空間では見えにくかったデータの構造が、t-SNEによって2次元平面上にはっきりと現れました。

t-SNEの重要なパラメータを理解しよう【応用編】

t-SNEをただ使うだけでなく、より効果的に活用するためには、いくつかの重要なパラメータを理解しておく必要があります。

n_components:何次元に削減するか

結論として、このパラメータは削減後の次元数を指定し、可視化が目的なので通常は2(2次元)または3(3次元)を指定します。

デフォルトは2です。3Dプロットで可視化したい場合は3を指定しますが、基本的には2のままで問題ありません。

perplexity:最も重要な調整項目

結論として、perplexityは各データ点がどれくらいの近傍点を考慮するかを決めるパラメータで、結果の見た目に大きく影響します。

この値は、データ点の密度の推定に関連しており、t-SNEの結果を大きく左右する最も重要なパラメータです。

  • 一般的に5〜50の間の値が推奨されます。
  • データセットのサイズに応じて調整する必要があります。
  • 値が小さすぎると、局所的な構造に過度に注目してしまい、データが意味のない小さな塊にバラバラになりがちです。
  • 値が大きすぎると、大域的な構造を重視しすぎて、細かなクラスタが潰れてしまうことがあります。

最適な値を見つけるには、いくつかの値で試してみて、最も解釈しやすい結果を選ぶのが一般的です。まずはデフォルト値の30で試し、そこから調整していくのが良いでしょう。

n_iter:計算の繰り返し回数

結論として、これは計算の最適化を行うステップ数を指定するパラメータで、通常はデフォルト値(1000)のままで問題ありません。

t-SNEは、データ点の配置を少しずつ調整していく反復計算によって最適化を行います。このn_iterはその反復回数を指定します。もし結果がうまく収束していないような警告が出る場合は、この値を20005000に増やしてみると改善することがあります。

random_state:結果を固定するおまじない

結論として、random_stateに任意の整数値を指定することで、誰がいつ実行しても全く同じ結果を得られるようになります。

t-SNEは、内部の処理で乱数を使用するため、何も指定しないと実行するたびにプロットの結果が微妙に(時には大きく)変わってしまいます。

分析結果を再現したり、ブログ記事などで他人と結果を共有したりする際には、random_state=42のようにシード値を固定することが非常に重要です。

t-SNEを使う上での注意点

t-SNEは非常に強力なツールですが、その結果を正しく解釈するためには、いくつかの重要な注意点を理解しておく必要があります。

計算コストが高い

結論として、t-SNEはデータ数の2乗に比例して計算量が増えるため、数十万件を超えるような大規模データへの適用には工夫が必要です。

データ数が数万件を超えてくると、計算に数分〜数時間かかることも珍しくありません。

もし大規模なデータセットにt-SNEを適用したい場合は、先にPCAで50次元程度まで次元削減を行ってから、その結果に対してt-SNEを適用するというテクニックがよく使われます。これにより、計算時間を大幅に短縮しつつ、良好な可視化結果を得られることが知られています。

クラスタ間の距離に意味はない

結論として、t-SNEのプロット結果における「クラスタ間の距離の大きさ」や「クラスタの密度」には、定量的な意味はありません。これは最も重要な注意点です。

これは非常によくある誤解です。例えば、プロット上でAクラスタとBクラスタが、CクラスタとDクラスタよりも大きく離れていたとしても、「AとBはCとDよりも関係性が薄い」と結論づけることはできません。

t-SNEはあくまで「似たものが集まっているか」という局所的な構造を可視化するためのツールです。クラスタ間の距離や、クラスタの大きさ・密度といった大域的な構造は正しく反映されません。結果を解釈する際は、この点を必ず念頭に置いてください。

可視化が目的、特徴量抽出には不向き

結論として、t-SNEで得られた2次元や3次元の座標を、そのまま別の機械学習モデルの入力特徴量として使うことは推奨されません。

t-SNEは、与えられたデータセット全体の関係性から座標を決定します。新しい未知のデータ点1つだけをtransformする機能はScikit-learnのTSNEクラスには実装されていません。

そのため、t-SNEはあくまでEDA(探索的データ分析)の一環として、データを理解・可視化するためのツールと割り切り、特徴量エンジニアリングの手段として使うのは避けるのが一般的です。

まとめ

今回は、高次元データを可視化するための強力な手法であるt-SNEについて、その基本からScikit-learnを使った実践、そして注意点までを網羅的に解説しました。

最後に、この記事の重要なポイントをまとめます。

  • t-SNEは、高次元データの局所的な構造を保持したまま、低次元(主に2D or 3D)に埋め込む非線形次元削減手法です。
  • Scikit-learnのsklearn.manifold.TSNEクラスを使えば、数行のコードで簡単にt-SNEを実装できます。
  • perplexityは結果に大きく影響する重要なパラメータで、データに応じて調整が必要です。
  • 結果の再現性を確保するために、random_stateは必ず指定しましょう。
  • **「クラスタ間の距離には意味がない」**など、結果を正しく解釈するための注意点を理解しておくことが非常に重要です。

t-SNEは、複雑なデータセットに隠された洞察を得るための素晴らしい第一歩となります。ぜひ、あなた自身が持っているデータセットでt-SNEを試してみてください。きっと、これまで見えなかったデータの新しい側面を発見できるはずです。

コメント

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