Python 機械学習融合モデル: スタッキングとブレンディング (コード付き)

1 スタッキング方法 スタッキング

弱いシステムは強いシステムになれるでしょうか?

写真


金融市場ではよくあることですが、複雑な分類の問題に直面した場合、解決策を探すときにさまざまなアプローチが登場することがあります。これらの方法は分類を推定できますが、他の分類よりも優れていない場合があります。この場合、論理的な選択は、それらをすべて保持し、その後、部分を統合して最終システムを作成することです。この多様なアプローチは、最も便利なアプローチの 1 つです。すべての卵を 1 つのカゴに入れることを避けるために、決定を複数のシステムに分割します。

この状況に対して多数の推定値を取得したら、N 個のサブシステムの決定をどのように組み合わせればよいでしょうか?簡単な答えとしては、平均的な判断をして使用することができます。しかし、サブシステムを最大限に活用する別の方法はあるのでしょうか?もちろん!

創造的に考えてください!
共通の目的を持つ複数の分類子は、マルチ分類子と呼ばれます。機械学習における多重分類器は、それらを組み合わせた結果を得るために推定および融合される一連の異なる分類器です。マルチモデル、マルチ分類子システム、組み合わせ分類子、意思決定委員会など、複数の分類子を指すために多くの用語が使用されます。これらは、次の 2 つの大きなカテゴリに分類できます。

統合手法: 同じ学習テクノロジーを使用して一連のシステムを結合し、新しいシステムを作成することを指します。袋詰めと吊り上げが最も長くなります。
ハイブリッド手法: 多様な学習者を受け入れ、新しい学習テクノロジーを使用してそれらを組み合わせます。スタッキング (またはスタックされた汎化) は、主要なハイブリッド複数分類子の 1 つです。

スタッキングを利用した複数分類器を構築する方法。

写真

写真

スタッキングワークフロー

写真

メタ分類子は、予測されたクラス ラベルまたは予測されたクラス確率に基づいてトレーニングできます。

写真

写真

EURUSDのトレンドを予測するためのスタッキングの例を示します

EURUSD のトレンド (EUR/USD トレンド) を推定したいと想像してください。まず、問題を分類問題に変換し、価格データを上昇と下降の 2 つのタイプ (またはクラス) に分けました。私が毎日行うすべての動きを推測するつもりはありません。私が検出したいのは主なトレンド、つまりロング取引の上昇 (クラス = 1) とショート取引の下落 (クラス = 0) だけです。

写真

事後分割を行いました。つまり、クラスを決定するためにすべての履歴データが使用されるため、将来の情報が考慮されます。したがって、現時点では上下の動きを保証できません。したがって、今日のコースの見積もりが必要です。

写真

この例の目的のために、3 つの別々のシステムを設計しました。これらは、異なる属性セットを使用する 3 つの異なる学習者です。同じ学習者アルゴリズムを使用するか、一部またはすべてのプロパティを共有するかは問題ではありません。重要なのは、多様性を保証するためにそれらが十分に異なっていなければならないということです。

写真

次に、これらの確率に基づいて取引します。E が 50% を超えている場合、E が大きいほどロングになることを意味します。 Eが50%未満の場合、Eが小さいほどショートエントリーです。

写真

理想的ではありませんが、ランダムよりは良いだけです

写真

系統的誤差も相関性が低い

写真

弱いプレイヤーのグループでもドリーム チームを結成できますか?
複数の分類子を構築する目的は、単一の分類子よりも優れた予測パフォーマンスを達成することです。これが当てはまるかどうか見てみましょう。

この例で使用する方法は、スタッキング アルゴリズムに基づいています。スタッキングの考え方は、レベル 0 モデルと呼ばれるメイン分類子の出力を、メタモデルと呼ばれる別の分類子の属性として使用して、同じ分類問題を近似するというものです。メタモデルはマージメカニズムを理解するために残されます。これは、レベル 0 モデルの応答と真の分類を接続する役割を果たします。

厳密な手順には、トレーニング セットを素のセットに分割することが含まれます。次に、データ全体で各レベル 0 学習者をトレーニングし、1 つのグループを除外し、それを除外さ​​れたグループに適用します。グループごとに繰り返すことにより、各学習者ごとに各データの推定値が取得されます。これらの推定値は、トレーニングされたメタモデルまたはレベル 1 モデルの属性になります。データは時系列であるため、1 日目から d-1 日目までのセットを使用して d 日目の推定値を作成することにしました。

写真

これはどのモードで機能しますか?
メタモデルには、分類ツリー、ランダム フォレスト、サポート ベクター マシンなど、あらゆる分類学習器が効果的です。この例では、最近傍アルゴリズムを使用することを選択しました。これは、メタモデルが新しいデータのカテゴリを推定して、過去のデータ内のクラス 0 分類の同様の構成を発見し、これらの同様の状況にカテゴリを割り当てることを意味します。

私のドリームチームがどれほどうまくいったか見てみましょう...

スタッキングモデルの平均誤差値が最も低い

写真

結論
これは、利用可能な多数の多重分類器の一例にすぎません。彼らは、最新の独創的なテクニックを通じて、ソリューションの一部を独自の答えに組み込むのを支援するだけでなく、真のドリーム チームを作成することもできます。個々のコンポーネントをシステムに統合する方法にも大きな改善の余地があります。

したがって、次回組み合わせが必要な場合は、もう少し時間をかけて可能性を調査してください。従来の平均を避け、習慣の力によってより洗練されたアプローチを模索してください。追加のパフォーマンスを提供する可能性があります

Kaggle コンペティションでのモデル融合アプリケーション

モデルの融合は、さまざまな ML タスクの精度を向上させることができる非常に強力な手法です。この記事では、Kaggle コンテストでの統合に対する私のアプローチを共有します。

最初の部分では、コミット ファイルから統合を作成する方法を見ていきます。 2 番目のパートでは、積み重ねられた一般化/ハイブリッド化によるアンサンブルの作成について見ていきます。

アンサンブルが汎化エラーを減らす理由を答えます。最後に、さまざまな統合方法とその結果、および実際に試してみられるコードを示します。 Kaggle アンサンブル ガイド アンサンブルが汎化エラーを減らす理由に答えます。最後に、さまざまな統合方法とその結果、および実際に試してみられるコードを示します。

スタック生成法は、複数のモデルを組み合わせる全く異なる方法です。結合学習器の概念について説明していますが、バギングやブースティングほど使用されません。バギングやブースティングとは異なりますが、異なるモデルを結合します。具体的なプロセスは次のとおりです:
1. トレーニング データ セットを 2 つの素のセットに分割します。
2. 最初のセットで複数の学習者をトレーニングします。
3. これらの学習者を 2 番目のセットでテストします
4. 3 番目のステップで取得した予測結果を入力として使用し、正しい応答を出力として使用して、トレーニングします高レベルの学習者、
ここで注意する必要があるのは、ステップ 1 ~ 3 と相互検証の効果です。勝者総取りではなく、非線形アルゴリズムを使用しています。組み合わせ学習法。

