見出し画像

Pythonで機械学習『Validation(検証)」

機械学習モデルをチューニングする上でも必要なバリデーションについて、勉強していきます。

目的

モデルの予測精度を評価し改善していくこと。
また、実際にテストデータから予測する際の精度を見積もること。


手法

1、ホールドアウト法

学習データを、学習データと検証データに切り分けること。単純でわかりやすい。
注意点としては、データ数が100みたいに少ない場合、使いづらい。(推定値のばらつきがおおきくなってしまうかららしい。詳しくはこちら。)

※データ数が少ないときは、後述するクロスバリデーションを使う。

ライブラリはscikitlearnで、書き方は、

train_x,valid_x,train_y,valid_y = train_test_split(X,Y,random_state=777)

他に引数がどんなのがあるかというと、

  • test_size=float 検証用データのサイズを指定。デフォルトは0.25、つまり学習データの25%を検証用データとして分割する。小数点以下は切り上げになる。int(整数)を指定することで、サイズではなくデータの個数を指定することもできる。

  • train_size=float 学習用データのサイズも指定できる。何も書かなければ、自動で1-test_sizeの値にしてくれる。

  • shuffle=bool  シャッフルするかどうか。デフォルトはTrue。時系列データの際には注意。

  • stratify=y   均等に分割させたいデータを指定する。たとえば目的変数yが0or1の2値分類だったら、学習データと検証用データの0or1の比率は同じにしたいから使う。

基本的には、test_sizeとrandom_stateのみでいいよね。

test_sizeはどれくらいがいいのか問題。

諸説ある。

その1。全体像を真似る。
決まったテストデータがあるなら、「学習データとテストデータの割合を真似る」ってのが使えるみたい。たとえば、学習データが100、テストデータが25だったら、学習データをtest_size=0.2(学習データ80検証データ20)で分割するというもの。

その2。よく使われる割合を真似る。
決まったテストデータがない場合、まず全データを学習用:テスト用=4:1で分ける。その後学習用をさらに学習用:検証用=3:1に分ける。
そうすると、学習:検証:テストが6:2:2に分割できる。

その3。データ大量時は、あんま変わんない。
データ数が1万とか10万とかの場合、9:1だろうが8:2だろうがあまり変わらないらしい。

などなど

公式ドキュメントはこちら

2、クロスバリデーション法

ホールドアウト法を繰り返して、最終的にはデータ全体を検証データとして使う方法。
書き方は、

from sklearn.model_selection import KFold

kf = KFold(n_splits=5,random_state=777)

for train_index,valid_index in kf.split(train_x)
     train_x,valid_x = train_x.iloc[train_index],train_x.iloc[valid_index]
     train_y,valid_y = train_y.iloc[train_index],train_y.iloc[valid_index]
     
     lgb_train = lgb.Dataset(train_x,train_y)と続く・・・。

出力結果が分割数分出てくるので、一つにまとめる。
log_lossやMAEは平均を出せば良い。
RMSEの場合、各foldのスコアの平均は、全体平均より低くなる。

n_splitsの数だけど、4か5が基本みたいだ。上記(ホールドアウト法 test_sizeはどれくらいがいいのか)の考え方と同じですね。

2値分類で、説明変数がどちらかに偏っている時、StratifiedKFoldを使う。ホールドアウト法では引数で指定すれば十分だったけど、KFoldの場合、クラスが違う。


この記事が気に入ったらサポートをしてみませんか?