ch0nny_log

[빅데이터분석] R _ 65. 서포트 벡터 머신 본문

빅데이터 분석(with 아이티윌)/R

[빅데이터분석] R _ 65. 서포트 벡터 머신

chonny 2024. 7. 23. 16:55

 


 

서포트 벡터 머신 이론.pdf
1.63MB

 

 

 

출처: 데이터관련 교육 카페 | [서포트 벡터 머신 이론] - Daum 카페

 

[서포트 벡터 머신 이론]

[서포트 벡터 머신 이론]  서포트 벡터 머신 이론.pdf1.63MB서포트 벡터머신 이론.pptx3.99MB ■ 이론설명1. 서포트 벡터 머신이란 무엇인가요 ? 답: ■ 이론설명2. 서포트 벡터 머신에서 결정경계

cafe.daum.net

 

 

 

1. 서포트 벡터 머신이란 무엇인가요 ?

 서포트 벡터 머신(support vector machine) 은 기계학습의 분야중 하나로
 정답 데이터가 있는 지도학습에 해당하는 부분입니다.
 분류를 하기 위해서 결정경계를 찾을 때 백터의 내적을 이용해서 결정경계를
 찾는 분류 알고리즘 입니다. 


 

 

2. 서포트 벡터 머신에서 결정경계가 무엇인가요?

 결정경계란 분류를 위한 기준선입니다. 2차원일 때는 선이고 3차원일 때는 평면이
 됩니다. 우리가 생각할 수 있는 부분은 3차원까지이고 차원이 더 많아지게 되면 
 평면이 아니라 초평면이 됩니다.

 

 

3. 아래에서 데이터를 가장 잘 분류한 결정경계는 ?

F 입니다. 두 클래스(군집) 사이의 거리가 가장 먼 선이 좋은 결정경계입니다.

 

 

 

4. 서포트 벡터머신에서 서포트 벡터는 무엇입니까? 

결정경계와 가까이 있는 데이터 포인트들을 의미합니다.
이 데이터들이 경계를 정의하는 결정적인 역활을 합니다.

 

 

 

 

 

5. 서포트 벡터머신에서 마진(Margin)이 무엇입니까?

점선으로 부터 결정경계까지의 거리가 마진입니다.
최적의 결정경계는 마진을 최대화 합니다.
6. 소프트 마진은 무엇이고 하드 마진은 무엇입니까 ?

- 하드 마진:  위쪽 그림은 이상치를 허용하지 않고 기준을 까다롭게 세운 모델임
-> 서포트 벡터와 결정 경계 사이 거리가 매우 좁아짐(마진이 작아짐 -> 오버피팅 문제 발생 할 수 있음)

- 소프트 마진: 이상치들이 마진안에 어느정도 포함되도록 너그럽게 기준을 잡음
-> 서포트 벡터와 결정 경계사이의 거리가 멀어짐 (오버피팅 문제를 줄일 수 있음)

 

 

7. 이런 오류를 어느정도 허용하는지 결정하는 하이퍼 파라미터는 무엇입니까 ?

C, GAMMA

- C가 커질 수록 하드마진 (오류를 허용안함) 이 일어나고 작을수록 소프트 마진(오류를 허용)이 일어남.
- GAMMA는 결정 경계를 얼마나 유연하게 그을것 인지 정해주는 것 
-> 높을 수록 학습데이터에 많이 의존하게 되어서 결정 경계를 구불구불하게 긋게 됨 (오버피팅이 일어남)
-> 작을 수록 언디 피팅이 발생 할 수 있음

 

 

8. 서포트 벡터와 관련된 수학식

 

9. 최적의 가중치 벡터를 찾는 과정

 

 

 

10.

 

 

 




1. 2차원 <- 경계선

2. 3차원 <- 경계면(평면)

3. 4차원 <- 3 차원 초 평면 

4. 5차원 <- 4차원 초 평면

 

 

 

- 내적의 벡터 경계선 찾기

- 마진을 최대화 (작업을 힌지 함수를 이용하여)

※ 마진을 최대한 넓힐 수 있는 소프트 벡터를 찾는 것


실습1. 아이리스 데이터 분류
# 아이리스 데이터 분류

#1. 데이터 불러오기
setwd('c:\\data')
iris<- read.csv('iris2.csv',header =T, fileEncoding ='euc-kr') 
head(iris)

