[ハンマー]クロス検証とグリッド検索



  • 検証セット
    モデルを評価してスーパーパラメータ調整を行うと、トレーニングセットから取り出したデータセットはテストセットを使用しなくなります.

  • クロス検証
    トレーニングセットを複数のフォルダに分割し、1つのフォルダが検証セットの役割を果たし、残りのフォルダでモデルトレーニングを行います.これは、すべてのロッドについて検証スコアを取得し、平均する方法である.


  • グリッドサーチ(Grid Search)
    スーパーパラメータ探索の自動化ツール.参照するパラメータをリストした後、クロス検証を行い、最適な検証ポイントのパラメータの組合せを選択します.最後に,これらのパラメータの組合せを用いて最終モデルを訓練した.

  • ランダムサーチ
    連続パラメータの値を参照するときに便利です.検索する値を直接リストするのではなく、サンプリング可能な確率分布オブジェクトを渡します.指定したサンプリング回数に基づいてクロス検証を行うため、検索量を調整できます.

  • cross_validate()
    クロス検証を実行する関数.

  • GridSearchCV
    クロス検証によるスーパーパラメータ検索.ベストモデルを見つけたら、トレーニングセット全体を使って最終モデルを訓練します.

  • RandomizedSearchCV
    クロス検証によりランダムスーパーパラメータ検索を行います.ベストモデルを見つけたら、トレーニングセット全体を使って最終モデルを訓練します.
  • 検証セット

    
    import pandas as pd
    wine = pd.read_csv('https://bit.ly/wine-date')
    
    data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
    target = wine['class'].to_numpy()
    
    from sklearn.model_selection import train_test_split
    train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)
    sub_input,val_input,sub_target,val_target=train_test_split(train_input,train_target,test_size=0.2,random_state=42)
    
  • トレーニング/テストデータ分離
  • 訓練データから検証データを分離
  • 
    from sklearn.tree import DecisionTreeClassifier
    
    dt = DecisionTreeClassifier(random_state=42)
    dt.fit(sub_input, sub_target)
    
    print(dt.score(sub_input, sub_target))
    print(dt.score(val_input, val_target))
    
  • 誇張にふさわしい
  • 検証セットを作るためにトレーニングセットが減った
  • 解決方法:クロス検証
  • クロス検証

    from sklearn.model_selection import cross_validate
    scores=cross_validate(dt,train_input,train_target)
    print(scores)
    
  • cross validate直接検証セット指定不要
  • デフォルトは5回のクロス検証
  • fit time:トレーニング時間
  • score time:検証時間
  • test score:フォルダのスコアを検証(テストスコアではありません!)
  • 
    import numpy as np
    print(np.mean(scores['test_score']))
    
    from sklearn.model_selection import StratifiedKFold
    scores=cross_validate(dt,train_input,train_target,cv=StratifiedKFold())
    print(np.mean(scores['test_score']))
    
  • 全てのデータを混ぜ合わせて配布しているので混ぜ合わせる必要はない
  • ただしクロス検証の場合、トレーニングセットをミックスするにはスプリッタを指定する必要がある
  • 回帰モデルはKFold、分類モデルはStratifiedKFold
  • splitter=StratifiedKFold(n_splits=10,shuffle=True,random_state=42)
    scores=cross_validate(dt,train_input,train_target,cv=splitter)
    print(np.mean(scores['test_score']))
    
  • 10つ折りのクロスチェックを行いたい場合は、それをスプリッタに保存し、スプリッタに入れます.
  • グリッドサーチ(1)

    
    from sklearn.model_selection import GridSearchCV
    params={'min_impurity_decrease':[0.0001,0.0002,0.0003,0.0004,0.0005]}
    
  • グリッド探索クラスのパラメータ値リストをディックマニュアルに作成する.
  • 
    gs=GridSearchCV(DecisionTreeClassifier(random_state=42),params,n_jobs=-1)
    
  • 参照オブジェクトモデルとparams変数をグリッド探索クラスに渡し、グリッド探索オブジェクトを作成する.
  • n jobs指定-1は、システム内のすべてのカーネルを使用します.
  • 
    gs.fit(train_input,train_target)
    
    dt=gs.best_estimator_
    
    print(dt.score(train_input,train_target))
    print(gs.best_params_)
    
  • gsオブジェクトがfitメソッドを呼び出した後、min不純物減少(5)*クロス検証(5)=25モデルを訓練する.
  • 検証点数が最も高いスーパーパラメータで訓練したモデルをbest推定器に格納し、単独で訓練することなくscoreを確認する
  • ベストパラメータはbestparamsに格納
  • 
    
    
    print(gs.cv_results_['mean_test_score'])
    
  • 5回のクロス検証で得られた点数
  • 最適スーパーパラメータ0.0001の位置で最も高い得点
  • best_index=np.argmax(gs.cv_results_['mean_test_score'])
    print(gs.cv_results_['params'][best_index])
    
  • argmax最大値インデックス抽出可能
  • argminが最小値のインデックスを抽出できる
  • グリッド検索(2)

    
    params = {'min_impurity_decrease': np.arange(0.0001, 0.001, 0.0001),
              'max_depth': range(5, 20, 1),
              'min_samples_split': range(2, 100, 10)
              }
    
  • arange関数は、2番目のパラメータに達するまで、1番目のパラメータ値から3番目のパラメータで並び続けます.
  • range関数は整数のみでarangeのように表示できます.
  • クロス検証回数は91510=1350回、5-折返し検証を行ったモデルは1350*5=6750個.
  • 
    gs=GridSearchCV(DecisionTreeClassifier(random_state=42),params,n_jobs=-1)
    gs.fit(train_input,train_target)
    print(gs.best_params_)
    print(np.max(gs.cv_results_['mean_test_score']))
    

    ランダムサーチ

    from scipy.stats import uniform,randint
    
    params = {'min_impurity_decrease': uniform(0.0001, 0.001),
              'max_depth': randint(20, 50),
              'min_samples_split': randint(2, 25),
              'min_samples_leaf': randint(1, 25),
              }
    
  • randint整数で数字を抽出
  • 誤抽出数
  • 
    from sklearn.model_selection import RandomizedSearchCV
    
    gs = RandomizedSearchCV(DecisionTreeClassifier(random_state=42), params, n_iter=100, n_jobs=-1, random_state=42)
    gs.fit(train_input, train_target)
    print(gs.best_params_)
    
  • n iterサンプリング回数指定可能.サンプリング回数は、システムリソースの許容範囲が大きいほどよい.
  • 
    print(np.max(gs.cv_results_['mean_test_score']))
    
    dt=gs.best_estimator_
    print(dt.score(test_input,test_target))
    
  • 最適パラメータトレーニングモデルでテスト
  • 참고문헌: 혼공머신