写真

すべてのトレーニングされたベース モデルは、トレーニング セット全体を予測するために使用されます。i 番目のトレーニング サンプルに対する j 番目のベース モデルの予測値は、新しいトレーニングの i 番目のサンプルの j 番目の特徴値として使用されます。トレーニング セット 最後に、新しいトレーニング セットに基づいてトレーニングします。同様に、予測プロセスでは、最初にすべての基本モデルの予測を実行して新しいテスト セットを形成し、最後にテスト セットを予測する必要があります。

以下では、sklearn モデルを迅速にスタックできる強力なスタッキング ツール、mlxtend ライブラリを紹介します。

StackingClassifier は API とパラメータ分析を使用します。

StackingClassifier(classifiers、meta_classifier、use_probas=False、average_probas=False、verbose=0、use_features_in_secondary=False)

パラメータ:

分類子: 基本分類子、配列形式、[cl1、cl2、cl3]。各基本分類子の属性はクラス属性 self.clfs_ に保存されます。
meta_classifier: ターゲット分類子、前の分類子を結合する分類子です
use_probas: bool (デフォルト: False)。True に設定すると、ターゲット分類子の入力は前の分類出力のカテゴリ確率値になります。カテゴリ ラベルではありません
Average_probas: bool (デフォルト: False)、確率値の出力を使用するときに前のパラメーターで平均を使用するかどうかを設定するために使用されます。
冗長 : int、オプション (デフォルト = 0)。使用時のログ出力を制御するために使用されます。verbose = 0 の場合は何も出力されません。verbose = 1 の場合、リグレッサーのシリアル番号と名前が出力されます。 verbose = 2、詳細なパラメータ情報を出力します。 verbose > 2、verbose を 2 未満に自動的に設定し、verbose -2 に設定します。
use_features_in_secondary: bool (デフォルト: False)。True に設定すると、最終的なターゲット分類子は分類子に基づきます。元のデータセットと同時に生成されたデータでトレーニングされます。 False に設定すると、最終分類子は、基本分類子によって生成されたデータを使用してのみトレーニングされます。

属性:
clfs_: 各基本分類子、リスト、形状の属性は [n_classifiers] です。
meta_clf_: 最終ターゲット分類子の属性

方法:

fit(X, y)
fit_transform(X, y=None, fit_params)
get_params(deep=True) (sklearn GridSearch を使用する場合)メソッドを呼び出してから、分類子のパラメーターを返します。
dict(X)
predict_proba(X)
score(X, y, Sample_weight=None)、指定されたデータの場合ラベルを設定し、評価精度を返します。
set_params(params)、分類器のパラメータを設定します。params の設定方法は sklearn の形式と同じです 

Python 融合モデルの実際のコードの一部

#原创公众号python风控模型
from sklearn.datasets import load_iris 
from mlxtend.classifier import StackingClassifier 
from mlxtend.feature_selection import ColumnSelector 
from sklearn.pipeline import make_pipeline 
from sklearn.linear_model import LogisticRegression 
   
iris = load_iris() 
X = iris.data 
y = iris.target 
   
pipe1 = make_pipeline(ColumnSelector(cols=(0, 2)), 
                      LogisticRegression()) 
pipe2 = make_pipeline(ColumnSelector(cols=(1, 2, 3)), 
                      LogisticRegression()) 
   
sclf = StackingClassifier(classifiers=[pipe1, pipe2],  
                          meta_classifier=LogisticRegression()) 
   
sclf.fit(X, y)  

1.1 積層方法の基本的な考え方

スタッキング手法 スタッキングは、近年モデル融合の分野で最もよく使われている手法であり、競技優勝チームが最もよく使用する融合手法の 1 つであるだけでなく、今後検討されるソリューションの 1 つでもあります。実際に産業に人工知能を導入するとき。強力な学習器の融合手法であるスタッキングは、優れたモデル効果、強力な解釈可能性、複雑なデータへの適応性という 3 つの主要な利点を兼ね備えており、最も優れたものです。核融合分野での先進的実践的先駆的アプローチ。スタッキングの応用例は数多くありますが、特に CTR (広告のクリック率予測) における実用的な GBDT+LR スタッキングが有名です。そこで、「2022年の機械学習演習」のメインコースでは、一般的なスタッキング手法を説明した後、CTRにおけるGBDT+LRの使い方を詳しく解説し、CTR演習を完了させます。

スタッキングとはどのようなアルゴリズムですか?その中心的な考え方は実際には非常に単純です - まず、下の図に示すように、スタッキング構造にはアルゴリズムの 2 つの層があります。最初の層はレベル 0 と呼ばれ、2 番目の層はレベル 1 と呼ばれます。レベル 0 には 1 つのアルゴリズムが含まれる場合があります。学習者ですが、レベル 1 には 1 つの学習者のみを含めることができます。トレーニング中は、まずレベル 0 にデータが入力されてトレーニングされ、トレーニング後、レベル 0 の各アルゴリズムが対応する予測結果を出力します。これらの予測結果を新しい特徴行列に結合し、それをトレーニング用のレベル 1 アルゴリズムに入力します。融合モデルによって出力される最終的な予測結果は、レベル 1 学習器によって出力される結果です。

画像

この処理において、レベル 0 が出力する予測結果は、一般的に次のように配置されます。

学習者 1 学習者 2 ... 学ぶ
サンプル1 xxx xxx ... xxx
サンプル2 xxx xxx ... xxx
サンプル3 xxx xxx ... xxx
... ... ... ... ...
サンプルm xxx xxx ... xxx

最初の列は、学習器 1 がすべてのサンプルで出力した結果、2 列目は学習器 2 がすべてのサンプルで出力した結果、というように続きます。
同時に、レベル 0 でトレーニングされた複数の強力な学習者は、基本学習者 (基本モデル) と呼ばれ、個別の学習者とも呼ばれます。レベル 1 で訓練された学習者はメタ学習者 (メタモデル) と呼ばれます。業界の慣例によれば、レベル 0 の学習者は、アンサンブル アルゴリズムやサポート ベクター マシンなど、高度な複雑さと強力な学習能力を備えた学習者です。レベル 1 の学習者は、解釈可能性が高く、比較的単純です。学習者 (デシジョン ツリー、線形回帰、ロジスティック回帰など)。このような要件があるのは、レベル 0 のアルゴリズムの責任は、元のデータとラベルの間の関係を見つけること、つまり、元のデータとラベルの間の仮説を確立することであり、強力な学習能力が必要となるためです。ただし、レベル 1 アルゴリズムの責任は、個々の学習者によって作成された仮定を融合し、最終的に融合モデルの結果を出力することです。これは、元のデータとデータの間の仮定を直接確立するのではなく、「最適な融合ルール」を見つけることに相当します。ラベル。

