서포트 벡터 머신(Support Vector Machine) 쉽게 이해하기

서포트 벡터 머신(SVM: Support Vector Machine)은 분류 과제에 사용할 수 있는 강력한 머신러닝 지도학습 모델이다. 일단 이 SVM의 개념만 최대한 쉽게 설명해본다. 중간중간 파이썬 라이브러리 scikit-learn을 사용한 아주 기초적인 실습을 통해 개념 이해를 돕는다.

목차는 아래와 같다.

  • 서포트 벡터 머신이란
  • 최적의 결정 경계(Decision Boundary)
  • 마진(Margin)
  • 이상치(Outlier)를 얼마나 허용할 것인가
  • 커널(Kernel)
    1. 다항식(Polynomial)
    2. 방사 기저 함수(RBF: Radial Bias Function)
  • 요약

내용이 많지 않으니 후딱 살펴보자.


서포트 벡터 머신이란

서포트 벡터 머신(이하 SVM)결정 경계(Decision Boundary), 즉 분류를 위한 기준 선을 정의하는 모델이다. 그래서 분류되지 않은 새로운 점이 나타나면 경계의 어느 쪽에 속하는지 확인해서 분류 과제를 수행할 수 있게 된다.

결국 이 결정 경계라는 걸 어떻게 정의하고 계산하는지 이해하는 게 중요하다는 뜻이다.

일단 예시를 보자.

만약 데이터에 2개 속성(feature)만 있다면 결정 경계는 이렇게 간단한 선 형태가 될 거다.

그러나 속성이 3개로 늘어난다면 이렇게 3차원으로 그려야 한다.

그리고 이 때의 결정 경계는 ‘선’이 아닌 ‘평면’이 된다.

우리가 이렇게 시각적으로 인지할 수 있는 범위는 딱 3차원까지다. 차원, 즉 속성의 개수가 늘어날수록 당연히 복잡해질 거다. 결정 경계도 단순한 평면이 아닌 고차원이 될 텐데 이를 “초평면(hyperplane)”이라고 부른다. (어렵게 생각할 필요는 없다. 일단 용어만 알고 넘어가자.)

최적의 결정 경계(Decision Boundary)

결정 경계는 무수히 많이 그을 수 있을 거다. 어떤 경계가 좋은 경계일까?

일단 아래 그림들을 보자.

어떤 그래프가 제일 위태로워 보이는가?
C를 보면 선이 파란색 부류와 너무 가까워서 아슬아슬해보인다.

그렇다면 어떤 결정 경계가 가장 적절해보이는가?
당연히 F다. 두 클래스(분류) 사이에서 거리가 가장 멀기 때문이다.

이제 결정 경계는 데이터 군으로부터 최대한 멀리 떨어지는 게 좋다는 걸 알았다. 실제로 서포트 벡터 머신(Support Vector Machine)이라는 이름에서 Support Vectors는 결정 경계와 가까이 있는 데이터 포인트들을 의미한다. 이 데이터들이 경계를 정의하는 결정적인 역할을 하는 셈이다.

이어서 마진(Margin)이라는 용어에 대해 알아보자.

마진(Margin)

마진(Margin)은 결정 경계와 서포트 벡터 사이의 거리를 의미한다.

아래 그림을 보면 바로 이해된다.

가운데 실선이 하나 그어져있는데, 이게 바로 ‘결정 경계’가 되겠다. 그리고 그 실선으로부터 검은 테두리가 있는 빨간점 1개, 파란점 2개까지 영역을 두고 점선을 그어놓았다. 점선으로부터 결정 경계까지의 거리가 바로 ‘마진(margin)’이다.

여기서 일단 결론을 하나 얻을 수 있다. 최적의 결정 경계는 마진을 최대화한다.

그리고 위 그림에서는 x축과 y축 2개의 속성을 가진 데이터로 결정 경계를 그었는데, 총 3개의 데이터 포인트(서포트 벡터)가 필요했다. 즉, n개의 속성을 가진 데이터에는 최소 n+1개의 서포트 벡터가 존재한다는 걸 알 수 있다.

이번엔 SVM 알고리즘의 장점을 하나 알 수 있다.

대부분의 머신러닝 지도 학습 알고리즘은 학습 데이터 모두를 사용하여 모델을 학습한다. 그런데 SVM에서는 결정 경계를 정의하는 게 결국 서포트 벡터이기 때문에 데이터 포인트 중에서 서포트 벡터만 잘 골라내면 나머지 쓸 데 없는 수많은 데이터 포인트들을 무시할 수 있다. 그래서 매우 빠르다.

※ scikit-learn 사용법

SVM에서 결정 경계를 구하는 건 상당히 복잡한 최적화 문제다. 이 계산 과정을 온전히 이해하는 건 나 같은 무지랭이에겐 너무 버거운 일일 거다.

