アンサンブル手法:改善された機械学習結果を生成するためのエレガントな手法
公開: 2022-03-11アンサンブル手法は、複数のモデルを作成し、それらを組み合わせて改善された結果を生成する手法です。 アンサンブル法は通常、単一モデルよりも正確な解を生成します。 これは、受賞したソリューションがアンサンブル手法を使用した多くの機械学習コンテストに当てはまります。 人気のあるNetflixコンテストでは、優勝者はアンサンブル手法を使用して強力な協調フィルタリングアルゴリズムを実装しました。 もう1つの例は、勝者がアンサンブル手法も使用したKDD2009です。 Kaggleコンテストでこれらの方法を使用した受賞者を見つけることもできます。たとえば、CrowdFlowerコンテストの受賞者へのインタビューは次のとおりです。
この記事を続ける前に、いくつかの用語を理解することが重要です。 記事全体を通して、データを使用してトレーニングしたアルゴリズムの出力を説明するために「モデル」という用語を使用しました。 このモデルは、予測を行うために使用されます。 このアルゴリズムは、ロジスティック回帰、決定木などの任意の機械学習アルゴリズムにすることができます。これらのモデルは、アンサンブルメソッドの入力として使用される場合、「ベースモデル」と呼ばれます。
このブログ投稿では、分類のためのアンサンブル手法について説明し、投票、スタッキング、バギング、ブースティングなど、広く知られているアンサンブル手法について説明します。
投票および平均化ベースのアンサンブル手法
投票と平均化は、最も簡単なアンサンブル手法の2つです。 どちらも理解しやすく、実装も簡単です。 投票は分類に使用され、平均化は回帰に使用されます。
どちらの方法でも、最初のステップは、トレーニングデータセットを使用して複数の分類/回帰モデルを作成することです。 各基本モデルは、同じトレーニングデータセットと同じアルゴリズムの異なる分割を使用して、または異なるアルゴリズムで同じデータセットを使用して、または他の方法で作成できます。 次のPython風の擬似コードは、異なるアルゴリズムで同じトレーニングデータセットを使用する方法を示しています。
train = load_csv("train.csv") target = train["target"] train = train.drop("target") test = load_csv("test.csv") algorithms = [logistic_regression, decision_tree_classification, ...] #for classification algorithms = [linear_regression, decision_tree_regressor, ...] #for regression predictions = matrix(row_length=len(target), column_length=len(algorithms)) for i,algorithm in enumerate(algorithms): predictions[,i] = algorithm.fit(train, target).predict(test)
上記の擬似コードに従って、各モデルの予測を作成し、予測と呼ばれるマトリックスに保存しました。各列には、1つのモデルからの予測が含まれています。
多数決
すべてのモデルは、各テストインスタンスの予測(投票)を行い、最終的な出力予測は、投票の半分以上を受け取るものです。 いずれの予測も投票の半分を超えない場合、アンサンブル法はこのインスタンスの安定した予測を行うことができなかったと言えます。 これは広く使用されている手法ですが、最終的な予測として、最も投票数の多い予測(投票数の半分未満であっても)を試すことができます。 一部の記事では、この方法が「多数決」と呼ばれているのを目にするかもしれません。
加重投票
各モデルが同じ権利を持つ多数決とは異なり、1つ以上のモデルの重要性を高めることができます。 加重投票では、より良いモデルの予測を複数回カウントします。 妥当な重みのセットを見つけるのはあなた次第です。
単純な平均化
単純な平均化方法では、テストデータセットのすべてのインスタンスについて、平均予測が計算されます。 この方法は、多くの場合、過剰適合を減らし、より滑らかな回帰モデルを作成します。 次の擬似コードコードは、この単純な平均化方法を示しています。
final_predictions = [] for row_number in len(predictions): final_predictions.append( mean(prediction[row_number, ]) )
加重平均
加重平均は、単純平均のわずかに変更されたバージョンであり、各モデルの予測に重みを掛けてから、それらの平均を計算します。 次の擬似コードコードは、加重平均を示しています。
weights = [..., ..., ...] #length is equal to len(algorithms) final_predictions = [] for row_number in len(predictions): final_predictions.append( mean(prediction[row_number, ]*weights) )
複数の機械学習モデルを積み重ねる
スタッキングは、スタッキング一般化とも呼ばれ、別の機械学習アルゴリズムを使用してモデルを組み合わせるアンサンブル手法です。 基本的な考え方は、トレーニングデータセットを使用して機械学習アルゴリズムをトレーニングし、これらのモデルを使用して新しいデータセットを生成することです。 次に、この新しいデータセットは、コンバイナー機械学習アルゴリズムの入力として使用されます。
スタッキング手順の擬似コードは次のように要約されます。
base_algorithms = [logistic_regression, decision_tree_classification, ...] #for classification stacking_train_dataset = matrix(row_length=len(target), column_length=len(algorithms)) stacking_test_dataset = matrix(row_length=len(test), column_length=len(algorithms)) for i,base_algorithm in enumerate(base_algorithms): stacking_train_dataset[,i] = base_algorithm.fit(train, target).predict(train) stacking_test_dataset[,i] = base_algorithm.predict(test) final_predictions = combiner_algorithm.fit(stacking_train_dataset, target).predict(stacking_test_dataset)
上記の擬似コードでわかるように、コンバイナーアルゴリズムのトレーニングデータセットは、基本アルゴリズムの出力を使用して生成されます。 擬似コードでは、トレーニングデータセットを使用して基本アルゴリズムが生成され、同じデータセットが再度使用されて予測が行われます。 しかし、私たちが知っているように、現実の世界では予測に同じトレーニングデータセットを使用しないため、この問題を克服するために、トレーニングデータセットが分割されるスタッキングの実装がいくつか見られる場合があります。 以下に、基本アルゴリズムをトレーニングする前にトレーニングデータセットが分割される擬似コードを示します。
base_algorithms = [logistic_regression, decision_tree_classification, ...] #for classification stacking_train_dataset = matrix(row_length=len(target), column_length=len(algorithms)) stacking_test_dataset = matrix(row_length=len(test), column_length=len(algorithms)) for i,base_algorithm in enumerate(base_algorithms): for trainix, testix in split(train, k=10): #you may use sklearn.cross_validation.KFold of sklearn library stacking_train_dataset[testcv,i] = base_algorithm.fit(train[trainix], target[trainix]).predict(train[testix]) stacking_test_dataset[,i] = base_algorithm.fit(train).predict(test) final_predictions = combiner_algorithm.fit(stacking_train_dataset, target).predict(stacking_test_dataset)
ブートストラップ集約
「バギング」とも呼ばれるBootstrapAggregatingという名前は、この戦略の重要な要素を要約したものです。 バギングアルゴリズムでは、最初のステップで複数のモデルを作成します。 これらのモデルは、ブートストラップサンプリング法を使用して元のデータセットからランダムに抽出されたデータセットのランダムなサブサンプルを使用して同じアルゴリズムを使用して生成されます。 ブートストラップサンプリングでは、いくつかの元の例が複数回表示され、いくつかの元の例はサンプルに存在しません。 m個の要素を持つサブデータセットを作成する場合は、元のデータセットからランダムな要素をm回選択する必要があります。 また、目標がn個のデータセットを生成することである場合は、この手順をn回実行します。