そういえば、スタッキングの本質は、アルゴリズムに融合ルールを見つけさせることであることに気づいたでしょうか。ほとんどの人はスタッキング アルゴリズムに似た系列構造に触れたことがないかもしれませんが、実際にはスタッキングのプロセスは投票方法や平均化方法と完全に一致しています。

画像

投票法では投票を使用して強い学習器の結果を融合し、平均化法では平均化を使用して強い学習器の結果を融合し、スタッキング法ではアルゴリズムを使用して強い学習器の結果を融合します。レベル 1 のアルゴリズムが線形回帰の場合、実際にはすべての強学習器の結果の加重和を解いており、線形回帰のトレーニング プロセスは加重和の重みを見つけるプロセスです。同様に、レベル 1 のアルゴリズムがロジスティック回帰である場合、実際にはすべての強学習器の結果の加重和を解き、その和に基づいてシグモイド関数を適用します。ロジスティック回帰をトレーニングするプロセスは、加重和の重みを見つけるプロセスです。他の単純なアルゴリズムにも同じことが当てはまります。

ほとんどのアルゴリズムでは、アルゴリズムによって検出された融合ルールを要約するための「加重和」のような明確な名前を見つけるのは困難ですが、本質的に、レベル 1 のアルゴリズムは、レベルの結果を結合する方法を学習しているだけです。 0 の出力はより適切に結合されるため、スタッキングは、学習者をトレーニングすることによって学習者の結果を結合する方法です平均化メソッドは出力結果を平均することであり、投票メソッドは出力結果を投票することです。最初の 2 つは人為的に定義された融合メソッドですが、このスタッキングはマシンに発見を支援させるためのものです。最高の融合メソッド。  この方法の基本的な利点は、他の融合方法では融合結果が特定の値を持つことしか保証できないのに対し、損失関数を最小化する方向でメタ学習者をレベル 1 でトレーニングできることです。推進する。したがって、スタッキングは投票と平均よりも効果的な方法です。実際のアプリケーションでは、スタッキングは多くの場合、投票や平均化の方法よりも優れたパフォーマンスを発揮します。
スタッキングの本質を理解すると、実装プロセスにおける次のような多くの詳細な問題が簡単に解決されます。

  • 融合アルゴリズムで正確なパラメータ調整を実行する必要がありますか?

個々の学習者は粗調整され、メタ学習者は微調整されます。適合が不十分な場合は、両方のタイプの学習者を微調整できます。理論的には、アルゴリズムの出力が実際のラベルに近ければ近いほど良いのですが、個々の学習者は、微調整して融合した後に簡単に過適合してしまう可能性があります。

  • スタッキングの効果を最大化するために個々の学習者アルゴリズムを選択するにはどうすればよいですか?

投票と平均化と一貫して、過剰適合を制御し、多様性を高め、アルゴリズムの全体的な計算時間に注意を払います。

  • 個々の学習者は、ロジスティック回帰やデシジョン ツリーなどのそれほど複雑ではないアルゴリズムを使用できますか?メタラーナーは xgboost のような非常に複雑なアルゴリズムにすることができますか?

すべてOKです。すべてがモデル効果の影響を受けます。レベル 0 では、モデルの多様性を高めるために弱学習器を追加し、弱学習器の効果がより優れている場合、これらのアルゴリズムを保持できます。レベル 1 では、オーバーフィットしない限り、任意のアルゴリズムを使用できます。個人的な推奨事項は、分類にはより複雑なアルゴリズムを使用できますが、回帰には単純なアルゴリズムを使用するのが最善です。

  • レベル 0 とレベル 1 のアルゴリズムは異なる損失関数を使用できますか?

はい、さまざまな損失関数が実際には同様の差、つまり真の値と予測値の差を測定するためです。ただし、損失が異なれば差に対する感度も異なるため、可能であれば同様の損失関数を使用することをお勧めします。

  • レベル 0 とレベル 1 のアルゴリズムは異なる評価指標を使用できますか?

個人的な提案レベル 0 とレベル 1 のアルゴリズムは同じモデル評価インデックスを使用する必要があります。スタッキングでは 2 つのアルゴリズム グループが直列に接続されていますが、これら 2 つのアルゴリズム グループのトレーニングは完全に分離されています。深層学習でも、強力なアルゴリズムと弱いアルゴリズムが直列に接続された同様の構造があります。たとえば、畳み込みニューラル ネットワークは、直列に接続された強力な畳み込み層と弱い線形層で構成されます。畳み込み層の主な役割は次のとおりです。特徴とラベルの間の関係を見つけるため 線形層の主な役割は、仮定と出力を統合することです。ただし、ディープラーニングでは、ネットワーク上のすべての層のトレーニングが同時に実行されるため、損失関数が低減されるたびにネットワーク全体の重みを更新する必要があります。ただし、スタッキングでは、レベル 1 のアルゴリズムは、重みを調整するときにレベル 0 の結果にまったく影響を与えません。したがって、最終的な融合後に 2 つのアルゴリズム グループが必要な結果を確実に取得できるようにするには、評価指標はトレーニング中に使用する必要があります。トレーニングのベースライン。

2 sklearnでスタッキングを実装する

クラス sklearn.ensemble.StackingClassifier(
推定値,
Final_estimator=None, *,
cv=なし、
stack_method="auto"、
n_jobs=なし、
passthrough=False、
詳細=0)

クラス sklearn.ensemble.StackingRegressor(
推定器、
Final_estimator=None,*,
cv= なし、
n_jobs= なし、
passthrough=False、
verbose=0)

パラメータ 説明する
推定者 個々の評価者のリスト。 sklearn では、個別のエバリュエーターとして 1 つのエバリュエーターのみを使用する場合、
モデルは実行できますが、多くの場合、効果はあまり良くありません。
最終推定者 メタ学習者、評価者は 1 人だけです。融合モデルが分類タスクを実行する場合、メタ学習者は分類アルゴリズムである必要があります。
融合モデルが回帰タスクを実行する場合、メタ学習者は回帰アルゴリズムである必要があります。
履歴書 は、特定のタイプ、フォールド数、および相互検証のその他の詳細を指定するために使用されます。
単純な K 分割相互検証を実行することも、sklearn で相互検証クラスを入力することもできます。
スタックメソッド 分類器に固有のパラメーターは、個々の学習者によって出力された特定のテスト結果を表します。
パススルー メタ学習者をトレーニングするときに、元のデータを特徴行列として追加するかどうか。
n_jobs、詳細 スレッドの数と監視パラメータ。

sklearn で、estimatorsfinal_estimator を入力するだけでスタッキングを実行できます。投票方法で使用される個々の学習者の組み合わせを引き続き使用し、ランダム フォレストをメタ学習者として使用してスタッキングを完了できます。

  • ツールライブラリとデータ
#常用工具库
import re
import numpy as np
import pandas as pd
import matplotlib as mlp
import matplotlib.pyplot as plt
import time

