본문 바로가기
실용적인프로그래밍/R

[R] Machine learning (2) - Support vector machine (SVM, part 1)

by 인포메틱스 2020. 7. 9.
반응형

오늘은 Support vector machine (SVM)에 대해서 이야기해보려고 합니다!

 

SVM은 Machine learning methods중에서 쓸만한 방법중 하나라고 생각합니다.! (SVM이 최고라능~!)

 

어떤 데이터를 넣어도 중간 이상은 하는 방법! 이라고 생각합니다.

 


오늘도 데이터셑은 ggplot2에 있는 diamonds를 이용할 것입니다.

 

데이터셑 불러오거나 관련된 설명은 Linear regression 포스팅 앞부분을 참고해주세요!

mopipe.tistory.com/37

 

Machine learning (1) - Linear regression

machine learning에서 가장 기본적인 linear regression에 대해 포스팅하려고 합니다. 포스팅해야할 주제는 많은데 정리가 잘 안되네요~ ㅎㅎㅎ 요번에 machine learning 관련 내용 멘토링을 하다보니 이 포스�

mopipe.tistory.com

 

 

> library(ggplot2)
> data("diamonds")
> data1<-diamonds
> View(data1)
> 

 

 

 

머신러닝 하면서 가장 중요한것중 하나가!  바로 test set, train set 만드는 것이죠!  (이 내용도 Linear regression에서 좀 더 자세하게 설명해놓았습니다.)

 

> set.seed(7054)
> r<-sample(nrow(data1),nrow(data1)/3)
> test_set<-data1[r,]
> train_set<-data1[-r,]
> nrow(test_set)
[1] 17980
> nrow(train_set)
[1] 35960
> nrow(test_set)+nrow(train_set)
[1] 53940
> 

 

여기까지 준비단계고 본격적으로 SVM을 해보도록 하죠!

 

package는 e1071을 이용하겠습니다.

 

많은 package가 있지만 e1071이 빠르다 라고만 알고있었으나, 2019년도즈음해서 다른 package들이 나왔네요.

 

다른 package는 써보질 않아서 패스! (추후에 비교하는 포스팅 써볼겠습니다.)

 

본론에 들어가기 전에! SVM은  Classification, regression이 두가지로 분석이 가능합니다.

 

Classification하는 경우가 SVM 방법을 사용하는 것이고, regression하는 경우가 SVR 방법을 사용하는 것입니다.

 

SVM은 많이 알려져있으나, SVR의 경우 많이 알려져있지 않죠.

 

오늘은 SVM만 다루어보겠습니다.


SVM (Support Vector Machine) 방법

1. 데이터 수정

 

SVM은 classification해야되기 때문에  아까 만든 train set, test set에서 약간 수정을 해줘야 합니다.

 

먼저 연구가설은 carat, depth, table,  x, y, z를 이용해서 cut의 상태를 알 수가 있을 것이다. (price도 넣으려다가 당연히 가격이 높을수록 cut상태가 좋겠죠?, 그래서 뺏습니다. carat은 그냥.. 뒀습니다.)

 

diamonds cut상태 기준은 다음과 같이 확인할 수가 있습니다.

> help("diamonds")
> 

 

 

우리는 여기에서 cut상태를 Premium, Ideal vs. Fair, Good, Very Good로 나누어서 learning 시켜보도록 하겠습니다.

 

그렇다면 train set, test set에서 표시를 해줘야겠죠?

 

> train_set$cut_status<-NA
> train_set$cut_status[train_set$cut=='Fair'|train_set$cut=='Good'|train_set$cut=='Very Good']=0
> train_set$cut_status[train_set$cut=='Premium'|train_set$cut=='Ideal']=1
> train_set$cut_status=as.factor(train_set$cut_status)
> class(train_set$cut_status)
[1] "factor"
> table(train_set$cut_status)

    0     1 
12364 23596 
> 
> test_set$cut_status<-NA
> test_set$cut_status[test_set$cut=='Fair'|test_set$cut=='Good'|test_set$cut=='Very Good']=0
> test_set$cut_status[test_set$cut=='Premium'|test_set$cut=='Ideal']=1
> test_set$cut_status=as.factor(test_set$cut_status)
> class(test_set$cut_status)
[1] "factor"
> table(test_set$cut_status)

    0     1 
 6234 11746 
