scikit-learnでPCA散布図を描いてみる

高次元の特徴量を持つデータの分布をおおまかに把握する方法として、PCA(主成分分析)で次元削減した後散布図を描く方法がある。 ここでは、Dockerを用いてデータ分析プラットフォームAnaconda環境を構築し、scikit-learnを使ってPCA散布図を描いてみる。

環境

Ubuntu 16.04.1 LTS 64bit版、Docker 1.12.5

$ uname -a
Linux vm-ubuntu64 4.4.0-59-generic #80-Ubuntu SMP Fri Jan 6 17:47:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.1 LTS
Release:        16.04
Codename:       xenial

$ docker --version
Docker version 1.12.5, build 7392c3b

DockerでAnaconda環境を構築する

Anacondaはデータ分析・機械学習に特化したPythonディストリビューションであり、Numpy、Scipy、Matplotlib、Sympy、scikit-learn、pandasなどのライブラリやブラウザ上から対話的なスクリプト実行、プロット表示が行えるJupyter Notebookが標準でインストールされている。 今回はscikit-learnとMatplotlibしか使わないが、Jupyter Notebookを利用することでプロット結果の確認が簡単になるため、Anacondaを利用することにする。

Anacondaは公式でDockerイメージを提供しており、これを利用すると簡単に環境を構築することができる。

$ docker pull continuumio/anaconda
Using default tag: latest
latest: Pulling from continuumio/anaconda

8ad8b3f87b37: Pull complete
fa2bdab78aa4: Pull complete
074a37ca9de6: Pull complete
751e84aa2169: Pull complete
Digest: sha256:6e2b524bce61a32b1a85bb4fc88ba8f2079e3b41d8b324250a3be35c45d7d9ee
Status: Downloaded newer image for continuumio/anaconda:latest

$ docker run -i -t -p 8888:8888 continuumio/anaconda /bin/bash -c "/opt/conda/bin/conda install jupyter -y --quiet && mkdir /opt/notebooks && /opt/conda/bin/jupyter notebook --notebook-dir=/opt/notebooks --ip='*' --port=8888 --no-browser"

サーバが起動したら、ブラウザからhttp://[host ip address]:8888/を開くことでJupyter Notebookにアクセスできる。

f:id:inaz2:20170123193200p:plain

irisデータセットのPCA散布図を描いてみる

PCA(Principal Component Analysis; 主成分分析)は、高次元の特徴量を持つデータについて、元のデータのばらつきをよく表す低次元の合成変数を得る手法である。

ここでは分析対象として、有名なサンプルデータセットであるirisを用いることにする。

上の例を参考に、PCAで2次元に次元削減して散布図を描いてみると次のようになる。

%matplotlib inline
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA

iris = datasets.load_iris()

print iris.data.shape
# (150, 4)

print iris.target
"""
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
"""

X_reduced = PCA(n_components=2).fit_transform(iris.data)

print X_reduced.shape
# (150, 2)

plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=iris.target)
# <matplotlib.collections.PathCollection at 0x7f5d087be4d0>

f:id:inaz2:20170123203948p:plain

上の結果から、4次元の特徴量を持つデータを2次元の散布図としてプロットできていることがわかる。