59doit
[ R ] 서포트벡터머신 (SVM) 본문
서포트벡터머신
- 서포트벡터 분류기를 확장하여 비선형 클래스 경계를 수용할 수 있도록 개발한 분류 방법.
- 초평면(Hyperplane)
- 최대마진분류기(Maximum Margin Classifier): 데이터가 있을 때, 이것을 곡선이 아닌 직선이나 평면으로 구별하는 방법
- 초평면(Hyperplane): 최대 마진 분류기가 경계로 사용하는 선이나 면
- 분리초평면(Separating Hyperplane): 데이터를 완벽하게 분리하는 초평면
- 마진(Margin): 데이터와 초평면의 수직 거리(가장 짧은 거리)
- 최대마진 초평면(Maximal Margin Hyperplane): 마진이 가장 큰 초평면
- 최대마진분류기(Maximum Margin Classifier): 데이터가 초평면에 의해 가장 잘 분류
- 서포트벡터(Support Vector): 양쪽 데이터의 경계값을 포함하는 초평면 상에 위치한 데이터
- 소프트 마진(Soft margin) : 분리 초평면이 존재하지 않을 수도 있고, 최대 마진 분류기 또한 존재할 수 없는 경우가 많다. 이런 문제의 해결을 위하여 데이터를 분류할 때의 약간의 오차
- 서포트벡터 분류기(Support Vector Classifier): 소프트마진을 이용하여 데이터를 분류하는 것, 최대 마진 분류기를 확장한 것으로 몇몇 관측치를 희생하더라도 나머지 관측치를 더 잘 분류할 수 있는 방법
- 코스트(cost): 허용하는 오류의 정도, R에서는 tune.svm함수를 이용하여 코스트 값을 계산
- 커널 트릭을 이용하여 분류를 할 때 결정되어야 할 파라미터 : 코스트(cost): 오차 허용 정도
- 감마(Gamma): 커널과 관련된 파라미터
ex)
#1
credit1 <- read.csv("C:/credit.csv", header=TRUE) str(credit1) # 'data.frame': 1000 obs. of 21 variables: # $ Creditability : int 1 1 1 1 1 1 1 1 1 1 ... # $ Account.Balance : int 1 1 2 1 1 1 1 1 4 2 ... # $ Duration.of.Credit..month. : int 18 9 12 12 12 10 8 6 18 24 ... # $ Payment.Status.of.Previous.Credit: int 4 4 2 4 4 4 4 4 4 2 ... # $ Purpose : int 2 0 9 0 0 0 0 0 3 3 ... # $ Credit.Amount : int 1049 2799 841 2122 2171 2241 3398 1361 1098 3758 ... # $ Value.Savings.Stocks : int 1 1 2 1 1 1 1 1 1 3 ... # $ Length.of.current.employment : int 2 3 4 3 3 2 4 2 1 1 ... # $ Instalment.per.cent : int 4 2 2 3 4 1 1 2 4 1 ... # $ Sex...Marital.Status : int 2 3 2 3 3 3 3 3 2 2 ... # $ Guarantors : int 1 1 1 1 1 1 1 1 1 1 ... # $ Duration.in.Current.address : int 4 2 4 2 4 3 4 4 4 4 ... # $ Most.valuable.available.asset : int 2 1 1 1 2 1 1 1 3 4 ... # $ Age..years. : int 21 36 23 39 38 48 39 40 65 23 ... # $ Concurrent.Credits : int 3 3 3 3 1 3 3 3 3 3 ... # $ Type.of.apartment : int 1 1 1 1 2 1 2 2 2 1 ... # $ No.of.Credits.at.this.Bank : int 1 2 1 2 2 2 2 1 2 1 ... # $ Occupation : int 3 3 2 2 2 2 2 2 1 1 ... # $ No.of.dependents : int 1 2 1 2 1 2 1 2 1 1 ... # $ Telephone : int 1 1 1 1 1 1 1 1 1 1 ... # $ Foreign.Worker : int 1 1 1 2 2 2 2 2 1 1 ... |
#2 Creditability 컬럼의 0과 1의 숫자를 팩터형 1과 2로 바꿈
credit1$Creditability <- as.factor(credit1$Creditability) str(credit1) # 'data.frame': 1000 obs. of 21 variables: # $ Creditability : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ... # $ Account.Balance : int 1 1 2 1 1 1 1 1 4 2 ... # $ Duration.of.Credit..month. : int 18 9 12 12 12 10 8 6 18 24 ... # $ Payment.Status.of.Previous.Credit: int 4 4 2 4 4 4 4 4 4 2 ... # $ Purpose : int 2 0 9 0 0 0 0 0 3 3 ... # $ Credit.Amount : int 1049 2799 841 2122 2171 2241 3398 1361 1098 3758 ... # $ Value.Savings.Stocks : int 1 1 2 1 1 1 1 1 1 3 ... # $ Length.of.current.employment : int 2 3 4 3 3 2 4 2 1 1 ... # $ Instalment.per.cent : int 4 2 2 3 4 1 1 2 4 1 ... # $ Sex...Marital.Status : int 2 3 2 3 3 3 3 3 2 2 ... # $ Guarantors : int 1 1 1 1 1 1 1 1 1 1 ... # $ Duration.in.Current.address : int 4 2 4 2 4 3 4 4 4 4 ... # $ Most.valuable.available.asset : int 2 1 1 1 2 1 1 1 3 4 ... # $ Age..years. : int 21 36 23 39 38 48 39 40 65 23 ... # $ Concurrent.Credits : int 3 3 3 3 1 3 3 3 3 3 ... # $ Type.of.apartment : int 1 1 1 1 2 1 2 2 2 1 ... # $ No.of.Credits.at.this.Bank : int 1 2 1 2 2 2 2 1 2 1 ... # $ Occupation : int 3 3 2 2 2 2 2 2 1 1 ... # $ No.of.dependents : int 1 2 1 2 1 2 1 2 1 1 ... # $ Telephone : int 1 1 1 1 1 1 1 1 1 1 ... # $ Foreign.Worker : int 1 1 1 2 2 2 2 2 1 1 ... |
#3 학습데이터와 테스트데이터 구성
install.packages("recipes") install.packages("c:\\caret_6.0-90.tar.gz",repos=NULL,type="source") library(caret) set.seed(1234) |
caret 설치하는 과정에서의 오류 해결방법
trData <- createDataPartition(y = credit1$Creditability, p=0.7, list=FALSE) head(trData) # Resample1 # [1,] 1 # [2,] 2 # [3,] 3 # [4,] 4 # [5,] 6 # [6,] 7 train <- credit1[trData,] test <- credit1[-trData,] train # ... [ reached 'max' / getOption("max.print") -- omitted 653 rows ] test # ... [ reached 'max' / getOption("max.print") -- omitted 253 rows ] |
#4 파라미터 설정
install.packages("e1071") library("e1071") |
#5 커널 사용 튜닝 종류 radial linear polynomial
#5-1 radial 커널 사용 튜닝
result1 <- tune.svm(Creditability~., data=train, gamma=2^(-5:0), cost = 2^(0:4), kernel="radial") |
#5-2 linear 커널 사용 튜닝
result2 <- tune.svm(Creditability~., data=train, cost = 2^(0:4), kernel="linear") |
#5-3 polynomial 커널 사용 튜닝
result3 <- tune.svm(Creditability~., data=train, cost = 2^(0:4), degree=2:4, kernel="polynomial") |
tune.svm
tune.svm() 함수를 이용하여 gamma, cost 두개의 주요 파라미터의 최적값을 구한다
gamma는 초평면의 기울기이고, cost는 과적합에 따른 비용
과적합 될수록 cost가 상승함. 즉, 어느정도의 비용을 감수하더라도 모델을 훈련데이터에 맞추겠는지이다.
이상치는 초평면에 지대한 영향일때 제외한다
주어진 범위 내에서 gamma, cost을 최적값을 찾아준다
SVM의 C(Cost) 파라미터와 과적합의 해결
SVM을 잘 사용하려면 파라미터 값을 잘 찾아야하는데 이때, tune.svm 함수를 사용하여 최적값을 구한다.
costs는 과적합을 막는 정도를 지정하는 파라미터이다.
cost(점선)처럼 데이터를 잘못 분류하는 선을 긋게 되는 경우 얼마만큼의 cost를 지불해야 최적값이 찾아지는지...
gamma : 선형을 제외한 모든 커널에 요구되는 모수로, 디폴트는 1/(데이터 차원) 이다.
cost : 제약 위배의 비용으로, 디폴트는 1 이다
#6 튜닝된 파라미터 확인
result1$best.parameters # gamma cost # 8 0.0625 2 result2$best.parameters # cost # 1 1 result3$best.parameters # degree cost # 2 3 1 |
#7 SVM 실행
normal_svm1 <- svm(Creditability~., data=train, gamma=0.0625, cost=1, kernel = "radial") normal_svm2 <- svm(Creditability~., data=train, cost=1, kernel="linear") normal_svm3 <- svm(Creditability~., data=train, cost=1, degree=3, kernel = "polynomial") |
#8 결과 확인
summary(normal_svm1) # Call: # svm(formula = Creditability ~ ., data = train, gamma = 0.0625, cost = 1, kernel = "radial") # # # Parameters: # SVM-Type: C-classification # SVM-Kernel: radial # cost: 1 # # Number of Support Vectors: 479 # # ( 277 202 ) # # # Number of Classes: 2 # # Levels: # 0 1 summary(normal_svm2) # Call: # svm(formula = Creditability ~ ., data = train, cost = 1, kernel = "linear") # # # Parameters: # SVM-Type: C-classification # SVM-Kernel: linear # cost: 1 # # Number of Support Vectors: 371 # # ( 189 182 ) # # # Number of Classes: 2 # # Levels: # 0 1 summary(normal_svm3) # Call: # svm(formula = Creditability ~ ., data = train, cost = 1, degree = 3, kernel = "polynomial") # # # Parameters: # SVM-Type: C-classification # SVM-Kernel: polynomial # cost: 1 # degree: 3 # coef.0: 0 # # Number of Support Vectors: 463 # # ( 263 200 ) # # # Number of Classes: 2 # # Levels: # 0 1 |
#8 sv index 확인
normal_svm1$index normal_svm2$index normal_svm3$index |
#9 SVM으로 예측
normal_svm1_predict <- predict(normal_svm1, test) str(normal_svm1_predict) # Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 1 1 2 ... # - attr(*, "names")= chr [1:300] "5" "8" "9" "10" ... normal_svm2_predict <- predict(normal_svm2, test) str(normal_svm2_predict) # Factor w/ 2 levels "0","1": 2 2 2 1 2 2 2 1 1 2 ... # - attr(*, "names")= chr [1:300] "5" "8" "9" "10" ... normal_svm3_predict <- predict(normal_svm3, test) str(normal_svm3_predict) # Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ... # - attr(*, "names")= chr [1:300] "5" "8" "9" "10" ... |
#9 Confusion Matrix 구성 및 Statistics
#9-1 radial kernel 적용 시
confusionMatrix(normal_svm1_predict, test$Creditability) # Confusion Matrix and Statistics # # Reference # Prediction 0 1 # 0 29 11 # 1 61 199 # # Accuracy : 0.76 # 95% CI : (0.7076, 0.8072) # No Information Rate : 0.7 # P-Value [Acc > NIR] : 0.01249 # # Kappa : 0.3208 # # Mcnemar's Test P-Value : 7.709e-09 # # Sensitivity : 0.32222 # Specificity : 0.94762 # Pos Pred Value : 0.72500 # Neg Pred Value : 0.76538 # Prevalence : 0.30000 # Detection Rate : 0.09667 # Detection Prevalence : 0.13333 # Balanced Accuracy : 0.63492 # # 'Positive' Class : 0 |
#9-2 linear kernel 적용 시
confusionMatrix(normal_svm2_predict, test$Creditability) # Confusion Matrix and Statistics # # Reference # Prediction 0 1 # 0 33 19 # 1 57 191 # # Accuracy : 0.7467 # 95% CI : (0.6935, 0.7949) # No Information Rate : 0.7 # P-Value [Acc > NIR] : 0.04285 # # Kappa : 0.3141 # # Mcnemar's Test P-Value : 2.194e-05 # # Sensitivity : 0.3667 # Specificity : 0.9095 # Pos Pred Value : 0.6346 # Neg Pred Value : 0.7702 # Prevalence : 0.3000 # Detection Rate : 0.1100 # Detection Prevalence : 0.1733 # Balanced Accuracy : 0.6381 # # 'Positive' Class : 0 |
#9-3 polynomial kernel
confusionMatrix(normal_svm3_predict, test$Creditability) # Confusion Matrix and Statistics # # Reference # Prediction 0 1 # 0 20 16 # 1 70 194 # # Accuracy : 0.7133 # 95% CI : (0.6586, 0.7638) # No Information Rate : 0.7 # P-Value [Acc > NIR] : 0.3321 # # Kappa : 0.1762 # # Mcnemar's Test P-Value : 1.096e-08 # # Sensitivity : 0.22222 # Specificity : 0.92381 # Pos Pred Value : 0.55556 # Neg Pred Value : 0.73485 # Prevalence : 0.30000 # Detection Rate : 0.06667 # Detection Prevalence : 0.12000 # Balanced Accuracy : 0.57302 # # 'Positive' Class : 0 |
#10 iris 데이터 대상으로 예측
install.packages("kernlab") library(kernlab) model1 <- ksvm(Species~., data=iris) iris_predicted <- predict(model1, newdata=iris) table(iris_predicted, iris$Species) # iris_predicted setosa versicolor virginica # setosa 50 0 0 # versicolor 0 48 2 # virginica 0 2 48 |
predict() 함수를 통해 새로운 자료에 대한 분류(예측)을 수행 할 수 있다. 여기서는 모형 구축 에 사용된 자료를 재사용하여 분류를 수행하였다. 그 결과 setosa는 50개 모두, viginica와 versicolor는 50개 중 48개가 제대로 분류되었다
'통계기반 데이터분석' 카테고리의 다른 글
[ R ] 베이지안 (1) | 2022.12.02 |
---|---|
[ R ] install.packages 오류 (0) | 2022.12.02 |
[ R ] 인공신경망 #2 neuralnet 패키지이용 (0) | 2022.12.01 |
[ R ] 인공신경망 #1 (0) | 2022.12.01 |
[ R ] 앙상블 #2 - 랜덤포레스트 예제 (0) | 2022.11.30 |