ch0nny_log

[빅데이터분석] R _ 55. 하이퍼 파라미터 본문

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

[빅데이터분석] R _ 55. 하이퍼 파라미터

chonny 2024. 7. 12. 14:55

■ 나이브 베이즈 모델의 성능을 높이는 하이퍼 파라미터

 

■ 라플라스 추정기(p182)

위와 같이 분자의 요소하나가 0 이면 전체가 0 이 되면서 스팸의 우도가 0 이 되버립니다.
그러면 더 이상 계산을 진행할 수 없게 됩니다. 그래서 수학자 라플라스가 이걸 어떻게 했냐면 0을 1로 만들어주면서 아래와 같이 1을 다 더했습니다.

아주 작은값을 하나 더해서 계산이 될 수 있도록 하는데 이 값을 라플라스값라고 합니다. 

나이브 베이즈 모델의 성능을 높이기 위해서는 이 라플라스 값을 지정하는 하이퍼 파라미터를 쓰면 됩니다. 

 우리가 knn 일 때는 k 값을 조정해서 knn 모델의 성능을 높였는데 나이브베이즈는 라플라스 값을 주어서 나이브 베이즈 모델의 성능을 올리는데 사용합니다. 

 

knn시 k값을 1~100까지 홀수로 돌려 적절한 하이퍼 파라미터 값을 알아냈습니다.

(나이브 베이즈는 laplace를 0.001~0.1 사이의 작은 값으로 넣어주면 됩니다.)

하이퍼 파라미터 ?  머신러닝의 성능을 높이기 위해서 모델 개발가 직접 조정해줘야하는 파라미터
 예: knn 의 k 값 , 나이브베이즈의 laplace 값 

 

실습1. 나이브 베이즈 머신러닝 모델을 이용해서 정상버섯과 독버섯을 분류하기.

데이터 설명


# 1. 데이터 업로드
mush<- read.csv('c:\\data\\mushrooms.csv',stringsAsFactors = TRUE)
head(mush)​

# 2. 결측치확인
colSums(is.na(mush))​

# 3. 데이터 탐색
str(mush)

# 정상버섯과 독버섯의 데이터 비율 
table(mush$type) 
m_type<- prop.table(table(mush$type)) 

# 색상 목록 정의
colors <- c('#B2DFDB', '#FFCDD2' )

# plotly 를 사용한 원형 그래프 생성
fig <- plot_ly(labels = names(m_type),
               values = as.numeric(m_type),
               type = 'pie',
               marker = list(colors = colors) )

# 그래프 출력
fig

그래프 해석: 식용과 독버섯의 비율이 거의 동일하므로 기계학습이 잘됨을 예측 


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

k<- createDataPartition(mush$type, p=0.8, list = F) # 훈련 데이터 80%
K #80%에 해당하는 데이터 행의 인덱스 번호/ list = F를 써줘야 행렬로 출력됨

train_data <- mush[k,   ]
test_data <- mush[-k,  ]

dim(train_data) #6500열  23행
dim(test_data)  #1624열  23행

prop.table(table(train_data$type)) 
prop.table(table(test_data$type))​

# 5. 모델훈련시키기기
model <- naiveBayes(type~.,data=train_data)
model #버섯 데이터의 빈도표로 우도표를 생성


result <- predict(model,test_data[ ,-1]) #정답 빼고 넣음
result
색깔보다 냄새가 독버섯을 분류하는데 더 중요하다는 것을 알 수 있음 (우도표를 이용하여 식용 버섯과 독버섯을 알 수있음)

# 6. 모델 평가하기
sum(result==test_data[ ,1])/length(test_data[  ,1]) *100​

# 7. 거짓 긍정(FN) 값 확인
library(gmodels)
CrossTable(x=result, y=test_data[ ,1],chisq = TRUE)

정확도가 93.7%이고 FN값이 98개나 됨. (성능 개선 필요)


# 8. 모델의 성능 개선하기 (라플라스 값 사용)

library(e1071)
model2 <- naiveBayes(type~.,data=train_data, laplace = 0.0001)
model2

result2 <-predict(model2,test_data[ ,-1])
result2


# 9. 개선된 모델 성능 평가하기

sum(result2==test_data[ ,1])/length(test_data[ ,1])*100​


# 10. 거짓 긍정(FN) 값 재 확인
library(gmodels)
CrossTable(x=result2, y=test_data[ ,1],chisq = TRUE)

