의사 결정 나무(Tree Models)는 지니 불순도(Gini Impurity) 또는 정보 이득(Information Gain) 등의 기준을 사용하여 노드를 재귀적으로 분할하면서 나무 모델을 만드는 방법이다. 의사 결정 나무는 if-else의 조건문과 같은 형식이어서 이해하기 쉽고 속도가 빠르며, 여러 가지 피처 간의 상호 작용을 잘 표현해주고 다양한 데이터 유형에 사용할 수 있다는 장점이 있다. 특히 나무 모델 중 랜덤 포레스트(Random Forest)는 꽤 괜찮은 성능을 보여주어 기계 학습 대회가 열리는 Kaggle(http://www.kaggle.com/)에서도 가장 기본이 되는 알고리즘으로 자주 제시된다.
이 절에서는 의사 결정 나무의 기본 개념을 살펴보고 rpart, ctree, randomForest 패키지를 사용한 모델링 및 예측에 대해 알아본다.
의사 결정 나무 모델
의사 결정 나무는 데이터의 특징에 대한 질문을 하면서 응답에 따라 데이터를 분류해가는 알고리즘이다. 예를 들어, 그림 10-1은 다양한 도형을 분류하는 의사 결정 나무의 예다.
그림 10-1에서 검은색 원은 나무의 최상단으로부터 “사각형인가?”라는 질문에 No, “원인가?”라는 질문에 Yes, “검은색인가?”라는 질문에 Yes라는 대답에 의해 검은색 원만 포함된 그룹으로 분류된다. 마찬가지로 흰색 삼각형은 “사각형인가?”라는 질문에 No, “원인가?”라는 질문에 No라는 대답에 의해 흰색 삼각형만 포함된 그룹으로 분류된다.
각 단계에서의 질문은 상위 단계의 질문과 연관성이 있다. 예를 들어, 검은색 원을 분류해내는 마지막 질문인 “검은색인가?”라는 질문은 “원인가?”라는 질문에 대한 대답이 Yes인 경우에 이어지는 질문이다. 따라서 “검은색인가?”라는 질문은 모양에 대한 질문과 연관성이 있다. 이런 특징 때문에 나무 모델은 피처의 연관성을 잘 표현한다고 한다.
노드를 나누는 기준
그림 10-1에서 원, 삼각형, 사각형과 같은 도형이 그려진 곳을 노드(Node)라 한다. 노드 중 분류의 시작점에 해당하는 최상단에 위치한 노드를 뿌리 노드(루트 노드,Root Node), 더 이상 자식 노드가 없는 제일 하단의 노드를 잎사귀 노드(리프 노드,Leaf Node)라 한다.
의사 결정 나무는 각 노드마다 질문을 던지고 그 응답에 따라 가지를 쳐서 데이터를 분리한다. 데이터가 얼마나 잘 분리되었는지는 불순도(impurity)라는 기준으로 평가하며, 가장 좋은 질문은 한 노드의 데이터를 두 개의 자식 노드로 분리했을 때 자식 노드들의 불순도가 가장 낮아지는 질문이다.
불순도는 노드에 여러 분류가 섞여 있을수록 높다. 반면 하나의 분류만 있다면 낮다. 예를 들어, 그림 10-1의 뿌리 노드에는 원, 삼각형, 사각형, 검은색 사각형, 검은색 원이 섞여 있어 불순도가 높지만, 가장 오른쪽 아래 노드에는 흰색 원만 두 개가 있어 불순도가 낮다.
불순도 함수 f가 있다고 할 때 노드 A의 불순도 I(A)는 다음과 같이 정의한다.
이 식에서 C는 분류의 개수며, P_(iA)는 노드 A에 속한 분류 i인 표본의 비율이다.
가장 흔히 사용하는 불순도 함수는 지니 불순도(Gini Impurity)로, 다음과 같이 정의된다.
지니 불순도는 p=0 또는 p=1일 때 0이며 p=1/2일 때 가장 큰 값을 가지는 포물선이다. 지니 불순도를 식 10-2와 연관해서 생각해보면 노드에 특정 분류 i만 있거나 특정 분류 i가 전혀 없을 때 I(A)가 작은 값을 가지며, 여러 분류가 섞여 있을 때 큰 값을 갖게 된다. 그림 10-2에 지니 불순도 곡선을 보였다.
분류와 회귀 나무
여기서는 의사 결정 나무를 만드는 패키지 중 rpart를 사용하도록 한다. rpart는 잘 알려진 분류와 회귀 나무(CART, Classification and Regression Trees)의 아이디어를 구현한 패키지다.
-rpart::rpart : 재귀적 분할 및 회귀 나무(Recursive Partitioning and Regression Trees)를 생성한다.
rpart::rpart(
formula, # 모델 포뮬러
data, # 포뮬러를 적용할 데이터
)
-rpart::predict.rpart : rpart를 사용한 예측을 수행한다.
rpart::predict.rpart(
object, # rpart 객체
newdata, # 예측을 수행할 데이터
# 예측 결과 유형. prob(각 분류에 대한 확률), class(예측된 분류) 정도가 유용하다.
type=c("vector", "prob", "class", "matrix")
)
-rpart::plot.rpart : rpart를 그래프로 그린다.
rpart::plot.rpart(
x, # rpart 객체
# 노드 간격. uniform이 TRUE면 노드 간의 간격이 일정하게 그려지며,
# FALSE면 노드마다 에러에 비례한 간격이 주어진다.
uniform=FALSE,
# 가지 모양을 정하는 숫자로 0~1 값. 1은 사각형, 0은 V자 모양이다.
branch=1,
compress=FALSE, # TRUE면 나무를 좀 더 빽빽하게 그린다.
nspace, # 노드와 자식 노드 간의 간격
margin=1, # 의사 결정 나무를 그렸을 때 그림의 주변부에 위치한 잎사귀 노드에 추가로 부여할 여백
-rpart.plot::prp : rpart를 그래프로 그린다(plot.rpart보다 나은 그래프를 그린다).
rpart.plot::prp(
x, # rpart 객체
type=0, # 그림의 유형
extra=0, # 노드에 표시할 추가 정보의 유형
digits=2 # 표시할 숫자의 유효 자리
)
다음은 아이리스 데이터에 대해 rpart( )를 사용해 의사 결정 나무를 작성한 예다.
> install.packages("rpart")
> library(rpart)
> (m <- rpart(Species ~., data=iris))
n= 150
node), split, n, loss, yval, (yprob)
+ denotes terminal node
1) root 150 100 setosa (0.33 0.33 0.33)
2) Petal.Length< 2.45 50 0 setosa (1.00 0.00 0.00) *
3) Petal.Length>=2.45 100 50 versicolor (0.00 0.50 0.50)
6) Petal.Width< 1.75 54 5 versicolor (0.00 0.90 0.09) *
7) Petal.Width>=1.75 46 1 virginica (0.00 0.02 0.97) *
결과 화면에서 첫 행의 ‘n= 150’은 150개의 데이터가 있었음을 의미한다. 하단에는 의사 결정 나무가 표현되어 있는데, 들여쓰기는 가지가 갈라지는 모양을 뜻한다. *은 잎사귀 노드를 의미한다. 트리의 최상단인 뿌리 노드는 위 결과에 ‘1)’로 표시되어 있다. 각 노드에서 괄호 안에 표시된 세 숫자는 아이리스의 Species별 비율을 의미한다.
‘2)’는 뿌리 노드에서 좌측 가지 밑에 위치한 노드를 뜻한다. 이 가지로 가는 기준은 Petal.Length < 2.45다. 이 기준을 만족하는 경우는 setosa뿐이었고 이 노드에는 총 50개 데이터가 속한다.
좀 더 아래쪽의 ‘6)’은 잎사귀 노드로 Petal.Width < 1.75인 경우 3번 노드에서 좌측으로 갈라지는 가지 밑에 위치한다. 이 노드에서는 54개 데이터가 versicolor로 분류되었다.
모델을 좀 더 쉽게 보려면 plot( )을 사용한다. 다음 코드의 다양한 인자들은 트리가 좀 더 잘 보이게 조절하려고 사용한 것이다. compress는 나무를 좀 더 조밀하게 그린 것이고, margin은 여백, cex는 글자의 크기를 뜻한다. 그림 10-3에 실행 결과를 보였다.
> plot(m, compress=TRUE, margin=.2)
> text(m, cex=1.5)
그림 10-3을 통해 만들어진 트리의 의미를 볼 수는 있지만 그림에서 무언가 부족한 느낌이다. 이를 해결해주는 패키지가 rpart.plot이며, prp( ) 함수를 통해 다양한 시각화를 제공한다. 아래 코드는 prp( )를 사용해 rpart를 시각화한 예로, type=4를 지정해 모든 노드에 레이블을 붙였으며 extra=2를 지정해 각 노드에서의 관측값과 각 노드에서 올바르게 예측된 데이터의 비율을 출력했다. 그림 10-4는 실행 결과를 보여준다.
> install.packages("rpart.plot")
> library(rpart.plot)
> prp(m, type=4, extra=2, digits=3)
그림 10-4를 보면 Petal.Length < 2.45인 경우에 붓꽃의 종이 setosa로 예측되며, 이에 해당하는 50개 데이터 모두가 실제로 setosa임을 알 수 있다. 마찬가지로 Petal.Length >= 2.45, Petal.Width < 1.75인 경우 붓꽃의 종이 versicolor로 예측되는데, 이 조건에 해당하는 54개 데이터 중 49개가 실제로 versicolor였음을 알 수 있다.
rpart( )를 사용한 예측 역시 predict( )를 통해 수행한다. 다음은 붓꽃의 종을 type=“class”를 지정해 출력한 예다.
> head(predict(m, newdata=iris, type="class"))
1 2 3 4 5 6
setosa setosa setosa setosa setosa setosa
Levels: setosa versicolor virginica
지금까지 설명한 내용 외에도 rpart에는 과적합을 피하기 위한 가지치기pruning 함수인 prune.rpart( ), 나무 모델 생성에 대한 다양한 제어를 가능하게 하는 rpart.control( ) 등 다양한 성능 튜닝 함수가 있다. 더 자세한 내용은 CRAN의 rpart 페이지를 참고하기 바란다.
조건부 추론 나무
조건부 추론 나무(Conditional Inference Tree)는 CART(rpart가 구현한 의사 결정 나무 알고리즘) 같은 의사 결정 나무의 두 가지 문제를 해결한다. 첫째는 통계적 유의성에 대한 판단 없이 노드를 분할하는 데 따른 과적합(Overfitting)이다. 둘째는 다양한 값으로 분할 가능한 변수가 다른 변수에 비해 선호되는 문제다.
조건부 추론 나무는 조건부 분포(Conditional Distribution)에 따라 변수와 반응값(분류) 사이의 연관 관계를 측정하여 노드 분할에 사용할 변수를 선택한다. 또, 의사 결정 나무에서 노드를 반복하여 분할하면서 발생하는 문제인 다중 가설 검정(Multiple Testing)을 고려한 절차를 적용하여 적절한 시점에 노드의 분할을 중단한다.
따라서 rpart가 과적합 등의 이유로 성능이 잘 나오지 않는 경우 조건부 추론 나무를 사용해 효과를 볼 수 있다. 또, 조건부 추론 나무는 rpart보다 훨씬 이해하기 쉬운 그래프 기능을 제공하는 장점이 있다.
party::ctree( ) 함수가 조건부 추론 나무 기능을 제공한다.
-party::ctree : 조건부 추론 나무 모델을 생성한다.
party::ctree(
formula, # 모델 포뮬러
data # 포뮬러를 적용할 데이터
)
-party::predict.BinaryTree : ctree를 사용한 예측을 수행한다.
party::predict.BinaryTree(
obj, # BinaryTree 객체
newdata, # 예측을 수행할 데이터
# 예측 결과의 유형
# - response: 분류
# - node: 잎사귀 노드의 ID
# - prob: 각 분류에 대한 확률
type=c("response", "node", "prob")
)
아이리스 데이터에 ctree( )를 적용하여 Species 예측 모델을 만들어보자.
> install.packages("party")
> library(party)
> (m <- ctree(Species ~., data=iris))
Conditional inference tree with 4 terminal nodes
Response: Species
Inputs: Sepal.Length, Sepal.Width, Petal.Length, Petal.Width
Number of observations: 150
1) Petal.Length <= 1.9; criterion = 1, statistic = 140.264
2)* weights = 50
1) Petal.Length > 1.9
3) Petal.Width <= 1.7; criterion = 1, statistic = 67.894
4) Petal.Length <= 4.8; criterion = 0.999, statistic = 13.865
5)* weights = 46
4) Petal.Length > 4.8
6)* weights = 8
3) Petal.Width > 1.7
7)* weights = 46
만들어진 모델은 plot( )을 사용해 그림 10-5와 같이 보기 좋은 결과물로 얻을 수 있다.
> plto(m)
ctree( )의 결과 그림은 잎사귀 노드의 최종 분류 결과가 무엇이었는지, 또 만약 잘못 분류된 경우가 있다면 어느 정도인지를 알려주어 모델을 개선하는 데 도움을 준다. 예를 들어, 그림 10-5에서는 Node 6에 총 8개의 결과가 있는데(n=8), 이때 virginica, versicolor가 거의 동일한 숫자로 나타난 것을 알 수 있다. 따라서 이 경우를 개선하기 위한 피처나 모델을 개발한다면 성능을 더 향상시킬 수 있다.
노드 5의 경우 setosa 다음 종의 막대 그래프가 가장 높으나 그 종이 무엇인지는 그림으로 식별이 불가능하다. 두 번째 종은 iris$Species의 레벨을 확인하면 versicolor임을 알 수 있다.
> levels(iris$Species)
[1] "setosa" "versicolor" "virginica"
랜덤 포레스트
랜덤 포레스트(Random Forest)는 앙상블(Ensemble) 학습 기법을 사용한 모델이다. 앙상블 학습은 주어진 데이터로부터 여러 개의 모델을 학습한 다음, 예측 시 여러 모델의 예측 결과들을 종합해 사용하여 정확도를 높이는 기법을 말한다.
랜덤 포레스트는 두 가지 방법을 사용해 다양한 의사 결정 나무를 만든다. 첫 번째는 의사 결정 나무를 만들 때 데이터의 일부를 복원 추출로 꺼내고 해당 데이터에 대해서만 의사 결정 나무를 만드는 방식이다. 즉, 각 의사 결정 나무는 데이터의 일부만을 사용해 만들어진다. 두 번째는 노드 내 데이터를 자식 노드로 나누는 기준을 정할 때 전체 변수가 아니라 일부 변수만 대상으로 하여 가지를 나눌 기준을 찾는 방법이다.
새로운 데이터에 대한 예측을 수행할 때는 여러 개의 의사 결정 나무가 내놓은 예측 결과를 투표(voting) 방식으로 합한다. 예를 들어, 총 5개의 의사 결정 나무 중 Y를 예측한 나무가 3개, N을 예측한 나무가 2개면 Y를 최종 결과로 결정하는 방식이다.
랜덤 포레스트는 일반적으로 성능이 뛰어나고 의사 결정 나무 하나가 아니라 여러 개를 사용해 과적합 문제를 피한다.
R의 randomForest는 랜덤 포레스트를 구현한 패키지다.
-randomForest::randomForest : 랜덤 포레스트를 생성한다.
randomForest::randomForest(
formula, # 모델 포뮬러
data, # 포뮬러를 적용할 데이터
ntree=500, # 나무의 개수
mtry, # 노드를 나눌 기준을 정할 때 고려할 변수의 수
importance=FALSE # 변수의 중요도 평가 여부
)
-randomForest::predict.randomForest : randomForest를 사용한 예측을 수행한다.
randomForest::predict.randomForest(
object, # randomForest 객체
newdata, # 예측을 수행할 데이터
# 예측 결과의 유형
# - response: 예측값
# - prob: 예측 확률의 행렬
# - vote: 투표 결과 행렬
type=c("response", "prob", "vote")
)
-randomForest::importance : randomForest로부터 변수 중요도를 출력한다.
randomForest::importance(
x, # randomForest 모델
# 출력할 변수 중요도 유형으로 1은 정확도(Accuracy), 2는 노드 불순도로 변수 중요도를 표시한다.
# type이 지정되지 않으면 정확도, 불순도 모두에 대한 중요도가 출력된다.
type=NULL
)
-randomForest::varImpPlot : 변수 중요도의 그래프를 그린다.
randomForest::varImpPlot(
x,
type=NULL
)
랜덤 포레스트를 사용한 모델링
아이리스 데이터에 랜덤 포레스트 모델을 만들어보자.
> install.packages("randomForest")
> library(randomForest)
> m <- randomForest(Species ~., data=iris)
랜덤 포레스트는 여러 개의 의사 결정 나무로 구현되고, 각 의사 결정 나무는 데이터의 일부만 사용함을 앞에서 설명했다. 랜덤 포레스트 모델을 출력하면 모델 훈련에 사용되지 않은 데이터를 사용한 에러 추정치가 ‘OOB(Out of Bag )estimate of error rate’ 항목으로 출력된다. 아이리스에 대한 모델에서는 OOB 에러가 4%였으며 versicolor가 virginica로 예측된 경우가 3개, virginica가 versicolor로 예측된 경우가 3개 있었다.
> m
Call:
randomForest(x = iris[, 1:4], y = iris[, 5])
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 4%
Confusion matrix:
setosa versicolor virginica class.error
setosa 50 0 0 0.00
versicolor 0 47 3 0.06
virginica 0 3 47 0.06
예측에는 predict( ) 함수를 사용한다.
> head(predict(m, newdata=iris))
1 2 3 4 5 6
setosa setosa setosa setosa setosa setosa
Levels: setosa versicolor virginica
빠른 모델링을 위한 X와 Y의 직접 지정
랜덤 포레스트는 500개의 의사 결정 나무를 만든다. 따라서 모델링에 걸리는 시간이 길고 데이터의 양이 많아지면 ‘모델을 더 빨리 만들 수는 없을까?’라는 의문이 든다.
모델을 더 빨리 만드는 방법 중 하나는 포뮬러 대신 설명 변수(X), 종속 변수(Y)를 직접 지정하는 것이다. 포뮬러를 사용한 표현이 편리해 보이지만 (X, Y) 형태로 변수를 지정하는 경우에 비해 많은 메모리를 필요로 하고 속도가 더 느리다고 알려져 있다.
포뮬러 대신 변수를 직접 지정하는 방식은 randomForest( )를 비롯한 몇몇 모델링 함수에서 지원하므로 각 모델링 함수의 도움말을 잘 살펴보기 바란다. 다음은 Species를 Y, 그 외의 변수를 X로 하여 randomForest( )에 직접 지정한 예다.
> m <- randomForest(iris[,1:4], iris[,5])
변수 중요도 평가
‘9.2.3 변수 선택’ 절에서는 모델링에 사용할 변수를 선택하는 방법에 대해 살펴봤다. randomForest( ) 역시 변수의 중요도를 평가하고 모델링에 사용할 변수를 선택하는 데 사용할 수 있다. randomForest( )의 변수 중요도는 변수가 정확도와 노드 불순도 개선에 얼마만큼 기여하는지로 측정된다. 이렇게 구한 변수 중요도는 다른 모델(예를 들면, 선형 회귀)에 사용할 변수를 선택하는 데 사용할 수 있다. 즉, 이 방법은 변수 선택 방법 중 필터 방법이다.
변수의 중요도를 알아보려면 모델 작성 시 randomForest( )에 importance=TRUE를 지정한다. 그런 다음 importance( ), varImpPlot( )을 사용해 결과를 출력한다.
다음은 iris에 대한 랜덤 포레스트로부터 변수 중요도를 평가한 결과이다. 정확도(MeanDecreaseAccuracy)에서는 Petal.Length, Petal.Width, Sepal.Length, Sepal.Width 순으로 변수가 중요함을 알 수 있다. 노드 불순도 개선(MeanDecreaseGini)에서는 Petal.Width, Petal.Length, Sepal.Length, Sepal.Width 순으로 중요했다. 다수의 의사 결정 나무로부터 변수가 정확도와 노드 불순도 개선에 기여하는 측면을 평가하므로 평균(Mean)이 언급되어 있다.
> m <- randomForest(Species ~., data=iris, importance=TRUE)
> importance(m)
setosa versicolor virginica MeanDecreaseAccuracy MeanDecreaseGini
Sepal.Length 8.096178 8.1576978 10.0032189 12.3376347 11.8656862
Sepal.Width 7.182722 4.3372199 4.0146802 7.8337839 4.7586299
Petal.Length 22.382124 30.7347219 27.5662669 33.3958590 40.6587953
Petal.Width 21.428179 31.2740902 30.3960074 33.0973498 41.4712351
Species2 1.001002 -0.1758135 -0.6955584 -0.5352205 0.3564135
varImpPlot( )을 사용해 이를 그림으로 좀 더 쉽게 알아볼 수 있다.
> varImpPlot(m, main="varImpPlot of iris")
정규화 랜덤 포레스트(RRF, Regularized Random Forest)는 랜덤 포레스트를 개선한 변수 선택 방법으로, 부모 노드에서 가지를 나눌 때 사용한 변수와 유사한 변수로 자식 노드에서 가지를 나눌 경우 해당 변수에 패널티를 부여한다. 이 방식은 랜덤 포레스트를 직접 변수 선택에 사용하는 경우에 비해 좋은 변수들을 선택해주는 것으로 알려져 있다. 관심 있는 독자는 RRF 패키지를 사용해보기 바란다.
파라미터 튜닝
randomForest( )에는 나무 개수(ntree), 각 노드를 자식 노드로 나누는 기준을 정할 때 고려할 변수의 개수(mtry) 등의 파라미터가 있다. ntree나 mtry는 기본값이 자동으로 잘 부여되지만 모델 성능을 더욱 개선하고 싶다면 이 값들을 조절해볼 수 있다. 이들 파라미터를 정하는 한 가지 방법은 교차 검증을 사용하는 것이다.
ntree와 mtry의 다양한 조합에 대해 모델 성능을 평가해보자. 조합의 목록은 expand.grid( )로 만든다.
-expand.grid : 가능한 모든 팩터 레벨의 조합을 만든다.
expand.grid(
... # 벡터, Factor 또는 이들을 저장한 리스트
)
다음은 ntree를 10, 100, 200으로, mtry를 3, 4로 바꿔가면서 조합한 예다.
> (grid <- expand.grid(ntree=c(10, 100, 200), mtry=c(3, 4)))
ntree mtry
1 10 3
2 100 3
3 200 3
4 10 4
5 100 4
6 200 4
파라미터 조합을 10개로 분할한 데이터에 적용하여 모델의 성능을 평가하는 일을 3회 반복하여 최선의 파라미터를 찾아보자.
library(cvTools)
library(foreach)
library(randomForest)
set.seed(719)
K = 10
R = 3
cv <- cvFolds(NROW(iris), K=K, R=R)
grid <- expand.grid(ntree=c(10, 100, 200), mtry=c(3, 4))
result <- foreach(g=1:NROW(grid), .combine=rbind) %do% {
foreach(r=1:R, .combine=rbind) %do% {
foreach(k=1:K, .combine=rbind) %do% {
validation_idx <- cv$subsets[which(cv$which == k), r]
train <- iris[-validation_idx, ]
validation <- iris[validation_idx, ]
# 모델 훈련
m <- randomForest(Species ~.,
data=train,
ntree=grid[g, "ntree"],
mtry=grid[g, "mtry"])
# 예측
predicted <- predict(m, newdata=validation)
# 성능 평가
precision <- sum(predicted == validation$Species) / NROW(predicted)
return(data.frame(g=g, precision=precision))
}
}
}
코드에서 foreach 문의 .combine에 rbind를 사용한 점을 눈여겨보기 바란다. foreach( )에 .combine을 지정하지 않으면 반환 값이 리스트 형태가 된다. 여기서는 결과를 데이터 프레임으로 모으려고 rbind를 사용했다. 코드 수행 결과 result에 grid에서의 색인과 성능이 데이터 프레임으로 반환된다.
> result
g precision
1 1 1.0000000
2 1 1.0000000
3 1 0.9333333
4 1 0.9333333
5 1 1.0000000
...
176 6 0.9333333
177 6 0.9333333
178 6 0.9333333
179 6 0.9333333
180 6 1.0000000
g 값마다 묶어 성능의 평균을 구해보자. ddply( )를 사용한다.
> library(plyr)
> ddply(result, .(g), summarize, mean_precision=mean(precision))
g mean_precision
1 1 0.9444444
2 2 0.9533333
3 3 0.9533333
4 4 0.9555556
5 5 0.9533333
6 6 0.9555556
가장 높은 성능을 보인 조합은 g=4일 때와 g=6일 때다. 파라미터 조합을 grid에서 찾아보면 ntree=10, mtry=4인 경우와 ntree=200, mtry=4인 경우임을 알 수 있다.
> grid[c(4, 6), ]
ntree mtry
4 10 4
6 200 4
R을 이용한 데이터 처리&분석 실무 中
'R > R을 이용한 데이터 처리&분석 실무' 카테고리의 다른 글
서포트 벡터 머신 (0) | 2020.02.13 |
---|---|
신경망 (0) | 2020.02.12 |
다항 로지스틱 회귀 분석 (0) | 2020.02.12 |
로지스틱 회귀 모델 (0) | 2020.02.12 |
모델 평가 방법 - 2 (0) | 2020.02.11 |