반응형

+SVM (support vector machine)을 사용하여 간단하게 바이너리 분류하기


간단하게 말하면 가장 마진이 크도록 최적의 구분 라인 긋기. 약간의 판단 오류가 있더라면 데이터의 밀집 분포 정도에 따라 최적의 라인은 다를 수 있다. 판단오류가 하나도 없도록(과적합) 구분 라인을 만들면 오히려 임의의 값 예측시 정확도가 더 떨어질 수 있다. 


X 데이터 : 피쳐2개. 

Y데이터 : 라벨 (0, 1) binary 분류값.

SVM으로 최적 구분 라인 계산.

임의의 값에 대해 Y데이터 예측하기.


from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

# line split SVM

X = np.array([[1,2],
[5,8],
[1.5,1.8],
[8,8],
[1,0.6],
[9,11]])
y = [0,1,0,1,0,1]
clf = SVC(kernel='linear'1.0# C is error penalty. if C is bigger then more strictly but margin will be narrow...
clf.fit(X,y)
print(clf.predict([[0.58,0.76]]))
print(clf.predict([[10.58,10.76]]))

w = clf.coef_[0]
print(w)
a = -w[0] / w[1]

xx = np.linspace(0,12)
yy = a * xx - clf.intercept_[0] / w[1]

h0 = plt.plot(xx, yy, 'k-'label="non weighted div")

plt.scatter(X[:, 0], X[:, 1], = y)
plt.legend()
plt.show()

[해설]
x데이터의 벡터는 2차원이고 구분 레이블은 y로 0, 1로 두 그룹으로 나눈다.
SVC의 리턴값으노 clf로 피팅을 하게 되면
clf.predict()로 입력값 x에 대한 구분 레이블 y를 예측할 수 있다.

x데이터의 벡터요소(피쳐)를 x0, x1라 하면
새로운 좌표계의 1차원 좌표축을 z라하면
z = f (x0, x1) 
z>=0 이면 레이블1, z<0이면 레이블 0가 될 것이다. (z=0이면 1일까? 맞다.)

clf의 coef_로 w0, w1를 얻고, intercept로 b를 얻는다.
w0, w1는 입력값의 가중치. b 는 bias

z = w0*x0+w1*x1 + b 가 된다.
따라서 위 라인 (z=0으로 놓는다.)을 기준으로 분류한다.

위 라인을 x1(Y축)에 대해 정리하면
기울기는 -w0/w1
y절편은 -b/w1가 된다.
이 라인이 구분선이 된다.





+ Recent posts