>

Premium, Ideal일 경우 cut 상태가 1, 나머지는 0으로 변경했습니다.

 

1,0을 factor로 지정해줘야합니다. 그렇지 않으면 숫자로 인식해서 regression으로 자동으로 넘어갑니다.

 

2. Model 제작

 

이제 본격적으로 model을 만들어 봅시다!

> library(e1071)
> svm.model<-svm(cut_status~carat+depth+table+x+y+z,data=train_set)
> svm.model

Call:
svm(formula = cut_status ~ carat + depth + table + x + y + z, data = train_set)


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  radial 
       cost:  1 

Number of Support Vectors:  14934

>

model이 이렇게 생성이 되었고, 예측해봅세다!! (시간이 오래걸린다?! 똥컴이네 그렇다면 train_set, test_set을 줄여보세요, 줄이는 코드는 SVR포스팅에 기재해두었습니다.)

https://mopipe.tistory.com/39

 

Machine learning (3) - Support vector machine (SVR, part2)

오늘은 어제에 내용인 Support vector machine (classification)에 이어서 분석해보도록 하겠습니다. 데이터셑 만드는 것은 이전 포스팅을 참고하시고 코드만 적어놓겠습니다. ※ 윈도우로 진행해보니까 ��

mopipe.tistory.com

 

 

예측하는 방법은 Linear regression 때 사용하였던 predict함수를 사용하겠습니다. (참고하세요!!)

> tr_result<-predict(svm.model,train_set)
> table(tr_result,train_set$cut_status)
         
tr_result     0     1
        0  7877   809
        1  4487 22787
> te_result<-predict(svm.model,test_set)
> table(te_result,test_set$cut_status)
         
te_result     0     1
        0  3947   407
        1  2287 11339
>

Classification의 경우 모델이 잘 만들어졌는지 확인하기 위해 주로 사용하는 방법이 ROC curve AUC를 이용합니다.

 

ROC, AUC를 한꺼번에 잘 만들어 줄 수있는 Epi package를 이용하도록 하겠습니다.

> library(Epi)
> par(oma=c(1,1,1,1),mar=c(1,3,3,1))
> ROC(test = tr_result,stat=train_set$cut_status,plot='ROC',AUC=T,main='Predict cut status (Train Set)')
> ROC(test = te_result,stat=test_set$cut_status,plot='ROC',AUC=T,main='Predict cut status (Test Set)')
> 

 

결과 그래프는 다음과 같이 나왔습니다.

결과를 해석하자면!  AUC의 값은 1로 갈수록 좋은 경우입니다.

 

참고할 포스팅은 mopipe.tistory.com/6

 

정밀도와 재현율

