반응형

 


안녕하세요


오늘은 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(순진한)을 가정하고 있습니다.

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



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


우선 의사결정 트리부터~

반응형
반응형


안녕하세요!


오늘은 머신러닝의 지도학습, 분류 및 예측에 사용되는 알고리즘인


나이브 베이즈, 결정트리, 회귀 분석을 위해 필수적으로 알아야하는


확률에 대해 알아보도록 하겠습니다!



우선 확률을 이야기 하려면 어떤 사건이 발생해야 합니다.



잠깐! 여기서 사건이란 무엇일까요?


우선 확률과 관련된 용어를 알아봅시다!



어떤일이 발생하기위해 뭔가 해보는 것, 그것을 시행이라고 합니다.


예를 들어 동전을 던지는 것, 주사위를 던지는 것이 시행입니다.


단, 시행은 동일한 조건하에 행해져야 합니다.



표본공간이란 시행을 했을 때 나타나는 모든 결과를 의미합니다.


예를 들어, 주사위를 여러번 던졌을 때 1에서 6까지의 눈이 나오는 것,

그것을 모아놓은 것이 바로 표본공간입니다.



표본공간 속에서 사건이 일어납니다.


예를 들어, 주사위를 던질 때 1이 나오거나 짝수의 눈이 나오는 것을 사건이라고 합니다.



즉, 사건이란 시행을 하는 것이 아니라

시행을 했을 때 나오는 결과를 의미합니다.


따라서 사건은 표본 공간의 부분집합이 됩니다.



사건이 하나씩만 일어날 수 있는 것을 근원 사건이라고 합니다.


예를 들어, 주사위의 경우 1,2,3,4,5,6이 각각 나오는 것을 근원사건이라고 합니다.





[확률 기본]


확률은 아래와 같이 표현하며,

여기서 P는 Probability의 약자입니다.


P(A)



따라서 P(A)는 A가 일어날 사건이라고 표현합니다.




확률에도 크게 두가지 종류가 있습니다.


수학적 확률과 통계적 확률


우선, 수학적 확률이란, 수학적으로 어떤 이상적인 확률(의 결과)을 의미하는 것입니다.


예를 들어, 동전을 던졌을 때 앞면이 나올 확률을 1/2 이 되는 것입니다.



통계적 확률이란, 실제생활에서 일어나는 확률로

어떤 일을 했을 때, 어떤 일이 일어날 확률을 의미합니다.


예를 들어, 전체 30명의 학생들이 있고 이 중에 안경을 쓴 학생들이 10명이라고 했을 때,

30명 중에 어떤 한 학생이 안경을 쓰고 있을 확률은 10/30 이 되는 것입니다.



수학적 확률을 표현하는 방법


P(A)

= A사건이 일어날 원소의 갯수 / 표본공간의 원소의 갯수

= n(A) / n(S)



확률은 기본적으로 0보다 크거나 같고,

무조건 일어날 확률은 100%, 즉 1보다 작거나 같습니다.


0 <= P(A) <= 1





[조건부 확률]



확률은 결합 확률과 조건부 확률이 있습니다.


결합확률은 서로 배반되는 두 사상 A와 B가 있을 때,

두 사상이 연속적으로 또는 동시에 일어나는 확률을 의미합니다.


<결합확률 표기>


P(A ∩ B)




조건부 확률은 어떠한 상황이 주어졌을 때,

그 상황 속에서 다른 상황이 일어날 확률을 의미합니다.


<조건부확률 표기>


P(A | B)




[사건의 종류]



사건은 독립사건과 종속사건으로 나뉩니다.


독립사건이란, 두개의 사건이 일어났는데

두 사건이 전혀 연관되지 않았다면 독립사건입니다.


<독립사건 표기>


P(A | B) = P(A)




종속사건이란, 사건B가 일어났을 경우와 일어나지 않았을 경우에 따라,

사건 A가 일어날 확률이 다를 때 (즉, B의 영향을 받는 경우를 의미)

A는 B의 종속사건이라고 합니다.


