概要
“Pythonではじめる機械学習”の主成分分析(PCA)のところで、著名人の顔画像データ(LFW peopleデータセット)に対するk-近傍法の精度を確認している。
- LFW peopleのデータを、最低20枚以上の画像がある人物で絞り込んで読み込み
- 各人物の画像を最大でも50枚以内となるよう制限(配列要素数の制限手順についてはこちらを参照)
- 2063人の人物について、87×65ピクセルを1次元化した5,655個の数値配列を特徴量データ(X_people)、各画像の人物の番号を収めた配列(y_people)をターゲットデータとする
- 画像データを訓練データとテストデータに分割
- このデータセットをそのまま1-nnで予測したスコアは、0.2程度でそれほどよくない
- 画像データに主成分分析(PCA)を用いて、100個の主成分で変換したデータについても1-nnを適用していて、この場合のスコアは0.31
コード例ではPCAインスタンス生成時の引数としてwhiten=True
を指定しているが、これを指定しない場合、データ変換後のスコアは0.23でこうじょうしなかった。
なお、スコアが書籍掲載値と異なるが、画像データの内容も書籍と今回実行時で異なっている。
コードと実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import numpy as np from sklearn.datasets import fetch_lfw_people from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.decomposition import PCA ds = fetch_lfw_people(min_faces_per_person=20, resize=0.7) mask = np.zeros(ds.target.shape, dtype=np.bool) for target in np.unique(ds.target): mask[np.where(ds.target == target)[0][:50]] = 1 X_people = ds.data[mask] y_people = ds.target[mask] X_people /= 255 X_train, X_test, y_train, y_test = train_test_split( X_people, y_people, stratify=y_people, random_state=0) knn = KNeighborsClassifier(n_neighbors=1) knn.fit(X_train, y_train) print("Test score (1-nn): {:.2f}".format(knn.score(X_test, y_test))) pca = PCA(n_components=100, whiten=True, random_state=0).fit(X_train) X_train_pca = pca.transform(X_train) X_test_pca = pca.transform(X_test) knn.fit(X_train_pca, y_train) print("Test score (1-nn) w/ PCA: {:.2f}".format(knn.score(X_test_pca, y_test))) print("\nUsed data shape") print(X_train.shape, X_test.shape) print(X_train_pca.shape, X_test_pca.shape) print(y_train.shape, X_test.shape) # Test score (1-nn): 0.23 # Test score (1-nn) w/ PCA: 0.31 # # Used data shape # (1547, 5655) (516, 5655) # (1547, 100) (516, 100) # (1547,) (516, 5655) |