ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ISL] 8장 - Tree, Bagging, Random Forest, Boosting의 이해 (R 실습)
    Data Science/Data Science in R 2019. 12. 19. 06:16

    * 이론 : 업로드 예정

    * 소스코드 원본 : http://faculty.marshall.usc.edu/gareth-james/ISL

     

    사용 데이터 : Carseats

    1. classification tree 생성

    # Carseats$Sales가 8 미만이면 No, 이상이면 Yes로 분류
    High=ifelse(Sales<=8,"No","Yes")      
    Carseats=data.frame(Carseats,High)
    # fitting a classification tree
    tree.carseats=tree(High~.-Sales,Carseats)   
    summary(tree.carseats)

    plot(tree.carseats)
    text(tree.carseats, pretty = 0, cex = 0.7)

    tree.carseats

    2. Test Error 측정

    ###### test error estimation ###################
    set.seed(1)
    train=sample(1:nrow(Carseats), 200)
    Carseats.test=Carseats[-train,]
    High.test=High[-train]


    tree.carseats=tree(High~.-Sales,Carseats,subset=train)
    tree.pred=predict(tree.carseats,Carseats.test,type="class") 


    table(tree.pred,High.test)

    - 정분류율 : (84+44)/200 = 0.64

    - 하지만, 위의 트리가 너무 크므로 가지치기(Prunning)가 필요한 상태

     

    3. Prunning

    #### pruning the tree ####
    set.seed(1)
    cv.carseats=cv.tree(tree.carseats,FUN=prune.misclass)  # CV to determine the optimal tree size
    names(cv.carseats)
    # [1] "size"   "dev"    "k"      "method"
    # 위의 변수들이 Prunning 대상
    cv.carseats

    par(mfrow=c(1,2))
    plot(cv.carseats$size,cv.carseats$dev,type="b")
    plot(cv.carseats$k,cv.carseats$dev,type="b")

    - 8일 때가 best인 지점

    prune.carseats=prune.misclass(tree.carseats,best=8)
    plot(prune.carseats)
    text(prune.carseats,pretty=0)
    tree.pred=predict(prune.carseats,Carseats.test,type="class")
    table(tree.pred,High.test)

    - Prunning 결과로써, 훨씬 단순해진 트리로 볼 수 있다.

    - 정분류율 또한 0.7로 올라간 상태

     

    4. Regression Tree

    library(MASS)
    set.seed(1)
    train = sample(1:nrow(Boston), nrow(Boston)/2)
    tree.boston=tree(medv~.,Boston,subset=train)
    summary(tree.boston)


    plot(tree.boston)
    text(tree.boston,pretty=0,cex=0.7)
    cv.boston=cv.tree(tree.boston)
    plot(cv.boston$size,cv.boston$dev,type='b')

    - 6이 Prunning을 하기 적당함

    prune.boston=prune.tree(tree.boston,best=6)
    plot(prune.boston)
    text(prune.boston,pretty=0,cex=0.7)

    yhat=predict(tree.boston,newdata=Boston[-train,])
    boston.test=Boston[-train,"medv"]
    plot(yhat,boston.test)
    abline(0,1)

    - 트리 모델을 적합시켰을 때, 실제 데이터와 비슷한 수준으로 예측하는 모습을 볼 수 있음

     

    5. Bagging and Random Forest

    library(randomForest)

    set.seed(1)
    bag.boston=randomForest(medv~.,data=Boston,subset=train,mtry=13,importance=TRUE)  # bagging
    bag.boston

    yhat.bag = predict(bag.boston,newdata=Boston[-train,])
    plot(yhat.bag, boston.test)
    abline(0,1)
    mean((yhat.bag-boston.test)^2) ## [1] 23.59273

    - 위의 배깅 모델을 적합시켰을 때, RSS는 23.59273

    bag.boston=randomForest(medv~.,data=Boston,subset=train,mtry=13,ntree=25)
    yhat.bag = predict(bag.boston,newdata=Boston[-train,])
    mean((yhat.bag-boston.test)^2) ## 23.66716

    - 트리의 개수가 많이 줄어들었음에도 불구하고 RSS는 비슷한 수준

     

    #Random Forest

    set.seed(1)
    rf.boston=randomForest(medv~.,data=Boston,subset=train,mtry=6,importance=TRUE)  # random forest
    yhat.rf = predict(rf.boston,newdata=Boston[-train,])
    mean((yhat.rf-boston.test)^2) ## 19.62021

    - 배깅보다 RSS가 많이 줄어든 모습으로 보아 RF의 모델이 더 우수한 것을 알 수 있음

    importance(rf.boston)
    varImpPlot(rf.boston)

    - 위 모델에서 영향력 있는 변수는 위와 같다.

     

    6. Boosting

    library(gbm)

    set.seed(1)
    # boosting : each tree has 4 splits
    boost.boston=gbm(medv~.,data=Boston[train,],distribution="gaussian",n.trees=5000,interaction.depth=4)
    summary(boost.boston)   # relative influence plot

    - boosting시, 거주에 영향력 있는 변수는 위와 같다.

    yhat.boost=predict(boost.boston,newdata=Boston[-train,],n.trees=5000)
    mean((yhat.boost-boston.test)^2) #18.84709

    - 위 모델로 predict하였을 때 RSS는 18.84709

    - Bagging < RF < Boosting 순으로 모델이 우수하다

    boost.boston=gbm(medv~.,data=Boston[train,],distribution="gaussian",n.trees=5000,interaction.depth=4,shrinkage=0.2,verbose=F)
    yhat.boost=predict(boost.boston,newdata=Boston[-train,],n.trees=5000)
    mean((yhat.boost-boston.test)^2)

    - 부스팅에 shrinkage를 적합시키면 기존의 모델보다 조금 더 우수해지는 모습을 보인다.

    - 기존 boosting의 RSS는 18.84709, shrinkage를 적합한 boosting의 RSS는 18.33455 이다.

    댓글

by KUKLIFE