うーん・・・?

Inconsistent prediction results using LinearSVC from sklearn, – StackOverflow

質問と回答の意味は分かるし,単なる線形分類器なら何も悩む事は無いけど.
(真ん中に線を引いて,‐1か1かのバイナリだから;或いはハードマージンの場合)

切片なし.

import scipy as sc
import numpy as np
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score


N=6000
m=500

D = sc.sparse.random(N, m, random_state = 1)
D.data *= 2
D.data -= 1

X = sc.sparse.csr_matrix(D)
y = (X.sum(axis = 1) > .0) * 2 - 1.0 

x_train = X[:5000, :]
y_train = y[:5000, :]
x_test  = X[5000:, :]
y_test  = y[5000:, :]

clf = LinearSVC(C=.1, fit_intercept = False, loss= 'hinge')
clf.fit(x_train, np.asarray(y_train).ravel())

y_pred = clf.predict(x_test)


print("Direct prediction accuracy:\t", 100 - 100 * np.mean((np.sign(x_test * clf.coef_.T) != y_test) + 0.0), "%")
print("Direct prediction accuracy:\t", 100 - 100*np.mean((np.where(x_test * clf.coef_.T > 0, 1, -1) != y_test) + 0.0), "%")
print("CLF prediction accuracy:\t",  100 * clf.score(x_test, y_test), "%")
print(f'Accuracy: {100 * accuracy_score(y_test, y_pred)} %')#np.mean(y_pred == np.asarray(y_test).ravel())

Direct prediction accuracy: 90.8 %
Direct prediction accuracy: 91.3 %
CLF prediction accuracy: 91.3 %
Accuracy: 91.3 %

切片あり.

import scipy as sc
import numpy as np
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score


N=6000
m=500

D = sc.sparse.random(N, m, random_state = 1)
D.data *= 2
D.data -= 1

X = sc.sparse.csr_matrix(D)
y = (X.sum(axis = 1) > .0) * 2 - 1.0 

x_train = X[:5000, :]
y_train = y[:5000, :]
x_test  = X[5000:, :]
y_test  = y[5000:, :]

clf = LinearSVC(C=.1, fit_intercept = True, loss= 'hinge')
clf.fit(x_train, np.asarray(y_train).ravel())

y_pred = clf.predict(x_test)


print("Direct prediction accuracy:\t", 100 - 100 * np.mean((np.sign(x_test * clf.coef_.T + clf.intercept_) != y_test) + 0.0), "%")
print("Direct prediction accuracy:\t", 100 - 100*np.mean((np.where(x_test * clf.coef_.T + clf.intercept_ > 0, 1, -1) != y_test) + 0.0), "%")
print("CLF prediction accuracy:\t",  100 * clf.score(x_test, y_test), "%")
print(f'Accuracy: {100 * accuracy_score(y_test, y_pred)} %')#np.mean(y_pred == np.asarray(y_test).ravel())

Direct prediction accuracy: 91.1 %
Direct prediction accuracy: 91.1 %
CLF prediction accuracy: 91.1 %
Accuracy: 91.10000000000001 %

これ等が意味するのは,上記(質問の話)は決定境界上の扱いというより0の扱い(単にバイナリ処理)についてであり,下記は切片を置くと綺麗に(正しくという意味ではない)-1 or 1に分類されているので0の処理による誤りが無いって事だろう.

例えば,この場合(sklearn.svm.SVCの場合切片に関するオプション引数は無い).

import scipy as sc
import numpy as np
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score


N=6000
m=500

D = sc.sparse.random(N, m, random_state = 1)
D.data *= 2
D.data -= 1

X = sc.sparse.csr_matrix(D)
y = (X.sum(axis = 1) > .0) * 2 - 1.0 

x_train = X[:5000, :]
y_train = y[:5000, :]
x_test  = X[5000:, :]
y_test  = y[5000:, :]

clf = SVC(kernel='linear')
clf.fit(x_train, np.asarray(y_train).ravel())

y_pred = clf.predict(x_test)


print("Direct prediction accuracy:\t", 100 - 100 * np.mean((np.sign(x_test * clf.coef_.data.reshape(-1, 1)) != y_test) + 0.0), "%")
print("Direct prediction accuracy:\t", 100 - 100 * np.mean((np.sign(x_test * clf.coef_.data.reshape(-1, 1) + clf.intercept_) != y_test) + 0.0), "%")
print("Direct prediction accuracy:\t", 100 - 100*np.mean((np.where(x_test * clf.coef_.data.reshape(-1, 1) > 0, 1, -1) != y_test) + 0.0), "%")
print("Direct prediction accuracy:\t", 100 - 100*np.mean((np.where(x_test * clf.coef_.data.reshape(-1, 1) + clf.intercept_ > 0, 1, -1) != y_test) + 0.0), "%")
print("CLF prediction accuracy:\t",  100 * clf.score(x_test, y_test), "%")
print(f'Accuracy: {100 * accuracy_score(y_test, y_pred)} %')#np.mean(y_pred == np.asarray(y_test).ravel())