最後に、各データセットの要素数がmであるn個のデータセットがあります。 次のPython風の擬似コードはブートストラップサンプリングを示しています。
def bootstrap_sample(original_dataset, m): sub_dataset = [] for i in range(m): sub_dataset.append( random_one_element(original_dataset) ) return sub_dataset
バギングの2番目のステップは、生成されたモデルを集約することです。 この目的には、投票や平均化などのよく知られた方法が使用されます。
全体的な擬似コードは次のようになります。
def bagging(n, m, base_algorithm, train_dataset, target, test_dataset): predictions = matrix(row_length=len(target), column_length=n) for i in range(n): sub_dataset = bootstrap_sample(train_dataset, m) predictions[,i] = base_algorithm.fit(original_dataset, target).predict(test_dataset) final_predictions = voting(predictions) # for classification final_predictions = averaging(predictions) # for regression return final_predictions
バギングでは、各サブサンプルを互いに独立して生成できます。 したがって、生成とトレーニングを並行して実行できます。
また、いくつかのアルゴリズムでバギング戦略の実装を見つけることができます。 たとえば、ランダムフォレストアルゴリズムは、いくつかの違いがあるバギング手法を使用します。 ランダムフォレストはランダムな特徴選択を使用し、その基本アルゴリズムは決定木アルゴリズムです。
ブースト:弱いモデルを強いモデルに変換する
「ブースト」という用語は、弱いモデルを強いモデルに変換できるアルゴリズムのファミリーを表すために使用されます。 かなりのエラー率がある場合、モデルは弱くなりますが、パフォーマンスはランダムではありません(2項分類のエラー率は0.5になります)。 ブーストは、同じデータセットで各モデルをトレーニングすることによってアンサンブルを段階的に構築しますが、インスタンスの重みは最後の予測のエラーに従って調整されます。 主なアイデアは、モデルに難しいインスタンスに焦点を合わせるように強制することです。 バギングとは異なり、ブースティングは順次方式であるため、ここでは並列操作を使用できません。
ブースティングアルゴリズムの一般的な手順は次のように定義されています。
def adjust_dataset(_train, errors): #create a new dataset by using the hardest instances ix = get_highest_errors_index(train) return concat(_train[ix], random_select(train)) models = [] _train = random_select(train) for i in range(n): #n rounds model = base_algorithm.fit(_train) predictions = model.predict(_train) models.append(model) errors = calculate_error(predictions) _train = adjust_dataset(_train, errors) final_predictions = combine(models, test)
Adjust_dataset関数は、最も困難なインスタンスを含む新しいデータセットを返します。このデータセットを使用して、基本アルゴリズムからの学習を強制できます。
Adaboostは、ブースティング方法である広く知られているアルゴリズムです。 Adaboostの創設者は、その業績によりゲーデル賞を受賞しました。 ほとんどの場合、決定木アルゴリズムがAdaboostの基本アルゴリズムとして推奨され、sklearnライブラリでは、Adaboostのデフォルトの基本アルゴリズムは決定木(AdaBoostRegressorおよびAdaBoostClassifier)です。 前の段落で説明したように、同じ増分方法がAdaboostに適用されます。 各トレーニングサンプルの「硬度」に関するAdaBoostアルゴリズムの各ステップで収集された情報は、モデルに入力されます。 「データセットの調整」ステップは上記のステップとは異なり、「モデルの結合」ステップは加重投票を使用して計算されます。
結論
アンサンブル手法は、高度なアルゴリズムを考案し、高精度の結果を生成することで機械学習の競争に勝つことができますが、解釈可能性がより重要な業界では好ましくないことがよくあります。 それにもかかわらず、これらの方法の有効性は否定できず、適切なアプリケーションでのそれらの利点は途方もないものになる可能性があります。 ヘルスケアなどの分野では、機械学習アルゴリズムの精度を少しでも向上させることは、本当に価値のあることです。
- 機械学習理論とその応用の紹介:例を含むビジュアルチュートリアル
- 機械と信頼:AIバイアスを軽減する方法