web-dev-qa-db-ja.com

sklearn.ensemble.AdaBoostClassifierはSVMをbase_estimatorとして受け入れられませんか?

私はテキスト分類タスクを行っています。ここで、_ensemble.AdaBoostClassifier_を_base_estimator_としてLinearSVCとともに使用します。ただし、コードを実行しようとすると

_clf = AdaBoostClassifier(svm.LinearSVC(),n_estimators=50, learning_rate=1.0,    algorithm='SAMME.R')
clf.fit(X, y)
_

エラーが発生しました。 _TypeError: AdaBoostClassifier with algorithm='SAMME.R' requires that the weak learner supports the calculation of class probabilities with a predict_proba method_

最初の質問はsvm.LinearSVC()はクラスの確率を計算できませんか?確率を計算させる方法は?

次に、パラメーターalgorithmを変更して、コードを再実行します。

_clf = AdaBoostClassifier(svm.LinearSVC(),n_estimators=50, learning_rate=1.0, algorithm='SAMME')
clf.fit(X, y)
_

今回はTypeError: fit() got an unexpected keyword argument 'sample_weight'が発生します。 AdaBoostClassifier 、_Sample weights. If None, the sample weights are initialized to 1 / n_samples._で述べたように、_n_samples_に整数を割り当てても、エラーが発生しました。

2番目の質問は_n_samples_はどういう意味ですか?この問題を解決する方法は?

誰かが私を助けてくれることを願っています。

しかし、@ jmeのコメントによると、試した後

_clf = AdaBoostClassifier(svm.SVC(kernel='linear',probability=True),n_estimators=10,  learning_rate=1.0, algorithm='SAMME.R')
clf.fit(X, y)
_

プログラムは結果を取得できず、サーバーで使用されているメモリは変更されません。

3番目の質問はAdaBoostClassifierをbase_estimatorとしてSVCで機能させるにはどうすればよいですか?

14
allenwang

正しい答えは、あなたが探しているものに正確に依存します。 LinearSVCは、クラスの確率(AdaBoostClassifierで使用されるデフォルトのアルゴリズムで必要)を予測できず、sample_weightをサポートしていません。

サポートベクターマシンは名目上クラス確率を予測しないことに注意する必要があります。これらは、既知の問題がある手法であるPlattスケーリング(またはマルチクラスの場合はPlattスケーリングの拡張)を使用して計算されます。より少ない「人工的な」クラス確率が必要な場合は、SVMが適切でない可能性があります。

そうは言っても、あなたの質問を考えれば、最も満足のいく答えはグラハムの答えだと思います。あれは、

from sklearn.svm import SVC
from sklearn.ensemble import AdaBoostClassifier

clf = AdaBoostClassifier(SVC(probability=True, kernel='linear'), ...)

他のオプションがあります。 SGDClassifierをヒンジ損失関数とともに使用し、AdaBoostClassifierを設定してSAMMEアルゴリズムを使用できます(predict_proba関数は必要ありませんが、sample_weightのサポートは必要です)。

from sklearn.linear_model import SGDClassifier

clf = AdaBoostClassifier(SGDClassifier(loss='hinge'), algorithm='SAMME', ...)

AdaBoostClassifierに提供されているデフォルトのアルゴリズムを使用する場合は、ロジスティック回帰など、クラス確率をネイティブにサポートする分類子を使用するのがおそらく最善の答えです。これは、scikit.linear_model.LogisticRegressionを使用するか、Krisが提供するコードで使用されているログ損失関数を備えたSGDClassifierを使用して行うことができます。

プラットのスケーリングとは何かについて知りたい場合は、それがお役に立てば幸いです ジョンプラットの元の論文をここでチェックしてください

13
kevin

実際、LinearSVCは、Plattスケーリングを介してSVC出力を再スケーリングせずにAdaBoostClassifierに適用できます。つまり、AdaBoost.M1アルゴリズムは当初設計されており、分類子は出力として{1、1}を取ります。 AdaBoostClassifierでのデフォルトのアルゴリズムの選択は、マルチクラス分類用に設計されたAdaBoost.SAMMEアルゴリズム[2](アルゴリズムキーワード引数で「SAMME.R」を指定)です。

ただし、LinearSVCAdaBoostはpredict_probaを提供できません。反対に、SVM出力をシグモイド曲線に適合させて確率を提供するのではなく、出力に符号を保持することが必要な場合。次に、アルゴリズムをSAMME.RからSAMMEに変更するのが最も簡単な方法です。

[1] Y。 Freund、R。Schapire、「オンライン学習の決定理論的一般化とブースティングへの応用」、1995年。
[2] Zhu、H。Zou、S。Rosset、T。Hastie、「Multi-class AdaBoost」、2009

1
ReneWang

これはLinearSVCでは使用できないため、predict_probaメソッドを持つ学習器を使用する必要があります。カーネルを「linear」に設定してSVCを試してください。

clf = AdaBoostClassifier(svm.SVC(probability=True,kernel='linear'),n_estimators=50,       learning_rate=1.0, algorithm='SAMME')
clf.fit(X, y)

これがLinearSVCと同じ結果をもたらすかどうかはわかりませんが、ドキュメントには次のように書かれています。

パラメーターkernel = 'linear'のSVCに似ていますが、libsvmではなくliblinearの観点から実装されているため、ペナルティ関数と損失関数の選択の柔軟性が高く、(多数のサンプルに対して)より適切にスケーリングする必要があります。

また、One vsAllとOnevs Oneについて、それらの違いについても言及しています。

1
Graham Annett

AdaBoostClassifierLogisticRegressionと一緒に使用しようとすると同様の問題が発生しました。ドキュメントには、弱い分類子(またはbase_estimator)には、オプションのsample_weight=...キーワード引数をとるfitメソッドが必要であると記載されています。質問 #18306416

AdaBoostでSVMまたはロジスティック回帰を使用する場合は、sklearnの確率的勾配降下分類器をloss='hinge'(svm)またはloss='log'(ロジスティック)で使用します。

from sklearn.linear_model import SGDClassifier
from sklearn.ensemble import AdaBoostClassifier

clf = AdaBoostClassifier(SGDClassifier(loss='log'), ...)

YMMV

0
Kris