web-dev-qa-db-ja.com

scikit-learnで確率的分類子を組み合わせる最良の方法

私はロジスティック回帰とランダムフォレストがあり、それらを組み合わせて(アンサンブル)、平均をとることによって最終的な分類確率を計算したいと考えています。

サイエンスキットの学習でこれを行う組み込みの方法はありますか? 2つのアンサンブルを分類子自体として使用できる方法はありますか?または、自分の分類子をロールする必要がありますか?

24
user1507844

注: scikit-learn Voting Classifier は、おそらく今これを行うための最良の方法です


古い答え:

価値のあることについて、私はこれを次のようにしてしまいました:

class EnsembleClassifier(BaseEstimator, ClassifierMixin):
    def __init__(self, classifiers=None):
        self.classifiers = classifiers

    def fit(self, X, y):
        for classifier in self.classifiers:
            classifier.fit(X, y)

    def predict_proba(self, X):
        self.predictions_ = list()
        for classifier in self.classifiers:
            self.predictions_.append(classifier.predict_proba(X))
        return np.mean(self.predictions_, axis=0)
34
user1507844

Sklearn.ensemble.VotingClassifierはどうですか?

http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.VotingClassifier.html#sklearn.ensemble.VotingClassifier

説明に従って:

投票分類子の実装の背後にある考え方は、概念的に異なる機械学習分類子を組み合わせ、多数決または平均予測確率(ソフト投票)を使用してクラスラベルを予測することです。このような分類子は、個々の弱点のバランスを取るために、同等に機能する一連のモデルに役立ちます。

3
Gabriel

同じ問題がある場合 、私は過半数の投票方法を使用しました。確率/スコアを任意に組み合わせると、さまざまな分類子のパフォーマンスが異なる可能性があるという点で非常に問題があります(たとえば、2つの異なるカーネルを持つSVM +ランダムフォレスト+別のトレーニングセットでトレーニングされた別の分類子)。

さまざまな分類子を「重み付け」する1つの可能な方法は、Jaccardスコアを「重み」として使用することです。 (ただし、私が理解しているように、さまざまなスコアが「すべて等しくなる」わけではないことに注意してください。私がアンサンブルで使用している勾配ブースティング分類器は、すべてのスコアを0.97、0.98、1.00または0.41/0としています。IEは非常に自信過剰..)

3
GrimSqueaker

現在scikit-learnには、複数の推定量をスタックするために使用できるStackingClassifierがあります。

from sklearn.datasets import load_iris  
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import LinearSVC
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import StackingClassifier
X, y = load_iris(return_X_y=True)
estimators = [
    ('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
    ('lg', LogisticRegression()))
   ]
clf = StackingClassifier(
estimators=estimators, final_estimator=LogisticRegression()
)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, stratify=y, random_state=42
)
clf.fit(X_train, y_train)
clf.predict_proba(X_test)
1
Natheer Alabsi