導入 機械学習プロジェクトに取り組むとき、すべてのデータ サイエンティストが直面しなければならない質問が 1 つあります。それは、「自分のデータに最適な機械学習モデル アーキテクチャはどれか?」です。 [[326370]] 残念ながら、どちらのモデルが優れているかについては明確な答えはありません。このような不確実性に直面したときの通常のアプローチは、「実験する」ことです。 この記事では、データセット上で複数のモデルを素早くテストし、優れたパフォーマンスを発揮する可能性のある機械学習モデルを見つける方法を説明します。これにより、モデルの微調整と最適化に集中できるようになります。 機械学習データセット 実験を始める前に、データセットが必要です。ここでの問題は教師ありバイナリ分類タスクであると仮定します。まず、sklearn から乳がんデータセットを読み込みます。 - sklearn.datasetsからload_breast_cancer をインポートします
- X, y = データ = load_breast_cancer(return_X_y= True )
次に、データをトレーニング セットとテスト セットに分割する必要があります。分割比率は75/25です。 - sklearn.model_selectionからtrain_test_split をインポートします
- X_train、X_test、y_train、y_test = train_test_split(X、y、test_size=0.25、random_state=8675309) です。
Pythonコーディング このデータセットで 6 つの異なるモデルの適合度を簡単にテストします。 - ロジスティック回帰
- ランダムフォレスト
- K 最近隣
- サポートベクターマシン
- ガウス単純ベイズ
- XGBoost
各モデルの適合性をより正確に表現するには、実際にはデフォルトのパラメータを微調整する必要がありますが、デモンストレーションの目的で、全体的な考え方がより明確になるように、各モデルのデフォルトのパラメータを使用します。 - sklearn.linear_modelからLogisticRegression をインポートします
- sklearn.neighborsからKNeighborsClassifier をインポートします
- sklearn.svmからSVC をインポートします
- sklearn.ensembleからRandomForestClassifier をインポートします
- sklearn.naive_bayesからGaussianNB をインポートします
- xgboostからXGBClassifier をインポートします
- sklearnからmodel_selectionをインポート
- sklearn.utilsからclass_weightをインポートします
- sklearn.metricsからclassification_reportをインポート
- sklearn.metricsからconfusing_matrix をインポートします
- numpyをnpとしてインポートする
- pandasをpdとしてインポートする
- def run_exps(X_train: pd.DataFrame、y_train: pd.DataFrame、X_test: pd.DataFrame、y_test: pd.DataFrame) -> pd.DataFrame:
- '' '
- 多くのモデルをテストして勝者を見つけるための軽量スクリプト
- :param X_train: トレーニング分割
- :param y_train: トレーニングターゲットベクトル
- :param X_test: テスト分割
- :param y_test: テスト対象ベクトル
- :戻り値:予測のDataFrame
- '' '
- dfs = []
- モデル = [
- ( 'LogReg' 、ロジスティック回帰())、
- ( 'RF' 、 RandomForestClassifier())、
- ( 'KNN' 、 KNeighborsClassifier())、
- ( 'SVM' 、 SVC())、
- ( 'GNB' 、ガウスNB())、
- ( 'XGB' 、 XGBClassifier())
- ]
- 結果 = []
- 名前 = []
- スコアリング = [ '精度' 、 '精度加重' 、 '再現率加重' 、 'f1加重' 、 'roc_auc' ]
- target_names = [ '悪性' 、 '良性' ]
- のために モデル内のモデル名:
- kfold = model_selection.KFold(n_splits=5、シャッフル= True 、ランダム状態=90210)
- cv_results = model_selection.cross_validate(モデル、X_train、y_train、cv=kfold、スコアリング=スコアリング)
- clf = model.fit(X_train, y_train)
- y_pred = clf.predict(X_test)
- print(名前)
- print(分類レポート(y_test, y_pred, target_names=target_names))
- 結果を追加します(cv_results)
- names.append(名前)
- this_df = pd.DataFrame(cv_results)
- this_df[ 'モデル' ] =名前
- dfs.append(このdf)
- 最終 = pd.concat(dfs, ignore_index= True )
- 最終返却
- 最終 = run_exps(X_train、y_train、X_test、y_test)
- ファイナル
上記の Python コードには説明すべき点がたくさんあります。まず、トレーニング セットに 5 段階のクロス検証を適用して作成されたデータセットを保持するために使用される変数 dfs を作成します。 次に、モデルは、テストする各分類子の名前とクラスを含むタプルのリストに保存されます。この後、このリストをループして 5 段階のクロス検証を実行します。各実行の結果は、dfs リストに追加する pandas データフレームに記録されます。ここでの指標は 2 つのクラスの加重平均指標であることに注意する必要があります。 テストセットの分類レポートは次のとおりです。 評価結果 run_exps() スクリプトから返された final(dataframe) 内のデータを分析します。 各モデルのメトリックの分布をより正確に推定するために、30 個のサンプルに対して経験的ブートストラップを実行しました。さらに、パフォーマンス メトリックとフィッティング時間メトリックの 2 つのメトリックに焦点を当てます。次の Python コード ブロックはこれを実現します。 - ブートストラップ = []
- リスト内のモデルの場合( set ( final.model.values )):
- model_df = final.loc[final.model == モデル]
- ブートストラップ = model_df.sample(n=30, replace = True )
- bootstraps.append(ブートストラップ)
-
- bootstrap_df = pd.concat(bootstraps, ignore_index= True )
- results_long = pd.melt(bootstrap_df、id_vars=[ 'モデル' ]、var_name= 'メトリック' 、value_name= '値' )
- time_metrics = [ 'fit_time' , 'score_time' ] # フィット時間メトリック
- ## パフォーマンス指標
- results_long_nofit = results_long.loc[~results_long[ 'metrics' ].isin(time_metrics)] # 適合データなしで自由度を取得
- results_long_nofit = results_long_nofit.sort_values( by = '値' )
- ##時間メトリクス
- results_long_fit = results_long.loc[results_long[ 'metrics' ].isin(time_metrics)] #適合データを使用した自由度
- results_long_fit = results_long_fit.sort_values( by = '値' )
まず、5 段階のクロス検証からパフォーマンス メトリックをプロットしてみましょう。 - matplotlib.pyplot をpltとしてインポートします。
- Seaborn をSNSとしてインポートする
- plt.figure(図のサイズ=(20, 12))
- sns.set (フォントスケール=2.5)
- g = sns.boxplot(x= "モデル" 、y= "値" 、色相= "メトリック" 、データ=results_long_nofit、パレット= "Set3" )
- plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
- plt.title( '分類メトリックによるモデルの比較' )
- #plt.savefig( './benchmark_models_performance.png' 、dpi=300)
- plt.show()
サポート ベクター マシンはすべてのメトリックにわたってデータに適合していないのに対し、アンサンブル決定木モデル (ランダム フォレストと XGBoost) はデータに非常に適合していることは明らかです。 トレーニング時間はどうですか? - plt.figure(図のサイズ=(20, 12))
- sns.set (フォントスケール=2.5)
- g = sns.boxplot(x= "モデル" 、y= "値" 、色相= "メトリック" 、データ=results_long_fit、パレット= "Set3" )
- plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
- plt.title( '適合とスコア時間によるモデルの比較' )
- plt.show()
Random Forest は KNN、GNB、LogReg よりも遅いですが、パフォーマンスは KNN に次ぐものです。モデルの改良を続ける場合、おそらくほとんどの労力を Random Forest に集中させるでしょう。これは、パフォーマンスが XGBoost とほぼ同じ (95% 信頼区間はおそらく重複) でありながら、トレーニングがほぼ 4 倍高速だからです。 これらのモデルでさらに分析を実行する場合 (たとえば、各メトリックの信頼区間を計算する場合)、各メトリックの平均と標準偏差にアクセスする必要があります。 - メトリック = リスト(セット(results_long_nofit.メトリック.値))
- bootstrap_df.groupby([ 'モデル' ])[metrics].agg([np.std, np.mean])
- time_metrics = list( set ( results_long_fit.metrics.values ))
- bootstrap_df.groupby([ 'モデル' ])[time_metrics].agg([np.std, np.mean])
結論は 上記の分析では、平均精度、再現率などのみを考慮しています。現実の問題では、クラス全体の平均精度を気にすることはほとんどなく、むしろ特定のクラスの精度に特に興味があるでしょう。さらに、各機械学習モデルのハイパーパラメータは、データにどれだけ適合しているかを正確に評価するために調整する必要があります。 |