본문 바로가기

데이터 분석 (Data Analysis)/R

[데이터분석기사 실기] 예시문제 풀이 - 랜덤포레스트(Random Forest) - 작업 2유형

rm(list=ls())

library(dplyr)
library(knitr)
library(ggplot2)

setwd(".../data")

x.train <- read.csv("X_train.csv")
y.train <- read.csv("Y_train.csv")

x.test <- read.csv("X_test.csv")


x.train %>% tail(5)
y.train %>% head(5)

x.test %>% head(5)


# 트레이닝 셋
x.train %>% dim()
y.train %>% dim()

# 테스트 셋
x.test %>% dim()

# 학습할 데이터셋 병합
train <- merge(x.train, y.train, by='cust_id')
train %>% head(5)

# 결측값 처리

train$환불금액[is.na(train$환불금액)== TRUE] = 0
train$환불금액 %>% head()

x.test$환불금액[is.na(x.test$환불금액)== TRUE] = 0

# 범주형변수 factor 처리
str(train)

train$gender <- as.factor(train$gender)
train$주구매상품 <- as.factor(train$주구매상품)
train$주구매지점 <- as.factor(train$주구매지점)

x.test$주구매상품 <- as.factor(x.test$주구매상품)
x.test$주구매지점 <- as.factor(x.test$주구매지점)

# 구조 및 요약
train %>% str()
x.test %>% str()

train %>% summary()
x.test %>% summary()

# 범주형변수 One Hot encoding 처리 (train, test 모두)
library(caret)

# train 원핫인코딩
train$gender

gender_train <- train$gender # gender 변수 따로 빼두기

dummy <- dummyVars("~.-gender", data = train)
train <- data.frame(predict(dummy, newdata = train))

train$gender <- gender_train

train$주구매상품.소형가전 # random Forest 적합 과정에서 오류 발생 삭제. (row=1개)

train <- train[,-24]

# test 원핫인코딩

dummy <- dummyVars("~.", data = x.test)
x.test <- data.frame(predict(dummy, newdata = x.test))




# # 모형적합에 불필요한 변수 제거 (cust_id)
# train <- train[,-1]

# 데이터셋 나누기(일반적으로 훈련:검증:평가 = 6:2:2 이므로 훈련:검증 = 3:1 로 구성)

train %>% nrow()
x.test %>% nrow() # 훈련, 평가셋 비율 약 7:5

set.seed(210613) # 랜덤샘플링을 위한 시드값 고정
n <- nrow(train)
idx <- 1:n
training_idx <- sample(idx, n * .75)

idx <- setdiff(idx, training_idx) # setdiff() : 차집합
validate_idx <- sample(idx, n * .25)

training <- train[training_idx,]
validation <- train[validate_idx,]

training %>% head(5)
validation %>% head(5)

dim(training)
dim(validation)

# Random Forest
library(randomForest)

set.seed(0613)
rf_fit <- randomForest(gender ~ ., data=training)
rf_fit

par(mfrow=c(1,2))
plot(rf_fit) # tree 수에 따른 오차율의 감소
varImpPlot(rf_fit) # 설명변수의 중요도

# 평가
library(pROC)

rf_pred <- predict(rf_fit, validation, type='prob')

class(validation$gender)
class(rf_pred[,2])

roc(validation$gender, rf_pred[,2])
auc(roc(validation$gender, rf_pred[,2])) # AUC : 0.6891

# 정답 제출
final_predict <- predict(rf_fit, x.test, type='prob')

final <- data.frame(x.test$cust_id, final_predict[,2])

colnames(final) <- c("cust_id", "gender")

final %>% head(10)

write.csv(final, "예측값 정답 제출.csv")

아래 코드는 에러 파악 후 해결 과정입니다.

간혹 randomForest 패키지를 이용해 randomForest 모델링시

# Error : Type of predictors in new data do not match that of the training data. 와 같은 오류가 뜨더라고요.

 

