R의 결정 트리: 예제가 포함된 분류 트리
의사결정나무란 무엇입니까?
의사 결정 트리 분류 및 회귀 작업을 모두 수행할 수 있는 다재다능한 머신 러닝 알고리즘입니다. 매우 강력한 알고리즘으로 복잡한 데이터 세트를 피팅할 수 있습니다. 게다가, 의사결정 트리는 랜덤 포레스트의 기본 구성 요소로, 오늘날 사용 가능한 가장 강력한 머신 러닝 알고리즘 중 하나입니다.
R의 의사결정 트리 훈련 및 시각화
R 예제에서 첫 번째 결정 트리를 구축하기 위해 이 결정 트리 튜토리얼에서는 다음과 같이 진행합니다.
- 1단계: 데이터 가져오기
- 2단계: 데이터 세트 정리
- 3단계: 학습/테스트 세트 만들기
- 4단계: 모델 구축
- 5단계: 예측하기
- 6단계: 성능 측정
- 7단계: 초매개변수 조정
1단계) 데이터 가져오기
타이타닉의 운명이 궁금하다면 다음 영상을 시청하세요. 유튜브. 이 데이터 세트의 목적은 빙산과의 충돌 후 어떤 사람들이 생존 가능성이 더 높은지 예측하는 것입니다. 데이터 세트에는 13개의 변수와 1309개의 관측치가 포함되어 있습니다. 데이터 세트는 변수 X를 기준으로 정렬됩니다.
set.seed(678) path <- 'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/titanic_data.csv' titanic <-read.csv(path) head(titanic)
출력:
## X pclass survived name sex ## 1 1 1 1 Allen, Miss. Elisabeth Walton female ## 2 2 1 1 Allison, Master. Hudson Trevor male ## 3 3 1 0 Allison, Miss. Helen Loraine female ## 4 4 1 0 Allison, Mr. Hudson Joshua Creighton male ## 5 5 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female ## 6 6 1 1 Anderson, Mr. Harry male ## age sibsp parch ticket fare cabin embarked ## 1 29.0000 0 0 24160 211.3375 B5 S ## 2 0.9167 1 2 113781 151.5500 C22 C26 S ## 3 2.0000 1 2 113781 151.5500 C22 C26 S ## 4 30.0000 1 2 113781 151.5500 C22 C26 S ## 5 25.0000 1 2 113781 151.5500 C22 C26 S ## 6 48.0000 0 0 19952 26.5500 E12 S ## home.dest ## 1 St Louis, MO ## 2 Montreal, PQ / Chesterville, ON ## 3 Montreal, PQ / Chesterville, ON ## 4 Montreal, PQ / Chesterville, ON ## 5 Montreal, PQ / Chesterville, ON ## 6 New York, NY
tail(titanic)
출력:
## X pclass survived name sex age sibsp ## 1304 1304 3 0 Yousseff, Mr. Gerious male NA 0 ## 1305 1305 3 0 Zabour, Miss. Hileni female 14.5 1 ## 1306 1306 3 0 Zabour, Miss. Thamine female NA 1 ## 1307 1307 3 0 Zakarian, Mr. Mapriededer male 26.5 0 ## 1308 1308 3 0 Zakarian, Mr. Ortin male 27.0 0 ## 1309 1309 3 0 Zimmerman, Mr. Leo male 29.0 0 ## parch ticket fare cabin embarked home.dest ## 1304 0 2627 14.4583 C ## 1305 0 2665 14.4542 C ## 1306 0 2665 14.4542 C ## 1307 0 2656 7.2250 C ## 1308 0 2670 7.2250 C ## 1309 0 315082 7.8750 S
헤드 및 테일 출력에서 데이터가 섞이지 않은 것을 확인할 수 있습니다. 이것은 큰 문제입니다! 기차 세트와 테스트 세트 간에 데이터를 분할할 때 다음을 선택합니다. 만 클래스 1과 2의 승객(클래스 3의 승객은 관찰의 상위 80%에 포함되지 않음)은 알고리즘이 클래스 3의 승객의 특징을 결코 볼 수 없음을 의미합니다. 이러한 실수는 잘못된 예측으로 이어질 것입니다.
이 문제를 극복하기 위해 샘플() 함수를 사용할 수 있습니다.
shuffle_index <- sample(1:nrow(titanic)) head(shuffle_index)
의사결정트리 R 코드 설명
- Sample(1:nrow(titanic)): 1부터 1309까지(즉, 최대 행 수) 인덱스의 무작위 목록을 생성합니다.
출력:
## [1] 288 874 1078 633 887 992
이 인덱스를 사용하여 타이타닉 데이터 세트를 섞습니다.
titanic <- titanic[shuffle_index, ] head(titanic)
출력:
## X pclass survived ## 288 288 1 0 ## 874 874 3 0 ## 1078 1078 3 1 ## 633 633 3 0 ## 887 887 3 1 ## 992 992 3 1 ## name sex age ## 288 Sutton, Mr. Frederick male 61 ## 874 Humblen, Mr. Adolf Mathias Nicolai Olsen male 42 ## 1078 O'Driscoll, Miss. Bridget female NA ## 633 Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren) female 39 ## 887 Jermyn, Miss. Annie female NA ## 992 Mamee, Mr. Hanna male NA ## sibsp parch ticket fare cabin embarked home.dest## 288 0 0 36963 32.3208 D50 S Haddenfield, NJ ## 874 0 0 348121 7.6500 F G63 S ## 1078 0 0 14311 7.7500 Q ## 633 1 5 347082 31.2750 S Sweden Winnipeg, MN ## 887 0 0 14313 7.7500 Q ## 992 0 0 2677 7.2292 C
2단계) 데이터세트 정리
데이터의 구조는 일부 변수에 NA가 있음을 보여줍니다. 데이터 정리는 다음과 같이 수행됩니다.
- 변수 home.dest,cabin, name, X 및 ticket 삭제
- pclass에 대한 요인 변수를 생성하고 생존했습니다.
- NA를 버리세요
library(dplyr) # Drop variables clean_titanic <- titanic % > % select(-c(home.dest, cabin, name, X, ticket)) % > % #Convert to factor level mutate(pclass = factor(pclass, levels = c(1, 2, 3), labels = c('Upper', 'Middle', 'Lower')), survived = factor(survived, levels = c(0, 1), labels = c('No', 'Yes'))) % > % na.omit() glimpse(clean_titanic)
코드 설명
- select(-c(home.dest, Cabin, name, X, ticket)): 불필요한 변수 삭제
- pclass = Factor(pclass, level = c(1,2,3), labels= c('Upper', 'Middle', 'Lower')): 변수 pclass에 레이블을 추가합니다. 1은 Upper, 2는 Middle, 3은 Lower가 됩니다.
- Factor(survived,levels = c(0,1), labels = c('No', 'Yes')): 살아남은 변수에 레이블을 추가합니다. 1은 아니요가 되고 2는 예가 됩니다.
- na.omit(): NA 관찰을 제거합니다.
출력:
## Observations: 1,045 ## Variables: 8 ## $ pclass <fctr> Upper, Lower, Lower, Upper, Middle, Upper, Middle, U... ## $ survived <fctr> No, No, No, Yes, No, Yes, Yes, No, No, No, No, No, Y... ## $ sex <fctr> male, male, female, female, male, male, female, male... ## $ age <dbl> 61.0, 42.0, 39.0, 49.0, 29.0, 37.0, 20.0, 54.0, 2.0, ... ## $ sibsp <int> 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 1, 1,... ## $ parch <int> 0, 0, 5, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 4, 0,... ## $ fare <dbl> 32.3208, 7.6500, 31.2750, 25.9292, 10.5000, 52.5542, ... ## $ embarked <fctr> S, S, S, S, S, S, S, S, S, C, S, S, S, Q, C, S, S, C...
3단계) 열차/테스트 세트 생성
모델을 훈련하기 전에 다음 두 단계를 수행해야 합니다.
- 기차 및 테스트 세트 만들기: 기차 세트에서 모델을 훈련하고 테스트 세트(즉, 보이지 않는 데이터)에서 예측을 테스트합니다.
- 콘솔에서 rpart.plot 설치
일반적인 관행은 데이터를 80/20으로 분할하는 것입니다. 데이터의 80%는 모델을 훈련하는 데 사용되며 20%는 예측에 사용됩니다. 두 개의 별도 데이터 프레임을 생성해야 합니다. 모델 구축을 마칠 때까지 테스트 세트를 건드리고 싶지 않습니다. 세 개의 인수를 사용하는 함수 이름 create_train_test()를 만들 수 있습니다.
create_train_test(df, size = 0.8, train = TRUE) arguments: -df: Dataset used to train the model. -size: Size of the split. By default, 0.8. Numerical value -train: If set to `TRUE`, the function creates the train set, otherwise the test set. Default value sets to `TRUE`. Boolean value.You need to add a Boolean parameter because R does not allow to return two data frames simultaneously.
create_train_test <- function(data, size = 0.8, train = TRUE) { n_row = nrow(data) total_row = size * n_row train_sample < - 1: total_row if (train == TRUE) { return (data[train_sample, ]) } else { return (data[-train_sample, ]) } }
코드 설명
- function(data, size=0.8, train = TRUE): 함수에 인수를 추가합니다.
- n_row = nrow(data): 데이터세트의 행 수를 계산합니다.
- total_row = size*n_row: 기차 세트를 구성하기 위해 n번째 행을 반환합니다.
- train_sample <- 1:total_row : 첫 번째 행부터 n번째 행까지 선택
- if (train ==TRUE){ } else { }: 조건이 true로 설정되면 열차 세트를 반환하고 그렇지 않으면 테스트 세트를 반환합니다.
기능을 테스트하고 치수를 확인할 수 있습니다.
data_train <- create_train_test(clean_titanic, 0.8, train = TRUE) data_test <- create_train_test(clean_titanic, 0.8, train = FALSE) dim(data_train)
출력:
## [1] 836 8
dim(data_test)
출력:
## [1] 209 8
기차 데이터세트에는 1046개의 행이 있고 테스트 데이터세트에는 262개의 행이 있습니다.
무작위화 프로세스가 올바른지 확인하려면 table()과 결합된 prop.table() 함수를 사용합니다.
prop.table(table(data_train$survived))
출력:
## ## No Yes ## 0.5944976 0.4055024
prop.table(table(data_test$survived))
출력:
## ## No Yes ## 0.5789474 0.4210526
두 데이터세트 모두 생존자 수는 약 40%로 동일합니다.
rpart.plot 설치
rpart.plot은 conda 라이브러리에서 사용할 수 없습니다. 콘솔에서 설치할 수 있습니다.
install.packages("rpart.plot")
4단계) 모델 구축
모델을 구축할 준비가 되었습니다. Rpart 의사결정 트리 함수의 구문은 다음과 같습니다.
rpart(formula, data=, method='') arguments: - formula: The function to predict - data: Specifies the data frame- method: - "class" for a classification tree - "anova" for a regression tree
클래스를 예측하기 때문에 클래스 방법을 사용합니다.
library(rpart) library(rpart.plot) fit <- rpart(survived~., data = data_train, method = 'class') rpart.plot(fit, extra = 106
코드 설명
- rpart(): 모델을 피팅하는 함수입니다. 인수는 다음과 같습니다.
- 살아남았다 ~.: 의사결정나무의 공식
- data = data_train: 데이터세트
- method = 'class': 이진 모델 피팅
- rpart.plot(fit, extra= 106): 트리를 그립니다. 추가 기능은 101차 클래스의 확률을 표시하기 위해 2로 설정됩니다(이진 응답에 유용함). 당신은 소품 다른 선택 사항에 대한 자세한 내용은
출력:
루트 노드(그래프 상단, 깊이 0/3)에서 시작합니다.
- 맨 위에는 전반적인 생존 확률이 있습니다. 이는 충돌 사고에서 살아남은 승객의 비율을 보여줍니다. 승객 중 41%가 생존했다.
- 이 노드는 승객의 성별이 남성인지 여부를 묻습니다. 그렇다면 루트의 왼쪽 하위 노드(깊이 2)로 이동합니다. 63%는 남성이고 생존 확률은 21%입니다.
- 두 번째 노드에서는 남성 승객이 3.5세 이상인지 묻습니다. 그렇다면 생존 확률은 19%다.
- 어떤 기능이 생존 가능성에 영향을 미치는지 이해하기 위해 계속 그렇게 진행합니다.
의사결정나무의 많은 특성 중 하나는 데이터 준비가 거의 필요하지 않다는 것입니다. 특히 기능 확장이나 센터링이 필요하지 않습니다.
기본적으로 rpart() 함수는 지니 노트를 분할하기 위한 불순물 측정. 지니 계수가 높을수록 노드 내 인스턴스가 더 다양해집니다.
5단계) 예측하기
테스트 데이터 세트를 예측할 수 있습니다. 예측을 하려면 예측() 함수를 사용할 수 있습니다. R 의사 결정 트리에 대한 예측의 기본 구문은 다음과 같습니다.
predict(fitted_model, df, type = 'class') arguments: - fitted_model: This is the object stored after model estimation. - df: Data frame used to make the prediction - type: Type of prediction - 'class': for classification - 'prob': to compute the probability of each class - 'vector': Predict the mean response at the node level
테스트 세트를 통해 충돌 후 생존 가능성이 더 높은 승객을 예측하려고 합니다. 즉, 209명의 승객 중 누가 살아남을지 말지 알 수 있다는 뜻입니다.
predict_unseen <-predict(fit, data_test, type = 'class')
코드 설명
- 예측(fit, data_test, type = 'class'): 테스트 세트의 클래스(0/1)를 예측합니다.
도착하지 못한 승객과 성공한 승객을 테스트합니다.
table_mat <- table(data_test$survived, predict_unseen) table_mat
코드 설명
- table(data_test$survived, Predict_unseen): R의 올바른 의사결정 트리 분류와 비교하여 생존자로 분류되고 사망한 승객 수를 계산하는 테이블을 생성합니다.
출력:
## predict_unseen ## No Yes ## No 106 15 ## Yes 30 58
이 모델은 106명의 사망 승객을 정확하게 예측했지만 15명의 생존자를 사망으로 분류했습니다. 비유하자면, 모델은 승객 30명을 생존자로 잘못 분류했으나 사망한 것으로 밝혀졌습니다.
6단계) 성과 측정
다음을 사용하여 분류 작업에 대한 정확도 측정값을 계산할 수 있습니다. 혼란 매트릭스:
The 혼란 매트릭스 분류 성능을 평가하는 것이 더 나은 선택입니다. 일반적인 아이디어는 True 인스턴스가 False로 분류된 횟수를 계산하는 것입니다.
혼동 행렬의 각 행은 실제 목표를 나타내고, 각 열은 예측 목표를 나타냅니다. 이 행렬의 첫 번째 행은 사망한 승객(False 클래스)을 고려합니다. 106명은 사망한 승객으로 올바르게 분류되었습니다(진정한 부정), 나머지 XNUMX명은 생존자로 잘못 분류된 반면(거짓 긍정). 두 번째 줄은 생존자를 고려한 것으로, 양성계층은 58(진정한 긍정), 진정한 부정 30였습니다.
당신은 계산할 수 있습니다 정확도 테스트 혼동 행렬에서:
이는 행렬의 합에 대한 참양성과 참음성의 비율입니다. R을 사용하면 다음과 같이 코딩할 수 있습니다.
accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
코드 설명
- sum(diag(table_mat)): 대각선의 합
- sum(table_mat): 행렬의 합입니다.
테스트 세트의 정확도를 인쇄할 수 있습니다.
print(paste('Accuracy for test', accuracy_Test))
출력:
## [1] "Accuracy for test 0.784688995215311"
테스트 세트의 점수는 78%입니다. 훈련 데이터 세트를 사용하여 동일한 운동을 복제할 수 있습니다.
7단계) 초매개변수 조정
R의 의사결정 트리에는 적합도의 측면을 제어하는 다양한 매개변수가 있습니다. rpart 의사결정 트리 라이브러리에서 rpart.control() 함수를 사용하여 매개변수를 제어할 수 있습니다. 다음 코드에서 튜닝할 매개변수를 소개합니다. 다음을 참조할 수 있습니다. 소품 다른 매개변수의 경우.
rpart.control(minsplit = 20, minbucket = round(minsplit/3), maxdepth = 30) Arguments: -minsplit: Set the minimum number of observations in the node before the algorithm perform a split -minbucket: Set the minimum number of observations in the final note i.e. the leaf -maxdepth: Set the maximum depth of any node of the final tree. The root node is treated a depth 0
우리는 다음과 같이 진행합니다:
- 정확도를 반환하는 함수 생성
- 최대 깊이 조정
- 노드가 분할되기 전에 노드에 있어야 하는 최소 샘플 수를 조정합니다.
- 리프 노드에 있어야 하는 최소 샘플 수를 조정합니다.
정확도를 표시하는 함수를 작성할 수 있습니다. 이전에 사용한 코드를 간단히 래핑하면 됩니다.
- 예측: 예측_unseen <- 예측(fit, data_test, 유형 = '클래스')
- 생성 테이블: table_mat <- table(data_test$survived, 예측_unseen)
- 정확도 계산: Accuracy_Test <- sum(diag(table_mat))/sum(table_mat)
accuracy_tune <- function(fit) { predict_unseen <- predict(fit, data_test, type = 'class') table_mat <- table(data_test$survived, predict_unseen) accuracy_Test <- sum(diag(table_mat)) / sum(table_mat) accuracy_Test }
매개변수를 조정하고 기본값보다 모델을 개선할 수 있는지 확인할 수 있습니다. 참고로 0.78보다 높은 정확도를 얻어야 합니다.
control <- rpart.control(minsplit = 4, minbucket = round(5 / 3), maxdepth = 3, cp = 0) tune_fit <- rpart(survived~., data = data_train, method = 'class', control = control) accuracy_tune(tune_fit)
출력:
## [1] 0.7990431
다음 매개변수를 사용하여:
minsplit = 4 minbucket= round(5/3) maxdepth = 3cp=0
이전 모델보다 향상된 성능을 얻을 수 있습니다. 축하합니다!
요약
우리는 결정 트리 알고리즘을 훈련하기 위한 기능을 요약할 수 있습니다. R
도서관 | 목표 | 함수 | 클래스 | 파라미터 | 세부 정보 |
---|---|---|---|---|---|
부품 | R의 열차 분류 트리 | 르파트() | 수업 | 수식, df, 방법 | |
부품 | 회귀 트리 훈련 | 르파트() | 노바 | 수식, df, 방법 | |
부품 | 나무를 그려라 | rpart.plot() | 장착 모델 | ||
기지 | 예측 | 예측 () | 수업 | 장착 모델, 유형 | |
기지 | 예측 | 예측 () | 조사 | 장착 모델, 유형 | |
기지 | 예측 | 예측 () | 벡터 | 장착 모델, 유형 | |
부품 | 제어 매개 변수 | rpart.control() | 미스플릿 | 알고리즘이 분할을 수행하기 전에 노드의 최소 관측 수를 설정합니다. | |
미니버킷 | 최종 메모, 즉 나뭇잎에서 관찰의 최소 수를 설정합니다. | ||||
최대 깊이 | 최종 트리 노드의 최대 깊이를 설정합니다. 루트 노드는 깊이 0으로 처리됩니다. | ||||
부품 | 제어 매개변수를 사용하여 모델 학습 | 르파트() | 수식, df, 방법, 제어 |
참고: 훈련 데이터로 모델을 훈련하고 보이지 않는 데이터 세트, 즉 테스트 세트에서 성능을 테스트하십시오.