#算法辅助 & 数据
import sklearn
from sklearn.model_selection import KFold, cross_validate
from sklearn.datasets import load_digits #分类 - 手写数字数据集
from sklearn.datasets import load_iris
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

#算法(单一学习器)
from sklearn.neighbors import KNeighborsClassifier as KNNC
from sklearn.neighbors import KNeighborsRegressor as KNNR
from sklearn.tree import DecisionTreeRegressor as DTR
from sklearn.tree import DecisionTreeClassifier as DTC
from sklearn.linear_model import LinearRegression as LR
from sklearn.linear_model import LogisticRegression as LogiR
from sklearn.ensemble import RandomForestRegressor as RFR
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.ensemble import GradientBoostingRegressor as GBR
from sklearn.ensemble import GradientBoostingClassifier as GBC
from sklearn.naive_bayes import GaussianNB
import xgboost as xgb

#融合模型
from sklearn.ensemble import StackingClassifier
data = load_digits()
X = data.data
y = data.target

X.shape

np.unique(y) #10分类

Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.2,random_state=1412)

画像

  • 相互検証関数を定義する
def fusion_estimators(clf):
    """
    对融合模型做交叉验证,对融合模型的表现进行评估
    """
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    results = cross_validate(clf,Xtrain,Ytrain
                             ,cv = cv
                             ,scoring = "accuracy"
                             ,n_jobs = -1
                             ,return_train_score = True
                             ,verbose=False)
    test = clf.fit(Xtrain,Ytrain).score(Xtest,Ytest)
    print("train_score:{}".format(results["train_score"].mean())
          ,"
 cv_mean:{}".format(results["test_score"].mean())
          ,"
 test_score:{}".format(test)
         )
def individual_estimators(estimators):
    """
    对模型融合中每个评估器做交叉验证,对单一评估器的表现进行评估
    """
    for estimator in estimators:
        cv = KFold(n_splits=5,shuffle=True,random_state=1412)
        results = cross_validate(estimator[1],Xtrain,Ytrain
                             ,cv = cv
                             ,scoring = "accuracy"
                             ,n_jobs = -1
                             ,return_train_score = True
                             ,verbose=False)
        test = estimator[1].fit(Xtrain,Ytrain).score(Xtest,Ytest)
        print(estimator[0]
          ,"
 train_score:{}".format(results["train_score"].mean())
          ,"
 cv_mean:{}".format(results["test_score"].mean())
          ,"
 test_score:{}".format(test)
          ,"
")
  • 個々の学習者とメタ学習者の定義

以前に投票方法を説明したときに、個々の学習者の定義方法について詳しく説明し、次の 7 つのモデルを見つけるために多くの努力をしました。ここでは投票で選ばれた7モデルを使用します。

#逻辑回归没有增加多样性的选项
clf1 = LogiR(max_iter = 3000, C=0.1, random_state=1412,n_jobs=8)
#增加特征多样性与样本多样性
clf2 = RFC(n_estimators= 100,max_features="sqrt",max_samples=0.9, random_state=1412,n_jobs=8)
#特征多样性,稍微上调特征数量
clf3 = GBC(n_estimators= 100,max_features=16,random_state=1412) 

#增加算法多样性,新增决策树与KNN
clf4 = DTC(max_depth=8,random_state=1412)
clf5 = KNNC(n_neighbors=10,n_jobs=8)
clf6 = GaussianNB()

#新增随机多样性,相同的算法更换随机数种子
clf7 = RFC(n_estimators= 100,max_features="sqrt",max_samples=0.9, random_state=4869,n_jobs=8)
clf8 = GBC(n_estimators= 100,max_features=16,random_state=4869)

estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              , ("RandomForest2", clf7), ("GBDT2", clf8)
             ]
  • モデリングのために sklearn をインポートする
