LIBLINEARで分類したい!(2)


「2013年は彗星ラッシュだ!」と騒いでいたくせに、未だ今年最初の彗星が見れていない東です。

さて前回は、LIBLINEARにおける分類時のバイアスの効果について説明しました。
では、学習時にはバイアスはどのように働くのでしょうか。

■ バイアスと学習の関係。

前回引用したLIBLINEARの論文の2章を再掲します。

In some cases, the discriminant function of the classifier includes a bias term, b. LIBLINEAR handles this term by augmenting the vector w and each instance x_i with an additional dimension: w^T \leftarrow [w^T, b],  x_i^T \leftarrow [x_i^T, B], where B is a constant specified by the user.

識別関数にはバイアス項が含まれることがある。LIBLINEARはwと事例x_iの次元を増やすことで、この項に対処する。

前回は分類時の動作を説明するためにこの記述を引きましたが、学習時にもこの説明がそのまま当てはまります。具体的なデータで説明します。

1 1:1.2  2:-0.9
1 1:0.8  2:-0.5
1 1:0.4  2:-0.1
1 1:0.2  2:0.1
1 1:-0.2 2:0.5
1 1:-0.6 2:0.9
1 1:0.7  2:0.5
2 1:1.0  2:-0.9
2 1:0.6  2:-0.5
2 1:0.2  2:-0.1
2 1:0.0  2:0.1
2 1:-0.4 2:0.5
2 1:-0.8 2:0.9
2 1:-0.3 2:-0.5
test02.data

このデータに対してバイアス 1.0 を指定して学習コマンドを実行すると、内部では次のようにデータの次元を増やして、そこに指定されたバイアスの値を入れます。

1 1:1.2  2:-0.9 3:1.0
1 1:0.8  2:-0.5 3:1.0
1 1:0.4  2:-0.1 3:1.0
1 1:0.2  2:0.1  3:1.0
1 1:-0.2 2:0.5  3:1.0
1 1:-0.6 2:0.9  3:1.0
1 1:0.7  2:0.5  3:1.0
2 1:1.0  2:-0.9 3:1.0
2 1:0.6  2:-0.5 3:1.0
2 1:0.2  2:-0.1 3:1.0
2 1:0.0  2:0.1  3:1.0
2 1:-0.4 2:0.5  3:1.0
2 1:-0.8 2:0.9  3:1.0
2 1:-0.3 2:-0.5 3:1.0

その後、実際の学習処理が行なわれますが、この学習処理の動作はバイアス指定の有無に影響されません。つまり、バイアスを指定して学習した場合と、

$ ./train -B 1.0 test02.data test02.model

入力データの次元を増やして、バイアスを指定せずに学習した場合で、

$ ./train        test03.data test03.model

学習結果は同じものになります。出力されたモデルファイルを比較します。

solver_type L2R_L2LOSS_SVC_DUAL
nr_class 2
label 1 2
nr_feature 3
bias -1
w
1.091430672426507 
0.9838581679805346 
-0.2225436690102433 
solver_type L2R_L2LOSS_SVC_DUAL
nr_class 2
label 1 2
nr_feature 2
bias 1
w
1.091430672426507 
0.9838581679805346 
-0.2225436690102433 

5行目のbiasの値が異なりますが、6行目以降の分類境界を表すwの値はまったく同じです。

■ 次元を増やすだけでうまく分類できるの?

「次元を増やすだけでうまく分類できる」と言われてパッとすぐに理解することは難しいと思いますが、グラフを描くことで直感的に理解できると思います。

test02.predict
元のデータ(=バイアス指定なし) 次元を増やしたデータ(=バイアス指定あり)

次元を増やして一定の値(バイアスで指定した値)を入れるということは、データ全体を増やした次元の方向に持ち上げるということです。こうすると、分類境界面がうまくデータの隙間を通ることができるようになります。(註:分類境界面は必ず原点を通ります。)
右側の3次元グラフは、マウスの左ボタンでつまんで回すことができます。右ボタンで移動、中ボタンでズームもできますので、いろいろ動かしてみてください。

■ バイアスってどのくらいの値を指定すればいいの?

バイアスの値をいくつか変えて試してみます。

$ ./train -q -B 0.01 test02.data test02.A.model
$ ./predict          test02.data test02.A.model test02.A.predict
Accuracy = 57.1429% (8/14)

$ ./train -q -B 1.0  test02.data test02.B.model
$ ./predict          test02.data test02.B.model test02.B.predict
Accuracy = 100% (14/14)

$ ./train -q -B 100  test02.data test02.C.model
$ ./predict          test02.data test02.C.model test02.C.predict
Accuracy = 50% (7/14)

バイアスが1.0の場合はうまく分類できましたが、0.01や100を指定した場合はうまく分類できませんでした。
ここで使用したデータ(test02.data)はデータの値の範囲がすべて-1.0~1.0に収まっています。バイアスの値がデータの値の範囲に比べて小さすぎる場合には、バイアスの影響が小さくなりすぎてうまく分類できませんし、バイアスの値がデータの値の範囲に比べて大きすぎる場合には、バイアスの影響が大きくなりすぎて、これもまたうまく分類できません。バイアスの値としては、データの値の範囲と近い値を指定しておくのが良さそうです。
適切なバイアスを指定するにはデータの値の範囲を知る必要がありますが、SVMではスケーリングと言って事前にデータの範囲を調整しておくことが重要です。一般的には-1.0~1.0の範囲に値が収まるようにスケーリングしますので、バイアスとしては1.0を指定しておけば良いと思います。

■ まとめ

LIBLINEARのバイアスを学習の観点から見てみました。
また、バイアスの値としてどういう値を指定すべきかについても言及しました。

次回は、3個以上のクラスを分類するマルチクラス分類に挑戦します。


This entry was posted in 分類器, 機械学習 and tagged , . Bookmark the permalink.