Direct prediction accuracy: 92.4 %
Direct prediction accuracy: 92.8 %
Direct prediction accuracy: 92.9 %
Direct prediction accuracy: 92.8 %
CLF prediction accuracy: 93.9 %
Accuracy: 93.89999999999999 %
 
 
 

L2正則化でヒンジロスで,同じ事をやっていると思うけど,Accuracyの結果が約1%異なる.

LinearSVCではclf.coef_はnumpy.ndarrayで返ってくるけど,SVC(kernel=’linear’)ではsparse matrixで返ってくる.

plt.figure(figsize=(19, 10))
plt.scatter(x, x_test * clf.coef_.T)
plt.plot([min(x), max(x)], [0, 0], 'k--')
plt.savefig('linearsvc.png')

linearsvc

plt.figure(figsize=(19, 10))
plt.scatter(x, x_test * clf.coef_.data.reshape(-1, 1) + clf.intercept_)
plt.plot([min(x), max(x)], [0, 0], 'k--')
plt.savefig('svc.png')

svc

決定境界,マージン(0の領域)の扱いの違いか.であれば,データによって結果が異なるのでは?

for i in range(10):
    D = sc.sparse.random(N, m)
    D.data *= 2
    D.data -= 1

    X = sc.sparse.csr_matrix(D)
    y = (X.sum(axis = 1) > .0) * 2 - 1.0 

    x_train = X[:5000, :]
    y_train = y[:5000, :]
    x_test  = X[5000:, :]
    y_test  = y[5000:, :]

    clf = LinearSVC(C=.1, fit_intercept = False, loss= 'squared_hinge')
    clf.fit(x_train, np.asarray(y_train).ravel())

    clf2 = SVC(kernel='linear')
    clf2.fit(x_train, np.asarray(y_train).ravel())

    print(f'Loop: {i}')

    print("Direct prediction accuracy:\t", 100 - 100*np.mean((np.where(x_test * clf.coef_.T > 0, 1, -1) != y_test) + 0.0), "%")
    print("CLF prediction accuracy:\t",  100 * clf.score(x_test, y_test), "%")

    print("Direct prediction accuracy:\t", 100 - 100*np.mean((np.where(x_test * clf2.coef_.data.reshape(-1, 1) + clf2.intercept_ > 0, 1, -1) != y_test) + 0.0), "%")
    print("CLF prediction accuracy:\t",  100 * clf2.score(x_test, y_test), "%")

Loop: 0
Direct prediction accuracy: 93.1 %
CLF prediction accuracy: 93.1 %
Direct prediction accuracy: 94.3 %
CLF prediction accuracy: 93.7 %
Loop: 1
Direct prediction accuracy: 93.4 %
CLF prediction accuracy: 93.4 %
Direct prediction accuracy: 94.2 %
CLF prediction accuracy: 94.3 %
Loop: 2
Direct prediction accuracy: 93.5 %
CLF prediction accuracy: 93.5 %
Direct prediction accuracy: 93.5 %
CLF prediction accuracy: 93.4 %
Loop: 3
Direct prediction accuracy: 93.9 %
CLF prediction accuracy: 93.9 %
Direct prediction accuracy: 92.9 %
CLF prediction accuracy: 94.1 %
Loop: 4
Direct prediction accuracy: 93.3 %
CLF prediction accuracy: 93.3 %
Direct prediction accuracy: 93.2 %
CLF prediction accuracy: 93.2 %
Loop: 5
Direct prediction accuracy: 94.2 %
CLF prediction accuracy: 94.2 %
Direct prediction accuracy: 93.9 %
CLF prediction accuracy: 93.9 %
Loop: 6
Direct prediction accuracy: 93.7 %
CLF prediction accuracy: 93.7 %
Direct prediction accuracy: 92.6 %
CLF prediction accuracy: 93.7 %
Loop: 7
Direct prediction accuracy: 94.7 %
CLF prediction accuracy: 94.7 %
Direct prediction accuracy: 93.0 %
CLF prediction accuracy: 94.4 %
Loop: 8
Direct prediction accuracy: 94.2 %
CLF prediction accuracy: 94.2 %
Direct prediction accuracy: 93.9 %
CLF prediction accuracy: 94.4 %
Loop: 9
Direct prediction accuracy: 93.6 %
CLF prediction accuracy: 93.6 %
Direct prediction accuracy: 92.9 %
CLF prediction accuracy: 93.2 %

SVMでは予想通りの結果だが,LinearSVCは綺麗に一致する.

LinearSVCはバイアスサイズにもペナルティを課す為,SVMとは計算が大きく異なるけど,それが効いているんだろうか.

広告
カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中