web-dev-qa-db-ja.com

svmスケーリング入力値

私はlibSVMを使用しています。私の機能値が次の形式であるとしましょう:

                         instance1 : f11, f12, f13, f14
                         instance2 : f21, f22, f23, f24
                         instance3 : f31, f32, f33, f34
                         instance4 : f41, f42, f43, f44
                         ..............................
                         instanceN : fN1, fN2, fN3, fN4

2つのスケーリングを適用できると思います。

  1. 各ベクトルの平均と単位分散がゼロになるように、各インスタンスベクトルをスケーリングします。

        ( (f11, f12, f13, f14) - mean((f11, f12, f13, f14) ). /std((f11, f12, f13, f14) )
    
  2. 上記の行列の各列を範囲にスケーリングします。たとえば[-1、1]

RBFカーネル(libSVM)を使用した実験によると、2番目のスケーリング(2)によって結果が約10%向上することがわかりました。 (2)の結果が改善された理由がわかりませんでした。

スケーリングを適用する理由と、2番目のオプションで結果が改善される理由を誰かに説明してもらえますか?

15
user570593

標準的な方法は、各ディメンション(または属性、または列(この例では))の平均と単位の分散をゼロにすることです。

これにより、SVMの各次元が同じ大きさになります。から http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf

スケーリングの主な利点は、小さい数値範囲の属性を支配する大きい数値範囲の属性を回避することです。もう1つの利点は、計算中に数値の問題を回避できることです。カーネル値は通常、特徴ベクトルの内積に依存するためです。線形カーネルと多項式カーネルでは、属性値が大きいと数値的な問題が発生する可能性があります。各属性を[-1、+ 1]または[0,1]の範囲に線形にスケーリングすることをお勧めします。

19
user334856

それはあなたの元のデータに大きく影響すると思います。

元のデータの一部の列に極端な値がある場合、たとえば[-1,1]の範囲で線形にスケーリングすると、定義が失われると思います。

値の90%が100〜500の間にあり、残りの10%の値が-2000から+2500までの列があるとします。

このデータを線形にスケーリングすると、次のようになります。

-2000 -> -1 ## <- The min in your scaled data
+2500 -> +1 ## <- The max in your scaled data

 100 -> -0.06666666666666665 
 234 -> -0.007111111111111068
 500 ->  0.11111111111111116

元の100と500の間の識別可能性は、元のデータにあったものと比較して、スケーリングされたデータの方が小さいと主張することができます。

最後に、それはデータの詳細に非常に依存していると思います。パフォーマンスが10%向上したのは偶然の一致であり、両方のスケーリング方法を試したすべてのデータセットでこの大きさの違いは見られません。

同時に、他の回答にリストされているリンクの論文では、著者がデータを線形にスケーリングすることを推奨していることがはっきりとわかります。

誰かがこれが役に立つと思うことを願っています!

4
Thanos