s5unnyjjj's LOG
ML - Practice #4 : SVM 본문
본 글에서는 아래에 나열된 이론을 바탕으로 코드를 작성해보도록 한다.
1. SVM (참고링크) https://s5unnyjjj.tistory.com/64?category=939071
1_1. Binary Classification with Linear SVM
1_2. Kernel SVM
Binary Classification with Linear SVM
sklearn에서는 classification 모델 테스트를 위하여 여러가지 가상의 데이터를 생성하는 함수를 제공한다. 그 중, 클러스터링 용 가상데이터를 생성하는 함수인 make_blobs 함수를 사용하여 진행한다. training dataset과 test dataset에서 표본 데이터의 수는 각각 100개 씩이며 독립 변수의 수는 2개로 설정하였다. 그림으로 보면 아래와 같다.
Binary Classification with Linear SVM의 Objective function은 아래와 같이 정의된다.
SVM_model.py 하위에 있는 objective_function 함수
위의 objective function을 코드로 구현하면 아래와 같다.
위의 식에 작성된 L(Hinge)는 Hinge Loss(힌지로스)를 의미한다. Hinge Loss는 class내의 데이터 분포 간의 거리가 가장 먼 decision boundary를 찾기 위해 고안된 함수로 score function을 이용하여 계산된다.
SVM_model.py 하위에 있는 hinge_loss 함수
위의 hinge loss를 코드로 구현하면 아래와 같다.
위의 식에 작성된 s(theta)는 score function으로 식은 아래와 같다.
SVM_model.py 하위에 있는 score_function 함수
위의 score function을 코드로 구현하면 아래와 같다.
SVM_model.py 하위에 있는 prediction_function 함수
SVM 모델을 측정하는 식은 theta1*X + theta0 이며 코드로 구현하면 아래와 같다.
objective function의 미분을 이용하여 theta를 update함으로써 최적의 theta를 구한다.
SVM_model.py 하위에 있는 update_svm 함수
Objective function을 theta1으로 미분한 것을 이용하여 theta1을 업데이트 해주고, theta0으로 미분한 것을 이용하여 theta0을 업데이트해준다. 코드로 구현하면 아래와 같다.
위의 코드에 대한 추가적인 설명을 붙이고자 한다. hinge_loss(X, y, updated_theta)를 출력하면 아래와 같다.
(hinge_loss(X, y, updated_theta)>=0)이면 0보다 큰 값은 True로 저장되며 출력값은 아래와 같다.
y를 출력하면 아래와 같으며 shape은 (100, )이다. np.expand_dims(y, -1)에서 np.expand_dims 함수를 사용하면 축을 하나 늘려줄 수 있다. 추가적으로 axis=-1을 설정하게 되면 마지막 축을 늘려주도록 설정해줄 수 있다.
y[hinge]를 해주게 되면 y랑 같은 값이 출력되는 것을 아래에서 확인할 수 있다. 왜냐하면 위에서 hinge배열 값이 전부다 True 였기 때문이다.
임시로 hinge[0]값을 False로 바꿔준 후, y[hinge]를 출력하면 배열이 index가 0번째인 값이 y[0]값과는 반대로 -1로 바뀐 것을 아래에서 확인할 수 있다.
이렇게 y[hinge]를 해주는 이유는 hinge loss의 값이 0보다 작으면 미분값이 0이도록 설정하기 위해서이다. 왜냐하면 hinge loss가 0보다 작다는 것은 업데이트 할 필요 없다는 것을 의미하기 때문이다.
Result : Check the obtained decision boundary and marginal hyperplanes
우선 training dataset 상에서의 decision boundary와 marginal hyperplanes를 확인해보면 아래와 같으며, misclassified data는 7개임을 알 수 있다.
그 다음 test dataset 상에서의 decision boundary를 확인해보면 아래와 같으며, misclassified data는 9개임을 알 수 있다.
Result : Compare results from two different methods "Logistic regression and SVM"
sklearn라이브러리에서 불러온 Logistic regression모델과 위의 함수들을 통해 학습한 SVM 모델을 이용하여 training dataset상에서 결과를 확인해보면 아래와 같다. Logistic regression과 SVM은 최적화시키는 방법이 다르기때문에, 완전히 같은 선이 아님을 알 수 있다.
Kernel SVM
아래와 같은 dataset이 분포되어있는 경우 hyperplane을 이용하여 데이터를 분리할 수 없다.
위와 같은 상황에서 데이터를 분리할 수 없는 경우에는 Kernel을 사용하여 비선형경계를 사용하여 데이터를 분리하도록 Kernel-SVM 모델을 사용한다. Kernel-SVM에 사용되는 Kernel 종류는 많지만 여기서는 Gaussian Kernel과 Polynomial Kernel 만을 확인해본다. Gaussian Kernel의 식은 아래와 같다.
SVM_model.py 하위에 있는 gassian_kernel 함수
위의 Guasian Kernel을 코드로 구현하면 아래와 같다.
Polynomial Kernel의 식은 아래와 같다. (여기서 m은 degree를 의미하며 c는 bias를 의미한다.)
SVM_model.py 하위에 있는 polynomial_kernel 함수
위의 Polynomial Kernel을 코드로 구현하면 아래와 같다.
Result : Check the results of SVM with Gaussian Kernel or Polynomial Kernel
Gaussian Kernel을 이용하여 학습된 SVM 모델을 test dataset으로 예측한 결과는 아래와 같다. (sigma=1)
Polynomial Kernel을 이용하여 학습된 SVM 모델을 test dataset으로 예측한 결과는 아래와 같다. (m=3, c=1)
----------------------------------------------------------------------------------------------------
>> 위 내용은 필자가 직접 작성한 내용입니다.
>> 필자가 직접 구현한 코드를 아래의 링크에 업로드하였으니 참고바랍니다.
https://github.com/s5unnyjjj/ML_Practice-4
>> 부족한 점이 많을 수 있기에 잘못된 내용이나 궁금한 사항이 있으면 댓글 달아주시기 바랍니다.
>> 긴 글 읽어주셔서 감사합니다.