64次元を見てみる
CoddyのMachine Learningジャーニー「教師なし学習」セクションの一部。レッスン 29/51。
この章では、手書き数字を使ってPCAを実際に試します。章の終わりまでに、スキャン画像を少数の数値に圧縮し、そこから再構成します。
まず、見てみましょう。1つのスキャンは64ピクセルですが、64個の軸を持つグラフはないため、PCAはそれらを2つに圧縮します。
digits = load_digits()
X = digits.data
y = digits.target
points = PCA(n_components=2).fit_transform(X)
for d in range(10):
ax.scatter(points[y == d, 0], points[y == d, 1], label=str(d))ここではスケーラーを使いません。すべてのピクセルで単位は共通で、インクの値は0から16です。
PCAはyを一度も見ていません。点に色を付けているだけです。それでも各数字はそれぞれの領域に集まっています。その構造はピクセルの中にありました。
チャレンジ
中級子ども向けの手書きアプリは、子どもたちがどの数字を見間違える可能性があるかを知りたいと考えています。プログラムは、358のように続けて入力された数字をchosenに読み込みます。
- PCAを使って、1,797個すべてのスキャンをそれぞれ2つの数値に圧縮し、
pointsに格納します。 - 選択した各数字のスキャンを、数字のラベルを付けて散布図にします。凡例を追加して表示します。
report_closest(points, y, chosen)を呼び出します。
046の場合、次のように表示されます。
Closest on the map: 4 and 6 (13.6 apart)そして、次の図を描画します。その後、Coddyがグラフを説明します。
自分で試してみよう
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
# 類似度の測定より:選択された数字のうち、マップ上で中心が最も近い2つを表示する
def report_closest(points, y, chosen):
best = -1
for i in range(len(chosen)):
for j in range(i + 1, len(chosen)):
a = points[y == chosen[i]].mean(axis=0)
b = points[y == chosen[j]].mean(axis=0)
dist = np.sqrt(((a - b) ** 2).sum())
if best == -1 or dist < best:
best = dist
pair = (chosen[i], chosen[j])
print(f"Closest on the map: {pair[0]} and {pair[1]} ({best:.1f} apart)")
# 1,797個のスキャンデータ:各データの64ピクセルはXに、描かれた数字はyに格納される
digits = load_digits()
X = digits.data
y = digits.target
# 比較する数字を358のように続けて入力する
chosen = []
for ch in input():
chosen.append(int(ch))
# 以下の行は変更しないでください
fig, ax = plt.subplots()
ax.set_title("Digits that look alike")
ax.set_xlabel("Component 1")
ax.set_ylabel("Component 2")
# 以下にコードを書いてください
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
教師なし学習のすべてのレッスン
自分で練習してみよう: Pythonオンラインコンパイラ