반응형

 


안녕하세요


오늘은 R로 하는 머신러닝 지도학습 분류 3번째,


결정 트리에 대해 알아보도록 하겠습니다.




우선

1. 의사결정 트리란?


의사결정 rule을 계층적 나무구조로 도표화하여 분류 및 예측할 수 있는 분석 방법



분류율에 대한 정확도만 따지면 신경망 또는 회귀분석등의 분류 방법들보다 낮게 평가되기도 하지만


" 결과를 쉽게 이해하고 설명할 수 있으며 의사결정을 하는데 직접적으로 사용할 수 있다 "

는 장점이 있습니다!




2. 의사결정 트리의 알고리즘의 다양한 종류


각각의 이름과 알고리즘의 기준 속성은 다음과 같습니다.


ID3 : 엔트로피

C4.5, C5.0 : 정보획득량

CART : 카이제곱

CHAID : 카이제곱




3. 의사결정 트리 알고리즘에서 고려해야할 문제



1) 훈련 데이터를 어떤 속성으로 분할해야하는가?


위의 다양한 기준이 있는 이유 또한 이 질문에 대한 각각의 답을 낸 결과 아닐까요?



2) 트리 성장(분할과정)은 언제, 어떻게 정지해야하는가?


의사결정 트리를 시각화하여 순도가 높게 분류되는지 확인하기



3) 과적합 문제는 어떻게 해결해야할까?


가지치기(tree pruning)를 이용하여 불필요한 질문 제거하기




4. C5.0 알고리즘 이용하기

정보획득량을 기준으로 결정 트리를 시각화 하도록 하겠습니다.



정보획득량이란 무엇일까요?


정보획득량 = 분할전 엔트로피 - 분할 후 엔트로피



그렇다면 엔트로피의 공식을 알아봅시다.

위의 식을 이해하려면 log확률을 알아야합니다.


모르는 분들을 위해 제 블로그에 각각 간단하게 포스팅하였습니다~




5. 코드로 알아보기




 1. 의사결정 패키지 C50 을 설치한다.


2. 데이터를 로드한다.


3. 데이터를 suffle한다.


4. train 데이터와 test 데이터로 나눈다.


5. train 데이터로 분류 모델을 생성한다.


6. 분류모델과 test 데이터로 분류 결과를 예측한다.


7. Tree를 시각화한다.