#选择单个评估器中分数最高的随机森林作为元学习器
#也可以尝试其他更简单的学习器
final_estimator = RFC(n_estimators=100
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
clf = StackingClassifier(estimators=estimators #level0的7个体学习器
                         ,final_estimator=final_estimator #level 1的元学习器
                         ,n_jobs=8)

フィッティングを調整する前: つまり、min_impurity_decrease=0.0025 を追加しません。

fusion_estimators(clf) #没有过拟合限制
""
train_score:1.0 
 cv_mean:0.9812112853271389 
 test_score:0.9861111111111112
""

オーバーフィッティングを追加した後

fusion_estimators(clf) #精调过拟合
""
train_score:1.0 
 cv_mean:0.9812185443283005 
 test_score:0.9888888888888889
""
基準 投票法 スタッキング方法
5 分割相互検証 0.9666 0.9833 0.9812(↓)
テストセットの結果 0.9527 0.9889 0.9889(-)

テスト セットのスタッキングのスコアは投票方法と同じですが、5 分割交差検証スコアは投票方法ほど高くないことがわかります。これは、現在トレーニングしているデータが比較的単純であるためと考えられますが、データの学習がより困難になると、スタッキングの利点が徐々に現れるようになります。もちろん、現在使用しているメタ学習器はほぼデフォルトのパラメータを持っていますが、ベイジアン最適化を使ってメタ学習器のパラメータを微調整して比較すれば、スタッキング法の効果は投票法を上回る可能性があります。

3要素学習器の特徴行列

3.1 メタ学習者の特徴マトリックスに関する 2 つの問題

スタッキング プロセスでは、個々の学習者が元のデータに基づいてトレーニングおよび予測を行い、その予測結果を新しい特徴行列に整理してメタ学習器に入力して学習します。このうち、個々の学習者の予測結果、つまりメタ学習者が学習する必要がある行列は、一般的に次のように配置されます。

学習者 1 学習者 2 ... 学ぶ
サンプル1 xxx xxx ... xxx
サンプル2 xxx xxx ... xxx
サンプル3 xxx xxx ... xxx
... ... ... ... ...
サンプルm xxx xxx ... xxx

機械学習とモデルの融合に関する理解に基づいて、次の 2 つの問題を見つけるのは難しくありません。

  • まず、メタ学習者の特徴マトリックスに含まれる特徴が非常に少ない必要があります。

個々の学習者は 1 組の予測結果しか出力できませんが、これらの予測結果を並べて、新しい特徴行列の特徴の数は個々の学習者の数と同じになります。一般に、融合モデルには最大でも 20 ~ 30 の個々の学習者が存在します。これは、メタ学習者の特徴行列には最大でも 20 ~ 30 の特徴が存在することを意味します。この特徴量は、業界や競技会での機械学習アルゴリズムには決して十分ではありません。

  • 第二に、メタ学習者の特徴マトリックスにはサンプルが多すぎません。

個々の学習者の責任は、元のデータとラベルの間の仮説を見つけることです。この仮説が正しいかどうかを検証するために、個々の学習者の一般化能力に注目する必要があります。個々の学習者の汎化能力が強い場合にのみ、個々の学習者が出力した予測結果を安全にメタ学習器に入れて融合することができます。


ただし。スタッキング モデルをトレーニングするときは、元のデータ セットをトレーニング セット、検証セット、テスト セットの 3 つの部分に分割する必要があります。


そのうちの テスト セット 業界の慣例によれば、メタ学習器の特徴行列が産業用機械学習の特徴行列よりもはるかに小さいため、メタ学習器がそれほど複雑ではないアルゴリズムである必要があるのも不思議ではありません。特徴量とサンプルサイズの条件、必要な基準。これら 2 つの問題を解決するために、Stacking メソッドには複数の解決策があり、これらの解決策は sklearn の stacking クラスを通じて実装できます。 。一般に、検証セットはデータ セット全体の最大でも 30% ~ 40% しか占めません。これは、メタ学習者が使用する特徴行列のサンプル サイズが元のデータの最大 40% であることを意味します。 検証セット したがって、最終的には、生徒の真の学習レベルを予測して表すために使用できる、非常に小さな は、個々の学習者をトレーニングするために使用され、個々の学習者に完全に公開されているコンテンツです。トレーニング セットで予測が行われた場合、予測結果は「高い方」になり、個々の学習者の汎化能力を表すことはできません。 トレーニング セット


は融合モデル全体の効果をテストするために使用されるため、トレーニング プロセス中には使用できません。



クラス sklearn.ensemble.StackingClassifier(estimators、final_estimator=None、*、cv=None、stack_method="auto"、n_jobs=None、passthrough=False、verbose=0)

クラス sklearn.ensemble.StackingRegressor(estimators、final_estimator=None、*、cv=None、n_jobs=None、passthrough=False、verbose=0)

パラメータ 説明する
推定者 個々の評価者のリスト。 sklearn では、個別のエバリュエーターとして 1 つのエバリュエーターのみを使用する場合、
モデルは実行できますが、多くの場合、効果はあまり良くありません。
最終推定者 メタ学習者、評価者は 1 人だけです。融合モデルが分類タスクを実行する場合、メタ学習者は分類アルゴリズムである必要があります。
融合モデルが回帰タスクを実行する場合、メタ学習者は回帰アルゴリズムである必要があります。
履歴書 は、特定のタイプ、フォールド数、および相互検証のその他の詳細を指定するために使用されます。
単純な K 分割相互検証を実行することも、sklearn で相互検証クラスを入力することもできます。
スタックメソッド 分類器に固有のパラメーターは、個々の学習者によって出力された特定のテスト結果を表します。
パススルー メタ学習者をトレーニングするときに、元のデータを特徴行列として追加するかどうか。
n_jobs、詳細 スレッドの数と監視パラメータ。

3.2 サンプルサイズが小さすぎる場合の解決策: 相互検証

  • パラメータcv、スタッキングで相互検証を実行する
    スタッキング手法が提案された元の論文では、元の著者は当然のことながら、メタ学習者は特徴行列のサンプルサイズが小さすぎるという問題があるため、スタッキングプロセス内で相互検証を使用してメタ学習者の特徴行列を拡張するというアイデアが提案されています。の相互検証は学習者ごとに内部的に行われますが、この相互検証の結果は汎化能力の検証には使用されず、データを生成するためのツールとして直接使用されます。

具体的には、スタッキングプロセス中に次のような相互検証を実行します。

個々の学習者について、5 分割相互検証を実行すると仮定して、トレーニング データを 5 つの部分に分割し、トレーニング用の 4 つの部分と検証用の 1 つの部分に従って合計 5 つのモデルを構築し、5 回トレーニングします。
 

画像


相互検証プロセス中、各検証セット内のデータはトレーニング用のモデルに入力されないため、これらの検証セットの予測結果によってモデルの一般化能力を測定できます。

一般に、相互検証の最終出力は 5 つの検証セットのスコアですが、スコアを計算する前に、5 つの検証セットで予測を行って結果を出力する必要があります。したがって、 相互検証で 5 つのモデルを構築し、5 つのモデルによって出力される予測結果を順番に取得できます。これらの 5 つの予測結果は、完全なデータ内で分割された 5 つのサブセットにちょうど対応します。設定さえすれば、元のデータのサンプルに対応する予測結果が得られます。この垂直方向の積み方は、まさに砂浜に石を積み上げるようなもので、「積み方」の名前の由来となっています。 。これは、相互検証を完了すると、元のデータのすべてのデータの予測も完了することを意味します。ここで、 5 つのサブセットの予測結果を縦に積み重ね
 

画像


この方法を使用して予測すると、個々の学習者が出力する予測値の数 = サンプル サイズ となります。ちなみに、メタ学習 フィルターの特徴行列の行数は、元のデータのサンプル サイズと同じです。

学習者 1 学習者 2 ... 学ぶ
サンプル1 xxx xxx ... xxx
サンプル2 xxx xxx ... xxx
サンプル3 xxx xxx ... xxx
... ... ... ... ...
サンプルm xxx xxx ... xxx

スタッキング プロセス中に、この相互検証プロセスは必ず発生しますが、人間の介入の範囲内ではありません。ただし、パラメータ cv を使用して、使用する分割数、分類ラベルの分布を考慮するかどうかなど、使用する相互検証の種類を決定できます。具体的には、パラメータ cv に次のように入力できます。

入力なし、デフォルトでは 5 分割相互検証が使用されます


「sklearn」と入力任意の相互検証オブジェクト


入力任意の整数。層化K分割の分割数を表します。検証。層化 K 分割検証は、ラベル内の各カテゴリの割合を考慮する相互検証です。層化 K 分割相互検証を選択すると、相互検証により、各トレーニング中に元のラベル内のカテゴリの割合が保証されます。 = トレーニング ラベルのカテゴリ割合 = 検証ラベルのカテゴリ割合

 

画像


これで、メタ学習者にとって特徴行列サンプルが少なすぎるという問題をスタッキングがどのように処理するかがわかりました。内部相互検証は一般化能力を検証するものではなく、データを生成するためのツールであるため、相互検証自体で調整できることはあまりないことを再度強調する必要があります。唯一言及する価値があるのは、交差検証フォールドが大きい場合、モデルの抗体過剰適合能力が増加し、学習能力がわずかに低下することです。交差検証のフォールドが小さい場合、モデルは過剰適合する可能性が高くなります。ただし、データ量が十分に大きい場合、交差検証フォールドを多用しすぎても何のメリットも得られず、トレーニング時間が長くなるだけです。

estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              , ("RandomForest2", clf7), ("GBDT2", clf8)
             ]
