Deep Learning Tutorial

chainer and python

2章 実例を対象とした分類法入門

アイリスデータセット
データの中身はアイリスという花に関するもの。
アイリスデータセットは3つの種類の品種のデータに分類されます。

  • がく片の長さ(Sepal length)
  • がく片の幅(Sepal width)
  • 花弁の長さ(Petal length)
  • 花弁の幅(Petal width)

という特徴量がデータの中身です。

まずはデータを可視化します。

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

data = load_iris()
features = data['data']
feature_names = data['feature_names']
target = data['target']


pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
for i, (p0, p1) in enumerate(pairs):
    plt.subplot(2, 3, i + 1)
    for t, marker, c in zip(list(range(3)), ">ox", "rgb"):
        plt.scatter(features[target == t, p0], features[target == t, p1], marker=marker, c=c)
    plt.xlabel(feature_names[p0])
    plt.ylabel(feature_names[p1])
    plt.xticks([])
    plt.yticks([])

plt.show()

f:id:tsuruchan_0827:20160222193634p:plain




それでは、データの前処理をしていきましょう。

データはcmで統一されていますが、まずは平均を0、分散を1にする「正規化」という作業をしていきます。

scaler = StandardScaler()
scaler.fit(X)

そして、scikit-learnにはPolynomialFeaturesという多項式基底を作成する関数があります。
多項式基底を作ることにより、より分類を強化できます。

poly = preprocessing.PolynomialFeatures(10)
X = poly.fit_transform(np.c_[features[:,0], features[:,1], features[:,2], features[:,3]])


さて、前処理がおわったので、分類をしていきましょう。
今回使う分類アルゴリズムは以下の3つです。

では早速コードを見て行きましょう。

1.ロジスティック回帰

from sklearn import linear_model

LogicReg = linear_model.LogisticRegression(penalty='l2', C=15)
LogicReg.fit(X, y)

正則化にはL2正則化を指定します。
正則化についてはこのサイトがわかりやすいです。
breakbee.hatenablog.jp

2.K-近傍法

from sklearn.neighbors import KNeighborsClassifier

k_mean = KNeighborsClassifier(n_neighbors=2, algorithm='auto')
k_mean.fit(X, y)

ここで指定している”n_neighbors=2”とは...
以下のスライドを見るとわかります

www.slideshare.net
23,24ページ目ぐらいに書いてあります。

3.SVMサポートベクターマシン

from sklearn import svm

Svm = svm.SVC()
Svm.fit(X, y)

SVM

  • コストパラメータ: CC
  • RBFカーネルのパラメータ: γ

を決めるとより良い分類器になります。
詳しくは下のリンク先に書いてあります。
今回はデフォルト設定で行いました。
http://qiita.com/sz_dr/items/f3d6630137b184156a67



ここで、3つの分類器の分類結果を見てみましょう。

[ random_state=0 ]
LogicReg : 0.977777777778
k-mean   : 0.977777777778
svm      : 0.977777777778

どれも約98%の精度です。
ここで、random_stateの設定値を変えるとどうなるかを実験してみました。

[ random_state=10 ]
LogicReg : 1.0
k-mean   : 1.0
svm      : 1.0

なんと、random_state=10 にすると100%の精度になりました。

[ random_state=100 ]
LogicReg : 0.933333333333
k-mean   : 0.977777777778
svm      : 0.977777777778


アイリスデータセットは150×4しかデータがないため非常にデータ数が少ないです。
なので、乱数の種によっては運良く分類精度100%になることもありえるということがわかりました。


全体のコードです。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import decomposition
from sklearn import linear_model, preprocessing
from sklearn import svm
from sklearn.grid_search import GridSearchCV
from sklearn.datasets import load_iris
from sklearn.cross_validation import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler

data = load_iris()

features = data['data']               
feature_names = data['feature_names'] # ['sepal length (cm)','sepal width (cm)',
                                      # 'petal length (cm)','petal width (cm)']
target = data['target']               
target_names = data['target_names']   # ['setosa', 'versicolor', 'virginica']


poly = preprocessing.PolynomialFeatures(10)
X = poly.fit_transform(np.c_[features[:,0], features[:,1], features[:,2], features[:,3]])
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
y = np.array(target)
X, X_test, y, y_test = train_test_split(X_scaled, y, train_size=0.7, random_state=0)


LogicReg = linear_model.LogisticRegression(penalty='l2', C=15)
LogicReg.fit(X, y)
print('LogicReg :', LogicReg.score(X_test, y_test))

k_mean = KNeighborsClassifier(n_neighbors=2, algorithm='auto')
k_mean.fit(X, y)
print('k-mean   :', k_mean.score(X_test, y_test))

Svm = svm.SVC()
Svm.fit(X, y)
print('svm      :', Svm.score(X_test,y_test))