실측값 (Observation value) Positive Negative 예측값 (Prediction value) Positive True positive (TP) False Negative (FN) (1종 오류) Negative False positive (FP) (2종 오류) True negative (TN) 정밀도(P..

mopipe.tistory.com

Sens = (Sensitivity), Spec = (Specificity)입니다.

 

Specificity, Sensitivity = 예측시에 정확하게 진짜를 예측했을 경우 (각 1,0을 정확하게 예측햇는지 확인하는 것입니다.)

 

AUC도 1로 갈수록 전체적인 예측률이 높다! 라고 생각하시면 됩니다!

 

여기까지가 단순 예측 방법 이었다면, 이번에는 최적화를 한번 해보도록하겠습니다.

 

3. 최적화 방법

 

최적화 방법에는 tune이라는 기능을 사용하도록 하겠습니다.

 

SVM에서 C-classification같은 경우 gamma와 cost 두가지를 parameter로 갖습니다. 

 

default로 돌리게되면 최적의 parameter를 주지 않습니다.

 

그렇기 때문에 최적의 parameter를 찾아야 되는데, 원시적인 방법으로 여러 파라미터를 줘서 잘 맞는지 안 맞는지 확인 하는 방법이! 바로 tune기능을 사용하는 것입니다.

 

tune기능에다 cost, gamma 의 여러값들을 추가하게되면, 조합으로 여러 값들이 나오게 되고, 그 값들이 알아서 model에 적용되어 최적의 model을 가져다 줌니다.

 

일단 먼저 컴퓨터 사양을 알기때문에 train_set test_set둘다 3분의1 수준으로 내려줍니다.

 

> set.seed(7054)
> r<-sample(nrow(train_set),nrow(train_set)/3)
> train_set<-train_set[r,]
> set.seed(7054)
> r<-sample(nrow(test_set),nrow(test_set)/3)
> test_set<-test_set[r,]
> 

 

> best_svm.model<-tune.svm(cut_status~carat+depth+table+x+y+z,data=train_set,gamma=c(0.5,0.1,0.01),cost=c(0.1,2,4))
> best_svm.model

Parameter tuning of ‘svm’:

- sampling method: 10-fold cross validation 

- best parameters:
 gamma cost
   0.5    4

- best performance: 0.1475072 

> plot(best_svm.model)
>

plot을 보게되면, 색이 찐한 곳을 최적이라고 생각하면 됩니다.

 

저럴경우 parameter조절을 좀 더 해봐야죠. gamma를 더 올려보거나, cost값을 더 올려보거나 해서 진행하면 됩니다.

 

> summary(best_svm.model)

Parameter tuning of ‘svm’:

- sampling method: 10-fold cross validation 

- best parameters:
 gamma cost
   0.5    4

- best performance: 0.1475072 

- Detailed performance results:
  gamma cost     error  dispersion
1  0.50  0.1 0.1864679 0.008830755
2  0.10  0.1 0.1910563 0.008644736
3  0.01  0.1 0.2624719 0.010055713
4  0.50  2.0 0.1626075 0.008031498
5  0.10  2.0 0.1645250 0.006415543
6  0.01  2.0 0.1884692 0.010215722
7  0.50  4.0 0.1475072 0.009187367
8  0.10  4.0 0.1514252 0.006947002
9  0.01  4.0 0.1807938 0.008341648

> 

Summary를 통해 tune기능으로 어떻게 돌아가는지 확인할 수가 있습니다.

 

Detailed performance results를 보게 되면, parameter의 조합으로 돌린후 결과값들이 나오는 것을 확인할 수가 있습니다.

 

그리고 최적의 모델을 이용하려면,  best_svm.model에서 best.model이라는 것을 이용해야합니다.

 

그냥 best_svm.model을 사용하시면 작동이 안됩니다.

> tr_result<-predict(best_svm.model$best.model,train_set)
> table(tr_result,train_set$cut_status)
         
tr_result    0    1
        0 2805  348
        1 1309 7524
> te_result<-predict(best_svm.model$best.model,test_set)
> table(te_result,test_set$cut_status)
         
te_result    0    1
        0 1393  170
        1  750 3680
> library(Epi)
> par(oma=c(1,1,1,1),mar=c(4,4,3,1))
> ROC(test = tr_result,stat=train_set$cut_status,plot='ROC',AUC=T,main='Predict cut status (Train Set)')
> ROC(test = te_result,stat=test_set$cut_status,plot='ROC',AUC=T,main='Predict cut status (Test Set)')
>

 

best.model을 이용하게되면,아까의 결과보더 좀 더 나은 결과를 확인할 수가 있습니다.

 

  default Optimal (tune)
train set test set train set test set
Sensitivity 96.6% 96.5% 95.6% 95.6%
Specificity 63.7% 63.3% 68.2% 65.0%
AUC 0.801 0.799 0.819 0.803

AUC,Specificity가 올라간 것을 확인할 수가 있었고, 반면에 Sensitivity는 약간 떨어지는것을 볼 수가 있네요.

 

그러나 전체적으로는 향상했다! (AUC로 판단하기에는) 라고 판단이 됩니다.

 

 


여기까지 SVM에 대해서 분석해보았고 원래 SVM, SVR 둘 다 하려했으나, SVM 만드는데 시간이 오래걸려서 다음 포스팅으로 미루겠습니다.

728x90
반응형

댓글