final_estimator = RFC(n_estimators=100
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
def cvtest(cv):
    clf = StackingClassifier(estimators=estimators
                         ,final_estimator=final_estimator
                         , cv = cv
                         , n_jobs=8)
    start = time.time()
    clf.fit(Xtrain,Ytrain)
    print((time.time() - start)) #消耗时间
    print(clf.score(Xtrain,Ytrain)) #训练集上的结果
    print(clf.score(Xtest,Ytest)) #测试集上的结果
cvtest(2) #非常少的验证次数
""
3.8339908123016357
1.0
0.9861111111111112
""

cvtest(10) #普通的验证次数
""
13.57864761352539
1.0
0.9833333333333333
""

cvtest(30) #很大的验证次数
""
39.74843621253967
1.0
0.9833333333333333
""

cv のフォールド数が増加すると、トレーニング時間は確実に増加しますが、モデルのパフォーマンスは必ずしも確実ではありません。したがって、5 ~ 10 倍の相互検証を選択してください。同時に、スタッキングには相互検証アルゴリズムとメタ学習アルゴリズムが付属しているため、スタッキング メソッドの実行は投票メソッドや平均メソッドよりもはるかに遅くなります。、ここでスタッキング メソッドが使用されます。あまりユーザーフレンドリーではありません。

3.3 機能が少なすぎるソリューション

  • パラメータstack_method、個々の学習者が出力する結果のタイプを変更します

对于分类stacking来说,如果特征量太少,我们可以更换个体学习器输出的结果类型。具体来说,如果个体学习器输出的是具体类别(如[0,1,2]),那1个个体学习器的确只能输出一列预测结果。但如果把输出的结果类型更换成概率值、置信度等内容,输出结果的结构一下就可以从一列拓展到多列。

如果这个行为由参数stack_method控制,这是只有StackingClassifier才拥有的参数,它控制个体分类器具体的输出。stack_method里面可以输入四种字符串:"auto", "predict_proba", "decision_function", "predict",除了"auto"之外其他三个都是sklearn常见的接口。

clf = LogiR(max_iter=3000, random_state=1412)

clf = clf.fit(Xtrain,Ytrain)
#predict_proba:输出概率值
clf.predict_proba(Xtrain)

画像

#decision_function:每个样本点到分类超平面的距离,可以衡量置信度
#对于无法输出概率的算法,如SVM,我们通常使用decision_function来输出置信度
clf.decision_function(Xtrain)

画像

#predict:输出具体的预测标签
clf.predict(Xtrain)

画像


对参数stack_method有:

输入"auto",sklearn会在每个个体学习器上按照"predict_proba", "decision_function", "predict"的顺序,分别尝试学习器可以使用哪个接口进行输出。即,如果一个算法可以使用predict_proba接口,那就不再尝试后面两个接口,如果无法使用predict_proba,就尝试能否使用decision_function。


输入三大接口中的任意一个接口名,则默认全部个体学习器都按照这一接口进行输出。然而,如果遇见某个算法无法按照选定的接口进行输出,stacking就会报错。

因此,我们一般都默认让stack_method保持为"auto"。从上面的我们在逻辑回归上尝试的三个接口结果来看,很明显,当我们把输出的结果类型更换成概率值、置信度等内容,输出结果的结构一下就可以从一列拓展到多列。

  • predict_proba

对二分类,输出样本的真实标签1的概率,一列

对n分类,输出样本的真实标签为[0,1,2,3...n]的概率,一共n列

  • decision_function

对二分类,输出样本的真实标签为1的置信度,一列

对n分类,输出样本的真实标签为[0,1,2,3...n]的置信度,一共n列

  • predict

对任意分类形式,输出算法在样本上的预测标签,一列

在实践当中,我们会发现输出概率/置信度的效果比直接输出预测标签的效果好很多,既可以向元学习器提供更多的特征、还可以向元学习器提供个体学习器的置信度。我们在投票法中发现使用概率的“软投票”比使用标签类被的“硬投票”更有效,也是因为考虑了置信度。

  • 参数passthrough,将原始特征矩阵加入新特征矩阵

对于分类算法,我们可以使用stack_method,但是对于回归类算法,我们没有这么多可以选择的接口。回归类算法的输出永远就只有一列连续值,因而我们可以考虑将原始特征矩阵加入个体学习器的预测值,构成新特征矩阵。这样的话,元学习器所使用的特征也不会过于少了。当然,这个操作有较高的过拟合风险,因此当特征过于少、且stacking算法的效果的确不太好的时候,我们才会考虑这个方案。

控制是否将原始数据加入特征矩阵的参数是passthrough,我们可以在该参数中输入布尔值。当设置为False时,表示不将原始特征矩阵加入个体学习器的预测值,设置为True时,则将原始特征矩阵加入个体学习器的预测值、构成大特征矩阵。

  • 接口transform与属性stack_method_
estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              , ("RandomForest2", clf7), ("GBDT2", clf8)
             ]