그러나 파이썬 scikit-learn 라이브러리가 있으니 일단 이걸 통해 SVM을 구현해보자. 게다가 scikit-learn을 활용하면 모델을 구현할 때 사용되는 추가적인 개념도 익힐 수 있다.

일단 아래 그림과 같이 선을 긋는 연습을 해보자.

from sklearn.svm import SVC

classifier = SVC(kernel = 'linear')

training_points = [[1, 2], [1, 5], [2, 2], [7, 5], [9, 4], [8, 2]]
labels = [1, 1, 1, 0, 0, 0]

classifier.fit(training_points, labels) 

일단 SVC를 불러올 때 kernel='linear'라고 지정해줬다. 이건 뒤에서 설명할 예정이니 일단 넘어가고…!

레이블은 빨간 걸 1, 파란걸 0으로 보면 된다.

그리고 .fit() 안에 학습 데이터와 레이블을 넣어주면 짠!하고 선을 긋는 거다. 이게 끝이다.

이제 .predict() 메서드를 통해 분류를 해볼 수 있다. 예를 들어 [3, 2]라는 데이터를 넣어 예측을 하려면 이렇게

print(classifier.predict([[3, 2]]))

위 그림에서 직접 눈으로 [3, 2] 좌표를 찍어봐도 알 수 있듯 빨간 점, 1로 분류될 거다.

그리고 위에서 설명한 서포트 벡터, 결정 경계를 정의하는 서포트 벡터를 확인하려면 classifier.support_vectors_를 print 해보면 된다.

이렇게 나올 거다.

[[7, 5],
[8, 2],
[2, 2]]

파란 점 2개와 빨간 점 1개를 사용했다.

이상치(Outlier)를 얼마나 허용할 것인가

SVM은 ​​데이터 포인트들을 올바르게 분리하면서 마진의 크기를 최대화해야 하는데, 결국 이상치(outlier)를 잘 다루는 게 중요하다.

아래 그림을 보자. 선을 살펴보기에 앞서 왼쪽에 혼자 튀어 있는 파란 점과, 오른쪽에 혼자 튀어 있는 빨간 점이 있다는 걸 봐두자. 누가 봐도 아웃라이어다.

이제 위 아래 그림을 좀 더 자세히 비교해보자.

  • 위의 그림은 아웃라이어를 허용하지 않고 기준을 까다롭게 세운 모양이다. 이걸 하드 마진(hard margin)이라고 부른다. 그리고 서포트 벡터와 결정 경계 사이의 거리가 매우 좁다. 즉, 마진이 매우 작아진다. 이렇게 개별적인 학습 데이터들을 다 놓치지 않으려고 아웃라이어를 허용하지 않는 기준으로 결정 경계를 정해버리면 오버피팅(overfitting) 문제가 발생할 수 있다.
  • 아래 그림은 아웃라이어들이 마진 안에 어느정도 포함되도록 너그럽게 기준을 잡았다. 이걸 소프트 마진(soft margin)이라고 부른다. 이렇게 너그럽게 잡아 놓으니 서포트 벡터와 결정 경계 사이의 거리가 멀어졌다. 즉, 마진이 커진다. 대신 너무 대충대충 학습하는 꼴이라 언더피팅(underfitting) 문제가 발생할 수 있다.

오버피팅과 언더피팅에 대한 개념은 머신러닝에서 무조건 알아야 하는 개념이다. 아래 포스팅을 참고하자.

파라미터 C

그리고 scikit-learn에서는 SVM 모델이 오류를 어느정도 허용할 것인지 파라미터 C를 통해 지정할 수 있다. (기본 값은 1이다.)

classifier = SVC(C = 0.01)

C값이 클수록 하드마진(오류 허용 안 함), 작을수록 소프트마진(오류를 허용함)이다.

당연히 C의 최적 값은 데이터에 따라 다르다. 결국 여러가지 C값을 넣어보면서 모델을 검증하는 수밖에 없다.

커널(Kernel)

지금까지는 선형으로 결정 경계를 그을 수 있는 형태의 데이터 세트를 예시로 들었다. 그런데 만약 그러나 SVM이 선형으로 분리 할 수 없는 데이터 세트가 있다면 어떻게 해야 할까?

극단적인 예를 들어… 이런 데이터가 있다고 해보자.

빨간색 점을 파란색 점과 분리하는 직선을 그릴 수가 없다..!

그러나 다행히도 scikit-learn에서는 SVM 모델을 만들 때 kernel을 지정하여 해결할 수 있다.

보통은 이렇게 선형('linear')으로 지정하지만

from sklearn.svm import SVC

classifier = SVC(kernel = 'linear')