# 11. 거짓 긍정(FN) 값만 추출하기

library(gmodels)
a <- CrossTable(x=result2, y=test_data[ ,1])
a$t[1,2]​

# 12. 정확도 추출하기
b<- sum(result2==test_data[ ,1])/length(test_data[ ,1])*100
b​


# 13. 기본 for loop 문 연습

y<-0
jumpby <-0.0001
options(scipen = 999) #소숫점이 보이게 세팅

for(i in 1:10) {
  y<-y+ jumpby
  print(y)
}

# 14. FN 값과 정확도 출력하는 반복문 코드

library(e1071)
library(gmodels)

y <- 0
jumpby <- 0.00001

for (i in 1:10) {
  y <- y + jumpby
  model2 <- naiveBayes(type ~ ., data = train_data, laplace = y) 
  result2 <- predict(model2, test_data[, -1])
  
  # 이원 교차표의 출력을 억제
  ct <- capture.output(a <- CrossTable(x = result2, y = test_data[, 1], print.chisq = FALSE))
  
  fn_value <- a$t[1, 2]  # FN 값 추출
  accuracy <- sum(result2 == test_data[, 1]) / length(test_data[, 1]) * 100
  
  print(paste(y, '일때 FN 값', fn_value, '정확도는', accuracy))
}

 

★ 독버섯 나이브 베이즈 모델 코드 총정리
#1. 데이터 불러오기
mush <- read.csv("c:\\data\\mushrooms.csv", stringsAsFactors=TRUE)

#2. 데이터 관찰하기
dim(mush)
str(mush)

#3. 훈련과 테스트 분할하기
library(caret)
set.seed(1)

k <-  createDataPartition( mush$type, p=0.8, list=F) #  훈련 데이터 80%
train_data  <- mush[ k,    ]
test_data <- mush[ -k,    ]


#4. 모델 훈련하기
library(e1071)

model <-  naiveBayes( type ~  . ,  data=train_data, laplace=0.0001 )

#5. 테스트 데이터 예측하기

result <-  predict( model,  test_data[    , -1] )  # 정답 빼고 넣어줍니다.

#6. 모델 평가하기 
library(gmodels)
sum(result == test_data[  , 1] )  / length( test_data[  , 1 ]) * 100
CrossTable(x=result, y=test_data[   , 1], chisq=TRUE )

#7. 모델 개선하기

library(e1071)
library(gmodels)

y <- 0
jumpby <- 0.00001

for (i in 1:10) {
  y <- y + jumpby
  model2 <- naiveBayes(type ~ ., data = train_data, laplace = y) 
  result2 <- predict(model2, test_data[, -1])
  
  # 이원 교차표의 출력을 억제
  ct <- capture.output(a <- CrossTable(x = result2, y = test_data[, 1], print.chisq = FALSE))
  
  fn_value <- a$t[1, 2]  # FN 값 추출
  accuracy <- sum(result2 == test_data[, 1]) / length(test_data[, 1]) * 100
  
  print(paste(y, '일때 FN 값', fn_value, '정확도는', accuracy))
}

문제1. 위의 나이브 베이즈 코드 모음을 자동화 코드 11번에 추가하시오.
실습2. 독감 데이터로 나이브 베이즈 모델을 생성해서 독감환자인지 아닌지를 분류하는 모델을 로드하시오. 

#1. 데이터를 로드합니다.

flu <- read.csv("c:\\data\\flu.csv", stringsAsFactors=TRUE)
str(flu)

데이터 소개
patient_id : 환자번호
chills : 오한
runny_nose : 콧물
headache :  두통
fever : 열
flue : 독감여부

#2. 나이브 베이즈 모델을 생성합니다.
library(e1071)

model_flu <- naiveBayes( flu[   ,  -6],  flu[   , 6], laplace=0.0001 )
model_flu

쪽지시험 문제를 푸시면 됩니다.

test_data2 <- data.frame( chills='Y', runny_nose='N', headache='MILD', fever='Y')

result2 <-  predict( model_flu, test_data2) 
result2

독감환자 입니다.  그런데 확률을 봐야하니까 

library(naivebayes)
new_model <- naive_bayes(flue ~ ., data=flu[ ,-1], laplace=0.00001)
new_model
test_data2 <- data.frame( chills='Y', runny_nose='N', headache='MILD', fever='Y')
test_data2

result3 <-  predict( new_model, test_data2, type='prob')
result3