final_estimator = RFC(n_estimators=100
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
clf = StackingClassifier(estimators=estimators
                         ,final_estimator=final_estimator
                         ,stack_method = "auto"
                         ,n_jobs=8)
clf = clf.fit(Xtrain,Ytrain)

当我们训练完毕stacking算法后,可以使用接口transform来查看当前元学习器所使用的训练特征矩阵的结构

clf.transform(Xtrain).shape
# (1437, 70)

画像


这个70 代表这个一共有7个个体学习器,每个个体学习器都有10个概率输出
如之前所说,这个特征矩阵的行数就等于训练的样本量:

Xtrain.shape[0]
# 1437

不过你能判断为什么这里有70列吗?因为我们有7个个体学习器,而现在数据是10分类的数据,因此每个个体学习器都输出了类别[0,1,2,3,4,5,6,7,8,9]所对应的概率,因此总共产出了70列数据:

pd.DataFrame(clf.transform(Xtrain)).head()

画像


如果加入参数passthrough,特征矩阵的特征量会变得更大:

clf = StackingClassifier(estimators=estimators
                         ,final_estimator=final_estimator
                         ,stack_method = "auto"
                         ,passthrough = True
                         ,n_jobs=8)
clf = clf.fit(Xtrain,Ytrain)
clf.transform(Xtrain).shape #这里就等于70 + 原始特征矩阵的特征数量64
# (1437, 134)

画像


使用属性stack_method_,我们可以查看现在每个个体学习器都使用了什么接口做为预测输出:

clf.stack_method_

["predict_proba",
"predict_proba",
"predict_proba",
"predict_proba",
"predict_proba",
"predict_proba",
"predict_proba"]

不难发现,7个个体学习器都使用了predict_proba的概率接口进行输出,这与我们选择的算法都是可以输出概率的算法有很大的关系

4 Stacking融合的训练/测试流程

现在我们已经知道了stacking算法中所有关于训练的信息,我们可以梳理出如下训练流程:

  • stacking的训练
  1. 将数据分割为训练集、测试集,其中训练集上的样本为(M_{train}),测试集上的样本量为(M_{test})
     
  2. 将训练集输入level 0的个体学习器,分别在每个个体学习器上进行交叉验证。在每个个体学习器上,将所有交叉验证的验证结果纵向堆叠形成预测结果。假设预测结果为概率值,当融合模型执行回归或二分类任务时,该预测结果的结构为((M_{train},1)),当融合模型执行K分类任务时(K>2),该预测结果的结构为((M_{train},K))
     
  3. 将所有个体学习器的预测结果横向拼接,形成新特征矩阵。假设共有N个个体学习器,则新特征矩阵的结构为((M_{train}, N))。如果是输出多分类的概率,那最终得出的新特征矩阵的结构为((M_{train}, N*K))
     
  4. 将新特征矩阵放入元学习器进行训练。

画像

不难发现,虽然训练的流程看起来比较流畅,但是测试却不知道从何做起,因为:

  • 最终输出预测结果的是元学习器,因此直觉上来说测试数据集或许应该被输入到元学习器当中。然而,元学习器是使用新特征矩阵进行预测的,新特征矩阵的结构与规律都与原始数据不同,所以元学习器根本不可能接受从原始数据中分割出来的测试数据。因此正确的做法应该是让测试集输入level 0的个体学习器。

  • ただし、問題があります。レベル 0 の個々の学習者はトレーニング プロセス中に相互検証を実行します。相互検証は検証結果のみを出力し、トレーニングされたモデルからは出力されません。 。したがって、レベル 0 での予測に使用できるトレーニング済みモデルはありません。

トレーニング プロセスにおけるこの矛盾を解決するために、次のような隠れた手順があります。

  • スタッキングトレーニング
  1. データをトレーニング セットとテスト セットに分割します。トレーニング セットのサンプルは (M_{train})、テスト セットのサンプル サイズは (M_{test}) です。
     
  2. トレーニング セットをレベル 0 で個々の学習者に入力し、個々の学習者ごとに相互検証を実行します。個々の学習者ごとに、すべての相互検証の検証結果が垂直に積み上げられて、予測結果が形成されます。予測結果が確率値であると仮定します。融合モデルが回帰または二項分類タスクを実行する場合、予測結果の構造は ((M_{train},1)) になります。融合モデルが K 分類タスクを実行する場合 ( K>2)、予測結果の構造は ((M_{train},1)) 予測結果の構造は ((M_{train},K))
     
  3. 隠れたステップ: テストの準備として、すべてのトレーニング データを使用してすべての個別の学習者をトレーニングします。
     
  4. すべての個々の学習者の予測結果が水平方向に結合されて、新しい特徴行列が形成されます。個別の学習者が合計 N 人いると仮定すると、新しい特徴行列の構造は ((M_{train}, N)) になります。
     
  5. 新しい特徴マトリックスをトレーニング用のメタ学習器に入れます。
  • スタッキングテスト
  1. レベル 0 の個々の学習者にテスト セットを入力し、個々の学習者ごとに対応する結果を予測します。テスト結果が確率値であると仮定します。融合モデルが回帰または二項分類タスクを実行する場合、テスト結果の構造は ((M_{test},1)) になります。融合モデルが K 分類タスクを実行する場合 (K>2) )、テスト結果の構造は ((M_{test},1)) です。テスト結果の構造は ((M_{test},K)) です
     
  2. すべての個々の学習者の予測結果は、新しい特徴行列に水平方向に結合されます。合計 N 人の個別学習者がいると仮定すると、新しい特徴行列の構造は ((M_{test}, N)) になります。
     
  3. 新しい特徴行列を予測のためにメタ学習器に入れます。

したがって、スタッキングでは、個々の学習者に対してすべての相互検証を完了する必要があるだけでなく、相互検証の完了後にトレーニング データを再利用してすべてのモデルをトレーニングする必要があります。スタッキング フュージョンがより複雑で動作が遅いのも不思議ではありません。

ここまで投票方法と積み上げ方法について説明してきました。 sklearnでは以下の4つのカテゴリーについて説明します。

フュージョン法 親切
投票法 アンサンブル.VotingClassifier
平均化法 アンサンブル.VotingRegressor
積層方法の分類 アンサンブル.StackingClassifier
積み上げ回帰 アンサンブル.StackingRegressor

これらのクラスはモデル融合メソッドですが、単一のアルゴリズム クラスと同じようにこれらのメソッドを使用できます。手動パラメータ調整、相互検証、グリッド検索、ベイジアン最適化、パイプライン パッケージ化などの操作を、何もせずに簡単に実行できます。コードの互換性の問題が心配です。 ただし、sklearn の融合ツールは sklearn のエバリュエーターのみをサポートし、xgb および lgbm のネイティブ コードはサポートしないことに注意してください。したがって、ネイティブ コードでモデルを融合したい場合は、融合プロセスを自分で記述する必要があります。

2. 改良されたスタッキング方法: ブレンディング

1 ブレンディングの基本的な考え方とプロセス

ブレンディング フュージョンは、スタッキング フュージョンに基づいて改良されたアルゴリズムです。前のコースでは、スタッキング手法ではレベル 1 のアルゴリズムが使用されており、これによりフュージョン自体が損失関数を最小化する方向に進むことができると同時に、スタッキングでは独自の内部相互検証を使用してデータが生成されることを説明しました。 、トレーニング データを徹底的に使用できるため、モデルの全体的な効果が向上します。しかし、これらの操作の背後には 2 つの大きな問題があります。

  • スタッキング フュージョンには膨大な量の計算が必要であり、高い時間と計算能力コストがかかります

  • スタッキング フュージョンはデータとアルゴリズムの両方で複雑すぎるため、フュージョン モデルが過剰適合する可能性が高すぎます

スタッキングにおけるこれら 2 つの問題に対応して、大会優勝チームは練習中にさまざまな改善されたスタッキング方法を模索し続けました。現在、さまざまなスタッキング手法の中で最も効果的な手法の 1 つが、有名なブレンド手法です。ブレンディングは文字通り「混合」と訳されますが、その中心となる考え方は実際にはスタッキングとまったく同じです。つまり、2 層のアルゴリズムを直列に使用し、レベル 0 には複数の強力な学習器があり、レベル 1 にはメタ学習器が 1 つだけあり、レベル 0 の強力な学習者 データと実際のラベルの間の関係のフィッティング、予測結果の出力、新しい特徴行列の形成を担当し、レベル 1 のメタ学習者に新しい特徴行列で学習および予測させます。

画像