'poly' 같은 걸 넣어줄 수도 있다. 이어서 좀 더 알아보겠다. 다만, 다른 커널을 사용할 때는 주의가 필요하다. 머신러닝 모델이 약간의 오차를 허용해야 하는 건 너무나 당연한 거라 단순히 outlier 때문에 선형으로 분리할 수 ​​없다고 판단해서는 안 된다. 일부 아웃라이어에 맞추기 위해 비선형으로 결정 경계를 만들 필요가 없다는 뜻이다. 모든 점을 올바르게 분리하는 선을 그린다는 건 결국 모델이 데이터에 과도하게 적합해진다는, 즉 오버피팅 된다는 거니까.

다른 커널들에 대해서도 좀 알아보자.

1. 다항식 (Polynomial)

위에서 봤던 이 그림을 다시 보면

아무리 봐도 단순한 선형으로는 도저히 해결이 안 된다.

이때 다항식(polynomial) 커널을 사용하면 2차원에서 x, y 좌표로 이루어진 점들을 아래와 같은 식에 따라 3차원으로 표현하게 된다.

예를 들어 [1, 2] 점이 있다고 하면 이렇게 3차원으로 계산해놓는다.

그리고 이렇게 다항식 커널로 계산한 데이터 포인트들을 3차원으로 그려보면 이런 모양이 나타난다.

오… 드디어 뭔가 결정 경계를 그어볼 수 있는 꼴로 바뀐 걸 알 수 있다.

이렇게 다항식(polynomial) 커널을 사용하면 데이터를 더 높은 차원으로 변형하여 나타냄으로써 초평면(hyperplane)의 결정 경계를 얻을 수 있다.

역시 세상엔 천재들이 많고 수학은 정말 신기하다.

하나만 더 소개해야지.

2. 방사 기저 함수 (RBF: Radial Bias Function)

이건 이름이 좀 어려운데, 보통 RBF 커널 혹은 가우시안 커널이라고 부르기도 한다. (나도 RBF 커널이라는 표현을 써야겠다.)

sciklit-learn에서 모델을 불러올 때 파라미터로 kernel 값을 따로 안 넣어주었을 때의 기본값이 바로 이 'rbf'다. (위에서 언급했던 'linear', 'poly', 그리고 'sigmoid'와 같은 걸로 지정해줄 수도 있다.)

from sklearn.svm import SVC

classifier = SVC(kernel='rbf')

위에서 살펴본 'poly'(다항식) 커널은 2차원의 점을 3차원으로 변환했다.

그런데 이 RBF 커널은 2차원의 점을 무한한 차원의 점으로 변환한다…… 그래서 시각화하는 건 어렵고… 커널이 이 작업을 수행하는 방법에 대해서도 이해하기 어려우니 다루지 않을 거다. 상당히 복잡한 선형대수학이 사용된다는 것만 알고 넘어가자. 나도 잘 모른다.

그러나 하나 알고 가야 할 게 있다. 바로 감마(gamma)다.

파라미터 gamma

gamma는 (위에서 소개한 C와 마찬가지로) 파라미터다.

classifier = SVC(kernel = "rbf", C = 2, gamma = 0.5)

gamma결정 경계를 얼마나 유연하게 그을 것인지 정해주는 거다. 학습 데이터에 얼마나 민감하게 반응할 것인지 모델을 조정하는 거니까 C와 비슷한 개념이라 봐도 된다.

  • gamma값을 높이면 학습 데이터에 많이 의존해서 결정 경계를 구불구불 긋게 된다. 이는 오버피팅을 초래할 수 있다.
  • 반대로 gamma낮추면 학습 데이터에 별로 의존하지 않고 결정 경계를 직선에 가깝게 긋게 된다. 이러면 언더피팅이 발생할 수 있다.

그림으로 보면 이해가 쉬우니 살펴보자.

일단 gamma가 적당하면 이런 모양이다.

그러나 만약 gamma를 너무 높이면 이런 꼴이 되어 오버피팅이 발생한다.

반대로 gamma를 너무 낮게 잡으면 이렇게 결정 경계를 너무 대충 그려서 언더피팅이 발생한다.


요약

여기까지 이해하면 SVM, 서포트 벡터 머신 알고리즘에 대해 어느정도의 감은 잡은 셈이다.

