728x90

오늘은 R보다는 태양열 프로젝트를 주로 작업했습니다. 곧 있으면 마감인데 원하는 만큼 결과물이 좋지 않아서 조바심이 나네요. 먼저 R 요약 내용입니다.

R(나이브베이즈)

나이브베이즈 알기 전 조건부 확률 개념 먼저 보겠습니다.

축구 경기할 때의 승리/패배할 경우는 위와 같습니다. 이 중 승리를 하는데, 선제골의 여부에 따라 승리할 확률을 구할 수 있습니다. 종종 축구 경기 보면 캐스터가 말하길 "우리가 선제골을 넣으면 주로 승리를 하는데요 ~ " 혹은 '홈에서 경기를 하면 승리를 하는데요~' 이 모든 게 조건부 확률입니다. 식으로 나타내면 1번부터 3번까지 차례로 나타낼 수 있습니다.

베이즈 정리

2 번식을 1번에 대입하면 3번이 됩니다. 중요하게 볼 식은 3번입니다. 3번에 대해 자세히 살펴보겠습니다.

P(Y)가 조건이므로 P(x)는 당연히 아직 실행되지 않았습니다. 즉, 발생하기 전 확률이라 하여 사전 확률입니다. 이때 P(Y)은 

P(Y)는 상수이라고 하는데요 제 나름대로 예를 들자면..

 

동전 앞과 뒤, 둘 중 뭐가 나올지 모르기 때문에 둘 다 확률변수지만 앞이라는 조건이 결정이 되면 이는 확률변수가 아닌 상수로써 조건이 주어진 것이다. 즉 주어진 조건은 확률변수가 아닌 고정된 상수로 본다는 뜻이다.
P(X|Y) =  P(X) * P(Y|X) / P(Y) 에서 P(Y)는 고정된 값이므로 P(X|Y) 는 P(X) * P(Y|X) 값에 비례한다(이게 핵심)

 

*헷갈리지 않게 다시 정리
P(X|Y)의 조건 P(Y)는 상수이고, 그냥 단독적인 P(Y)는 확률변수이다.

 

조건으로 주어졌다는 것은 조건은 실행이 된다는 전제가 깔립니다. 시행이 되었으므로 어느 값을 가진 상수라는 것입니다. 상수는 한번 결정되면 변하지 않습니다. 따라서 분자인 P(X) * P(Y|X)에 따라서 비례를 한다 라는 것입니다.

 

R의 caret 패키지를 통해 구현하는 방법을 보겠습니다.

#데이터 불러오기
library(caret)
rawdata <- read.csv(file='heart.csv', header = TRUE)
str(rawdata)

#타켓 클래스 범주화
rawdata$target <- as.factor(rawdata$target)
unique(rawdata$target)

#연속형 독립변수의 표준화
rawdata$age <- scale(rawdata$age)
rawdata$trestbps <- scale(rawdata$trestbps)
rawdata$chol <- scale(rawdata$chol)
rawdata$thalach <- scale(rawdata$thalach)
rawdata$oldpeak <- scale(rawdata$oldpeak)
rawdata$slope <- scale(rawdata$slope)

#범주형 독립변수 
newdata <- rawdata
factorVar <- c('sex','cp','fbs','restecg','exang','ca','thal')
newdata[,factorVar] = lapply(newdata[,factorVar],factor)

#데이터 분리
set.seed(2020)
datatotal <-  sort(sample(nrow(newdata),size=nrow(newdata)*0.7))
train <- newdata[datatotal,]
test <-  newdata[-datatoal,]

train_x <- train[,1:12]
train_y <- train[,13]

test_x <- test[,1:12]
test_y <- test[,13]

#모델설정
ctrl <- trainControl(method='repeatedcv',repeats = 5)
nbFit <- train(target~.,
                  data=train,
                  method="naive_bayes",
                  trControl=ctrl,
                  #preProcess=c('center','scale'),
                  metric="Accuracy")
plot(nbFit)

#예측
pred_test <- predict(nbFit,newdata=test)
confusionMatrix(pred_test, test$target)

약 82%의 성능을 보였습니다. 스케일링을 하면 성능이 떨어져서 주석처리했습니다.

 

태양열 예측

첫 번째 시도:랜덤 포레스트 log 상태에서 스케일링에 따른 변화
-> 변화 없음

두 번째 시도: log 아닌 상태에서 스케일링에 따른 변화
->year 변수 삭제 후 MinMax or Robust 사용 시 가장 좋은 성능을 보임

세 번째 시도: 변수의 차분 변화에 따른 성능 측정(온도, 습도 등 차분을 통해 증감을 표현하여 패턴을 설명하고자, Cloud의 lag을 통해 1시간 전 Cloud가 끼치는 영향을 보고자)
->변수 2개 이상 동시 사용 시 성능 저하 발생, 가장 좋은 조합은.. 

랜덤포레스트'

'CV Score : '

7.801435294117648

'lgb'

'CV Score : '

8.27872655535256

 

많은 조합을 실험해 본 결과 위와 같은 조합이 7.801로 가장 나은 성능을 보였습니다. 하지만 눈에 띄는 결과물은 아녔기에 변수의 한계를 뚫고자 네 번째 시도를 진행 중입니다.

 

네번째 시도: extracted_features 활용
-> 모든 변수 사용 시 성능 저하 발생하여 VIF 및 RFECV 실행 중

extracted_features 함수를 통해 변수를 생선 한 결과 1600개 변수가 생성되었습니다. 하지만 결측 값으로 채워진 변수들이 대부분이었으며, 0과 1로 만 이루어진 변수들도 있었기에 이 두 가지 경우를 전처리하여 

121개 변수를 모두 사용하여 랜덤 포레스트의 중요도를 살펴봤습니다. 

랜덤포레스트' 'CV Score : ' 21.665118055555556 

중요도의 퍼센트를 보니까 아주 상~당히 낮았습니다. 아무래도 한정된 변수를 121개로 쪼개 놓으니까 설명력이 분산이 된 게 아닌가 싶습니다. 변수 선택을 하기 위해서  VIF, RFECV를 돌리고 있습니다. 결과는 내일 포스팅하겠습니다. 

728x90

+ Recent posts