ただし、スタッキングとは異なり、計算量を削減し、融合モデルの過学習のリスクを軽減するために、ブレンディングでは K 分割相互検証がキャンセルされ、メタ学習者のトレーニングに必要なデータ量が大幅に削減されます。以下のとおりであります:

  • ブレンディングトレーニング
  1. データをトレーニング セット、検証セット、テスト セットに分割します。トレーニング セットのサンプルは (M_{train})、検証セットのサンプルは (M_v)、テスト セットのサンプル サイズです。は (M_{テスト})
     
  2. トレーニング セットをレベル 0 で個々の学習者に入力し、個々の学習者に対して個別にトレーニングします。学習完了後、検証セット上で検証され、検証セット上の予測結果が出力されます。予測結果が確率値であると仮定します。融合モデルが回帰またはバイナリ分類タスクを実行する場合、予測結果の構造は ((M_v,1)) になります。融合モデルが K 分類タスクを実行する場合 (K>2) )、予測結果の構造は ((M_v,K)) です。現時点では、すべての学習者がトレーニングを受けています。
     
  3. すべての個々の学習者の検証結果が水平方向に結合されて、新しい特徴マトリックスが形成されます。合計 N 人の個別学習者がいると仮定すると、新しい特徴行列の構造は ((M_v, N)) になります。
     
  4. 新しい特徴マトリックスをトレーニング用のメタ学習器に入れます。
  • ブレンドテスト
  1. レベル 0 の個々の学習者にテスト セットを入力し、個々の学習者ごとに対応する結果を予測します。テスト結果が確率値であると仮定します。融合モデルが回帰または二項分類タスクを実行する場合、テスト結果の構造は ((M_{test},1)) になります。融合モデルが K 分類タスクを実行する場合 (K>2) )、テスト結果の構造は ((M_{test},1)) です。テスト結果の構造は ((M_{test},K)) です
     
  2. すべての個々の学習者の予測結果は、新しい特徴行列に水平方向に結合されます。合計 N 人の個別学習者がいると仮定すると、新しい特徴行列の構造は ((M_{test}, N)) になります。
     
  3. 事前テストのために新しい特徴マトリックスをメタ学習器に入れます

2 ブレンディングアルゴリズムを手動で実装する

def BlendingClassifier(X,y,estimators,final_estimator,test_size=0.2,vali_size=0.4):
    """
    该函数用于实现Blending分类融合
    X,y:整体数据集,会被分割为训练集、测试集、验证集三部分
    estimators: level0的个体学习器,输入格式形如sklearn中要求的[(名字,算法),(名字,算法)...]    
    final_estimator:元学习器
    test_size:测试集占全数据集的比例
    vali_size:验证集站全数据集的比例
    
    """
    
    #第一步,分割数据集
    #1.分测试集
    #2.分训练和验证集,验证集占完整数据集的比例为0.4,因此占排除测试集之后的比例为0.4/(1-0.2)
    X_,Xtest,y_,Ytest = train_test_split(X,y,test_size=test_size,random_state=1412)
    Xtrain,Xvali,Ytrain,Yvali = train_test_split(X_,y_,test_size=vali_size/(1-test_size),random_state=1412)
    
    #训练
    #建立空dataframe用于保存个体学习器上的验证结果,即用于生成新特征矩阵
    #新建空列表用于保存训练完毕的个体学习器,以便在测试中使用
    NewX_vali = pd.DataFrame()
    trained_estimators = []
    #循环、训练每个个体学习器、并收集个体学习器在验证集上输出的概率
    for clf_id, clf in estimators:
        clf = clf.fit(Xtrain,Ytrain)
        val_predictions = pd.DataFrame(clf.predict_proba(Xvali))
        #保存结果,在循环中逐渐构筑新特征矩阵
        NewX_vali = pd.concat([NewX_vali,val_predictions],axis=1)
        trained_estimators.append((clf_id,clf))
    #元学习器在新特征矩阵上训练、并输出训练分数
    final_estimator = final_estimator.fit(NewX_vali,Yvali)
    train_score = final_estimator.score(NewX_vali,Yvali)
    
    #测试
    #建立空dataframe用于保存个体学习器上的预测结果,即用于生成新特征矩阵
    NewX_test = pd.DataFrame()
    #循环,在每个训练完毕的个体学习器上进行预测,并收集每个个体学习器上输出的概率
    for clf_id,clf in trained_estimators:
        test_prediction = pd.DataFrame(clf.predict_proba(Xtest))
        #保存结果,在循环中逐渐构筑特征矩阵
        NewX_test = pd.concat([NewX_test,test_prediction],axis=1)
    #元学习器在新特征矩阵上测试、并输出测试分数
    test_score = final_estimator.score(NewX_test,Ytest)
    
    #打印训练分数与测试分数
    print(train_score,test_score)
#逻辑回归没有增加多样性的选项
clf1 = LogiR(max_iter = 3000, C=0.1, random_state=1412,n_jobs=8)
#增加特征多样性与样本多样性
clf2 = RFC(n_estimators= 100,max_features="sqrt",max_samples=0.9, random_state=1412,n_jobs=8)
#特征多样性,稍微上调特征数量
clf3 = GBC(n_estimators= 100,max_features=16,random_state=1412) 

#增加算法多样性,新增决策树与KNN
clf4 = DTC(max_depth=8,random_state=1412)
clf5 = KNNC(n_neighbors=10,n_jobs=8)
clf6 = GaussianNB()

#新增随机多样性,相同的算法更换随机数种子
clf7 = RFC(n_estimators= 100,max_features="sqrt",max_samples=0.9, random_state=4869,n_jobs=8)
clf8 = GBC(n_estimators= 100,max_features=16,random_state=4869)

estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              #, ("RandomForest2", clf7), ("GBDT2", clf8)
             ]
final_estimator = RFC(n_estimators= 100
                      #, max_depth = 8
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
#很明显,过拟合程度比Stacking要轻,但是测试集的表现没有stacking强
BlendingClassifier(X,y,estimators,final_estimator)

画像

#验证比例越大,模型学习能力越弱 - 注意验证集比例上限0.8,因为有0.2是测试数据
BlendingClassifier(X,y,estimators,final_estimator,vali_size=0.7)

画像

#blending的运行速度比stacking快了不止一个档次……
BlendingClassifier(X,y,estimators,final_estimator,vali_size=0.1)
""
1.0 0.9833333333333333
""

画像

基準 投票法 スタッキング ブレンド
5 分割相互検証 0.9666 0.9833 0.9812(↓) -
テストセットの結果 0.9527 0.9889 0.9889(-) 0.9833(↓)

結果から判断すると、投票方法が最も安定して優れたパフォーマンスを示していますが、これは選択したデータセットが比較的単純なデータセットであるという事実に関係しており、同時に投票方法は調整されたアルゴリズムでもあります。最も多く、最も適切な場所にあります。スタッキングとブレンディングは、大規模なデータ セットで実行する場合により多くの利点を示します。ここまででブレンディングの説明は終了ですが、「2022年機械学習実戦」公式講座では、xgboostなどの複雑なアルゴリズムへのブレンディングの応用についてさらに詳しく解説していきます。

元のアドレス: https://www.cnblogs.com/lipu123/p/17563377.html

Python 機械学習についてさらに詳しく知りたい場合は、公式アカウント (Python リスク コントロール モデル) をフォローしてください。

おすすめ

転載: blog.csdn.net/toby001111/article/details/133305657