다음의 패키지가 설치되어 있지 않으면 설치한다.
#install.packages("mlbench") # 데이터셋
#install.packages("tree") # 의사결정나무 #R 3.6버전 이상 필요
#install.packages("ipred") # 배깅
#install.packages("randomForest") #랜덤포레스트
#install.packages("pdp") #부분의존도 그림
R 패키지 mlbench를 불러온 후 data 함수를 통해 내장된 데이터 BreastCancer를 불러올 수 있다.
총 699개의 관측치와 11개의 변수가 있다.
library(mlbench)
data(BreastCancer)
dim(BreastCancer)
## [1] 699 11
변수 11개의 이름 및 설명은 다음과 같다.
변수명 | 변수 설명 |
---|---|
ID | Sample code number |
Cl.thickness | Clump Thickness |
Cell.size | Uniformity of Cell Size |
Cell.shape | Uniformity of Cell Shape |
Marg.adhesion | Marginal Adhesion |
Epith.c.size | Single Epithelial Cell Size |
Bare.nuclei | Bare Nuclei |
Bl.cromatin | Bland Chromatin |
Normal.nucleoli | Normal Nucleoli |
Mitoses | Mitoses |
Class | Class |
이는 RStudio 콘솔에서 help(BreastCancer)
을
실행하거나, 우측 하단 창의 “Help”로 들어가서 “BreastCancer”를 검색하면
확인할 수 있다.
첫 6개의 관측치는 다음과 같다.
head(BreastCancer)
## Id Cl.thickness Cell.size Cell.shape Marg.adhesion Epith.c.size
## 1 1000025 5 1 1 1 2
## 2 1002945 5 4 4 5 7
## 3 1015425 3 1 1 1 2
## 4 1016277 6 8 8 1 3
## 5 1017023 4 1 1 3 2
## 6 1017122 8 10 10 8 7
## Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses Class
## 1 1 3 1 1 benign
## 2 10 3 2 1 benign
## 3 2 3 1 1 benign
## 4 4 3 7 1 benign
## 5 1 3 1 1 benign
## 6 10 9 7 1 malignant
Id는 사용하지 않으며, Class가 maligant인지 benign인지 예측하는 것이 목표이다.
Id 열을 제거한다.
BreastCancer <- BreastCancer[,-1]
변수별 결측치 개수를 확인한다. 결측이 있는 관측치를 제거한다.
colSums(is.na(BreastCancer))
## Cl.thickness Cell.size Cell.shape Marg.adhesion Epith.c.size
## 0 0 0 0 0
## Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses Class
## 16 0 0 0 0
BreastCancer <- BreastCancer[complete.cases(BreastCancer), ]
dim(BreastCancer)
## [1] 683 10
설명변수의 데이터형을 보면 ordered factor로 되어있다.
head(BreastCancer$Cell.size)
## [1] 1 4 1 8 1 10
## Levels: 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10
class(BreastCancer$Cell.size)
## [1] "ordered" "factor"
Class를 제외한 설명변수를 모두 수치형으로 변환한다.
XIdx <- !(names(BreastCancer) %in% 'Class')
BreastCancer[XIdx] <-
Map(as.numeric, BreastCancer[XIdx])
전체 데이터의 30%를 테스트 데이터로 사용한다. 테스트 데이터로
사용할 자료점의 인덱스를 BC.TsIdx
에 저장한다.
BC.n <- nrow(BreastCancer)
ratioTs <- 0.3
BC.nTs <- round(ratioTs * BC.n)
BC.nTr <- BC.n-BC.nTs
set.seed(1)
BC.TsIdx <- sample(BC.n, BC.nTs)
mlbench를 불러온 후 data
함수를 통해 내장된 데이터
BostonHousing를 불러올 수 있다.
총 506개의 관측치와 14개의 변수가 있다.
data(BostonHousing)
dim(BostonHousing)
## [1] 506 14
변수 14개의 이름 및 설명은 다음과 같다.
변수 이름 | 변수 설명 |
---|---|
crim | per capita crime rate by town |
zn | proportion of residential land zoned for lots over 25,000 sq.ft |
indus | proportion of non-retail business acres per town |
chas | Charles River dummy variable (= 1 if tract bounds river; 0 otherwise) |
nox | nitric oxides concentration (parts per 10 million) |
rm | average number of rooms per dwelling |
age | proportion of owner-occupied units built prior to 1940 |
dis | weighted distances to five Boston employment centres |
rad | index of accessibility to radial highways |
tax | full-value property-tax rate per USD 10,000 |
ptratio | pupil-teacher ratio by town |
b | 1000(B - 0.63)2 where B is the proportion of blacks by town |
lstat | percentage of lower status of the population |
medv | median value of owner-occupied homes in USD 1000’s |
이는 RStudio 콘솔에서 help(BostonHousing)
을
실행하거나, 우측 하단 창의 “Help”로 들어가서 “BostonHousing”을 검색하면
확인할 수 있다.
첫 6개의 관측치는 다음과 같다.
다른 변수들을 이용해 medv를 예측하는 것이 목적이다.
head(BostonHousing)
## crim zn indus chas nox rm age dis rad tax ptratio b lstat
## 1 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 4.98
## 2 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 9.14
## 3 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 4.03
## 4 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 2.94
## 5 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 5.33
## 6 0.02985 0 2.18 0 0.458 6.430 58.7 6.0622 3 222 18.7 394.12 5.21
## medv
## 1 24.0
## 2 21.6
## 3 34.7
## 4 33.4
## 5 36.2
## 6 28.7
결측치가 없고, 설명변수들의 데이터형에 문제가 없으므로 전처리를 따로 하지 않는다.
전체 데이터의 30%를 테스트 데이터로 사용한다. 테스트 데이터로
사용할 자료점의 인덱스를 BH.TsIdx
에 저장한다.
BH.n <- nrow(BostonHousing)
ratioTs <- 0.3
BH.nTs <- round(ratioTs * BH.n)
BH.nTr <- BH.n-BH.nTs
set.seed(1)
BH.TsIdx <- sample(BH.n, BH.nTs)
tree 패키지의 tree
함수를 사용하여 의사결정나무를
적합할 수 있다.
BreastCancer[-BC.TsIdx, ]
를 통해 train 데이터를
선택하여 data
인자로 넣어준다.
formula로 어떤 변수를 사용하여 어떤 변수를 예측할지 지정해준다.
Class~.
는 나머지 모든 변수로 Class
를
예측한다는 formula이다.
library(tree)
BC.TreeFit<-tree(Class~., data=BreastCancer[-BC.TsIdx, ])
적합 결과를 출력하면 다음과 같이 각 노드에서 어떻게 분할되는지 볼 수 있다.
한 눈에 알아보기는 어렵다.
BC.TreeFit
## node), split, n, deviance, yval, (yprob)
## * denotes terminal node
##
## 1) root 478 605.20 benign ( 0.67155 0.32845 )
## 2) Cell.size < 2.5 302 73.88 benign ( 0.97351 0.02649 )
## 4) Cl.thickness < 6.5 297 33.54 benign ( 0.98990 0.01010 )
## 8) Bare.nuclei < 4.5 288 0.00 benign ( 1.00000 0.00000 ) *
## 9) Bare.nuclei > 4.5 9 11.46 benign ( 0.66667 0.33333 ) *
## 5) Cl.thickness > 6.5 5 0.00 malignant ( 0.00000 1.00000 ) *
## 3) Cell.size > 2.5 176 150.90 malignant ( 0.15341 0.84659 )
## 6) Cell.size < 4.5 63 84.63 malignant ( 0.39683 0.60317 )
## 12) Bare.nuclei < 3.5 25 25.02 benign ( 0.80000 0.20000 )
## 24) Normal.nucleoli < 2.5 17 0.00 benign ( 1.00000 0.00000 ) *
## 25) Normal.nucleoli > 2.5 8 10.59 malignant ( 0.37500 0.62500 ) *
## 13) Bare.nuclei > 3.5 38 29.59 malignant ( 0.13158 0.86842 ) *
## 7) Cell.size > 4.5 113 20.10 malignant ( 0.01770 0.98230 )
## 14) Bl.cromatin < 4.5 25 13.94 malignant ( 0.08000 0.92000 ) *
## 15) Bl.cromatin > 4.5 88 0.00 malignant ( 0.00000 1.00000 ) *
plot 함수로 tree 구조를 그릴 수 있으나 노드에 대한 정보는 보여주지 않는다.
text 함수과 같이 쓰면 좋다.
plot(BC.TreeFit)
text(BC.TreeFit)
tree.control
로 마디를 언제까지 분할할지 지정할 수
있다.
mindev
를 지정하면 끝마디의 deviance가 뿌리마디의
deviance의 mindev
배보다 클 때까지만 분할한다.
mindev
는 기본 0.01이며 커질수록 더 적게 분할하며
작아질수록 더 많이 분할한다.
BC.BigTreeFit<-tree(Class~., data=BreastCancer[-BC.TsIdx, ],
control = tree.control(BC.nTr, mindev = 0.001))
BC.SmallTreeFit<-tree(Class~., data=BreastCancer[-BC.TsIdx, ],
control = tree.control(BC.nTr, mindev = 0.1))
mindev
가 작은 경우
plot(BC.BigTreeFit)
text(BC.BigTreeFit)
mindev
가 큰 경우
plot(BC.SmallTreeFit)
text(BC.SmallTreeFit)
이론 강의의 교차검증 예제와 비슷한 방식으로 최적 모형을 고르려고 한다.
교차검증 예제에서는 주어진 모형 집합이 있으나 의사결정나무에서는 데이터에 따라 모형이 결정되므로 그대로 적용할 수는 없다.
최적 모형을 선택하는 대신 최적 끝마디 수를 선택한다.
cv.tree
에 적합된 의사결정나무와 fold의 수
K
를 입력해주면 된다. K
의 기본값은
10
이다.
다음 그래프는 끝마디 수에 따른 교차검증 deviance를 나타낸 것이다.
\(\text{비용복잡도}(\alpha)=\text{나무 } T\text{의 } deviance + \alpha |T|\)에서 \(x\)축이 \(|T|\), \(y\)축이 교차검증 \(deviance\)에 해당된다.
\(\text{비용복잡도}(\alpha)\)를 최소로 하는 \(|T|\)를 \(\alpha\)의 함수로 볼 수 있으며 \(x\)축을 \(|T|\) 대신 \(\alpha\)에 대해서 표현할 수 있다. 그래프 위에 나타나 있다.
BC.TreeCV <- cv.tree(BC.BigTreeFit)
plot(BC.TreeCV)
BC.TreeCV
에는 끝마디 수에 따른 교차검증 deviance가
저장되어있으며 이를 최소로하는 끝마디 수를 BestSize
에
저장한다.
prune.tree
함수를 이용해 적합된 나무
BC.TreeFit
를 끝마디 수가 BestSize
가 되도록
가지치기한다.
BestSize <- BC.TreeCV$size[which.min(BC.TreeCV$dev)]
BestSize
## [1] 5
BC.TreePruned <- prune.tree(BC.BigTreeFit, best = BestSize)
가지치기된 나무는 다음과 같다.
plot(BC.TreePruned)
text(BC.TreePruned)
BC.TreeFit
을 사용하여 테스트 데이터를
예측한다.
predict
에서 type
을
'class'
로 하여 속한 그룹을 예측하도록 한다. 지정하지 않을
경우 확률이 계산된다.
confusion matrix와 accuracy를 계산한다.
BC.TreeFit.pred <- predict(BC.TreeFit, BreastCancer[BC.TsIdx, ], type = 'class')
table(pred=BC.TreeFit.pred, true=BreastCancer$Class[BC.TsIdx])
## true
## pred benign malignant
## benign 114 3
## malignant 9 79
BC.TreeFit.Acc <- mean(BC.TreeFit.pred==BreastCancer$Class[BC.TsIdx])
BC.TreeFit.Acc
## [1] 0.9414634
다음은 BC.TreePruned
의 예측 결과이다.
BC.TreePruned.pred <- predict(BC.TreePruned, BreastCancer[BC.TsIdx, ], type = 'class')
table(pred=BC.TreePruned.pred, true=BreastCancer$Class[BC.TsIdx])
## true
## pred benign malignant
## benign 119 7
## malignant 4 75
BC.TreePruned.Acc <- mean(BC.TreePruned.pred==BreastCancer$Class[BC.TsIdx])
BC.TreePruned.Acc
## [1] 0.9463415
회귀분석 자료에도 같은 방식으로 의사결정나무를 적합한다.
반응변수인 medv
가 수치형이며 별도의 설정없이
자동으로 회귀모형이 적합된다.
class(BostonHousing$medv)
## [1] "numeric"
BH.TreeFit<-tree(medv~., data=BostonHousing[-BH.TsIdx, ])
BH.TreeFit
## node), split, n, deviance, yval
## * denotes terminal node
##
## 1) root 354 30070.0 22.76
## 2) lstat < 9.615 149 11640.0 29.89
## 4) rm < 6.941 100 3846.0 25.70
## 8) dis < 1.77785 5 528.4 44.86 *
## 9) dis > 1.77785 95 1385.0 24.69
## 18) rm < 6.5435 61 534.0 22.98 *
## 19) rm > 6.5435 34 350.3 27.76 *
## 5) rm > 6.941 49 2460.0 38.44
## 10) rm < 7.435 28 295.4 34.08 *
## 11) rm > 7.435 21 922.7 44.25
## 22) ptratio < 17.7 16 213.6 46.68 *
## 23) ptratio > 17.7 5 312.7 36.48 *
## 3) lstat > 9.615 205 5365.0 17.58
## 6) lstat < 15 91 1057.0 21.19 *
## 7) lstat > 15 114 2177.0 14.70
## 14) crim < 5.51111 57 631.6 17.22 *
## 15) crim > 5.51111 57 820.3 12.18 *
plot(BH.TreeFit)
text(BH.TreeFit)
tree.control
로 마디를 언제까지 분할할지 지정할 수
있다.
mindev
를 지정하면 끝마디의 deviance가 뿌리마디의
deviance의 mindev
배보다 클 때까지만 분할한다.
mindev
는 기본 0.01이며 커질수록 더 적게 분할하며
작아질수록 더 많이 분할한다.
BH.BigTreeFit<-tree(medv~., data=BostonHousing[-BH.TsIdx, ],
control = tree.control(BH.nTr, mindev = 0.001))
BH.SmallTreeFit<-tree(medv~., data=BostonHousing[-BH.TsIdx, ],
control = tree.control(BH.nTr, mindev = 0.1))
mindev
가 작은 경우
plot(BH.BigTreeFit)
text(BH.BigTreeFit)
mindev
가 큰 경우
plot(BH.SmallTreeFit)
text(BH.SmallTreeFit)
BH.TreeFit.pred <- predict(BH.TreeFit, BostonHousing[BH.TsIdx, ])
plot(x=BH.TreeFit.pred, y=BostonHousing$medv[BH.TsIdx])
#예측값의 범주 수가 끝마디 수 이하라는 한계가 있음.
BH.TreeFit.MSE <- mean((BH.TreeFit.pred-BostonHousing$medv[BH.TsIdx])^2)
BH.TreeFit.MSE
## [1] 18.81051
bagging
함수를 사용하여
학습할 수 있다.bagging
함수에서는 정해진 개수만큼 나무를 만드는데 이를
nbagg
에 지정하면 된다.library(ipred)
BC.Bag <- bagging(Class~., data = BreastCancer[-BC.TsIdx, ],
nbagg = 100, coob=TRUE)
BC.Bag
##
## Bagging classification trees with 100 bootstrap replications
##
## Call: bagging.data.frame(formula = Class ~ ., data = BreastCancer[-BC.TsIdx,
## ], nbagg = 100, coob = TRUE)
##
## Out-of-bag estimate of misclassification error: 0.0356
BC.Bag
은 100개의 나무로 이루어져있으며 이 나무들의
정보는 BC.Bag$mtrees
에 저장되어있다.
BC.Bag$mtrees
는 길이가 100인 리스트이며 하나의
원소가 하나의 나무를 나타낸다.
length(BC.Bag$mtrees)
## [1] 100
BC.Bag
의 첫번째 나무를 확인하면 다음과 같다.
BC.Bag$mtrees[[1]]$btree
## n= 478
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 478 163 benign (0.658995816 0.341004184)
## 2) Cell.size< 3.5 333 23 benign (0.930930931 0.069069069)
## 4) Bare.nuclei< 3.5 300 3 benign (0.990000000 0.010000000)
## 8) Cl.thickness< 7 298 1 benign (0.996644295 0.003355705)
## 16) Normal.nucleoli< 7.5 297 0 benign (1.000000000 0.000000000) *
## 17) Normal.nucleoli>=7.5 1 0 malignant (0.000000000 1.000000000) *
## 9) Cl.thickness>=7 2 0 malignant (0.000000000 1.000000000) *
## 5) Bare.nuclei>=3.5 33 13 malignant (0.393939394 0.606060606)
## 10) Cell.size< 1.5 11 2 benign (0.818181818 0.181818182)
## 20) Epith.c.size>=1.5 9 0 benign (1.000000000 0.000000000) *
## 21) Epith.c.size< 1.5 2 0 malignant (0.000000000 1.000000000) *
## 11) Cell.size>=1.5 22 4 malignant (0.181818182 0.818181818)
## 22) Normal.nucleoli>=6 6 2 benign (0.666666667 0.333333333)
## 44) Cl.thickness< 6.5 4 0 benign (1.000000000 0.000000000) *
## 45) Cl.thickness>=6.5 2 0 malignant (0.000000000 1.000000000) *
## 23) Normal.nucleoli< 6 16 0 malignant (0.000000000 1.000000000) *
## 3) Cell.size>=3.5 145 5 malignant (0.034482759 0.965517241)
## 6) Marg.adhesion< 1.5 6 2 malignant (0.333333333 0.666666667)
## 12) Cl.thickness< 7 2 0 benign (1.000000000 0.000000000) *
## 13) Cl.thickness>=7 4 0 malignant (0.000000000 1.000000000) *
## 7) Marg.adhesion>=1.5 139 3 malignant (0.021582734 0.978417266)
## 14) Cell.size< 4.5 15 2 malignant (0.133333333 0.866666667)
## 28) Marg.adhesion< 5.5 3 1 benign (0.666666667 0.333333333)
## 56) Cl.thickness>=7.5 2 0 benign (1.000000000 0.000000000) *
## 57) Cl.thickness< 7.5 1 0 malignant (0.000000000 1.000000000) *
## 29) Marg.adhesion>=5.5 12 0 malignant (0.000000000 1.000000000) *
## 15) Cell.size>=4.5 124 1 malignant (0.008064516 0.991935484)
## 30) Bl.cromatin< 4.5 19 1 malignant (0.052631579 0.947368421)
## 60) Normal.nucleoli< 2.5 4 1 malignant (0.250000000 0.750000000)
## 120) Cell.size>=8.5 1 0 benign (1.000000000 0.000000000) *
## 121) Cell.size< 8.5 3 0 malignant (0.000000000 1.000000000) *
## 61) Normal.nucleoli>=2.5 15 0 malignant (0.000000000 1.000000000) *
## 31) Bl.cromatin>=4.5 105 0 malignant (0.000000000 1.000000000) *
다음은 BC.Bag
의 1 – 3번째 나무를 나타낸
그래프이다.
par(mfrow=c(1,3))
for(i in 1:3) {
plot(BC.Bag$mtrees[[i]]$btree)
text(BC.Bag$mtrees[[i]]$btree)
}
par(mfrow=c(1,1))
BC.Bag
는 이러한 나무 100개로 이루어져있다.BC.Bag.pred <- predict(BC.Bag, newdata = BreastCancer[BC.TsIdx, ])
table(pred=BC.Bag.pred, true=BreastCancer$Class[BC.TsIdx])
## true
## pred benign malignant
## benign 119 4
## malignant 4 78
BC.Bag.Acc <- mean(BC.Bag.pred==BreastCancer$Class[BC.TsIdx])
BC.Bag.Acc
## [1] 0.9609756
패키지 “pdp”의 partial
함수로 부분의존도 함수를
계산한 후 그 결과를 plotPartial
에 입력하여 부분의존도
그림을 그릴 수 있다.
partial
함수에는 적합된 모델과 모델에 포함된
설명변수 중 관심있는 변수 하나의 이름을 지정해줘야한다.
“ipred”나 “randomForest” 등 자주 사용되는 여러 패키지들에서 학습된 모델을 지원한다.
세포 크기(Cell.size
)가 증가할수록
Class
가 악성(“maligant”)일 확률의 예측값이 증가한다.
library(pdp)
BC.Bag.Cell.size <- partial(BC.Bag, pred.var = 'Cell.size', which.class="malignant")
plotPartial(BC.Bag.Cell.size)
덩어리 굵기(Cl.thickness
)가 증가할수록
Class
가 악성(“maligant”)일 확률의 예측값이 증가한다.
BC.Bag.Cl.thickness <- partial(BC.Bag, pred.var = 'Cl.thickness', which.class="malignant")
plotPartial(BC.Bag.Cl.thickness)
접착력(Marg.adhesion
)이 증가할수록
Class
가 악성(“maligant”)일 확률의 예측값이 증가한다.
BC.Bag.Marg.adhesion <- partial(BC.Bag, pred.var = 'Marg.adhesion', which.class="malignant")
plotPartial(BC.Bag.Marg.adhesion)
수치형 자료에 대해서도 별 다른 설정없이 회귀모형을 적합시킬 수 있다.
BH.Bag <- bagging(medv~., data = BostonHousing[-BH.TsIdx, ], nbagg = 100, coob=TRUE)
BH.Bag
##
## Bagging regression trees with 100 bootstrap replications
##
## Call: bagging.data.frame(formula = medv ~ ., data = BostonHousing[-BH.TsIdx,
## ], nbagg = 100, coob = TRUE)
##
## Out-of-bag estimate of root mean squared error: 4.321
BH.Bag.pred <- predict(BH.Bag, newdata = BostonHousing[BH.TsIdx, ])
plot(x=BH.Bag.pred, y=BostonHousing$medv[BH.TsIdx])
BH.Bag.MSE <- mean((BH.Bag.pred-BostonHousing$medv[BH.TsIdx])^2)
BH.Bag.MSE
## [1] 11.43528
범죄율(crim
)이 증가할수록 집값(medv
)의
예측값이 감소한다.
library(pdp)
BH.Bag.crim <- partial(BH.Bag, pred.var = 'crim')
plotPartial(BH.Bag.crim)
방의 수(rm
)가 증가할수록 집값(medv
)의
예측값이 증가한다.
BH.Bag.rm <- partial(BH.Bag, pred.var = 'rm')
plotPartial(BH.Bag.rm)
지위가 낮은 사람의 비율(lstat
)이 증가할수록
집값(medv
)의 예측값이 감소한다.
BH.Bag.dis <- partial(BH.Bag, pred.var = 'lstat')
plotPartial(BH.Bag.dis)
randomForest
함수를 이용하여
랜덤포레스트를 적합할 수 있다.randomForest
에서는 나무의 개수 ntree
와 각
노드에서 사용할 후보 변수의 수 mtry
를 지정해야한다.ntree
의 기본값은 500이며 분류모형일 때, mtry
\(\approx \sqrt{p}\), 회귀모형일 때,
mtry
\(\approx
p/3\)이다.library(randomForest)
BC.RF <- randomForest(Class~., data = BreastCancer[-BC.TsIdx, ], importance = TRUE)
BC.RF
##
## Call:
## randomForest(formula = Class ~ ., data = BreastCancer[-BC.TsIdx, ], importance = TRUE)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 3
##
## OOB estimate of error rate: 2.93%
## Confusion matrix:
## benign malignant class.error
## benign 313 8 0.02492212
## malignant 6 151 0.03821656
BC.RF.pred <- predict(BC.RF, newdata = BreastCancer[BC.TsIdx, ])
table(pred=BC.RF.pred, true=BreastCancer$Class[BC.TsIdx])
## true
## pred benign malignant
## benign 119 3
## malignant 4 79
BC.RF.Acc <- mean(BC.RF.pred==BreastCancer$Class[BC.TsIdx])
BC.RF.Acc
## [1] 0.9658537
importance
함수를 사용하여 중요도를 구할 수
있다.
특정 변수의 값을 데이터 내에서 랜덤하게 섞어서 예측에 도움이 되지 않도록 만든 후 예측했을 때, 결과가 얼마나 안 좋아지는지를 계산한다.
더 많이 나빠질수록 예측에 중요한 변수라 볼 수 있다.
head(importance(BC.RF)[,3:4])
## MeanDecreaseAccuracy MeanDecreaseGini
## Cl.thickness 16.35911 8.078830
## Cell.size 20.71841 55.937150
## Cell.shape 16.82963 36.713881
## Marg.adhesion 11.57630 7.561247
## Epith.c.size 12.11946 15.477940
## Bare.nuclei 24.01128 34.412627
varImpPlot
함수를 사용하면 중요도를 그림으로 나타낼
수 있다.
두 가지 기준 공통으로 Cell.size
,
Bare.nuclei
가 중요한 것으로 보인다.
varImpPlot(BC.RF)
세포 크기(Cell.size
)가 증가할수록
Class
가 악성(“maligant”)일 확률의 예측값이 증가한다.
library(pdp)
BC.RF.Cell.size <- partial(BC.RF, pred.var = 'Cell.size', which.class="malignant")
plotPartial(BC.RF.Cell.size)
덩어리 굵기(Cl.thickness
)가 증가할수록
Class
가 악성(“maligant”)일 확률의 예측값이 증가한다.
BC.RF.Cl.thickness <- partial(BC.RF, pred.var = 'Cl.thickness',
which.class="malignant")
plotPartial(BC.RF.Cl.thickness)
접착력(Marg.adhesion
)이 증가할수록
Class
가 악성(“maligant”)일 확률의 예측값이 증가한다.
BC.RF.Marg.adhesion <- partial(BC.RF, pred.var = 'Marg.adhesion',
which.class="malignant")
plotPartial(BC.RF.Marg.adhesion)
BH.RF <- randomForest(medv~., data = BostonHousing[-BH.TsIdx, ], importance = TRUE)
BH.RF
##
## Call:
## randomForest(formula = medv ~ ., data = BostonHousing[-BH.TsIdx, ], importance = TRUE)
## Type of random forest: regression
## Number of trees: 500
## No. of variables tried at each split: 4
##
## Mean of squared residuals: 12.77443
## % Var explained: 84.96
BH.RF.pred <- predict(BH.RF, newdata = BostonHousing[BH.TsIdx, ])
plot(x=BH.RF.pred, y=BostonHousing$medv[BH.TsIdx])
BH.RF.MSE <- mean((BH.RF.pred-BostonHousing$medv[BH.TsIdx])^2)
BH.RF.MSE
## [1] 8.248459
importance
함수를 사용하여 중요도를 구할 수
있다.
특정 변수의 값을 데이터 내에서 랜덤하게 섞어서 예측에 도움이 되지 않도록 만든 후 예측했을 때, 결과가 얼마나 안 좋아지는지를 계산한다.
더 많이 나빠질수록 예측에 중요한 변수라 볼 수 있다.
head(importance(BH.RF))
## %IncMSE IncNodePurity
## crim 15.485362 2022.2782
## zn 3.665558 182.2067
## indus 12.583043 2523.8158
## chas 3.036134 125.7982
## nox 16.168554 2001.0150
## rm 34.064639 8152.3665
varImpPlot
함수를 사용하면 중요도를 그림으로 나타낼
수 있다.
두 가지 기준 공통으로 lstat
, rm
이
중요한 것으로 보인다.
varImpPlot(BH.RF)
범죄율(crim
)이 증가할수록 집값(medv
)의
예측값이 감소한다.
BH.RF.crim <- partial(BH.RF, pred.var = 'crim')
plotPartial(BH.RF.crim)
방의 수(rm
)가 증가할수록 집값(medv
)의
예측값이 증가한다.
BH.RF.rm <- partial(BH.RF, pred.var = 'rm')
plotPartial(BH.RF.rm)
고용센터와의 거리(dis
)가 증가할수록
집값(medv
)의 예측값이 감소한다.
BH.RF.dis <- partial(BH.RF, pred.var = 'dis')
plotPartial(BH.RF.dis)
예측모형은 반응변수(\(Y\))의 형태에 따라 분류분석과 회귀분석으로 나뉜다.
분류분석 : 반응변수가 범주형
회귀분석 : 반응변수가 연속형
BC.LoR <- glm(Class~.,family=binomial, data = BreastCancer[-BC.TsIdx, ])
BC.LoR
##
## Call: glm(formula = Class ~ ., family = binomial, data = BreastCancer[-BC.TsIdx,
## ])
##
## Coefficients:
## (Intercept) Cl.thickness Cell.size Cell.shape
## -9.27948 0.42112 -0.05391 0.32709
## Marg.adhesion Epith.c.size Bare.nuclei Bl.cromatin
## 0.27034 0.21076 0.33346 0.52543
## Normal.nucleoli Mitoses
## 0.18384 0.19185
##
## Degrees of Freedom: 477 Total (i.e. Null); 468 Residual
## Null Deviance: 605.2
## Residual Deviance: 76.76 AIC: 96.76
BC.LoR.prob <- predict(BC.LoR, newdata = BreastCancer[BC.TsIdx, ], type="response")
BC.LoR.pred=ifelse(BC.LoR.prob<0.5,"benign","malignant")
table(pred=BC.LoR.pred, true=BreastCancer$Class[BC.TsIdx])
## true
## pred benign malignant
## benign 120 4
## malignant 3 78
BC.LoR.Acc <- mean(BC.LoR.pred==BreastCancer$Class[BC.TsIdx])
BC.LoR.Acc
## [1] 0.9658537
로지스틱 회귀모형과 Random Forest의 예측성능이 가장 좋다.
BC.LoR.Acc # Logistic regression
## [1] 0.9658537
BC.TreeFit.Acc # Decision tree
## [1] 0.9414634
BC.TreePruned.Acc # Decision tree (pruning)
## [1] 0.9463415
BC.Bag.Acc # Bagging
## [1] 0.9609756
BC.RF.Acc # Random Forest
## [1] 0.9658537
BH.LM <- lm(medv~., data = BostonHousing[-BH.TsIdx, ])
BH.LM
##
## Call:
## lm(formula = medv ~ ., data = BostonHousing[-BH.TsIdx, ])
##
## Coefficients:
## (Intercept) crim zn indus chas1 nox
## 34.541276 -0.102680 0.038190 0.010701 2.170592 -18.288461
## rm age dis rad tax ptratio
## 3.908293 0.001806 -1.384502 0.259984 -0.008548 -0.928456
## b lstat
## 0.009673 -0.539785
BH.LM.pred <- predict(BH.LM, newdata = BostonHousing[BH.TsIdx, ])
plot(x=BH.LM.pred, y=BostonHousing$medv[BH.TsIdx])
BH.LM.MSE <- mean((BH.LM.pred-BostonHousing$medv[BH.TsIdx])^2)
BH.LM.MSE
## [1] 19.26122
Random Forest의 예측성능이 가장 좋으며 Bagging이 그 다음으로 좋다.
BH.LM.MSE # Linear model
## [1] 19.26122
BH.TreeFit.MSE # Decision tree
## [1] 18.81051
BH.Bag.MSE # Bagging
## [1] 11.43528
BH.RF.MSE # Random forest
## [1] 8.248459
ISLR 패키지에 있는 Carseats
데이터에서 유아 카시트
판매량를 분석해보려고 한다. 먼저 ISLR 패키지를 다운받는다. 이는 Gareth
James, Daniela Witten 등이 저술한 책 An
Introduction to Statistical Learning with Applications in R에서
다루는 데이터셋이 모여있는 패키지이다.
install.packages("ISLR")
Carseats
데이터는 400개의 매장에서 유아 카시트 판매량을
기록한 자료이다. (help(Carseats, package = "ISLR")
참고)
데이터는 아래와 같이 불어올 수 있다.
library(ISLR)
data(Carseats)
head(Carseats, n=3)
## Sales CompPrice Income Advertising Population Price ShelveLoc Age Education
## 1 9.50 138 73 11 276 120 Bad 42 17
## 2 11.22 111 48 16 260 83 Good 65 10
## 3 10.06 113 35 10 269 80 Medium 59 12
## Urban US
## 1 Yes Yes
## 2 Yes Yes
## 3 Yes Yes
먼저 Sales
변수는 연속형 변수이므로 regression tree를
적합하려고 한다. 다음 물음에 답하여라.
set.seed(2023217)
를 실행하여
random seed를 2023217로 고정한다.mtry
옵션을 바꿔가며 예측 오차가
어떻게 나오는지 살펴보아라.앞서 Sales
변수를 연속형 변수로 다뤘다면 이번에는 이를
전처리하여 새로운 High
라는 변수를 만들어 categorical tree를
적합하려고 한다. High
변수는 Sales
가 8 초과면
yes, 8 이하면 no로 정의된다.
High <- ifelse(Carseats$Sales <= 8, "No", "Yes")
Carseats.cat <- data.frame(Carseats, High)