범주형변수의 범주가 많거나 train과 test 셋들의 범주 차이가 생겨 발생하는 오류인데, 범주 levels이 차이가 안나더라도 오류가 발생한다고 합니다. (예를들면, training set의 a변수에서 범주가 43개, test set에서의 a변수에서 범주가 42개)

따라서 원 핫 인코딩으로 문제를 해결했고, auc값도 올라갔네요. 문제는 시험환경에서 1분내로 돌아갈지가 의문입니다.

 

먼저 보일 코드는 위 오류가 발생한 코드입니다.

 

 

아래코드는 원핫인코딩으로 오류 해결하고 모델링

 

rm(list=ls())

library(dplyr)
library(knitr)
library(ggplot2)

setwd(".../data")

x.train <- read.csv("X_train.csv")
y.train <- read.csv("Y_train.csv")

x.test <- read.csv("X_test.csv")


x.train %>% tail(5)
y.train %>% head(5)

x.test %>% head(5)


# 트레이닝 셋
x.train %>% dim()
y.train %>% dim()

# 테스트 셋
x.test %>% dim()

# 학습할 데이터셋 병합
train <- merge(x.train, y.train, by='cust_id')
train %>% head(5)

# 결측값 처리

train$환불금액[is.na(train$환불금액)== TRUE] = 0
train$환불금액 %>% head()

x.test$환불금액[is.na(x.test$환불금액)== TRUE] = 0

# 범주형변수 factor 처리
str(train)

train$gender <- as.factor(train$gender)
train$주구매상품 <- as.factor(train$주구매상품)
train$주구매지점 <- as.factor(train$주구매지점)

x.test$주구매상품 <- as.factor(x.test$주구매상품)
x.test$주구매지점 <- as.factor(x.test$주구매지점)

# 구조 및 요약
train %>% str()
x.test %>% str()

train %>% summary()
x.test %>% summary()

# 범주형변수 One Hot encoding 처리 (train, test 모두)
library(caret)

# train 원핫인코딩
train$gender

gender_train <- train$gender # gender 변수 따로 빼두기

dummy <- dummyVars("~.-gender", data = train)
train <- data.frame(predict(dummy, newdata = train))

train$gender <- gender_train

train$주구매상품.소형가전 # random Forest 적합 과정에서 오류 발생 삭제. (row=1개)

train <- train[,-24]

# test 원핫인코딩

dummy <- dummyVars("~.", data = x.test)
x.test <- data.frame(predict(dummy, newdata = x.test))




# # 모형적합에 불필요한 변수 제거 (cust_id)
# train <- train[,-1]

# 데이터셋 나누기(일반적으로 훈련:검증:평가 = 6:2:2 이므로 훈련:검증 = 3:1 로 구성)

train %>% nrow()
x.test %>% nrow() # 훈련, 평가셋 비율 약 7:5

set.seed(210613) # 랜덤샘플링을 위한 시드값 고정
n <- nrow(train)
idx <- 1:n
training_idx <- sample(idx, n * .75)

idx <- setdiff(idx, training_idx) # setdiff() : 차집합
validate_idx <- sample(idx, n * .25)

training <- train[training_idx,]
validation <- train[validate_idx,]

training %>% head(5)
validation %>% head(5)

dim(training)
dim(validation)

# Random Forest
library(randomForest)

set.seed(0613)
rf_fit <- randomForest(gender ~ ., data=training)
rf_fit

par(mfrow=c(1,2))
plot(rf_fit) # tree 수에 따른 오차율의 감소
varImpPlot(rf_fit) # 설명변수의 중요도

# 평가
library(pROC)

rf_pred <- predict(rf_fit, validation, type='prob')

class(validation$gender)
class(rf_pred[,2])

roc(validation$gender, rf_pred[,2])
auc(roc(validation$gender, rf_pred[,2])) # AUC : 0.6891

# 정답 제출
final_predict <- predict(rf_fit, x.test, type='prob')

final <- data.frame(x.test$cust_id, final_predict[,2])

colnames(final) <- c("cust_id", "gender")

final %>% head(10)

write.csv(final, "예측값 정답 제출.csv")