web-dev-qa-db-ja.com

scikit-learnでSVMに標準化を適用する方法は?

私はscikit-learnの現在の安定したバージョン0.13を使用しています。クラス _sklearn.svm.LinearSVC_ を使用して、いくつかのデータに線形サポートベクター分類子を適用しています。

Scikit-learnのドキュメントの 前処理に関する章 で、以下を読みました。

学習アルゴリズムの目的関数で使用される多くの要素(サポートベクターマシンのRBFカーネルや線形モデルのl1およびl2正則化器など)は、すべての特徴がゼロを中心とし、同じ次数の分散を持つことを前提としています。ある特徴の分散が他の特徴よりも桁違いに大きい場合、目的関数が支配的になり、推定量が期待どおりに他の特徴から正しく学習できなくなる可能性があります。

質問1:標準化は、一般的なSVMだけでなく、私の場合のように線形カーネル関数を持つものにも役立ちますか?

質問2:私が理解している限り、トレーニングデータの平均と標準偏差を計算し、テストデータにこの同じ変換を適用する必要がありますクラス _sklearn.preprocessing.StandardScaler_ 。ただし、SVM分類器に送る前にトレーニングデータを変換する必要があるのか​​、それともテストデータだけを変換する必要があるのか​​がわかりません。

つまり、これを行う必要がありますか?

_scaler = StandardScaler()
scaler.fit(X_train)                # only compute mean and std here
X_test = scaler.transform(X_test)  # perform standardization by centering and scaling

clf = LinearSVC()
clf.fit(X_train, y_train)
clf.predict(X_test)
_

それとも私はこれをしなければなりませんか?

_scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)  # compute mean, std and transform training data as well
X_test = scaler.transform(X_test)  # same as above

clf = LinearSVC()
clf.fit(X_train, y_train)
clf.predict(X_test)
_

要するに、LinearSVCで妥当な結果を得るために、トレーニングデータでscaler.fit(X_train)またはscaler.fit_transform(X_train)を使用する必要がありますか?

25
pemistahl

どちらでもない。

scaler.transform(X_train)は効果がありません。 transform操作が適切に行われていません。あなたはしなければならない

X_train = scaler.fit_transform(X_train)

X_test = scaler.transform(X_test)

または

X_train = scaler.fit(X_train).transform(X_train)

トレーニングデータとテストデータの両方で常に同じ前処理を行う必要があります。そして、はい、データに対するあなたの信念を反映していれば、標準化は常に優れています。特にkernel-svmの場合、それはしばしば重要です。

35
Andreas Mueller

Pipelineを使用して、トランスフォーマーとエスティメータを一度にチェーン(または結合)してみませんか?データを個別にフィッティングおよび変換してから推定器を使用する手間を省きます。スペースも節約できます。

from sklearn.pipeline import Pipeline

pipe_lrSVC = Pipeline([('scaler', StandardScaler()), ('clf', LinearSVC())])
pipe_lrSVC.fit(X_train, y_train)
y_pred = pipe_lrSVC.predict(X_test)
7
vosirus