brunch

You can make anything
by writing

C.S.Lewis

by 첨물 May 23. 2021

빅분기실기연습(10)

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="참값")



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari