現状の正解率もわかったところで、ランダムフォレストのパラメーターを調整していきたいと思います。今はチュートリアルの通りのRandomForestClassifier(n_estimators = 100) しか設定していませんが、これ以外にも多くのパラーメーターがあるみたいです。
3.2.4.3.1. sklearn.ensemble.RandomForestClassifier — scikit-learn 0.19.2 documentation
さらっと見てみるとこんな感じです。それほど理解していないので説明はかなりザクっとしています。
- n_estimators : integer, optional (default=10) ツリーの数
- criterion : string, optional (default=”gini”) データの分割方法
- max_features : int, float, string or None, optional (default=”auto”) 最大の特徴量
- max_depth : integer or None, optional (default=None) ツリーの深さ。何も措定しない場合は全部のみる
- min_samples_split : int, float, optional (default=2) 分割するために最低限必要とするサンプル
- min_samples_leaf : int, float, optional (default=1) 葉を作るために最低限必要とするサンプル
- min_weight_fraction_leaf : float, optional (default=0.) 合計値に対する最低限の重み
- max_leaf_nodes : int or None, optional (default=None) 最大の葉を数を指定
- min_impurity_split : float, 木の成長を止めるためのしきい値
- min_impurity_decrease : float, optional (default=0.) ノードが分割するしきい値
- bootstrap : boolean, optional (default=True) bootstrapを使うかどうかの選択
- oob_score : bool (default=False) 精度を推定するためにout-of-bagサンプルを使用するかどうかの選択
- n_jobs : integer, optional (default=1) 並列処置の数を指定する
- random_state : int, RandomState instance or None, optional (default=None) シード値を設定するかどうかの選択(乱数を固定するかどうか)
- verbose : int, optional (default=0) ツリーの成長の冗長性をコントロールする
- warm_start : bool, optional (default=False) すでに学習をしたモデルに新しく学習させるかどうか
- class_weight : dict, list of dicts, “balanced”, それぞれのクラスに重みをつけるかどうか
これらのパラメーターになんの値を設定すればいいのか全然わからないので、グリッドサーチという総当たりを行いたいと思います。
グリッドサーチの詳細はこちら。
3.2. Tuning the hyper-parameters of an estimator — scikit-learn 0.19.2 documentation
グリッドサーチとは
パラメーターを事前に辞書型で設定しておき、それをモデルに順番に当てはめるだけです
from sklearn.model_selection import GridSearchCV parameters = { 'n_estimators' : [30, 50, 100, 300], 'max_features' : [10, 20, 30], 'random_state' : [0], 'n_jobs' : [1], 'min_samples_split' : [10, 30, 50, 100], 'max_depth' : [10, 30, 50, 100] } clf1 = GridSearchCV(RandomForestClassifier(), parameters) clf1.fit(train_X, train_y) print(clf1.best_estimator_)
おそらく順番に実行していますので、かなり時間がかかります。
待っている間に暇ですので、AKBの新曲『センチメンタルトレイン』を聞いてみたのですが、なんとなく乃木坂でも聞いたことありますね。グッグって見たらmパクリ騒動の話があったらしいです。
全然終わる気配がしないので、FlaskというPython製Webアプリケーションフレームワークの公式サイトでも見ていきます。
Flaskへ ようこそ — Flask v0.5.1 documentation
まずはインストールしろ、と書いてありますので、インストールをします。
sudo easy_install Flask
インストールできたか確認。
$ flask --version Flask 0.12.2 Python 3.6.2
Flaskをインストールできました。
グリッドサーチの方も終わったぽいです。 だいたい15分くらいかかっていました。 結果はこんな感じです。
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', max_depth=100, max_features=30, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=10, min_weight_fraction_leaf=0.0, n_estimators=30, n_jobs=1, oob_score=False, random_state=0, verbose=0, warm_start=False)
max_depthとmax_featuresは最大の値がベストとされていますね。n_estimatorsは最低の値がベストとされています。最初のパラメーターを若干ミスったような気がします。
パラメータを下記で設定し直します。
parameters = { 'n_estimators' : [5, 10, 30], 'max_features' : [30, 60, 100], 'random_state' : [0], 'n_jobs' : [1], 'min_samples_split' : [5, 10], 'max_depth' : [100, 150, 200] }
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', max_depth=100, max_features=30, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=5, min_weight_fraction_leaf=0.0, n_estimators=30, n_jobs=1, oob_score=False, random_state=0, verbose=0, warm_start=False)
そんなに変わっていないということは、やはりこれがベストなんですかね? そもそもとしましてはグリップリサーチは万能ではないとのことですが、ひとまずこのパラメーターを設定してみます。
forest = RandomForestClassifier(n_estimators=30, max_depth=100, max_features=30, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=5, min_weight_fraction_leaf=0.0, oob_score=False, random_state=0, verbose=0, n_jobs=1, ) forest = forest.fit(train_data_features, train["name_int"])
学習させ直したところで、k分割交差検証をさせてみます。
from sklearn.model_selection import cross_val_score print(cross_val_score(forest, train_data_features, train['name_int'], cv=20))
[ 0.96039604 0.96039604 0.96039604 0.96039604 0.97029703 0.96039604 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96969697 0.96969697 0.96969697 0.96969697 0.97979798 0.96969697]
お、全体的に1分上がって、9割6分になっています。
y_preds = forest.predict(train_X) confusion_matrix(test_y, y_preds)
array([[940, 26], [ 34, 0]])
昨日のがこちら
array([[926, 31], [ 43, 0]])
数値が変わっていますが、改善されたのかよくわからないですね。
今日の結果
今日のAKBの呟きは64件でした。 最後という単語が並んでいましたので、誰か卒業するのかと思いました。
{'嬉しい': 9, '可愛い': 6, '楽しい': 5, 'すごい': 4, 'ない': 3, '優しい': 2, '明るい': 1, '暗い': 1, 'やすい': 1, 'うい': 1, 'いい': 1, '遅い': 1, '詳しい': 1, 'よい': 1, 'かわいい': 1, '熱い': 1, '凄い': 1, '長い': 1, '良い': 1, 'うまい': 1, '面白い': 1, 'ぽい': 1}) '公演': 19, '最後': 13, '私': 12, '応援': 12, 'お願い': 11, '今日': 10, '嬉しい': 9, 'ん': 9, 'ちゃん': 9, '生誕': 8, '祭': 8, 'おりん': 8, '皆さん': 7, '日': 7, 'チームフォー': 7, '手': 7, 'する': 44, '公演': 19, 'なる': 14, '最後': 13, '私': 12, '応援': 12, '見る': 12, 'お願い': 11, '今日': 10, '嬉しい': 9, 'ん': 9, 'ちゃん': 9, '生誕': 8, '祭': 8, 'おりん': 8, 'てる': 8, 'くださる': 8, 'いる': 8,