CUBE SUGAR CONTAINER

技術系のこと書きます。

Python: scikit-learn のハイパーパラメータを GridSearchCV で最適化する

機械学習のアルゴリズムにおいて、人が調整する必要のあるパラメータのことをハイパーパラメータと呼ぶ。 これは自動では決められないので、色々な値を試したりして汎化性能が高くなるものを選ばなきゃいけない。 今回はハイパーパラメータを決めるのに scikit-learn に実装されている GridSearchCV という機能を使ってみる。 これを使うと、あらかじめいくつか候補を与えることで、その中から汎化性能が高くなるものを選んでくれる。

使った環境は次の通り。

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G29
$ python --version
Python 3.6.2

下準備

まずは必要なパッケージをインストールしておく。

$ pip install scikit-learn numpy scipy

サンプルコード

次のサンプルコードでは GridSearchCV を使って DecisionTreeClassifier の最適なハイパーパラメータを探索している。 DecisionTreeClassifier というのは決定木のアルゴリズムを使った分類器を指す。 データセットには、みんな大好きアイリス (あやめ) データセットを使った。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV


def main():
    # アイリスデータセットを読み込む
    dataset = datasets.load_iris()

    # 教師データとラベルデータを取り出す
    features = dataset.data
    targets = dataset.target

    # 優れたハイパーパラメータを見つけたいモデル
    clf = DecisionTreeClassifier()

    # 試行するパラメータを羅列する
    params = {
        'max_depth': list(range(1, 20)),
        'criterion': ['gini', 'entropy'],
    }

    grid_search = GridSearchCV(clf,  # 分類器を渡す
                               param_grid=params,  # 試行してほしいパラメータを渡す
                               cv=10,  # 10-Fold CV で汎化性能を調べる
                               )

    # グリッドサーチで優れたハイパーパラメータを探す
    grid_search.fit(features, targets)

    print(grid_search.best_score_)  # 最も良かったスコア
    print(grid_search.best_params_)  # 上記を記録したパラメータの組み合わせ


if __name__ == '__main__':
    main()

説明はコメントでしてるけど、基本的には GridSearchCV に分類器とハイパーパラメータの候補を渡す。 その上でデータセットに対して学習 (fit) させると、最も汎化性能の高い組み合わせがメンバの best_params_ に入る。

実行してみる

上記のサンプルコードを適当な名前で保存したら実行してみよう。 すると、候補の中で最も高い汎化性能が得られるものは精度が 0.96 であることが分かる。 そして、そのときのパラメータは criterionginimax_depth3 ということが分かった。

$ python gridsearch.py
0.96
{'criterion': 'gini', 'max_depth': 3}

まとめ

scikit-learn でハイパーパラメータの調整をするときは GridSearchCV を使うと便利。