위에서 다룬 내용을 가볍게 요약하면 아래와 같다.

  • SVM은 분류에 사용되는 지도학습 머신러닝 모델이다.
  • SVM은 서포트 벡터(support vectors)를 사용해서 결정 경계(Decision Boundary)를 정의하고, 분류되지 않은 점을 해당 결정 경계와 비교해서 분류한다.
  • 서포트 벡터(support vectors)는 결정 경계에 가장 가까운 각 클래스의 점들이다.
  • 서포트 벡터와 결정 경계 사이의 거리를 마진(margin)이라고 한다.
  • SVM은 허용 가능한 오류 범위 내에서 가능한 최대 마진을 만들려고 한다.
  • 파라미터 C는 허용되는 오류 양을 조절한다. C 값이 클수록 오류를 덜 허용하며 이를 하드 마진(hard margin)이라 부른다. 반대로 C 값이 작을수록 오류를 더 많이 허용해서 소프트 마진(soft margin)을 만든다.
  • SVM에서는 선형으로 분리할 수 없는 점들을 분류하기 위해 커널(kernel)을 사용한다.
  • 커널(kernel)은 원래 가지고 있는 데이터를 더 높은 차원의 데이터로 변환한다. 2차원의 점으로 나타낼 수 있는 데이터를 다항식(polynomial) 커널은 3차원으로, RBF 커널은 점을 무한한 차원으로 변환한다.
  • RBF 커널에는 파라미터 감마(gamma)가 있다. 감마가 너무 크면 학습 데이터에 너무 의존해서 오버피팅이 발생할 수 있다.

추천 글

“서포트 벡터 머신(Support Vector Machine) 쉽게 이해하기”의 26개의 댓글

  1. 안녕하세요. 이 글을 읽고 SVM을 이용하려고 하는데 도움 많이 되었습니다.
    질문이 있는데, 마지막 plot들에서처럼 경계선을 그리고 배경색을 바꾸는 방법을 알수 있을까요?
    염치 없지만 혹 코드를 공유해주실수 있다면 너무 감사드리겠습니다..

  2. 안녕하세요, margin 설명하신 부분에서 ‘그리고 그 실선으로부터 검은 테두리가 있는 빨간점 1개, 파란점 2개까지 영역을 두고 점선을 그어놓았다.이게 바로 ‘마진(margin)’이다.’ 이 설명이 아닌, ‘그리고 그 실선으로부터 검은 테두리가 있는 빨간점 1개, 파란점 2개까지 영역을 두고 점선을 그어놓았다. 점선으로부터 Decision Boundary까지의 거리가 ‘마진(margin)’이다.’ 가 맞지 않을지 궁금합니다~

    1. 저는 지금까지 점선부터 점선까지가 마진(margin)인줄 알고 있었고, 본문 읽을 때도 저도 모르게 은근슬쩍 넘어갔는데,
      지적해주신 덕에 제대로 알고 가네요! 두분다 감사합니다 🙂

  3. 맛깔나고 재미지게 잘 표현을 하신거 같습니다.

    이해가 안되던 부분에 도움이 크게 되었습니다.

  4. 아워(아무튼 워라밸)님 정말 이해하기 쉽게 작성하셨네요:)
    이해안가던 부분을 옆에서 말하듯, 혼자 설명하듯 적어놓으셔서
    편하게 쉽게 읽고 갑니다! 앞으로도 많이 올려주세요! 즐찾해놨어욤!

  5. 워라벨님, 고맙습니다.
    나이 먹고 학교에 갔는데, 인공지능이 대세라 온통 과목이 인공지능을 이용하네요. 갑자기 훅훅 진도가 나가서 정신 못 차리고 학기 말까지 왔는데, 과제를 하려고 이리저리 검색하다가 들어와서 잘 읽고 갑니다. 아직은 머리가 복잡하지만, 그래도 개념이 조금 잡히네요.

  6. 정말 이제까지 읽어본 SVM 모델 설명 중 가장 마음에 들었습니다. 정말 많은 도움이 되었어요. 감사합니다..!

  7. 타이타닉 생존자를 시작으로 머신러닝에 입문하면서 관련 정보를 찾아보다가 워라밸님 블로그 알게 되었습니다. 여기서 생존자 예측을 위해 여러 방법을 사용하는 데, -Logistic Regression, KNN or k-Nearest Neighbors, Support Vector Machines, Naive Bayes classifier, Decision Tree, Random Forrest, Perceptron, Artificial neural network, RVM or Relevance Vector Machine – 거의 대부분 관련 정보를 입문자인 제가 쉽게 이해 할 수 있도록 해주셔서, 진심으로 감사하다는 말씀 드리고 싶네요 ^^

  8. 처음 머신러닝 입문했는데 너무 설명이 잘 되게 적어주셔서 도움이 많이 되었습니다! 앞으로도 좋은 글 많이 써주세요~

  9. 또 감탄하고 갑니다. 이런 댓글 참 잘 못 쓰고 안 쓰는데, 너무 감사해서 댓글 남겨요!
    소설 읽듯 술술 읽히고, 개념도 잘 잡혀요. 감사합니다!

  10. 요즘 머신러닝 관심이 많아 찾아보고 있는데 정말 이해하기 쉽고 간략하게 정리해주셨네요.
    많이 배우고 갑니다. 즐거운 하루 되세요~

댓글 남기기