예를 들어, 비가 오면 우산이 팔릴 확률이 높아지는 것은

두 사건의 관계가 종속 관계라는 것을 의미합니다.


<종속사건 표기>


P(A | B) = P(A ∩ B) / P(B)




오늘은 여기까지!


다음 포스팅할


나이브 베이즈 이론과 결정트리, 회귀분석에서


이를 활용하는 방법에 대해 같이 포스팅하도록 하겠습니다!



내용 출처: 그림으로 설명하는 개념 쏙쏙 통계학

EBS 고교강의 친절한 하영쌤의 수학

반응형
반응형

안녕하세요!


저는 매일매일 딥러닝을 위해 공부를 하고 있습니다!


하지만....

요즘 너무 바빠서 블로그 운영을 가끔 포스팅하고 있네요ㅜ


더 열심히 올리도록 하겠습니다!!


사설은 여기까지!


오늘은 지도학습의 분류 방법 중  KNN알고리즘에 대해 알아보도록 하겠습니다!


지도학습이 무엇인지 궁금하시다면 여기로!



우선 KNN이란 무엇일까요?


KNN이란, k Nearest Neighbors의 약자로 k개의 가장 근처의 이웃들을 내 이웃으로 보고 분류하는 방법입니다.


즉, 유사성을 인식하여 결과를 추정하는 것이죠.


단, 같은 거리안에 여러개의 그룹이 있으면 다수결에 의해서 가장 많은 그룹을 선택하는 방법



예를들어,


 유유상종이라는 사자성어도 있듯이 사회적으로도 비슷한 사람끼리 모이는 성질이 있습니다.


또한 가구점이 모이는 상가지역이 따로 형성되어 있거나 한약방이 밀집되어 있는 지역이 따로 모여있는 경우가 있습니다.


이러한 특성을 가진 데이터를 분석목적으로 만들어진 알고리즘이 knn입니다!




머신러닝에서는 실습으로 그 방법을 알아보도록 하겠습니다!



[실습 방법]



1. 데이터 로드


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


3. 데이터를 shuffle한다.


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


5. 데이터를 정규화 한다.


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


7. label과 데이터를 나눈다.


8. 가장 좋은 k값을 찾는다.


9. taining 데이터로 knn모델을 훈련시킨다.


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


11. 이원 교차표를 그려서 확인한다.


12. 튜닝한다.





[코드 확인하기]



1. 데이터 로드

# 데이터를 로드할 때 디렉토리를 넣어주어야합니다.


# 매번 넣는 것이 귀찮다면 아래의 코드를 삽입하세요.(r studio기준)

# setwd("디렉토리")


# header = T: data의 header를 가져오겠다.

# stringsAsFactors = FALSE : data를 Factor로 변환하지 않겠다.

wbcd <- read.csv("wisc_bc_data.csv", header=T, stringsAsFactors = FALSE)


2. label이 될 컬럼을 factor로 변환한다.

wbcd$diagnosis <- factor(wbcd$diagnosis, levels =c("B","M"),          labels = c("Benign","Maliganant"))

> 보다 명확한 labeling을 위해 범주형 데이터인 factor로 변환하였다.


3. 데이터를 shuffle한다.

# set.seed란 랜덤한 값을 시작하기 전에 사용하면 이후에도 같은 값으로 랜덤값을 갖는다.

set.seed(123) wbcd_shuffle <- wbcd[sample(nrow(wbcd)), ]

> 데이터를 shuffle하는 이유: training 데이터와 test데이터를 보다 형평성있게 할당하기 위해서


4. 필요없는 데이터를 제거한다.

# 현재 wbcd 데이터 프레임에 id라는 컬럼이 필요없다.

# dataframe에서 컬럼을 제외하고 출력하는 방법으로

# 코드 해석: wbcd_shuffle에서 1번컬럼은 제외하고 나머지 컬럼을 wbcd2에 할당한다.

wbcd2 <- wbcd_shuffle[-1]


5. 데이터를 정규화한다.

# normalize라는 정규화함수를 사용자 정의 함수로 생성한다.

