R프로그램_랜덤포레스트를이용한 IRIS 품종 예측
이번에는 앙상블 기법을 이용하여 IRIS 데이터를 Train과 Test로 7:3 나눈 후 품종을 예측하고, 예측한 모델의 성능을 평가해보도록 하겠다.
지난번에 rpart를 이용한 의사결정나무를 이용하여 분류했을 때, 오분류율이 높았는데, 하나의 의사결정나무를 이용하는 것이 아닌 여러 개를 만들어 각각에서 만든 것을 합쳐서 좀 더 오분류율을 낮추는 작업을 "랜덤포레스트"라는 기법으로 해 보려고 한다.
일단 randomForest 패키지를 설치하고, iris 데이터를 불러오자
.libPaths("c:/myRproject/Library")
install.packages("randomForest")
library(randomForest)
head(iris)
다음이 중요한데, iris 데이터가 총 150개의 행으로 이루어진 데이터이니, 이걸 train과 test로 7:3 나누려고 한다. 105개를 train으로, 45개가 test 데이터가 된다. 그런데 이상하게 해 보면 107개, 43개로 나뉘었다.
그리고 그 값은 매번 달라졌다. 이류를 보니 sample() 함수에서 prob=c(0.7, 0.3)의 의미는 1을 뽑는데, 70% 확률로 뽑고, 2를 뽑는데 30% 확률로 뽑으라는 개념이 들어갔기 때문이다. replace=T는 1을 뽑고 다시 집어넣어 1,2 중에 뽑으라는 복원 추출 의미이다. 그 후 1이 뽑힌 index를 따로 추려서 train으로, 2가 뽑힌 index를 모아 test로 만들었다.
idx<-sample(2,nrow(iris), replace=T, prob=c(0.7, 0.3))
train<-iris[idx==1,]
test<-iris[idx==2,]
다음은 train 데이터를 랜덤포레스트로 훈련시키는 과정이다. R에서는 매우 간단하게 아래와 같이 표현한다.
randomForest(종속변수, 독립변수, data=..., ntree= 의사결정나무 개수, proximity=T)
model<-randomForest(Species~.,data=train,ntree=100, proximity=T)
model
> model
Call:
randomForest(formula = Species ~ ., data = train, ntree = 100, proximity = T)
Type of random forest: classification
Number of trees: 100
No. of variables tried at each split: 2
OOB estimate of error rate: 3.6%
Confusion matrix:
setosa versicolor virginica class.error
setosa 36 0 0 0.00000000
versicolor 0 33 2 0.05714286
virginica 0 2 38 0.05000000
여기서 보면 OOB(Out of Bag)가 나오는데, 잘못 분류될 확률이다. 3.6%
Confusion matrix를 보자. 이건 좌측은 참값, 위쪽은 예측값을 나타내는 표이다. 특 versicolor는 33을 versicolor로 예측했지만 2개는 virginica로 예측했다는 것이다. 마찬가지로 virginica 2개를 versicolor로 예측하고, virginica로 38개 예측했다. 이 정도의 에러를 갖는 모델을 randomForest로 만들었다는 것이다.
모델을 만드는데, 4개의 변수 중 어떤 것이 더 영향을 많이 주었는지 보여주는 함수는 importance(), 예상했듯이 꽃잎의 길이와 너비가 이 모델 만드는데 기여도가 높았다.
> importance(model)
MeanDecreaseGini
Sepal.Length 5.621839
Sepal.Width 1.140228
Petal.Length 38.902863
Petal.Width 27.410115
그럼 다음으로 완벽하지는 않지만 이 정도의 모델을 이용하여 test로 떼어 놓은 데이터 셋을 이용하여 제대로 품종을 맞출 수 있는지 검증해보자. 예측하는 것은 predict(model, newdata=test, type="class") 함수를 사용했다. 그리고 위와 같은 confusion matrix로 실제 참값과 예측한 값을 table로 보여주는 table() 함수를 사용했다. model이 완벽하지 않아서 그런지 virginica 1개를 versicolor로 오분류하였다.
predict<- predict(model, newdata = test, type = "class")
table(predict, test$Species)
predict setosa versicolor virginica
setosa 14 0 0
versicolor 0 14 0
virginica 0 1 10
지난번처럼 분류한 것을 plot으로 그려보았다.
plot(predict, test$Species, xlab="예측값", ylab="참값")
plot(jitter(as.numeric(predict)), jitter(as.numeric(test$Species)), xlab="예측값", ylab="참값")