#2. 데이터iris# 데이터 살펴보기
colSums(is.na(iris))
str(iris)
summary(iris) # 정규화(0~1 사이의 데이터로 만드는 작업)하기전

iris$Species <- as.factor(iris$Species)

#3. 훈련과 테스트 분할(iris훈련과 테스트 분할)
library(caret)
set.seed(1)
k <-  createDataPartition( iris$Species, p=0.9, list=F)
train_data <- iris[  k ,   ]
test_data <- iris[  -k,    ]
nrow(train_data)   # 135
nrow(test_data)    # 15

#4. 모델 훈련
library(e1071)

svm_model <-  svm(Species ~ . ,  data=train_data, kernel="linear")
svm_model
## 설명: kernel 옵션으로 선형으로 할지 비선형으로 할지를 정해 줄 수 있음. (선형:linear,비선형:radial)

#5. 모델 예측
result <-  predict( svm_model,  test_data[   , c(1:4) ])
result
                    

#6. 모델 평가
sum( result == test_data$Species) / length(test_data$Species)  # 0.93​
설명: 100% 를 못만든 이유는 선형이기 때문입니다. 비선형으로 다시 모델을 만들어야합니다.
실습 1.2. 다시 커널 트릭을 사용해서 비선형 모델로 학습해서 테스트 데이터의 정확도를 확인하시오 !
#7.모델 재훈련
library(e1071)

svm_model2 <-  svm( Species ~ . ,  data=train_data, kernel="radial")

#8. 모델 재예측
result2 <-  predict( svm_model2,  test_data[   , c(1:4) ])
                     result2
                     
#6. 모델 평가 
sum( result2 == test_data$Species) / length(test_data$Species)  #100%​

설명: 100% 

 

■ Kernlab 패키지를 설치하고 ksvm 함수로 서포트 벡터 머신 분류 모델을 생성

실습2.Kernlab 패키지를 설치하고 ksvm 함수로 서포트 벡터 머신 아이리스 분류 모델을 생성하시오.
#1. 패키지 설치
install.packages('kernlab')
library(kernlab)

#2. 모델 훈련
svm_model3 <-  ksvm(Species ~ . ,  data=train_data, kernel="vanilladot")
svm_model3

#5. 모델 예측
result3 <-  predict( svm_model3,  test_data[   , c(1:4) ])
result3


#6. 모델 평가
sum( result3 == test_data$Species) / length(test_data$Species)  # 0.93​

 

설명: vanilladot가 비선형이긴 하지만 정확도가 높지않음
실습2.1. 책에 나오는 kernel ='rbfdot'를 이용해서 모델을 생성하고 정확도를 확인하시오.
#1. 패키지 설치
install.packages('kernlab')
library(kernlab)

#2. 모델 훈련
svm_model4 <-  ksvm(Species ~ . ,  data=train_data, kernel='rbfdot')
svm_model4

#5. 모델 예측
result4 <-  predict( svm_model4,  test_data[   , c(1:4) ])
result4


#6. 모델 평가
sum( result4 == test_data$Species) / length(test_data$Species)  # 1​

설명:  100%   

 

실습 3. 어제 로지스틱회귀로는 분류를 100% 못한 데이터셋인 mtcars 를 이용해서 분류시도 
#1. 패키지 설치
install.packages('kernlab')
library(kernlab)

#2. 모델 훈련
svm_model4 <-  ksvm(Species ~ . ,  data=train_data, kernel='rbfdot')
svm_model4

#5. 모델 예측
result4 <-  predict( svm_model4,  test_data[   , c(1:4) ])
result4


#6. 모델 평가
sum( result4 == test_data$Species) / length(test_data$Species)  # 1

# 데이터 로드 (변속기가 수동인지 자동인지를 분류하기 위한 데이터)
data(mtcars) 

# am 변수를 팩터형으로 변환
mtcars$am <- as.factor(mtcars$am)
head(mtcars)


# 필요한 변수만 선택
mtcars_subset <- mtcars[, c("am", "mpg", "wt", "hp")]

# 훈련 데이터와 테스트 데이터를 분리
library(caret)
set.seed(1)

train_num <- createDataPartition(mtcars_subset$am, p = 0.7, list = FALSE)
train_data <- mtcars_subset[train_num,]
test_data <- mtcars_subset[-train_num,]

nrow(train_data) # 훈련 데이터의 개수 24
nrow(test_data)  # 테스트 데이터의 개수 8

# 모델 생성 및 하이퍼파라미터 설정
library(e1071)

# C와 gamma 값을 조정하여 모델 훈련
set.seed(1)
mtcars_svm_model <- svm(am ~ mpg + wt + hp, data = train_data, kernel = "radial", cost = 10, gamma = 0.1)
mtcars_svm_model
# 모델 예측
result <- predict(mtcars_svm_model, test_data[, -1]) #정답제외하고 예측함
result

# 모델 평가
accuracy <- sum(result == test_data$am) / length(test_data$am)
accuracy

# 교차 테이블
library(gmodels)
r1 <- CrossTable(x = test_data$am, y = result)
r1$t

# 정확도 및 교차 테이블 출력
cat("Accuracy: ", accuracy, "\n")
print(r1)​

 

정확도 : 87.5%
실습4. wine 데이터를 분류하는 서포트 벡터 머신 모델을 생성하시오.
# 데이터 로드
wine <- read.csv("c:\\data\\wine2.csv",stringsAsFactors = TRUE)
head(wine)

# am 변수를 팩터형으로 변환
wine$Type <- as.factor(wine$Type)
head(wine)


# 훈련 데이터와 테스트 데이터를 분리
library(caret)
set.seed(1)

train_num <- createDataPartition(wine$Type, p = 0.8, list = FALSE)
train_data <- wine[train_num,]
test_data <- wine[-train_num,]

nrow(train_data) # 훈련 데이터의 개수
nrow(test_data)  # 테스트 데이터의 개수

# 모델 생성 및 하이퍼파라미터 설정
library(e1071)

# C와 gamma 값을 조정하여 모델 훈련
set.seed(1)
wine_svm_model <- svm(Type ~ . , data = train_data, kernel = "radial", cost = 10, gamma = 0.1)

# 모델 예측
result <- predict(wine_svm_model, test_data[, -1]) # 정답제외하고 예측함
result

# 모델 평가
accuracy <- sum(result == test_data$Type) / length(test_data$Type)
accuracy

# 교차 테이블
library(gmodels)
r1 <- CrossTable(x = test_data$Type, y = result)
r1$t

# 정확도 및 교차 테이블 출력
cat("Accuracy: ", accuracy, "\n")
print(r1)​

정확도: 97.05%

실습5. for loop 문을 돌려서 최적의 c값과 gamma 값을 찾으시오.

# 데이터 로드
wine <- read.csv("c:\\data\\wine2.csv",stringsAsFactors = TRUE)
head(wine)

# am 변수를 팩터형으로 변환
wine$Type <- as.factor(wine$Type)
head(wine)


# 훈련 데이터와 테스트 데이터를 분리
library(caret)
set.seed(1)

train_num <- createDataPartition(wine$Type, p = 0.8, list = FALSE)
train_data <- wine[train_num,]
test_data <- wine[-train_num,]

nrow(train_data) # 훈련 데이터의 개수
nrow(test_data)  # 테스트 데이터의 개수

# 모델 생성 및 하이퍼파라미터 설정
library(e1071)

# C와 gamma 값을 조정하여 모델 훈련

C_values <- c(1:100)
gamma_values <- 2^(-20:-1)

results <- data.frame( C=numeric(), gamma=numeric(), accuracy=numeric() )

for ( C in  C_values) {
  for ( gamma in gamma_values) { 
    
    set.seed(1)
    wine_svm_model <- svm(Type ~ . , data = train_data, kernel = "radial", cost = C, gamma = gamma )
    
# 모델 예측
    result <- predict(wine_svm_model, test_data[, -1]) # 정답제외하고 예측함
    
# 모델 평가
    accuracy <- sum(result == test_data$Type) / length(test_data$Type)
    
    results <- rbind( results, data.frame(C=C, gamma=gamma, accuracy=accuracy))
    
  }
}

# 내림차순으로 정렬
library(doBy)
orderBy(~-accuracy,results)

set.seed(1)
best_model <- svm(Type ~ . , data = train_data, kernel = "radial", cost = 63, gamma = 0.00097656250  )

##전진 제거법 : 독립변수를 하나씩 추가하면서 모델의 정확도를 보며 모델생성
##후진 제거법 : 처음에는 모든 독립변수를 다 넣고 모델 생성하고 나서
## -> 덜 유의미한 변수를 하나씩 제거하면 모델을 생성


# 모델 예측
result <- predict(best_model, test_data[, -1]) # 정답제외하고 예측함

# 모델 평가
accuracy <- sum(result == test_data$Type) / length(test_data$Type)
accuracy  #0.85

 

실습5.1. 아래의 스크립트에 최적의 C 와 gamma 값을 for loop 문을 돌려서 알아내시오 !
# 데이터 로드 (변속기가 수동인지 자동인지를 분류하기 위한 데이터)
data(mtcars) 

# am 변수를 팩터형으로 변환
mtcars$am <- as.factor(mtcars$am)
head(mtcars)

# 필요한 변수만 선택
mtcars_subset <- mtcars[   , c("am", "mpg", "wt", "hp")]
mtcars_subset

# 훈련 데이터와 테스트 데이터를 분리
library(caret)
set.seed(1)

train_num <- createDataPartition(mtcars_subset$am, p = 0.7, list = FALSE)
train_data <- mtcars_subset[train_num,]
test_data <- mtcars_subset[-train_num,]

nrow(train_data) # 24
nrow(test_data)  # 8

# C와 gamma 값을 조정하여 모델 훈련

C_values <- c(1:100)
gamma_values <- 2^(-20:-1)

results <- data.frame( C=numeric(), gamma=numeric(), accuracy=numeric() )

for ( C in  C_values) {
  for ( gamma in gamma_values) { 
    
# 모델 생성 및 하이퍼파라미터 설정
library(e1071)

# C와 gamma 값을 조정하여 모델 훈련
set.seed(1)
mtcars_svm_model <- svm(am ~ mpg + wt + hp, data = train_data, kernel = "radial", cost = C, gamma = gamma)

# 모델 예측
result <- predict(mtcars_svm_model, test_data[, -1])   # 정답제외하고 예측함

# 모델 평가
accuracy <- sum(result == test_data$am) / length(test_data$am)

results <- rbind( results, data.frame(C=C, gamma=gamma, accuracy=accuracy))
 }
}

results

# C 가 16,  gamma 가  0.25 가 정확도 100% 가 나오는 하이퍼 파라미터 입니다.​

 

실습6. 미국 대한 입학 데이터를 가지고 서포트 벡터 머신 모델을 생성하는데 정확도 100%인 c와 gamma를 알아내시오.
# 데이터를 불러옵니다.
mydata <- read.csv("c:\\data\\binary.csv", header = TRUE)
head(mydata)

# admit 변수를 팩터형으로 변환
mydata$admit <- as.factor(mydata$admit)

# 훈련과 테스트를 8대 2로 나눕니다.
library(caret)
set.seed(123)
k <- createDataPartition(mydata$admit, p = 0.8, list = FALSE)
train_data <- mydata[k, ]
test_data <- mydata[-k, ]
nrow(train_data)   # 321
nrow(test_data)    # 79

# 데이터 정규화 함수 정의
normalize <- function(x) {
  return((x - min(x)) / (max(x) - min(x)))
}

# 정규화 진행 (admit 변수를 제외하고 정규화)
train_data_n <- as.data.frame(lapply(train_data[, -1], normalize))
test_data_n <- as.data.frame(lapply(test_data[, -1], normalize))

# 정규화된 데이터에 admit 변수 추가
train_data_n$admit <- train_data$admit
test_data_n$admit <- test_data$admit

# SVM 모델 생성 및 하이퍼파라미터 튜닝
library(e1071)

# 하이퍼파라미터 값 설정
C_values <- c(1:100)
gamma_values <- 2^(-20:-1)

results <- data.frame(C = numeric(), gamma = numeric(), accuracy = numeric())

for (C in C_values) {
  for (gamma in gamma_values) {

# 모델 생성 및 하이퍼파라미터 설정
set.seed(1)
mydata_svm_model <- svm(admit ~ ., data = train_data_n, kernel = "radial", cost = C, gamma = gamma)
    
# 모델 예측
result <- predict(mydata_svm_model, test_data_n[, -4]) # admit 변수를 제외하고 예측
    
# 모델 평가
 accuracy <- sum(result == test_data_n$admit) / length(test_data_n$admit)
    
# 결과 저장
results <- rbind(results, data.frame(C = C, gamma = gamma, accuracy = accuracy))
  }
}


# 정확도 기준으로 정렬
library(doBy)
results_sorted <- orderBy(~ -accuracy, results)
print(results_sorted)

# 0.74 이상의 정확도를 가진 모델이 있는지 확인
high_accuracy_models <- results_sorted[results_sorted$accuracy >= 0.74, ]
print(high_accuracy_models)