decision_tree_fun <- function(){

# 1. 필요한 패키지 설치

# install.packages("C50")

# C50 라이브러리

library(C50) # 이원교차표 라이브러리

library(gmodels)

# tree 시각화를 위한 패키지 library(rpart) library(rattle)

# 2. 데이터 로드하기 print("분석할 csv파일을 입력하세요 ")

data <- file.choose()

na.string <- NA


table1 <- read.csv(data, header = T, na.string = na.string) d_col <- menu(c(colnames(table1),'none'), title="삭제할 컬럼을 선택하시오 ")

table1 <- table1[,-d_col]


l_col <- menu(colnames(table1), title="label이 될 컬럼을 선택하시오 ")

# 연속형데이터는 factor로 변환하지 않는다.

# 팩터 라벨 한글 제거 fctr_ls <- which( sapply(table1, class) == "factor" ) if( length(fctr_ls) !=0 ) { cat('***주의***\nFactor에 한글이 포함되어 있으면 에러가 발생할 수 있습니다.

\nFactor 라벨을 영문 혹은 숫자로 변경하십시오.\n\n') while( TRUE ) { chg_num <- menu(c('SKIP', colnames(table1)[fctr_ls]) , title = "라벨을 변환할 팩터컬럼을 선택하세요\n

-> 더이상 변환할 컬럼이 없다면 SKIP을 선택합니다.") if( chg_num == 1 ) break chng_lv <- NULL lv <- levels( table1[,fctr_ls[chg_num-1]] ) for( i in 1:length(lv) ) { chng_lv <- c(chng_lv, readline( paste('기존 :', lv[i], '-> 변경 : ')) ) } levels( table1[,fctr_ls[chg_num-1]] ) <- chg_lv } }


trials <- readline(prompt = "trials 값을 입력하세요 ")

# 3. 데이터 shuffle 하기 # 조절할 것1_set.seed() set.seed(11) table_shuffle <- table1[sample(nrow(table1)),]


# 4. train 데이터와 test 데이터 나누기 train_num <- round(0.7*nrow(table_shuffle),0) table_train <- table_shuffle[1:train_num, ] table_test <- table_shuffle[(train_num +1): nrow(table_shuffle), ] l_col <- colnames(table1)[l_col] ncol1 <- which(colnames(table1) == l_col)

# 5. 분류모델을 생성한다. # 조절할 것2_trials: 시도할 횟수 정함 model <- C5.0(table_train[ ,-ncol1], table_train[ ,ncol1], trials = as.numeric(trials)) result <- predict(model, table_test[ ,-ncol1])

# 6. 테스트 데이터로 예측한 결과(정확도) 확인

CrossTable(x = table_test[,ncol1], y= result)


# 7. Tree 시각화하기 # as.formula와 paste로 ~.을 붙여야한다.

tree <- rpart(label~. , data=data.frame(table1[,-ncol1], label = table1[,l_col]), control=rpart.control(minsplit=2))

# color 지정하기 fancyRpartPlot(tree,palettes = c("Greys","RdPu")) }


결과






오늘은 여기까지!!


다음은 회귀분석으로 돌아오겠습니다~


또 봐요~

반응형
반응형


안녕하세요~


오늘은 머신러닝 지도학습 알고리즘 중


나이브 베이즈 분류 알고리즘을 알아봅시다!!



나이브 베이지 분류란?

베이지안 기법 기반의 분류기는 훈련 데이터를 활용해 특정 값이 제공하는 증거기반으로 결과가 관측될 확률을 계산하는 방법


(사전확률을 이용해 사후확률을 알 수 있습니다.)



그렇다면,


나이브 베이즈 알고리즘은

언제 사용할까?



결과에 대한 전체 확률을 추정하기 위해 동시에 여러 속성 정보를 고려해야만 하는 문제에 가장 적합합니다.


모든 사건이 독립이라면 다른 사건을 관측해 어떤 사건을 예측하는 것은 불가능합니다. 


다시말해, 종속사건이 예측모델링에 기반이 됩니다.



<배경 지식>


조건부 확률





R 을 통해 본 나이브베이즈 분류 알고리즘


data : 영화 관람객

data설명: data frame형태의 데이터

column: 나이, 성별, 직업, 결혼여부, 이성친구, 장르(label)



[실습 순서]



1. 데이터 로드


2. 필요없는 데이터를 정제한다.


3. label(정답)이 될 컬럼을 factor로 변환한다.


4. train 데이터와 test 데이터로 나눈다.


5. library(e1071)을 이용하여

train 데이터로 naivebayes모델을 훈련시킨다.


6. 모델의 정확도를 확인한다.


7. 이원 교차표를 그려서 결과를 확인한다.


8. 튜닝한다.





직접 사용자 정의 function()으로 만들어 코드를 재사용 하고자 하였습니다.


naive_bayes_fun <- function() {

# 1. 데이터를 로드한다. # 내 컴퓨터에서 파일을 선택할 수 있는 창이 켜진다. data <- file.choose() na.string <- NA table1 <- read.csv(data, stringsAsFactors = F, na.string = na.string) # menu()를 사용하면 관련된 것의 숫자(순서)를 return한다. col <- menu(colnames(table1), title = "라벨이 될 컬럼 이름을 입력하세요 ") # readline()함수를 이용하면 사용자가 입력한 값을 읽어들일 수 있다. lap <- readline(prompt = "laplace값을 입력하세요 ")

# 2. data 정제: 매번 다르기때문에 여기서는 생략함 # 3. label을 factor로 변환한다.

# CrossTable Error 때문에 여기서는 전부 factor로 변환하였습니다.

for(i in 1:dim(table1)[2]){ table1[,i] <- factor(table1[,i]) } # 4. 훈련데이터와 테스트 데이터로 나눈다. set.seed(12) # 행의 건수 확인 train_cnt <- round(0.7 * dim(table1)[1]) # shuffle 하는 방법 중 하나 train_indx <- sample(1:dim(table1)[1], train_cnt, replace = F) table_train <- table1[train_indx,] table_test <- table1[-train_indx,]

# 5. 나이브 베이즈 함수를 이용해서 장르(label)를 분류하는 모델을 생성한다. library(e1071) # V1~: label(기준으로 사용), laplace: positive double controlling Laplace smoothing. # laplace로 공격적으로 필터링하는 정도를 조절할 수 있음 model1 <- naiveBayes(table_train[,col]~. , data = table_train, laplace = as.numeric(lap))

# 6. 모델로 테스트 데이터로 정확도 측성한다. # 예측하기 result1 <- predict(model1, table_test[, -col]) # 7. 이원 교차표로 분류의 최종 결과를 확인한다. library(gmodels) # 실제 예측 CrossTable(x = table_test[,col], y = result1)


# 정확도 확인하기

prop.table(table(ifelse(table_test[,col]==result1,"o","x" )))

}


# 8. 튜닝한다.


더 알맞은 shuffled data을 위해 set.seed()값으로 변경하고

laplace 값을 조절하여

필터링하는 정도를 조절하여 더 나은 값을 얻을 수 있습니다. (여기서는 0.1로 주어 결과를 내보았음)




[결과]




# 참고: 보시면 알 수 있듯이 여기 movie data는 굉장이 적은 데이터이기 때문에

training data 와 test data로 나눌 때 굉장히 불편했습니다.

큰데이터로 각각의 data의 비율을 변경해보세요~



[정확도]


prop.table(table(ifelse(table_test[,col]==result,"o","x" )))


 o            x 


0.75            0.25 





나이브 베이즈 알고리즘의

한계점


나이브 베이즈 알고리즘은 데이터에 대한 약간 naive(순진한)을 가정하고 있습니다.

특히 데이터 셋의 모든 특징을 동등하게 중요하고 독립적이라고 가정합니다.



이 한계점을 극복하기위한 다양한 분류 알고리즘에 대해 앞으로 알아보도록 하겠습니다!


우선 의사결정 트리부터~

반응형
반응형

안녕하세요 오랜만에 돌아왔습니다~


SQL에 이어


데이터 분석, 머신러닝을 위한 R에 대해 포스팅하겠습니다~




우선 R에 대해 알아야겠죠?



BASIC그림 출처: https://vimeo.com/basicagency




가장 먼저

R로 데이터를 로드하고 패키지를 사용하는 방법에 대해 알아보겠습니다.



Tip 1. csv파일을 R에서 로드하는 방법


 

read.csv( "파일위치", header = T)



Tip 2. 변수에 넣기


 

변수이름 <- read.csv( "파일위치", header = T)




Tip 3. 패키지 설치하는 방법


 

install.packages("패키지이름")



Tip 4. 라이브러리 사용하는 방법


 

library("라이브러리이름")






이제 기본적인 R의 자료구조와 연산자 그리고 함수에 대해 알아보겠습니다!



1. R의 자료구조




 

Vector: 같은 데이터 타입을 갖는 1차원 배열구조


Matrix: 같은 데이터 타입을 갖는 2차원 배열구조


Array: 같은 데이터 타입을 갖는 다차원 배열구조


Data Frame: 각각의 데이터 타입을 갖는 컬럼으로 이루어진 2차연 배열구조 (데이터베이스의 table과 유사함)


List: 서로 다른 데이터 구조의 데이터 타입(vector, matrix, array, data frame)이 중첩된 구조





2. R의 연산자



 

산술 연산자: + , - , / , * , ^, %% 등..


비교 연산자: > , < , >= , <= , == , != 


논리 연산자: & , && (and) , | , || (or) , ! (not)




* 참고1: R에서 같음을 비교하는 연산자는 == 이다.

 = (equal) 을 두개 사용해야한다.



* 참고2: &과 &&, | 과 || 의 차이


& 과 | 는 벡터화된 연산에 사용된다.


&& 과 || 는 벡터화 되지 않은 연산에서 사용한다.




3. R 의 기본 함수



 

문자함수: toupper, tolower, substr, gsub, paste , ...


숫자함수: round, tunc, ..


날짜함수: Sys.Date(), defftime, ...


변환함수: as.character, integer, as.Date, as.factor, format, ... 


일반함수: is.na, ifelse, ...


그룹함수: max, min, sum, length, table, ...





이 중 format, ifelse, length 함수에 대해 더 자세히 알아볼까요?



1. format 함수


 

format(as.Date('2018/05/15'), '%A')


결과: "화요일"



* 참고: as.Date는 날짜로 변환시켜주는 변환 함수



format 함수에서 '%A'자리에 쓸 수 있는 것과 의미


'%A' : 요일을 출력 / '%Y' or '%y' : 연도 / '%m' : 달 / '%d' : 일 / '%H' : 시간 / '%M' : 분 / '%S': 초



2. ifelse 함수


 

ifelse( 등급 == 1 , 'A' , 'B' )



ifelse ( 조건 , 조건 True , 조건 False)


* 참고: ifelse는 중첩하여 사용할 수 있다. 



3. length 함수


 

x <- c( 1, 2, 3)


length(x)


결과: 3



벡터이든 행렬이든 전체 원소의 갯수를 출력




추가적으로!


만약 원하는 함수가 패키지에도 존재하지 않을 때!

혹은

나만의 함수를 만들고 싶을 때!




함수를 생성하는 방법에 대해 알아보도록 하겠습니다.



 

함수이름 <- function(parameter, ...) {


(if / for .. 등 연산)


}



*참고: R에서 사용자 정의 함수에서 return문은 필수가 아니다.




예제: 앞으로 다가올 요일의 날짜를 출력하는 함수







오늘은 여기까지~


다음은 시각화로 찾아오겠습니다!



반응형
반응형



안녕하세요!


오늘부터 쿼리의 검색 속도를 높일 수 있는 SQL 튜닝을 포스팅하겠습니다.


대용량 데이터 환경(빅데이터)에서 필수가 되어가고 있습니다.


이제 인덱스 튜닝에 대해 알아보도록 하겠습니다.



[인덱스 튜닝의 종류]



1. index range scan

2. index unique scan

3. index skip scan

4. index full scan

5. index fast full scan

6. index merge scan

7. index bitmap merge scan

8. index join

 


index range scan과 index unique scan은

이전에 index 포스팅 에서 다뤘습니다!



"예제를 위한 테이블 소개"


[사원] 테이블


EMPNO

ENAME

JOB

SAL

DEPT

 ALLEN

 SALESMAN

 1250

 서울시

 2 

 BAKE

 SALESMAN

 1600

 서울시

 3 

 CLARK

 MANAGER

 3000

 세종시

 4 

 WARD

 CLERK

 1100

 인천광역시

 5 

 JAMES

 ANALYST

 3000

 부산광역시

 6 

 FORD

 ANALYST

 3000

 세종시

 7 

 SMITH

 CLERK

 1300

 세종시

 8 

 MILLER

 MANAGER

 2450

 서울시



index skip scan

인덱스 전부 스캔하지 않고 SKIP해서 스캔하는 엑세스 방법


예제1. 직업과 월급으로 결합컬럼 인덱스를 생성하고

아래의 SQL이 index scan할 수 있도록 힌트를 주세요



      SQL1> SELECT ename, job, sal

                         FROM 사원

                         WHERE sal = 3000;

 




결합 컬럼 인덱스의 첫번째 컬럼이 where 절에서 검색조건으로 존재해야

그 인덱스를 엑세스할 수 있습니다.


하지만 위와 같은 상황일 때,

emp_job_sal 인덱스를 엑세스하게 하려면 인덱스 스킵 조건을 쓸 수 있습니다.



단, 인덱스 스킵 스캔의 효과를 보기위한 조건이 있습니다.

결합컬럼 인덱스의 첫번째 컬럼의 종류가 많으면 그 효과를 볼 수 없습니다.



index full scan


인덱스 전체를 처음부터 끝까지 스캔하는 방법


예제2. 사원 테이블의 사원번호에 primary key를 생성하고

사원의 인원수가 몇 명인지 카운트 하세요




위의 SQL을 실행하면 INDEX FULL SCAN을 하게 됩니다.

TABLE FULL SCAN보다 훨씬 더 성능이 좋습니다.



만약 위의 결과에서 index full scan이 되지 않는다면 어떻게 해야할까요?



쿼리에 index full scan hint를 추가하면 됩니다.


index full scan의 힌트는

 /*+ index_fs(사원 emp_empno_pk) */ 

입니다.


(잘 모르겠다면 예제1번의 정답을 다시 확인하고 오세요!)

 



index fast full scan


index full scan보다 더 성능이 좋은 스캔 방법


병렬처리가 가능합니다.


예제3. 부서와 부서별 인원수를 출력하는데

빠르게 출력될 수 있도록 적절한 인덱스를 생성하고 힌트를 주고

병렬처리하여 실행하세요.




<SQL3_2의 힌트 설명>


병렬_인덱스(테이블, 인덱스이름, 사용할 CPU개수)



인덱스가 무엇인지 궁금하다면 여기로!




오늘은 여기까지!


중요한 인덱스 튜닝은 index range scanindex skip scan이랍니다~

알아두고 넘어갑시다!



이 글이 도움되셨다면 아래 공감 꾹~ 



반응형

+ Recent posts