SVM

696 days ago by encafe

Hiroshi TAKEMOTO (take@pwv.co.jp)

はじめに

SVMは、オーバーフィッティングを避けて効率よく識別関数を求めることができる 手法です。

「集合知」の例題にそってカーネルメソッドとSVMについてSageを使ってまとめて みます。

# 線形クラス分類の例 # データの用意 c1 = [[1,2],[1,4],[2,4]] c2 = [[2,1],[5,1],[4,2]] # プロットして分布を確認 pl1 = list_plot(c1, rgbcolor='red') pl2 = list_plot(c2, rgbcolor ='blue') (pl1+pl2).show(xmin=0, xmax=5, ymin=0) 
       
# 各クラスに判別値をセット v1 = [-1, -1, -1] v2 = [1, 1, 1] # (x, y, 判別値)のリストを作成 data = [flatten((pt, v)) for (pt, v) in zip(c1 + c2, v1 + v2)] data 
       
[[1, 2, -1], [1, 4, -1], [2, 4, -1], [2, 1, 1], [5, 1, 1], [4, 2, 1]]
[[1, 2, -1], [1, 4, -1], [2, 4, -1], [2, 1, 1], [5, 1, 1], [4, 2, 1]]
# 最もフィットするw1, w2, bを求める var('x1 x2 w1 w2 b') model(x1, x2) = w1*x1 + w2*x2 + b fit = find_fit(data, model, solution_dict=True); fit 
       
{b: 0.19629629629454115, w1: 0.32592592592445591, w2:
-0.43333333333645996}
{b: 0.19629629629454115, w1: 0.32592592592445591, w2: -0.43333333333645996}
f(x1, x2) = model.subs(fit); pl3 = plot3d(f(x1, x2), (x1, 0, 5), (x2, 0, 5)) pl4 = list_plot([(x, y, f(x, y)) for (x, y) in c1], rgbcolor='red') pl5 = list_plot([(x, y, f(x, y)) for (x, y) in c2], rgbcolor='blue') (pl3+pl4+pl5).show(xmin=0, xmax=5) 
       
# 判別式が0の線を表示 pl6 = implicit_plot(f(x1, x2) == 0, (x1, 0, 5), (x2, 0, 5)) (pl1 + pl2 +pl6).show(xmin=0, xmax=5, ymin=0) 
       
# LIBSVMを使って計算する cls = v1 + v2; print cls dat = c1 + c2; print dat 
       
[-1, -1, -1, 1, 1, 1]
[[1, 2], [1, 4], [2, 4], [2, 1], [5, 1], [4, 2]]
[-1, -1, -1, 1, 1, 1]
[[1, 2], [1, 4], [2, 4], [2, 1], [5, 1], [4, 2]]
# svm.pyを2カ所修正した # 動作を確認するために、集合知の9.9.2の例題を実行する load svm.py prob = svm_problem([1,-1],[[1,0,1],[-1,0,-1]]) param = svm_parameter(kernel_type = LINEAR, C=float(10)) m = svm_model(prob, param) 
       
*
optimization finished, #iter = 1
nu = 0.025000
obj = -0.250000, rho = 0.000000
nSV = 2, nBSV = 0
Total nSV = 2
*
optimization finished, #iter = 1
nu = 0.025000
obj = -0.250000, rho = 0.000000
nSV = 2, nBSV = 0
Total nSV = 2
m.predict([1,1,1]) 
       
1.0
1.0
# 例題に適応 prob = svm_problem(v1 + v2,c1 + c2) m = svm_model(prob, param) 
       
*
optimization finished, #iter = 4
nu = 0.033333
obj = -1.000000, rho = 0.000000
nSV = 2, nBSV = 0
Total nSV = 2
*
optimization finished, #iter = 4
nu = 0.033333
obj = -1.000000, rho = 0.000000
nSV = 2, nBSV = 0
Total nSV = 2
m.predict([1, 4]) 
       
-1.0
-1.0
data = [] for x in srange(0, 5, 0.1): for y in srange(0, 5, 0.1): data.append( (x, y, m.predict([x, y])) ) 
       
