pythonのライブラリでおなじみ、scikit-learnで主成分分析をする方法。
最終的には累積寄与率をプロットできるようにしたい。
タスクとしては基本的な手書き文字認識を題材にする。
基本
import matplotlib.pyplot as plt import seaborn as sns sns.set_style("whitegrid") import sklearn.decomposition # PCAで使うはこれだけ import sklearn.datasets data = sklearn.datasets.load_digits(n_class=5) # sklearnに付属の手書き文字データ pca = sklearn.decomposition.PCA(n_components=2) pca.fit(data.data)
ここで用意したデータはscikitlearnに付属している手書き文字データ。今回はプロットしやすいようにラベル数は5個にしておいた。
基本的な(主成分分析を扱う)部分は最後の2行だけ。
※seabornって何?って思った人はこちら:グラフが綺麗に描けるpythonのライブラリseabornを使うとグラフを描くのが楽しくなる - 技術メモ
2成分プロット
第一主成分と第二主成分を軸にとって二次元プロットする方法。
pca_point = pca.fit_transform(data.data) color = ["r","c","m","b","g"] plt.scatter(*pca_point.T, marker=".", color=map(lambda x:color[x], data.target)) plt.xlabel("PC1") plt.ylabel("PC2") plt.show()
重要なところは最初の一行。元データを主成分でなす空間に射影する関数。
第2主成分まででも結構分けられるんだね。
寄与率・累積寄与率
第一成分、第二成分の基底ベクトルの具体的な値を見る
pca.components_
寄与率を見て、累積寄与率をプロットしてみる。
pca = sklearn.decomposition.PCA()
pca.fit(data.data)
ev_ratio = pca.explained_variance_ratio_
ev_ratio = np.hstack([0,ev_ratio.cumsum()])
plt.plot(ev_ratio)
plt.show()
今回は第3成分以降も取りたかったので引数は与えない形にした。
寄与率は3行目の方法で出てくる。これはnumpyのarrayで格納されているので、numpyの累積和を求める関数(cumsum())が使えるというのがポイント。また、あえて先頭に0を加えることで原点を通るようにしている。
感想
こんな簡単に分析できるなんてscikit-learnすごい!グリッドを入れたらグラフが見やすい!seabornすごい!グラフが綺麗に描けるpythonのライブラリseabornを使うとグラフを描くのが楽しくなる - 技術メモ
補足
手書き文字データの中身を見てみる
plt.figure() for i in range(1,11): plt.subplot(2,5,i) plt.imshow(data.images[i], cmap="gray") plt.show()
参考サイト:
PythonでMNISTを利用する方法まとめ - Qiita
sklearn.datasets.load_digits — scikit-learn 0.20.1 documentation
sklearn.decomposition.PCA — scikit-learn 0.20.1 documentation