서포트 벡터 머신(SVM, Support Vector Machine)은 서로 다른 분류에 속한 데이터 간에 간격이 최대가 되는 선(또는 평면)을 찾아 이를 기준으로 데이터를 분류하는 모델이다.
서포트 벡터 머신 모델
그림 10-10에 서포트 벡터 머신의 개념을 그림으로 나타냈다. 흰색 원과 검은색 원은 서로 다른 분류를 뜻한다. 서포트 벡터 머신은 각 분류에 속하는 데이터로부터 같은 간격으로, 그리고 최대로 멀리 떨어진 선 또는 평면을 찾는다. 이러한 선 또는 평면을 최대 여백 초평면(Maximum Margin Hyperplane)이라고 하고, 이 평면이 분류를 나누는 기준이 된다. 그림 10-10에서는 대각선 방향의 직선이 최대 여백 초평면에 해당한다. 그리고 이 직선과 가장 가까운 각 분류에 속한 점들을 서포트 벡터라고 한다.
모든 데이터를 항상 초평면으로 나눌 수 있는 것은 아니다. 그림 10-11을 보자. 그림의 좌측에 보인 검은색 점과 흰색 점들은 X 축 위에 뒤섞여 있다. 이 두 분류를 구분할 수 있는 기준은 곡선이므로 ‘평면’을 찾는 서포트 벡터 머신을 사용할 수 없다.
이 문제는 커널 트릭(Kernel Trick)이라는 기법으로 해결한다. 커널 트릭의 기본 아이디어는 주어진 데이터를 적절한 고차원으로 옮긴 뒤 변환된 차원에서 서포트 벡터 머신을 사용해 초평면을 찾는 것이다. 예를 들어, 그림 10-11의 오른쪽에 보인 것처럼 데이터를 1차원에서 2차원으로 변환할 수 있다면 두 그룹을 나누는 직선을 찾을 수 있게 된다.
서포트 벡터 머신 모델의 핵심 수식은 벡터 간 내적 계산이다. 커널 트릭에서는 실제로 데이터를 고차원으로 변환하는 대신 고차원에서 벡터 간 내적 계산을 했을 때와 같은 값을 반환하는 함수들을 사용한다. 이 함수들을 사용하면 마치 데이터를 고차원으로 옮긴 듯한 효과를 일으키면서도 데이터를 고차원으로 옮기는 데 따른 계산 비용 증가는 피할 수 있다. 이러한 함수들을 커널 함수(Kernel Function)라고 부른다.
커널 함수의 대표적인 예에는 다항 커널(Polynomial Kernel)과 가우시안 커널(Gaussian Kernel,레이디얼 베이스 함수 커널Radial Basis Function Kernel)이 있다. d차원 다항식에 대한 다항 커널을 식 10-8에 보였다.
다항 커널은 입력의 모든 차원의 조합인 공간에서 내적을 계산한 것과 같은 결과를 반환한다. 예를 들어, 2차원 입력 벡터 x=(x1 x2)T, y=(y1 y2)T에 d=2인 다항 커널을 사용하면 다음 결과를 얻는다.
결국 식 10-8은 (x1 x2)T을 다음에 보인 좌표로 옮긴 뒤 내적을 계산한 것과 같은 효과를 준다.
반면 가우시안 커널은 무한 차원으로 데이터를 옮긴 뒤 그곳에서 내적을 계산한 것과 같은 결과를 반환한다.
가우시안 커널을 식 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 |