pl7 = list_plot3d(data) pl8 = list_plot([(x, y, m.predict([x, y])) for (x, y) in c1], rgbcolor='red') pl9 = list_plot([(x, y, m.predict([x, y])) for (x, y) in c2], rgbcolor='blue') (pl8 + pl9 +pl7).show(xmin=0, xmax=5, ymin=0) 
       
# 文字認識 p0 = [0,1,1,1,0, 1,0,0,0,1, 1,0,0,0,1, 1,0,0,0,1, 0,1,1,1,0] p1 = [0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0] p2 = [0,1,1,1,1, 1,0,0,1,0, 0,0,1,0,0, 0,1,0,0,0, 1,1,1,1,1] p3 = [0,1,1,1,0, 1,0,0,1,0, 0,0,1,1,0, 1,0,0,0,1, 0,1,1,1,0] p4 = [0,0,1,0,0, 0,1,0,0,0, 1,0,0,1,0, 1,1,1,1,1, 0,0,0,1,0] v = [0,1,2,3,4] param = svm_parameter(kernel_type = LINEAR, C=float(10)) prob = svm_problem(v,[p0,p1,p2,p3,p4]) m = svm_model(prob, param) 
       
*
optimization finished, #iter = 1
nu = 0.015385
obj = -0.153846, rho = 0.538462
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.018182
obj = -0.181818, rho = -0.090909
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.033333
obj = -0.333333, rho = 0.000000
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.016667
obj = -0.166667, rho = 0.166667
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.016667
obj = -0.166667, rho = -0.666667
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.018182
obj = -0.181818, rho = -0.636364
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.018182
obj = -0.181818, rho = -0.454545
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.028571
obj = -0.285714, rho = 0.142857
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.011765
obj = -0.117647, rho = 0.176471
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.016667
obj = -0.166667, rho = 0.166667
nSV = 2, nBSV = 0
Total nSV = 5
*
optimization finished, #iter = 1
nu = 0.015385
obj = -0.153846, rho = 0.538462
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.018182
obj = -0.181818, rho = -0.090909
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.033333
obj = -0.333333, rho = 0.000000
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.016667
obj = -0.166667, rho = 0.166667
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.016667
obj = -0.166667, rho = -0.666667
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.018182
obj = -0.181818, rho = -0.636364
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.018182
obj = -0.181818, rho = -0.454545
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.028571
obj = -0.285714, rho = 0.142857
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.011765
obj = -0.117647, rho = 0.176471
nSV = 2, nBSV = 0
*
optimization finished, #iter = 1
nu = 0.016667
obj = -0.166667, rho = 0.166667
nSV = 2, nBSV = 0
Total nSV = 5
# テスト用の画像を作成する def mesh(x, y, tbl): idX = int(x) idY = int(4.9-y) return tbl[idY][idX] m0_1 = [[0,1,1,1,0], [0,1,0,0,1], [0,1,0,0,1], [0,1,0,0,1], [0,1,1,1,0]] m1_1 = [[0,0,1,0,0], [0,1,1,0,0], [0,0,1,0,0], [0,0,1,0,0], [0,1,1,1,0]] m1_2 = [[0,0,0,1,0], [0,0,0,1,0], [0,0,1,0,0], [0,0,1,0,0], [0,0,1,0,0]] t0_1 = flatten(m0_1) t1_1 = flatten(m1_1) t1_2 = flatten(m1_2) 
       
# テスト用画像の表示 contour_plot(lambda x, y : mesh(x, y, m0_1), (x, 0, 4.9), (y, 0, 4.9), aspect_ratio=1).show() contour_plot(lambda x, y : mesh(x, y, m1_1), (x, 0, 4.9), (y, 0, 4.9), aspect_ratio=1).show() contour_plot(lambda x, y : mesh(x, y, m1_2), (x, 0, 4.9), (y, 0, 4.9), aspect_ratio=1).show() 
       




# テスト用画像の認識 print m.predict(t0_1) print m.predict(t1_1) print m.predict(t1_1) 
       
0.0
1.0
1.0
0.0
1.0
1.0
# 学習用画像の認識 print m.predict(p0) print m.predict(p1) print m.predict(p2) print m.predict(p3) print m.predict(p4) 
       
0.0
1.0
2.0
3.0
4.0
0.0
1.0
2.0
3.0
4.0