전공관련/기타 etc.

[LibSVM] libsvm을 이용한 2-class classifier (1) - SVM이란 무엇인가.

매직블럭 2014. 2. 12. 18:10

모든내용은 개인 공부내용 기록용이며 매우 초보적인 내용이며 

처음 개념을 접하는 사람에게 약간의 도움이 될수도 있겠지.. 라는 생각에 기록합니다.

틀린 내용이 많을 수 있습니다.


==================================================================================


자 눈앞에 사진 한장이 있다고 가정을 해보자.


이 사진에 있는것이 사람인가 아닌가


또는 자전거가 있는가 아닌가.


이러한 문제들은 주어진 상황이 A라는 상황인지 아니면 A가 아닌 상황인지 이런식으로 두가지 class로 구분하는


문제이다.


이러한 2-class classifier 중에서 일반화 능력이 가장 좋다고 알려진 것이 바로 SVM 이다.


SVM 은 Support Vector Machine 의 약자로 학습데이터를 두개의 클래스로 나누는 가장 적절한 결정선을 찾아주는 classifier 이다.


이해를 쉽게 하기 위해 2차원에서 먼저 생각을 해보자


학습 샘플이 아래의 그림과 같이 초록색과 빨간색으로 주어 졌다고 가정을 하자.


이때 주어진 학습 샘플에 대해서는 A, B, C, D 모두 올바르게 클래스를 구분하는 결정 직선을 제시하였다.



물론 이렇게 결정직선을 정하고 새로운 자연상태의 데이터가 들어왔을때 저 학습샘플의 범주 내에서만 나타난다면


얼마나 좋겠는가.. 어떤 데이터가 들어오던지 올바르게 분류할 테니까 말이다..


하지만 실제로 우리가 사용하게 되는 환경에서는 데이터가 저런 형태로만 들어오는 것이 아니다.


예를 들어 C의 형태로 클래스 구분을 한다면 녹색 특징들이 모여있는곳에서 약간 오른쪽 아래로 새로운 특징이


들어올 가능성이 매우 다분하다. 


이럴 경우에는 녹색이 속한 클래스와 매우 근접하고 빨간색이 속한 클래스와는 매우 멀리 떨어져 있음에도


결정직선이 초록색 그룹에 가까이 붙어있어서 녹색 클래스의 데이터임에도 빨간색 그룹으로 분류해 버릴 가능성이 더 크다


이러한 문제를 해결하기 위해 트레이닝 데이터를 그냥 나누는 것이 아니라 새로운 데이터에 대비하여 일반화 능력을 


극대화 하는 결정 직선을 찾는것이 SVM 의 역할이다.


위 그림에서 보면 D 의 결정직선이 육안으로 보기에도 가장 두 클래스를 적절하게 나눠 준다.


클래스 사이의 거리도 적절히 멀기 때문에 새로운 데이터가 들어왔을때 올바르게 분류 할 확률도 가장 높다.


자 그럼 SVM에서 Support Vector 가 무엇을 의미하느냐 하는건 아래의 그림을 보면 알수 있다.



Support Vector 란 말 그대로 도움을 주는 벡터들 이다.


이 벡터들은 어떻게 결정되는고 하니 일단 클래스를 나누는 결정직선이 선택 되면 


그 직선에서 제일 가까운 벡터들이 Support Vector 가 되는것이다.


이때 A Class 의 Support Vector 와 B Class 의 Support Vector 사이의 거리를 margin(여백) 이라 하는데


SVM 의 역할을 다시 말하자면 이 Margin을 최대로 하는 결정직선을 찾는것이다.


이 결정직선을 찾는 과정은 수학적으로 풀어 나가려면 조건부 최적화니 KKT니 Wolf duel 이니 뭐 복잡하다.


수식은 나중에 필요하면 찾아보도록 하고.. 


일단 SVM 이 이런 개념이라는 것만 알고 넘어가도록 하자.


그리고 하나 추가로 알아야 할 개념이 Kernel 에 대한 개념이다.


위에서 예시로 보인대로 하나의 직선으로 두개의 클래스가 딱 나뉘면 얼마나 좋겠냐마는 일반적으로


그런 경우보다는 하나의 직선으로 나뉘지 않는 경우가 더 욱 많이 존재한다.


예를들어 아래와 같은 형태로 데이터가 들어왔다고 가정을 해보자.

이런 형태의 데이터는 하나의 직선으로 빨간네모 집합과 초록 동그라미 집합으로 나눌수가 없다.


이럴 경우 한번에 두개의 집합으로 나누는 방법은 크게 두가지가 있는데 이는 KAIST 김창익 교수님이 


강의때 예시로 설명하신 방법으로 처음 개념을 이해하기에 매우 좋은 방법인 듯 하여 이곳에 설명한다.


첫번째 방법은 아래 그림처럼 곡선 형태의 결정선을 구하여 가운데 집합을 잘라내는 방법이다.


다른 하나의 방법은 직선으로 주어져 있던 입력샘플의 공간을 아래처럼 휘어진 공간으로 변형시키고


이전에 사용하던 직선으로 잘라내는 방법이다.



잘라내는 곡선형태의 칼을 만들기는 간단하지 않은 방법이지만 데이터 공간의 차원을 변화시키는 일은 상대적으로


쉽게 해결 할 수 있다고 한다.


이렇게 샘플의 차원을 바꿔주는 역할을 하는것이 Kernel 이라고 한다.


이러한 Kernel 을 이용하여 차원을 변경하면 아래 예시처럼 쉽게 나누기 어렵던 문제도 간단하게 나눌수 있게 변형된다는


장점이 있다.




뭐 이런 개념이라는것만 알아두고 우리가 SVM을 직접 구현 하기는 매우 어렵고 


이미 개발되어 라이브러리로 제공되는 유용한 SVM이 대표적으로 두가지가 있다.


하나는 SVM Light ( http://svmlight.joachims.org/ )이고


다른 하나는 다음 포스팅에서 사용할 LibSVM( http://www.csie.ntu.edu.tw/~cjlin/libsvm/ ) 이다.


둘다 간단한 조작으로 사용 가능하게 구현 되어 있고 설명문도 같이 있어서 기본적인 사용은 크게 어렵지 않다.