#author("2024-01-26T04:08:32+00:00","","")
#author("2024-01-26T04:09:08+00:00","","")
[[武藤]]

*交差検証によるパラメータ調整 [#zb71e422]
**データ分割・調整手順 [#vcef11e8]
*** 1. train / testに分割 [#p930d310]
*** 2. K分割交差検証によって,trainを"調整用train" / "検証データ"に分割 [#cdca70d7]
"調整用train"と"検証データ"の分割をK回実行する
-(shuffleしない限り)trainデータが全て"調整用train"と"検証データ"の役が回るようにする
--1回のみの分割でパラメータ調整すると,そのときの「"調整用train"に対する"検証データ"スコア」で最も高いパラメータが選ばれてしまい,他の"調整用train" / "検証データ"の組み合わせに対しては最適でない可能性がある
--全ての"調整用train" / "検証データ"の組み合わせに対してバランスよく評価の高いパラメータを選ぶ際に交差検証が有効
#ref(cv5_for_tuning.png,,30%)
[[https://free.kikagaku.ai/tutorial/basic_of_machine_learning/learn/machine_learning_hyperparameters]]

*** 3. 1つのパラメータ組み合わせに対して,K通りの「"調整用train"に対する"検証データ"スコア」を算出し,平均化((GridSearchCVドキュメントのAttributes→best_score_の項目参照「https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html」))[#k7deaa40]

*** 4. 平均スコアが最も高いパラメータで学習モデル構築 [#d2f72672]
-Trainに対して最適パラメータで再学習((ドキュメントの図参照「https://scikit-learn.org/stable/modules/cross_validation.html」))
-GridSearchCVの場合,「.best_estimator_」の中に最適パラメータのモデルが入っているため,これを用いる.
 PipeLineなしの場合
 gscv = GridSearchCV(estimator(学習器), param_grid(辞書式パラメータリスト), 
        scoring(f1_macro/f1_microなど), cv(Kの数), verbose = 1)
 gscv.fit(trainX, trainY)  # 自動的にK通りの"調整用train" / "検証データ"の組み合わせで各パラメータパターンの平均スコアが算出
 gscvBM = gscv.best_estimator_  # 最適パラメータのモデル

*** 5. 学習モデルでtestを予測 [#dc7296c1]
 print(gscvBM.score(testX, testY))  # testに対する評価
testは未知データに対する汎化性能評価のために用いられる

*** 補足 [#b42275a9]
未知データ(test)に対して交差検証は必要か?(パラメータ調整に加えて)
-J分割した各train/testパターンのtrainに対してさらにK分割してパラメータ調整するということ
--各train(調整train/検証データ)で最適パラメータは異なるため,J通りの予測スコアを平均すること自体に意味があるのか疑問(それは単にデータ全体に対する評価になるかもしれない)
--パラメータ調整に時間を要するなら,J倍になるので非現実

*** 参考 [#iab78737]
-[[https://www.codexa.net/cross_validation/]]
-[[https://qiita.com/hikonyun/items/0da02808f19caa06d226]]
-[[https://gochikika.ntt.com/Learning/cv.html]]
-[[https://qiita.com/tomov3/items/039d4271ed30490edf7b]]

** 交差検証でシャッフルするかしないかの議論 [#ma4cf229]
-自前で交差検証する際に使いそうな「StratifiedKFold」の引数で「shuffle=True/False」があり,挙動の違いのメモ.
-また,「StratifiedKFold」と「StratifiedShuffleSplit」の違いについて

*** StratifiedKFold(shuffle = True/False)について [#q515710f]
-各クラスを均等割合でtrain/test(or検証データ)に分割するのは変わらない
-StratifiedKFoldのドキュメントや調べた限りでは,Falseは元のデータと同様の順序でデータ分割される.Trueはデータの順序を(random_stateに基づいて)シャッフルしてからK個の組み合わせにデータ分割される.
--データの順序が元からバラバラならFalseでも良さそう?

#ref(StratifiedKFold.png,,40%)
[[https://www.case-k.jp/entry/2021/02/14/155742]]

***「StratifiedShuffleSplit」について [#t6437fd4]
-各クラスの割合を均等に保ったまま各クラスからランダムに抽出し,train(or調整用train) / test(or検証データ)に割り当てる
-繰り返し割り当てられる,1回も割り当てられないデータなどが生じる
-同クラスの順序や他クラスとの関係性に依存しないため,より汎化的なモデル評価が可能
--%%主観的にはデータを万遍なく回してほしい,順序関係があまりないデータを使っていたので,StratifiedKFold%%

#ref(tratifiedShuffleSplit.png,,40%)

*** 補足 [#s9adde97]
-GridSearchCVでは引数が分類器かつ2(多)クラス問題ならdefaultでStratifiedKFoldだが,shuffle=Falseとなっている模様((GridSearchCVドキュメントのParameters→cvの項目参照「https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html」))
--train_test_split()で層化抽出(stratify)が設定されていると,強制的にshuffle=Trueになる
--train_test_split()において層化抽出(stratify)が設定されていると,強制的にshuffle=Trueになる

*** 参考 [#b8af288f]
-https://qiita.com/chorome/items/54e99093050a9473a189
-https://stackoverflow.com/questions/45969390/difference-between-stratifiedkfold-and-stratifiedshufflesplit-in-sklearn
-https://www.case-k.jp/entry/2021/02/14/155742
-https://nakano-tomofumi.hatenablog.com/entry/2018/01/15/172427

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS