의사결정트리는 데이터를 분류하는 모델중 하나인데, 특정 기준에 따라 데이터들이 분류되는 과정을 반복한다.

최종적인 목표는 각 노드들의 엔트로피 지수를 0으로, 즉 한 노드(공간)에 같은 특성을 가진 데이터들만 모이게 하는 것이다.


아래 그림을 보자.



해당 트리는 Income와 Lot size를 기준으로 데이터들을 동질한 집단으로 모으는 과정을 거쳤다. 

즉 선과 선으로 둘러쌓인 공간은 한 개의 노드와 마찬가지이며, 각 선들은 처음 그림에서의 분류 기준과 같은 것이다.


트리의 분류가 끝나게 되면 바로 위 그림처럼 특정 공간에는 같은(동질의)데이터만 오거나, 

오차율을 무시할 수 있을만큼 동질적인 수준의 데이터가 모이게 된다.


이제 코드와 함께 보자


credit.csv


저번 csv파일 입출력 포스팅에 썼던 은행 고객 데이터를 다시 사용한다.


우리가 예측해야하는 값은 17번째 열인 default 인데, 이 deault행은 해당 고객이 

"대출을 기간 내에 상환할 것인지"에 대해 Yes(상환) No(상환실패) 로 분류한 것이다. 


즉 1행부터 16행까지 다양한 변수들에 따라서 상환 여부를 예측하는 모델을 만들어야 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#crdit data 를 이용한 은행 대출 확인#
# step1. prepare data set#
credit <- read.csv("credit.csv",stringsAsFactors = TRUE)
View(credit)
 
#대출지원자 특성 확인 
table(credit$checking_balance)
table(credit$savings_balance) #저축해놓은 자산 
 
#대출의 특성 확인
summary(credit$months_loan_duration) #대출기간 4-72달 
#평균적으로는 18개월 
summary(credit$amount) #대출액 총액 
 
#분류 액수 확인
table(credit$default) #협의한 기간 내 반납했는지 
cs


우선 csv를 읽어온 후, 간단히 몇가지 변수들에 대해 요약통계를 출력해본다.

그리고 마지막 table(칼럼) 명령어를 확인하여, 해당 칼럼내 변수들의 비율을 확인한다


즉 우리가 오늘 사용할 데이터는 상환 여부가 Yes 인 것이 700개, No 인 것이 300개가 있다는 것이다. 


1
2
3
4
5
6
7
8
9
10
11
12
#훈련과 테스트 데이터에 대한 무작위 샘플 생성
#예제와 같은 무작위 수열을 사용하기 위해 set.seed(); 사용
set.seed(12345)
credit_rand<- credit[order(runif(1000)),]
#1000개의 데이터를 난수로 섞겠다
 
#credit과 credit_rand를 비교
summary(credit$amount)
summary(credit_rand$amount)
head(credit$amount)
head(credit_rand$amount)
#순서는 바뀐거지만 내용은 안변함 
cs

set.seed(숫자) 명령어는 어떤 환경에서든 동일한 랜덤값을 가질 수 있도록 기준점을 설정해준다.

즉 set.seed 없이 runif명령어를 사용하여 순서를 섞게 된다면,

학교 실습실 컴퓨터에서 해당 명령어를 실행할 때와, 집 컴퓨터에서 해당 명령어를 실행할 때마다 랜덤으로 섞이는 데이터의 결과가 달라질 것이다.


어떤 환경에서 진행하건 "모델"은 동일한 모델이 나와야 하기 때문에 - 

즉 동일 환경에서 모델을 만들 수 있도록 하는 장치라고 생각하면 된다.


해당 명령어를 사용하고 요약통계를 확인하면 순서는 변했지만, 내용 자체는 변하지 않았음을

Head() 명령어와 summary() 명령어로 확인할 수 있다. 


1
2
3
4
5
6
7
8
 
#데이터 쪼개기 (학습 / 검증용) 
credit_train<-credit_rand[1:900,]
credit_test<-credit_rand[901:1000,]
 