normalize <- function(x) {            return ( (x-min(x)) / (max(x) - min(x)) ) }

ncol <- which(colnames(wbcd2) == "diagnosis")

# lapply(list or vector,function): function을 수행한 결과가 리스트로 리턴됨.

# (굉장히 자주 쓰이는 함수)

# as.data.frame: dataframe으로 변환하는 함수


# factor인 label을 제외하고 normalize한다. wbcd_n <- as.data.frame(lapply(wbcd2[-ncol],normalize))


# 정규화한 data테이블과 제외한 label을 합쳐준다(SQL에서 JOIN과 같은 느낌) wbcd_n <- cbind(wbcd2[1], wbcd_n)



6. train 데이터와 test 데이터로 나눈다. (머신러닝_ 지도학습이기 때문)

# 여기서는 9:1로 나눈다.


train_num<-round(0.9*nrow(wbcd_n),0) wbcd_train<-wbcd_n[1:train_num,] wbcd_test<-wbcd_n[(train_num+1):nrow(wbcd_n),]


7. label과 데이터를 나눈다.

# train 데이터와 test 데이터의 수를 맞춰서 label을 나눈다.

wbcd_train_label <- wbcd2[1:train_num,1] wbcd_test_label <- wbcd2[(train_num+1):nrow(wbcd_n),1]


8. 가장 좋은 k값을 찾는다.

# 없다면 install한다

# install.packages("caret")

# install.packages("e1071")


library(caret) library(e1071)


# repeats가 높아지면 어떠한 max(k)에 수렴함 repeats = 10 numbers = 10 tunel = 10 # "데이터가 부정확, 불완전 또는 불합리한가 어떤가를 확인하기 위해서 사용되는 처리" set.seed(1234) x = trainControl(method = "repeatedcv", # numbers만큼 쪼개겠다. 1개를 validation, 나머지 train 반복 number = numbers, # number 한바퀴가 repeat = 1 repeats = repeats, classProbs = TRUE, summaryFunction = twoClassSummary) model1 <- train(diagnosis~. , data = wbcd_train, method = "knn", preProcess = c("center","scale"), trControl = x, metric = "ROC", tuneLength = tunel)


# 가장 좋은 k값

k_n <- max(model1$bestTune)

> 코드 출처: K Nearest Neighbor : Step by Step Tutorial


9. taining 데이터로 knn모델을 훈련시킨다.

# knn 함수가 있는 library

library(class) result1 <- knn(train=table_train, test=table_test, cl= table_train_label, k = k_n )


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

prop.table( table(ifelse(table1[(mm+1):nrow(table_n), col1]==result1,"o","x" )))


11. 이원 교차표를 그려서 확인한다.

library(gmodels) CrossTable( x= table_test_label, y= result1, prop.chisq=FALSE)

> 이원 교차표: 두 변수 간의 관련성 분석을 위해 한 변수는 열(column)에, 다른 변수는 행(row)에 배치하여 행과 열이 교차하는 칸(cell)에 필요한 빈도(frequency), 백분율(percentage) 등을 나타낸 표
(출처: PART 2. 기초데이터분석 - kocw)


12. 튜닝한다.


1. shuffle set.seed()값 변경하기

2. repeats를 높여본다.



k-NN 알고리즘을 흔히 게으르다고 하는 이유:


엄격한 학습의 정의하에 게으른 학습자는 실제 어떤것도 학습하지 않는다.

대신 훈련데이터를 글자 그대로 저장하기만 한다. (인스턴스 기반, 암기기반이라고 부름)

따라서 훈련이 매우 빠르게 일어난다.

 하지만 실제 훈련단계에서는 아무것도 훈련하지 않기 때문에

예측단계는 상대적으로 느린 경향보인다.





오늘은 여기까지!


이렇게 긴 코드를 디테일하게 설명 해본 적이 없어서

노력은 했는데 잘 전달했는지 모르겠어요~


궁금하신 점은 댓글로 달아주세요!


* 관련 데이터는 저작권확인해보고 올리도록하겠습니다!

반응형

+ Recent posts