Pythonで機械学習 - Evaluation


構築する予測モデルに用いるアルゴリズムの評価として、交差検証(Cross-Validation)による精度の評価を行います。

# 準備

必要なライブラリをインポートします。交差検証には、Scikit-LearnのStratifiedKFold(層化k-分割)を使用します。


```python
import pandas as pd
from sklearn.model_selection import StratifiedKFold
import numpy as np
from sklearn.ensemble import RandomForestClassifier
```

整形済みデータを読み込みます。


```python
train = pd.read_csv("train_prep.csv")
```

読み込んだデータから、検証に用いる説明変数と目的変数をそれぞれ準備します。


```python
expvars = ["Pclass","SexInt","AgeFillNa","FareFillNa","IsAlone"] # 説明変数のリスト
data = train.copy()[expvars] # 説明変数
label = train["Survived"] # 目的変数
```

# モデルの構築と評価

k-分割は、テストデータを一定数に分割（今回は10）し、9つが学習データ、1つが検証データという組み合わせを順次つくり、予測モデルを構築します。


```python
clf = RandomForestClassifier()
skf = StratifiedKFold(n_splits=10,random_state=1)
scores = []
for train_ix,test_ix in skf.split(data,label): # テストデータを分割し、順次処理
    clf.fit(data.ix[train_ix],label.ix[train_ix]) # 予測モデルの構築
    score = clf.score(data.ix[test_ix],label.ix[test_ix]) # 予測モデルの精度評価を検証データで行う。
    scores.append(score)
```

# 精度の確認

精度を確認します。10回分のモデル構築と検証を実施していますが、平均は08.7%です。


```python
print scores
print np.mean(scores) # スコアの平均
```

    [0.69999999999999996, 0.77777777777777779, 0.7640449438202247, 0.8651685393258427, 0.84269662921348309, 0.797752808988764, 0.84269662921348309, 0.7865168539325843, 0.8314606741573034, 0.86363636363636365]
    0.807175122007


# モデルの選択

同様にして、複数のアルゴリズムで精度を比較し、最も精度が高いものを選択します。

アルゴリズムをインポートします。


```python
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC, LinearSVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import Perceptron
from sklearn.linear_model import SGDClassifier
algs = [
    RandomForestClassifier,
    DecisionTreeClassifier,
    LogisticRegression,
    LinearSVC,
    KNeighborsClassifier,
    GaussianNB,
    Perceptron,
    SGDClassifier
]
```

精度を評価する処理を関数化します。


```python
def cross_validate(clf,data,label):
    skf = StratifiedKFold(n_splits=10,random_state=1)
    scores = []
    for train_ix,test_ix in skf.split(data,label): # テストデータを分割し、順次処理
        clf.fit(data.ix[train_ix],label.ix[train_ix]) # 予測モデルの構築
        score = clf.score(data.ix[test_ix],label.ix[test_ix]) # 予測モデルの精度評価を検証データで行う。
        scores.append(score)
    return np.mean(scores)
```

各アルゴリズムによる交差検証を行い精度を確認してみます。


```python
results = {}
for alg in algs:
    clf = alg() #分類器の作成
    score = cross_validate(clf,data,label) # 交差検証
    alg_name = str(type(clf)).split("'")[1].split(".")[-1] # インスタンスからアルゴリズム名を取得
    results[alg_name] = score # アルゴリズム名と精度を格納
```

結果を可視化すると、アルゴリズムの中ではランダムフォレストが最も精度が良いと言えます。


```python
print pd.Series(results).sort_values(ascending=False)
```

    RandomForestClassifier    0.813830
    LogisticRegression        0.786749
    DecisionTreeClassifier    0.785764
    GaussianNB                0.762242
    LinearSVC                 0.738409
    KNeighborsClassifier      0.716363
    Perceptron                0.593985
    SGDClassifier             0.579110
    dtype: float64

### ロジスティック回帰
ロジスティック回帰は、各項目がどの程度、結果に影響しているかを定量的に把握できます。


```python
clf = LogisticRegression()
clf.fit(data,label)
```




    LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
              intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
              penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
              verbose=0, warm_start=False)




```python
clf.coef_
```




    array([[ -1.03219247e+00,   2.53219867e+00,  -2.91694603e-02,
              1.80351166e-03,   9.32819823e-02]])




```python
pd.DataFrame(columns=data.columns,data=clf.coef_)
```




<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Pclass</th>
      <th>SexInt</th>
      <th>AgeFillNa</th>
      <th>FareFillNa</th>
      <th>IsAlone</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-1.032192</td>
      <td>2.532199</td>
      <td>-0.029169</td>
      <td>0.001804</td>
      <td>0.093282</td>
    </tr>
  </tbody>
</table>
</div> 

[戻る](https://qiita.com/nittaryo1977/private/b16386ef78152a20bc2b)