#분류 변수의 비율 확인 - 트래이닝과 테스트 셋에 대한 비율 
prop.table(table(credit_train$default))
prop.table(table(credit_test$default))
cs

데이터를 학습용으로 900개, 검증용으로 100개로 나눈다.

이제 준비는 끝났고, 모델을 생성해보도록 하자.


1
2
3
4
5
6
7
8
9
10
11
12
13
#######################
##step2 모델 생성######
#######################
 
#가장 단순한 결정 트리 생성
#install.packages("C50")
library(C50)
#?C5.0
View(credit_train)
credit_model<-C5.0(credit_train[-17],credit_train$default)
#(17열을 빼고 모델을 생성한다 = 디폴트, 예측해야하는 값이기 때문)
#뒤에는 예측하고싶은 목표변수 = 디폴트값 
#x=샘플 900중 16개변수 가지고 예측 / 트리사이즈 67개 
cs

트리 생성은 C50 라이브러리를 사용한다. 없다면 설치하자.


라이브러리를 불러온 후, 모델을 생성하는데 모델 생성은 C5.0() 명령어를 사용한다.

명령어를 자세히 보면 C5.0(트레이닝 데이터 셋,타겟변수) 꼴로 넣어주면 된다


우리는 Train data를 가지고 모델을 만드는데, 여기서 17번째 열은 default, 

즉 우리가 예측을 해야하는 행이기 때문에 당연히 빼고 데이터셋을 넣어준다.

그리고 그 후에는 예측해야하는 타겟변수(train data의 default 열) 을 넣어준다.


이렇게 만든 모델은 credit_model 변수에 넣어준 후, 트리를 확인해본다.


1
2
3
4
#트리 상세하게 보려면
summary(credit_model)
#제일아래 보면 ㅍ요약표 있는데 에러가 13.9퍼 /
#즉 125개가 잘못 분류된거 900개중 
cs


트리 모델을 만들고 summary를 통해 이를 확인하면


이런 모양이 뜰 것이다,


위에서부터 설명하면, 900개의 데이터를 가지고 모델 생성을 하여, 76개 - 8.6%가 에러가 났으며

트리를 만드는데 각 변수의 사용 빈도(중요도)는 

checking_balance, credit_history ~ 순으로 나타난다.


참고로 트리에서 중요한 변수일수록 트리 모형 생성에서 부모 노드(최상위 노드)에 

가까운 분류 기준으로 위치한다. 


포스팅 첫번째 사진으로 예를 들면 outlook 이 가장 중요하고, 

humidity  windy는 그보다는 덜 중요한 변수라는 것.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
############################
#######3step 3 모델평가## ##
############################
credit_pred<-predict(credit_model,credit_test)
credit_pred
#크레딧 모델을 가지고 credit_test를 이용하여 테스트
 
 
#교차표 그리기 (예측과 실제)
library(gmodels)
CrossTable(credit_test$default,credit_pred,
           prop.chisq=FALSE,prop.c=FALSE,prop.r=FALSE,
           dnn=c("actual default""predict default"))
 
#검증용 data의 default값을 credit_pred(예측값) 과 비교해보겠다 
#73퍼의 정확도와 27퍼의 오차율
 
cs

이제 모델 평가를 해보겠다.


C5.0에서는 predict함수를 사용해 모델을 통한 예측값을 가지고 올 수 있다. 

predict(모델,예측하고싶은 데이터 셋) 을 넣어주면 된다


해당 예측의 정확도를 살펴보기 위해서 gmodels 라이브러리를 이용한

크로스테이블을 생성하겠다.




테이블을 보면 predict default 은 우리가 생상한 모델로 test set 의 default을 no 라고 예측,

actual default은 train set의 진짜 yes 와 no를 나타내고 있다.


즉 예측도 no이고 진짜도 no인가 58 / 예측 yes 진짜 yes 인것은 15로 

오늘 만든 모델의 정확도는 73%임을 알 수 있다.


다음 포스팅에는 부스팅을 통해 해당 정확도를 올릴 수 있는 방법을 알아보도록 하겠다.






+ Recent posts