본문 바로가기

R/R을 이용한 데이터 처리&분석 실무

서포트 벡터 머신

반응형

서포트 벡터 머신(SVM, Support Vector Machine)은 서로 다른 분류에 속한 데이터 간에 간격이 최대가 되는 선(또는 평면)을 찾아 이를 기준으로 데이터를 분류하는 모델이다.

 

서포트 벡터 머신 모델

그림 10-10에 서포트 벡터 머신의 개념을 그림으로 나타냈다. 흰색 원과 검은색 원은 서로 다른 분류를 뜻한다. 서포트 벡터 머신은 각 분류에 속하는 데이터로부터 같은 간격으로, 그리고 최대로 멀리 떨어진 선 또는 평면을 찾는다. 이러한 선 또는 평면을 최대 여백 초평면(Maximum Margin Hyperplane)이라고 하고, 이 평면이 분류를 나누는 기준이 된다. 그림 10-10에서는 대각선 방향의 직선이 최대 여백 초평면에 해당한다. 그리고 이 직선과 가장 가까운 각 분류에 속한 점들을 서포트 벡터라고 한다.

그림 10-10

모든 데이터를 항상 초평면으로 나눌 수 있는 것은 아니다. 그림 10-11을 보자. 그림의 좌측에 보인 검은색 점과 흰색 점들은 X 축 위에 뒤섞여 있다. 이 두 분류를 구분할 수 있는 기준은 곡선이므로 ‘평면’을 찾는 서포트 벡터 머신을 사용할 수 없다.

 

이 문제는 커널 트릭(Kernel Trick)이라는 기법으로 해결한다. 커널 트릭의 기본 아이디어는 주어진 데이터를 적절한 고차원으로 옮긴 뒤 변환된 차원에서 서포트 벡터 머신을 사용해 초평면을 찾는 것이다. 예를 들어, 그림 10-11의 오른쪽에 보인 것처럼 데이터를 1차원에서 2차원으로 변환할 수 있다면 두 그룹을 나누는 직선을 찾을 수 있게 된다.

그림 10-11

 

서포트 벡터 머신 모델의 핵심 수식은 벡터 간 내적 계산이다. 커널 트릭에서는 실제로 데이터를 고차원으로 변환하는 대신 고차원에서 벡터 간 내적 계산을 했을 때와 같은 값을 반환하는 함수들을 사용한다. 이 함수들을 사용하면 마치 데이터를 고차원으로 옮긴 듯한 효과를 일으키면서도 데이터를 고차원으로 옮기는 데 따른 계산 비용 증가는 피할 수 있다. 이러한 함수들을 커널 함수(Kernel Function)라고 부른다.

 

커널 함수의 대표적인 예에는 다항 커널(Polynomial Kernel)과 가우시안 커널(Gaussian Kernel,레이디얼 베이스 함수 커널Radial Basis Function Kernel)이 있다. d차원 다항식에 대한 다항 커널을 식 10-8에 보였다.

식 10-8

다항 커널은 입력의 모든 차원의 조합인 공간에서 내적을 계산한 것과 같은 결과를 반환한다. 예를 들어, 2차원 입력 벡터 x=(x1 x2)T, y=(y1 y2)T에 d=2인 다항 커널을 사용하면 다음 결과를 얻는다.

결국 식 10-8은 (x1 x2)T을 다음에 보인 좌표로 옮긴 뒤 내적을 계산한 것과 같은 효과를 준다.

반면 가우시안 커널은 무한 차원으로 데이터를 옮긴 뒤 그곳에서 내적을 계산한 것과 같은 결과를 반환한다.

가우시안 커널을 식 10-9에 보였다.

식 10-9

 

서포트 벡터 머신 학습

SVM 모델을 위한 패키지에는 e1071, kernlab 등이 있다. e1071은 효율적인 SVM 구현체로 잘 알려진 libsvm을 R에서 사용할 수 있도록 한 패키지며, kernlab은 커널 기반의 기계 학습 알고리즘을 R에서 구현한 것으로 사용자가 C++ 코드의 수정 없이 기능을 손쉽게 확장할 수 있다. 표 10-9에 이 장에서 알아볼 kernlab, e1071 패키지의 함수들을 보였다.

 

  • kernlab::ksvm : 서포트 벡터 머신을 생성한다.

kernlab::ksvm(
  x,        # 모델 포뮬러
  data=NULL # 포뮬러를 적용할 데이터
)

kernlab::ksvm(
  x, y=NULL,  # 데이터
  # 데이터를 정규화할지 여부. 기본값인 TRUE는 평균 0, 분산 1이 되도록 데이터를 변환한다.
  scaled=TRUE,
  # 사용할 커널. 기본값은 rbfdot으로 Radial Basis Function이다. kernel에 지정할 수 있는
  # 함수의 목록은 help(kernlab::dots)에서 볼 수 있다.
  kernel="rbfdot",
  # 커널 파라미터를 리스트로 지정한다. kernel이 rbfdot인 경우 kpar를 automatic으로
  # 지정하면 데이터로부터 휴리스틱으로 적절한 파라미터를 찾는다.
  kpar="automatic"
)

 

  • ksvm::predict.ksvm : ksvm을 사용한 예측을 수행한다.

ksvm::predict.ksvm(
  object,   # ksvm 객체
  newdata,  # 예측을 수행할 데이터
  # 예측 결과의 유형. response는 예측값, probabilities는 확률을 반환한다.
  type="response"
)

 

  • e1071::svm : 서포트 벡터 머신을 생성한다.

e1071::svm(
  formula,     # 모델 포뮬러
  data=NULL,   # 데이터
)

e1071::svm(
  x, y=NULL,   # 데이터
  scale=TRUE,  # 변수를 정규화해야 하는지 여부
  # 분류, 회귀 등의 모델 중 만들 모델. y 값이 팩터인지 여부에 따라
  # 분류 또는 회귀 모델이 자동으로 지정되지만 type에 모델을 지정해 특정 모델을 강제할 수 있다.
  type = NULL,
  kernel ="radial",  # 커널 함수
  gamma=if(is.vector(x)) 1 else 1/ncol(x), # 커널 파라미터 gamma
  cost=1  # 커널 파라미터 cost
)

 

  • e1071::tune : 그리드 탐색(Grid Search; 인자로 주어진 모든 가능한 경우에 대해 테스트해보는 방식)을 사용한 파라미터 튜닝을 수행한다.

e1071::tune(
  method,   # 최적화할 함수
  train.x,  # 포뮬러 또는 독립 변수의 행렬을 지정
  train.y,  # 예측할 분류. 만약 train.x가 포뮬러면 무시
  data,     # 포뮬러를 적용할 데이터
  ...       # method에 추가로 전달할 인자
)

 

 

아이리스에 포뮬러를 사용하여 SVM 모델을 만들어보자.

> install.packages("kernlab")
> library(kernlab)
> (m <- ksvm(Species ~ ., data=iris))
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 1 

Gaussian Radial Basis kernel function. 
 Hyperparameter : sigma =  0.476214318695748 

Number of Support Vectors : 70 

Objective Function Value : -5.611 -5.5261 -25.5803 
Training error : 0.02 

만들어진 모델로부터의 예측에는 predict( )를 사용한다.

> head(predict(m, newdata=iris))
[1] setosa setosa setosa setosa setosa setosa
Levels: setosa versicolor virginica

ksvm( ) 함수는 가우시안 커널을 기본으로 사용한다. 만약 커널 함수를 바꾸고 싶다면 kernel 파라미터에 원하는 함수를 지정한다. 다음은 vanilladot(특별한 변환 없이 내적을 계산함)을 지정한 예다.

> ksvm(Species ~., data=iris, kernel="vanilladot")
 Setting default kernel parameters  
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 1 

Linear (vanilla) kernel function. 

Number of Support Vectors : 30 

Objective Function Value : -0.9559 -0.2781 -16.2753 
Training error : 0.02 

커널에 사용하는 파라미터는 kpar에 리스트 형태로 지정한다. 다음은 3차(degree=3) 다항 커널을 사용한 예다.

> (m <- ksvm(Species ~., data=iris, kernel="polydot", kpar=list(degree=3)))
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 1 

Polynomial kernel function. 
 Hyperparameters : degree =  3  scale =  1  offset =  1 

Number of Support Vectors : 27 

Objective Function Value : -0.019 -0.0155 -4.817 
Training error : 0.006667 

 

SVM을 잘 사용하려면 파라미터 값을 잘 찾아야 한다. 파라미터를 정하는 한 가지 방법은 교차 검증이다. 또 다른 방법은 SVM 패키지가 제공하는 파라미터 튜닝을 사용하는 것이다.

 

e1071에서는 tune( ) 함수를 사용해 모델을 튜닝할 수 있다. help(tune)을 입력해 자세한 사용법을 알아보기 바란다. 다음은 가우시안 커널에서 gamma와 cost 파라미터를 찾는 example(tune)의 일부를 보여준다.

> install.packages("e1071")
> library(e1071)
> tune(svm, Species ~., data=iris, gamma=2^(-1:1), cost=2^(2:4))
Parameter tuning of `svm':
- sampling method: 10-fold cross validation
- best parameters:
  gamma cost
    0.5    4
- best performance: 0.05333333

tune( )의 반환 값은 객체며, 객체의 속성은 attributes( )로 살펴볼 수 있다. 다음은 최적 파라미터 값을 빼내는 코드의 예다.

> attributes(result)
$names
[1] "best.parameters" "best.performance" "method"       "nparcomb"
[5] "train.ind"       "sampling"         "performances" "best.model"

$class
[1] "tune"

> result$best.parameters           # 최적 파라미터
  gamma cost
1   0.5    4

> result$best.parameters["gamma"]  # 최적 파라미터 중 gamma
  gamma
1   0.5

> result$best.parameters["cost"]   # 최적 파라미터 중 cost
  cost
1    4

 

 

 

R을 이용한 데이터 처리&분석 실무 中

 

반응형

'R > R을 이용한 데이터 처리&분석 실무' 카테고리의 다른 글

클래스 불균형  (0) 2020.02.13
신경망  (0) 2020.02.12
의사 결정 나무  (0) 2020.02.12
다항 로지스틱 회귀 분석  (0) 2020.02.12
로지스틱 회귀 모델  (0) 2020.02.12