본문 바로가기
1-1. 지도학습 (이산자료)/2) 의사결정 나무

R 랜덤포레스트 예시 (신용등급예시)

by makhimh 2022. 11. 23.

먼저 아래 패키지를 설치합시다. 

install.packages("randomForest")
install.packages("caret")


randomForest 패키지에는 의사결정나무 함수가 들어있습니다. caret 패키지에는 예시에 사용할 데이터가 들어 있습니다. 

패키지를 불러옵시다.

library(caret)
library(randomForest)


데이터를 불러오고 변수에 저장해줍니다. 

data(GermanCredit)

data=GermanCredit


이후 과정은 번호를 붙여 진행하겠습니다. 

 

1. 데이터 살펴보기

데이터가 굉장히 방대하기 때문에 일부만 추려서 살펴보겠습니다. 

> data[1:5,7:10]
  NumberPeopleMaintenance Telephone ForeignWorker Class
1                       1         0             1  Good
2                       1         1             1   Bad
3                       2         1             1  Good
4                       2         1             1  Good
5                       2         1             1   Bad

 

마지막 열인 Class 가 신용등급입니다. 변수를 독립변수와 결과변수로 나눈다면 Class 열은 결과변수에 해당됩니다. 데이터프레임의 열의 수는 아래와 같이 62개입니다. 

 

> dim(data)
[1] 1000   62

 

Class 열을 제외한 61개 열이 독립변수입니다. 신용도에 영향을 미치는 인자라고 생각되는 변수들입니다. Good 을 1로, Bad를 0으로 바꿔줍니다. 

 

data$Class=as.factor(ifelse(data$Class=='Good',1,0)) #good=1,bad=0

 

2. 결측치 확인 및 제거

결측치의 위치를 확인하고 제거해줍니다. 

 

#결측치 위치 확인 함수
where.na.df=function(df){ 
  
  res=data.frame(row=NA,col=NA)
  
  
  for (i in 1:dim(df)[1]){
    for (j in 1:dim(df)[2]){
      
      if (is.na(df[i,j])){
        res=rbind(res,c(i,j))
      }
      
    }
  }
  
  res=res[-1,]
  rownames(res)=NULL
  
  return(res)
  
}

where.na.df(data) #결측치 위치확인
data = na.omit(data) #결측치 제거

 

 

3. 훈련데이터셋, 테스트데이터셋 나누기

1000개의 데이터를 훈련데이터셋과 테스트데이터셋으로 나누겠습니다. 전체의 25%를 테스트 데이터셋으로 만들겠습니다. 코드는 아래와 같습니다. 

 

set.seed(999)
id_test=sample(1:nrow(data),nrow(data)*0.25)

data_test=data[id_test,]
data_train=data[setdiff(1:nrow(data),y=id_test),]

 

4. 모델 만들기

신용도를 예측하는 모델을 만들 것입니다. 의사결정나무라는 알고리즘을 사용할 것입니다. 아래와 같이 입력합니다. Class~. 은 Class 를 종속변수로, 나머지를 독립변수로 사용한다는 의미입니다. 모델을 만들 때는 data_train 만 사용합니다. 훈련용으로 분류한 데이터입니다.

 

model=randomForest(Class~. ,data=data_train) #error 발생 시 response 를 factor로 바꿔주면됨

 

 

모델 생성 결과는 아래와 같습니다. 

 

> model

Call:
 randomForest(formula = Class ~ ., data = data_train) 
               Type of random forest: classification
                     Number of trees: 500
No. of variables tried at each split: 7

        OOB estimate of  error rate: 24.13%
Confusion matrix:
     Bad Good class.error
Bad   84  143  0.62995595
Good  38  485  0.07265774

 

5. 중요도 그래프 출력

varImpPlot 함수를 이용하여 중요도그래프를 출력합니다. 

 

varImpPlot(model)

 

 

6. 트리 그래프 출력

 

트리그래프 출력을 위해서 rpart.plot 패키지가 필요합니다. 설치하고 불러옵니다. 아래와 같이 rpart 함수로 모델 생성을 해주고 prp 함수로 트리를 그려줍니다. 

 

library(rpart.plot)

model_r=rpart(Class~. ,data=data_train) #error 발생 시 response 를 factor로 바꿔주면됨
prp(model_r)

 

7. 모델 평가

predict 함수를 이용하여 테스트셋의 결과변수를 구해줍니다. confusionMatrix 함수를 이용하여 평가 결과를 출력합니다. 

 

pred=predict(model, data_test)
confusionMatrix( table(pred, data_test$Class) )

 

정확도는 0.768이 나옵니다. 

 

> confusionMatrix( pred, data_test$Class)
Confusion Matrix and Statistics

    
pred   0   1
   0  35  20
   1  38 157
                                          
               Accuracy : 0.768           
                 95% CI : (0.7107, 0.8189)
    No Information Rate : 0.708           
    P-Value [Acc > NIR] : 0.02015         
                                          
                  Kappa : 0.3951          
                                          
 Mcnemar's Test P-Value : 0.02560         
                                          
            Sensitivity : 0.4795          
            Specificity : 0.8870          
         Pos Pred Value : 0.6364          
         Neg Pred Value : 0.8051          
             Prevalence : 0.2920          
         Detection Rate : 0.1400          
   Detection Prevalence : 0.2200          
      Balanced Accuracy : 0.6832          
                                          
       'Positive' Class : 0

 

roc 커브도 그려줍니다. roc 커브를 그리기 위해 predict 의 type 을 prob로 바꿔야합니다. 

 

library(Epi)
pred_p=predict(model, data_test,type='prob')
ROC(test = pred_p[,2],
    stat = data_test$Class,
    plot = "ROC")

 

 

#전체 코드 모아보기

library(caret)
library(randomForest)

#1. 데이터
data(GermanCredit)
data=GermanCredit

data$Class=as.factor(ifelse(data$Class=='Good',1,0)) #good=1,bad=0

#2. 결측치 확인

#결측치 위치 확인 함수
where.na.df=function(df){ 
  
  res=data.frame(row=NA,col=NA)
  
  
  for (i in 1:dim(df)[1]){
    for (j in 1:dim(df)[2]){
      
      if (is.na(df[i,j])){
        res=rbind(res,c(i,j))
      }
      
    }
  }
  
  res=res[-1,]
  rownames(res)=NULL
  
  return(res)
  
}

where.na.df(data) #결측치 위치확인
data = na.omit(data) #결측치 제거


#3. train, test data set
set.seed(999)
id_test=sample(1:nrow(data),nrow(data)*0.25)

data_test=data[id_test,]
data_train=data[setdiff(1:nrow(data),y=id_test),]

#4.model
model=randomForest(Class~. ,data=data_train) #error 발생 시 response 를 factor로 바꿔주면됨

#5.plot importance
varImpPlot(model)

#6.plot tree
library(rpart.plot)

model_r=rpart(Class~. ,data=data_train) #error 발생 시 response 를 factor로 바꿔주면됨
prp(model_r)

#7.evaluate
pred=predict(model, data_test)
confusionMatrix( pred, data_test$Class)

#roc curve
library(Epi)
pred_p=predict(model, data_test,type='prob')
ROC(test = pred_p[,2],
    stat = data_test$Class,
    plot = "ROC")

댓글