(Kaggle)ランダムフォレストのパラメータを調整する影響をTitanic生存者予測モデルで評価した

#1　はじめに

　　機械学習を学ぶ上でのチュートリアルとして皆さん必ず通る道であろうタイタニック号生存者の予測について、私が行った方法を備忘として記録します。

　前回、Titanicの生存者予測をランダムフォレストによって行いました。その際に使用したパラメータを変えたことによる正解率への影響を評価しました。

　プログラム全体については下記をご覧下さい。
　https://qiita.com/Fumio-eisan/items/77339fc737a3d8cfe179



#2　ランダムフォレストのパラメータ影響評価

　ランダムフォレストは決定木を複数用意して、多数決を取ることで決定木の過学習を平準化するアルゴリズムのことです。

その特徴として、

１．多数決によるアンサンブル学習のため過学習が起こりにくい
２．特徴量の標準化や正規化の処理が必要ない
３．ハイパーパラメータが少ない（サンプリング数と決定木の特徴量数くらい）
４．どの特徴量が重要かを知ることができる

といったことが挙げられます。

　ニューラルネットワークなどのディープランニングのようなキラキラした技術に対して、堅牢な枯れた技術といわれることもあるようです。
　機械学習初心者である私がまずは実際に手を動かして感触を確かめてみたいと思います。

参考にさせて頂いたページ
http://aiweeklynews.com/archives/50653819.html



#2-1　n_estimatorsの影響について

```python

x=[]
y=[]
for i in [1,2,3,4,5,6,7,8,9,10,15,20,25,30,40,50]:
    clf = RandomForestClassifier(
        n_estimators = i ,
        max_depth=5,
        random_state = 0)
    clf = clf.fit(train_X , train_y)
    pred = clf.predict(test_X)
    fpr, tpr , thresholds = roc_curve(test_y,pred,pos_label = 1)
    auc(fpr,tpr)
    accuracy_score(pred,test_y)
    y.append(accuracy_score(pred,test_y))
    x.append(i)
    
plt.scatter(x, y)
plt.xlabel('n_estimators')
plt.ylabel('accuracy')
plt.show()

```

![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/2821c212-27e5-f98f-ed59-836e3444b6dd.png)

　n_estimatorsとは、決定木の数のことになります。
　n_estimatorsについては10程度でサチレートしていることが分かります。さらに50まで上げると過学習になるのか値が下がってきました。
 https://amalog.hateblo.jp/entry/hyper-parameter-search






#2-2　criterionの影響について

```python

x=[]
y=[]
z=[]
for i in [1,2,3,4,5,6,7,8,9,10,15,20,25,30,40,50,100]:
    clf = RandomForestClassifier(
        criterion='gini',
        n_estimators = i ,
        max_depth=5,
        random_state = 0)
    clf = clf.fit(train_X , train_y)
    pred = clf.predict(test_X)
    fpr, tpr , thresholds = roc_curve(test_y,pred,pos_label = 1)
    auc(fpr,tpr)
    accuracy_score(pred,test_y)
    y.append(accuracy_score(pred,test_y))
    
    clf_e = RandomForestClassifier(
        criterion='entropy',
        n_estimators = i ,
        max_depth=5,
        random_state = 0)
    clf_e = clf_e.fit(train_X , train_y)
    pred_e = clf_e.predict(test_X)
    fpr, tpr , thresholds = roc_curve(test_y,pred_e,pos_label = 1)
    auc(fpr,tpr)
    accuracy_score(pred_e,test_y)
    z.append(accuracy_score(pred_e,test_y))

    x.append(i)
    
plt.xlabel('n_estimators')
plt.ylabel('accuracy')
plt.plot(x,y,label="gini")
plt.plot(x,z,label="entropy")
plt.legend(bbox_to_anchor=(1, 1), loc='center right', borderaxespad=0, fontsize=18)
```


![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/9bf01d48-2f16-c887-2c07-f3e150288276.png)

　ジニ関数と情報エントロピーの取り扱いの差による影響を評価しました。
前回でも紹介させていただきましたが、ジニ関数は回帰を得意としており情報エントロピーはカテゴリーデータを得意としているようです。
　決定木数が10未満の時はほとんど変わらない値をとっており、その後10～40まではジニ関数が高くなります。しかし、その後は情報エントロピーのほうが優位になることが分かりました。
　この要因については私の理解に及ばないところがあり、宿題とします。。。

http://data-analysis-stats.jp/2019/01/14/%E6%B1%BA%E5%AE%9A%E6%9C%A8%E5%88%86%E6%9E%90%E3%81%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E8%A7%A3%E8%AA%AC/


#2-3　ramdom_stateの影響について


```python

from sklearn.ensemble import RandomForestClassifier
x=[]
y=[]
z=[]
for i in [1,2,3,4,5,6,7,8,9,10,15,20,25,30,40,50,60,70,80,90,100]:
    clf = RandomForestClassifier(
        criterion='gini',
        n_estimators = 10 ,
        max_depth=5,
        random_state = i)
    clf = clf.fit(train_X , train_y)
    pred = clf.predict(test_X)
    fpr, tpr , thresholds = roc_curve(test_y,pred,pos_label = 1)
    auc(fpr,tpr)
    accuracy_score(pred,test_y)
    y.append(accuracy_score(pred,test_y))
    
    clf_e = RandomForestClassifier(
        criterion='entropy',
        n_estimators = 10 ,
        max_depth=5,
        random_state = i)
    clf_e = clf_e.fit(train_X , train_y)
    pred_e = clf_e.predict(test_X)
    fpr, tpr , thresholds = roc_curve(test_y,pred_e,pos_label = 1)
    auc(fpr,tpr)
    accuracy_score(pred_e,test_y)
    z.append(accuracy_score(pred_e,test_y))

    x.append(i)
    
    

plt.xlabel('ramdom_state')
plt.ylabel('accuracy')
plt.plot(x,y,label="gini")
plt.plot(x,z,label="entropy")
plt.legend(bbox_to_anchor=(1, 1), loc='center right', borderaxespad=0, fontsize=18)
```

![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/4f96a85d-8a02-ed71-1485-57f752d52c76.png)

　次にrandom_stateを変更させてみました。こちらはかなり安定していないことが分かります。凡そこちらも10回程度でサチレートしているように見えます。
　そもそもこの値の意味は、再現性を担保させるためとのことです。

https://teratail.com/questions/99054

>random_stateを指定すると、同じ乱数を発生させることができる。目的は再現性を担保するため。
乱数が必要な理由は、弱予測器（たち）の作成にデータの一部をランダムに選ぶ必要があるから。


#3　まとめ
　今回の確認により、大きく正解率に影響するのはn_estimators：決定木数であることが分かりました。ある程度大きい値を入れることでサチレートしていくことが確認できました。
　仮に計算時間が多量にかかる場合は、自動的にサチレートしたら止まるような細工を入れることが必要になります。