일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 상관관계
- 데이터분석가
- Dense_Rank
- 히스토그램 그리기
- 팀스파르타
- 회귀분석 알고리즘
- 단순회귀 분석
- if문 작성법
- sqld
- 그래프 생성 문법
- 데이터분석
- 순위출력
- loop 문
- count
- max
- merge
- 여러 데이터 검색
- Sum
- difftime
- sql
- 총과 카드만들기
- 그래프시각화
- Intersect
- 빅데이터분석
- %in%
- 정보획득량
- 회귀분석
- 불순도제거
- 빅데이터
- 막대그래프
- Today
- Total
ch0nny_log
[빅데이터분석] R _ 57. 의사 결정 트리 본문
★ 점심시간 문제:독버섯을 분류하는데 있어 가장 중요한 컬럼이 무엇인가? 정보획득량이 가장 높은게 무엇인가?
mush <- read.csv("c:\\data\\mushrooms.csv", stringsAsFactors=T) install.packages("FSelector") library(FSelector) # for 정보획득량 library(doBy) # for 정렬 mush<- information.gain( type ~ . , mush, unit='log2') orderBy (~attr_importance, mush)
= odor 가 제일 정보획득량이 높음
■ 의사결정트리란?
의사결정트리는 데이터의 속성을 기준으로 분할하여 트리 형태로 모델링하는 분류 예측 모델입니다.
이는 주어진 데이터에서 특정 속성을 기준으로 데이터를 분할하고,
그 분할된 데이터에 대해 반복적으로 동일한 과정을 적용하여 최종적으로 예측을 수행합니다.
의사결정트리는 각 노드에서 데이터를 분할하는 기준을 설정하고, 그 기준에 따라 데이터를 분류합니다.
이를 통해 데이터의 패턴을 발견하고, 새로운 데이터를 분류하거나 예측할 수 있는 모델을 만듭니다.
회귀분석과 의사결정트리는 현업에서 선호하는 머신러닝 알고리즘입니다.
신경망이 정확도는 뛰어나지만, 의사결정트리를 더 선호하는 경우가 있습니다. 그 이유는 ?
※ 불순도를 줄이는 질문을 계속 던지면서 순도가 좋아지게 분류를 해나가는 것
- 순도가 높다는 것 -> 같은 데이터들이 대부분이라는 것
- 불순도가 높다는 것 -> 여러 종류의 데이터들이 섞여 있다는 것
■ 지니계수란?
지니 계수(Gini Index)를 결정 트리에 사용하는 이유는 다음과 같습니다:
- 분류 정확도 향상: 지니 계수는 노드의 불순도를 측정하는 데 사용됩니다. 불순도가 낮을수록 같은 클래스의 샘플들이 많이 포함되어 있다는 의미입니다. 지니 계수를 최소화함으로써 분류의 정확도를 높일 수 있습니다.
- 계산의 효율성: 지니 계수는 계산이 비교적 간단하며, 빠르게 수행될 수 있습니다. 이는 대규모 데이터셋을 처리할 때 중요한 장점입니다.
- 분할 기준 제공: 지니 계수는 각 노드를 어떻게 분할할지 결정하는 기준이 됩니다. 즉, 특정 속성의 특정 값을 기준으로 데이터를 분할할 때 지니 계수를 사용하여 불순도를 최소화하는 방향으로 분할합니다.
1) a = 2/5 = 0.4 / (1-a) = 3/5 = 0.6
2) 1- (0.4^2 +0.6^2) = 0.48 <- JINI 계수
3) 0보다 높으므로 불순도가 높음
■ 정보획득량?
■ 불순도 평가방법
의사결정트리 모델의 불순도 평가 방법은 다음과 같습니다:
- 엔트로피
- 지니계수
- 카이제곱 검정
의사결정트리 패키지로는 C50과 party가 있습니다. C50은 엔트로피 지수로 정보획득량을 구하며, party는 카이제곱 검정으로 정보획득량을 구합니다.
문제 1. (컴퓨터로 정보 획득량 구하기) 구매여부에 가장 영향이 큰 변수는 무엇인가? (즉 정보획득량이 가장 높은 컬럼이 무엇인가 ?)
buy <- data.frame( cust_name=c('SCOTT','SMITH','ALLEN','JONES','WARD'), card_yn=c('Y','Y','N','Y','Y'), intro_yn=c('Y','Y','N','N','Y'), before_buy_yn=c('Y','Y','Y','N','Y'), buy_yn=c('Y','Y','N','Y','Y') )
컬럼소개: card_yn : 카드 소유유무
intro_yn : 지인소개
before_buy_yn : 이전구매여부
buy_yn : 구매여부 ( 종속변수)library(FSelector) # 정보 획득량 구하기 library(doBy) # 자동 정렬 처리 information.gain( buy_yn ~ . , buy, unit='log2')
-> 카드 소유 유무가 가장 영향을 미침
-> cust_name 은 이름이기 때문에 상관 xinformation.gain( buy_yn ~ . , buy[ ,c(2:5)], unit='log2')
문제 2. 위 결과를 시각화 하시오.
# 데이터 불러오기 buy <- data.frame( cust_name=c('SCOTT','SMITH','ALLEN','JONES','WARD'), card_yn=c('Y','Y','N','Y','Y'), intro_yn=c('Y','Y','N','N','Y'), before_buy_yn=c('Y','Y','Y','N','Y'), buy_yn=c('Y','Y','N','Y','Y') ) buy library(FSelector) # 정보 획득량 구하기 library(doBy) # 자동 정렬 처리 library(plotly) weights <- information.gain( buy_yn ~ . , buy[ , c(2:5)], unit='log2') weights orderBy( ~ attr_importance, weights ) # 1. 데이터 불러오기 a <- orderBy( ~ attr_importance, weights ) info_gain_df <- data.frame( col1=rownames(a), col2=a$attr_importance) info_gain_df # 색깔 지정하기 colors <- c('#FFCDD2','#E1BEE7','#BBDEFB') # 4. plotly 를 사용한 막대 그래프 생성하기 fig <- plot_ly( info_gain_df, x = ~col1, y = ~ col2, type = 'bar', marker = list(color = colors)) # 5. 그래프 출력 fig
■ R을 이용해서 의사결정 트리모델 만들기
실습 2
데이터: 화장품 고객 데이터 (skin.csv)
1) 순서:
#1. 데이터 불러오기
#2. 데이터 살펴보기
#3. 훈련 데이터와 테스트 데이터 분리하기
#4. 의사결정트리 모델 만들기
#5. 테스트 데이터 예측하기
#6. 모델 성능 확인하기
#7. 모델 성능 평가하기
2) 코드구현:
설명: 결혼유무를 가장 중요한 결정 요인으로 골랐습니다. 그리고 나이와 직업 순서로 정보획득량이 높아서 위와 같이 질문 나무를 생성함
#1. 데이터 불러오기 setwd("c:\\data") skin <- read.csv("skin.csv" , stringsAsFactors=T, fileEncoding = "euc-kr") head(skin) #2. 데이터 살펴보기 colSums(is.na(skin)) #3. 훈련 데이터와 테스트 데이터 분리하기 library(caret) set.seed(1) train_num <- createDataPartition( skin$cupon_react, p=0.8, list=F) length(train_num) # 25 train_data <- skin[ train_num, ] test_data <- skin[ -train_num, ] nrow(train_data) # 25 nrow(test_data) # 5 #4. 의사결정트리 모델 만들기 install.packages("C50") library(C50) # 질문 나무 만드는 패키지 model <- C5.0( train_data[ , c(-1, -7) ], train_data[ , 7] ) ## 고객번호와 정답을 제외 정답 model ## Classification Tree ## Number of samples: 25 -> ## Number of predictors: 5 -> 가지를 5개 만들었다. summary(model) plot (model) #5. 테스트 데이터 예측하기 # 1) 훈련 데이터의 정확도 train_result <- predict( model, train_data[ , c(-1, -7) ] ) train_result sum(train_result ==train_data[ ,7])/25*100 #정확도 88% # 2) 테스트 데이터의 정확도 test_result <- predict( model, test_data[ , c(-1, -7) ] ) test_result sum(test_result ==test_data[ ,7])/5*100 #정확도 80% #6. 모델 성능 확인하기 library(C50) model2 <- C5.0( train_data[ , c(-1, -7) ], train_data[ , 7] ,trials = 5 ) model2 ## trials = 5 의 의미 : 의사결정트리 모델 5개를 생성해서 5개의 모델이 ## 예측한 결과를 가지고 다수결을 붙여서 다수결에 의해서 예측하겠다는 뜻 #7. 모델 성능 평가하기 test_result2 <- predict( model2, test_data[ , c(-1, -7) ] ) test_result2 sum(test_result2 ==test_data[ ,7])/5*100 #정확도 60%
설명: 훈련 데이터의 정확도는 100% 인데 트스트가 60% 입니다. 오버피팅이 발생했습니다. 오버피팅이 적게 일어나면서 정확도는 좋은 적절한 trials 값을 알아내야합니다.
실습 2. 아이리스 꽃의 품종을 분류하는 의사결정트리 모델을 생성하시오.
데이터: 아이리스 데이터
#1. 데이터 불러오기 setwd("c:\\data") iris <- read.csv("iris2.csv" , stringsAsFactors=T, fileEncoding = "euc-kr") head(iris) #2. 데이터 살펴보기 colSums(is.na(iris)) # 결측치 0개 #3. 훈련 데이터와 테스트 데이터 분리하기 library(caret) set.seed(1) train_num <- createDataPartition( iris$Species, p=0.8, list=F) length(train_num) # 120 train_data <- iris[ train_num, ] test_data <- iris[ -train_num, ] nrow(train_data) # 120 nrow(test_data) # 30 #4. 의사결정트리 모델 만들기 install.packages("C50") library(C50) # 질문 나무 만드는 패키지 model <- C5.0( train_data[ ,-5], train_data[ , 5] ) ## 정답을 제외 정답 model #가지를 3개 만들음음 summary(model) plot (model) #5. 테스트 데이터 예측하기 # 1) 훈련 데이터의 정확도 train_result <- predict( model, train_data[ ,-5 ] ) train_result sum(train_result ==train_data[ ,5])/120 *100 #정확도 95.83% # 2) 테스트 데이터의 정확도 test_result <- predict( model, test_data[ , -5 ] ) test_result sum(test_result ==test_data[ ,5])/30*100 #정확도 96.66% #6. 모델 성능 확인하기 y <- 0 jumpby <-1 options(scipen=999) for ( i in 1:10 ) { model<-C5.0(train_data[ ,-5],train_data[ ,5], trials=y) test_result2 <- predict(model, test_data[ ,-5]) a<- sum(test_result2 == test_data[ ,5])/30 *100 #100% y <- y + jumpby print(paste(i,'일때',a)) } library(C50) model2 <- C5.0( train_data[ , -5], train_data[ , 5] ,trials = 5 ) model2 ## trials = 5 의 의미 : 의사결정트리 모델 5개를 생성해서 5개의 모델이 ## 예측한 결과를 가지고 다수결을 붙여서 다수결에 의해서 예측하겠다는 뜻 #7. 모델 성능 평가하기 test_result2 <- predict( model2, test_data[ , -5 ] ) test_result2 sum(test_result2 ==test_data[ ,5])/30*100 #정확도 96.66% train_result <- predict( model2, train_data[ ,-5 ] ) train_result sum(train_result ==train_data[ ,5])/120 *100 #정확도 100%
실습3. 은행 대출 불이행자 예측 모델
#1. 데이터를 불러옵니다. credit <- read.csv("credit.csv", stringsAsFactors=T) head(credit) #2. 데이터를 살펴봅니다. str(credit) # 데이터 설명 checking_balance : 예금계좌 saving_balance : 적금계좌 amount : 대출금액 default : 채무불이행 여부(종속변수) # amount을 히스토그램 그래프로 그려보시오! hist(credit$amount) summary(credit$amount) Min. 1st Qu. Median Mean 3rd Qu. Max. 250 1366 2320 3271 3972 18424 최소250마르크(천칠백 오십만원) ~ 18,424(12억 8천만원) 정답컬럼: default ---> yes : 대출금 상환안함 no : 대출금 상환함 prop.table( table(credit$default) ) 30% 에 해당하는 사람들이 대출금을 상환하지 않고있어서 머신러닝 모델을 만들어서 대출금을 상환하지 않을것으로 예측되는 고객은 아예 대출을 안해주게 해서 대출금 상환안하는 고객의 비율을 최대한 낮춰보는것이 머신러닝 모델을 만드는 목적입니다. # 결측치 확인 colSums( is.na(credit)) #3. 훈련 데이터와 테스트 데이터 분리 library(caret) set.seed(1) train_num <- createDataPartition( credit$default, p=0.9, list=F) train_data <- credit[ train_num, ] test_data <- credit[ -train_num, ] nrow(train_data) #900 nrow(test_data) #100 ncol(train_data) # 17 head(train_data) # 종속변수가 17번째 컬럼입니다. #4. 모델 생성 library(C50) credit_model <- C5.0( train_data[ , -17], train_data[ , 17] ) #5. 모델 확인 summary(credit_model) Decision tree: checking_balance = unknown: no (356/42) # 예금통장이 unknown 인 사람들 356이 # 돈을 갚았고 42명은 예외입니다. checking_balance in {< 0 DM,> 200 DM,1 - 200 DM}: :...amount > 8648: yes (31/6) 대출금액이 8648 마르크보다 더 큰 사람들중 31명이 amount <= 8648: 대출금을 상환하지 않았습니다. 대출금액이 8448 이하 :...credit_history in {perfect,very good}: 인 사람들중에 신용이력이 perfect,very good :...housing in {other,rent}: yes (26/3) 인 사람들중에서 집이 랜트이거나 기타유형 이면 돈 안갚았습다. : housing = own: 집이 자가 소유인데 : :...savings_balance in {> 1000 DM,500 - 1000 DM, 적금이 있으면 : : unknown}: no (8/2) 8명이 대출금 갚았습니다.(2명 예외) #6. 모델 예측 train_result <- predict( credit_model, train_data[ , -17] ) test_result <- predict( credit_model, test_data[ , -17] ) #7. 모델 평가 #훈련 정확도 sum( train_result == train_data[ , 17] ) / 900 * 100 # 83.33 % #테스트 정확도 sum( test_result == test_data[ , 17] ) / 100 * 100 # 67% #8. 모델 개선 문제172. trials 파라미터를 주고 모델의 성능을 올리시오 ! y <- 1 jumpby <-1 options(scipen=999) for ( i in 1:20 ) { credit_model2 <- C5.0( train_data[ , -17], train_data[ , 17], trials=y ) test_result2 <- predict( credit_model2, test_data[ , -17] ) a<- sum(test_result2 == test_data[ ,17])/100 *100 #100% y <- y + jumpby print(paste(i,'일때',a)) } [1] "6 일때 78" 이 나왔습니다. 정확도만 봐서는 안되고 FN (거짓부정) 을 같이 봐야합니다. library(gmodels) # 의사결정 나무의 갯수는 1 ~100까지만 지정할 수 있습니다. credit_model2 <- C5.0( train_data[ , -17], train_data[ , 17], trials=6 ) test_result2 <- predict( credit_model2, test_data[ , -17] ) x <- CrossTable( test_data[ , 17], test_result2 ) x$t y x no yes no 65 5 yes 17 13
★ 마지막 문제: 와인데이터를 이용하여 의사결정 트리모델을 올리고 정확도를 올리시오.
#1. 데이터를 불러옵니다. wine <- read.csv("wine2.csv", stringsAsFactors=T) head(wine) #2. 데이터를 살펴봅니다. str(wine) #3. 결측치 확인 colSums(is.na(wine)) # 결측치 없음음 #3. 훈련 데이터와 테스트 데이터 분리 library(caret) set.seed(1) train_num <- createDataPartition( wine$Type, p=0.8, list=F) train_data <- wine[ train_num, ] test_data <- wine[ -train_num, ] nrow(train_data) #143 nrow(test_data) #34 #4. 모델 생성 library(C50) model <- C5.0( train_data[ , -1], train_data[ , 1] ) #5. 모델 확인 summary(model) #6. 모델 예측 train_result <- predict( model, train_data[ , -1] ) test_result <- predict( model, test_data[ , -1] ) #7. 모델 평가 #훈련 정확도 sum( train_result == train_data[ , 1] ) / 143 * 100 # 99.3% #테스트 정확도 sum( test_result == test_data[ , 1] ) / 34 * 100 # 94.12% #8. 모델 개선 y <- 1 jumpby <-1 options(scipen=999) for ( i in 1:20 ) { model2 <- C5.0( train_data[ , -1], train_data[ , 1], trials=y ) test_result2 <- predict( model2, test_data[ , -1] ) a<- sum(test_result2 == test_data[ ,1])/34 *100 #100% y <- y + jumpby print(paste(i,'일때',a)) } [1] "4 일때 100" 으로 가장 높음
'빅데이터 분석(with 아이티윌) > R' 카테고리의 다른 글
[빅데이터분석] R _ 59. 상관관계 (0) | 2024.07.16 |
---|---|
[빅데이터분석] R _ 58. 단순 회귀분석 알고리즘 (1) | 2024.07.16 |
[빅데이터분석] R _ 56. 규칙기반 알고리즘(one r/riper 알고리즘) (0) | 2024.07.12 |
[빅데이터분석] R _ 55. 하이퍼 파라미터 (1) | 2024.07.12 |
[빅데이터분석] R _ 54. 나이브 베이즈 확율 (1) | 2024.07.11 |