Quiet Time


■ 7장 신경망과 서포트 벡터 머신
  • 머신러닝의 3가지 종류
    • 1.지도학습 : 
          -분류: knn, 나이브 베이즈, 결정트리
          -회귀: 선형회귀, 신경망, 서포트 벡터 머신
          2.비지도학습: k-means
          3.강화학습: 핑퐁, 틱텍토

■ 7장 신경망 목차
     1.신경망에 대한 이해
     2.신경망 구조
     3.신경망 실습 
          - 콘크리트 data
          - 보스톤 하우징 data
          - 무성이 발표 data ( 화력발전 데이터, 페이스북 데이터 ) 
     4.서포트 벡터 머신의 이해 
     5.서포트 벡터 머신 실습 
          - 필기체를 컴퓨터가 인식할수 있게 학습 
          - ?
          
■ 1. 신경망에 대한 이해 
          학습 데이터 
               ↓
          학습 규칙 --> 학습 데이터에서 모델을 찾아내는 기법 (신경망) 
               ↓     
     입력 데이터 --->       신경망   --->     결과
 (시멘트,물,강화제, ...)                   콘크리트 강도 
  다음 거리뷰(사진)                        번호판, 사람얼굴

    


          컴퓨터            vs           뇌 
            ↓                           ↓
정보를 메모리의 특정위치 저장          정보를 저장하는 공간이 따로 없다.
                                        ↓
                                  신경세포(뉴런)의 연결관계를 변경하는
                                  방식으로 저장한다.
                                        ↓
                                  신경세포는 그저 다른 신경세포에서 
                                  오는 신호를 받아 자신의 신호를 내보내는
                                  역할만 한다. 


 사람 : 뉴런수 (850억개) 
고양이 : 뉴런수 (10억개)
 쥐   : 뉴런수 (7천5백만개)
바퀴벌레 : 뉴런수 몇백만개 
하루살이 : 최신 최첨단 ANN보다 많다. 




인공 신경망
신경세포(뉴런)
노드
신경세포의 연결
연결 가중치

바이어스: -> 가중치와 함께 신경망의 정보를 저장하는데 관여하는 변수 
v = w1 * x1 + w2 * x2 + w3 * x3 +b
v = wx + b
w = [w1 w2 w3]
x = [x1 x2 x3] ^T

y = f(v)
활성함수 
1. 입력신호의 가중의 합을 구한다
2. 활성함수에 가중합을 입력해 얻은 값을 외부로 출력한다. 






입력층 : 들어오는 신호를 다음 노드에 전달하는 창구역할 
은닉층 : 신경망 외부에서는 이 노드에 직접 접근 할 수 없다. 
출력층 : 노드들의 출력이 신경망의 최종값이 된다. 


단층 신경망 : 입력층 --> 출력층 바로감

다층 신경망 : 

     얕은 신경망 : 입력층 --> 은닉층 -> 출력층
      
     심층 신경망 : 입력층 --> 은닉층 -> 출력층






※ 정규화 
  1. 표준정규분포: scale()
  2. 최대최소변환: normalize() 함수를 만들었음 : ( 0 ~ 1 ) 사이의 값

입력값과 출력 값은 정해져있고

가중치와 바이어스를 역전파로 찾아내는게 신경망 학습의 원리 

실제값과 오차를 구하는 함수 : 비용함수 


■ 신경망의 지도학습
    학습의 종류         학습 데이터
1.지도학습            {입력값, 정답}

     -1. 연습문제 하나를 현재의 지식으로 문제의 답을 구한다.
     -2. 정답과 비교한다.
     -3. 틀렸으면 잘못된 지식(가중치, 바이어스)을 교정한다.
     -4. 모든 문제에 대해서 1 ~ 3번 단계를 반복한다. (역전파)
     
2.비지도 학습         {입력값}

     정답이 없으니 해법을 배우지 못하고 문제의 구문이나 형태를 가지고     
     유형을 나눠보는것 

3.강화학습            {입력값, 출력값, 출력에 대한 점수}

■ 2. 신경망 실습 1 (콘크리트 데이터) 

분석 목적 : 건물의 내구성을 결정하는 콘크리트의 내구려겡 믿을만한 예측 모델 만들기

     입력 재료의 구성 목록을 고려해서 어떻게 입력 재료를 조합했을때 콘크리트의 강도가 높은지를 알아내고 시팓.

     입력값                  출력값
       ↓                      ↓
     콘크리트 재료들         콘크리트 강도 

 UCI의 머신러닝 DATA
1.mount of cement : 콘크리트의 총량
2.slag  : 시멘트
3.ash   : 회분 (시멘트)
4.water :  물
5.superplasticizer : 고성능 감수재(콘크리트 강도를 높이는 첨가제)
6.coarse aggregate : 굵은 자갈
7.fine aggregate : 잔 자갈
8.aging time      : 숙성시간

위의 데이터를 8 : 2 로 나눠서 8을 가지고 훈련을 시키고 모델을 만든다.

2를 가지고 검증을 한다.





##### 7장 : 신경망(Neural Network)과 서포트 벡터 머신(Support Vector Machines) -------------------

##### Part 1: 신경망 -------------------
## 예제 : 콘크리트의 강도 모델링  ----

## 2단계 : 데이터 준비와 살펴보기 ----
# 데이터 읽기와 구조 확인

concrete <- read.csv("concrete.csv")
str(concrete)


# 정규화 함수
normalize <- function(x) { 
  return((x - min(x)) / (max(x) - min(x)))
}


# 전체 데이터 프레임에 정규화 적용
concrete_norm <- as.data.frame(lapply(concrete, normalize))


# 0과1 사이에 범위 확인
summary(concrete_norm$strength)


# 본래 데이터의 최소값, 최대값 비교
summary(concrete$strength)


# 훈련과 테스트 데이터 생성
concrete_train <- concrete_norm[1:773, ]
concrete_test <- concrete_norm[774:1030, ]


## 3단계 : 데이터로 모델 훈련 ----
# neuralnet 모델 훈련
install.packages("neuralnet")
library(neuralnet)


# 하나의 은닉 뉴런에 대한 단순한 ANN
concrete_model <- neuralnet(formula = strength ~ cement + slag +
                              ash + water + superplastic + 
                              coarseagg + fineagg + age,
                              data = concrete_train)


# 망(network) 시각화
plot(concrete_model)


## 4단계 : 모델 성능 평가 ----


# 모델 결과
model_results <- compute(concrete_model, concrete_test[1:8])


# 강도값 예측
predicted_strength <- model_results$net.result


# 예측값과 실제값간의 상관 관계 확인
cor(predicted_strength, concrete_test$strength)


## 5단계 : 모델 성능 향상 ----
# 5개 은닉 뉴런인 복잡한 뉴런망

concrete_model2 <- neuralnet(strength ~ cement + slag +
                               ash + water + superplastic + 
                               coarseagg + fineagg + age,
                               data = concrete_train, hidden = 5)


# 망(network) 시각화
plot(concrete_model2)


# 결과 평가
model_results2 <- compute(concrete_model2, concrete_test[1:8])
predicted_strength2 <- model_results2$net.result
cor(predicted_strength2, concrete_test$strength)








보스톤 주택가격 데이터로 해보자 ! 




##### 7장 : 신경망(Neural Network)과 서포트 벡터 머신(Support Vector Machines) -------------------
##### Part 1: 신경망 -------------------
## 예제 : 콘크리트의 강도 모델링  ----
## 2단계 : 데이터 준비와 살펴보기 ----
# 데이터 읽기와 구조 확인
boston <- read.csv("boston.csv")
str(boston)


# 정규화 함수
normalize <- function(x) {
  return((x - min(x)) / (max(x) - min(x)))
}


# 전체 데이터 프레임에 정규화 적용
boston_norm <- as.data.frame(lapply(boston, normalize))


# 0과1 사이에 범위 확인
summary(boston_norm$MEDV)




# 훈련과 테스트 데이터 생성
boston_train <- boston_norm[1:773, ]
boston_test <- boston_norm[774:1030, ]


## 3단계 : 데이터로 모델 훈련 ----
# neuralnet 모델 훈련
install.packages("neuralnet")
library(neuralnet)

str(boston)
# 하나의 은닉 뉴런에 대한 단순한 ANN
boston_model <- neuralnet(formula = MEDV ~ 
                              data = boston_train)

# 망(network) 시각화
plot(boston_model)


## 4단계 : 모델 성능 평가 ----

# 모델 결과
model_results <- compute(boston_model, boston_test[1:8])

# 강도값 예측
predicted_strength <- model_results$net.result

# 예측값과 실제값간의 상관 관계 확인
cor(predicted_strength, boston_test$strength)


## 5단계 : 모델 성능 향상 ----
# 5개 은닉 뉴런인 복잡한 뉴런망
boston_model2 <- neuralnet(strength ~ cement + slag +
                               ash + water + superplastic +
                               coarseagg + fineagg + age,
                               data = boston_train, hidden = 5)


# 망(network) 시각화
plot(boston_model2)


# 결과 평가
model_results2 <- compute(boston_model2, boston_test[1:8])
predicted_strength2 <- model_results2$net.result
cor(predicted_strength2, boston_test$strength)





  1. R 기본 수업 
  2. R 을 활용한 기계학습
     *머신러닝의 종류 3가지
          1.지도학습
               분류 : KNN, 나이브베이즈, 결정트리, SVM
               회귀 : 회귀분석, 신경망
          2.비지도학습 : K-means
          3.강화학습 : 틱텍토, 핑퐁


서울아산병원 영상분석팀에 취업한 친구가 ...
     포트폴리오 : 틱텍토,오라클 database 
                    
■ 7장 . 신경망과 서포트 벡터 머신 




■ 7장 신경망 목차
     1.신경망에 대한 이해
     2.신경망 구조
     3.신경망 실습 
          - 콘크리트 data
          - 보스톤 하우징 data
          - 무성이 발표 data ( 화력발전 데이터, 페이스북 데이터 ) 
     4.서포트 벡터 머신의 이해 
     5.서포트 벡터 머신 실습 
          - 필기체를 컴퓨터가 인식할수 있게 학습 

■ 7.4 서포트 벡터 머신 

빨간색공과 파란색 공이 모여잇는데 이것을 하나의 끊이지 않는 직선으로 구분하고 싶다면?

무수히 많은 직성을 그을 수 있다. 

y = 2x + 3

d = w^t*x + w0 > 0 : 빨간색
d = w^t*x + w0 < 0 : 파란색





좌표축이 2개면 ? 경계선은 직선의 방적식

좌표축이 3개면 ? 경계면 

d = w^t*x + w0 <- 절편
w0 : 절편
d = 경계면까지의 거리

t== 가중치 벡터 
x == 공의 위치 벡터

경계선(면) 까지의 거리인 d의 부호만으로도 빨간색인지 파란색인지를 알 수 있다.

"공의 위치를 알려주는 위치 벡터가 x라고 한다며 ㄴ
x 의 위치가 경계면 (또는 경계선) 의 위에 있느냐 아래에 있느냐에 따라 d의 
부호가 바뀐다. "

d = w^t + w0



"2차원 평면과 두개의 데이터의 집합이 있다.
그리고 둘 사이의 경계를 주기를 원한다
우리는 이 경계의 넓이를 조절 할 수 있고 
이 경계선의 방향을 조절 할 수 있다. "

우리의 목표는 가능한 적당한 넓이의 경계선을 찾는것이고
그리고 데이터간의 경계를 유지시키는 것이다.


이 구분의 경계선의 직선의 방정식은

w^t      *      x      +      b = 0
↓               ↓             ↓ 
normal vector 공의 위치벡터     scalar vector (바이어스)

바이어스는 원점으로 부터의 변위를 제어한다
두 분리선에는 어느정도 margin을 각각 갖게 한다
우리는 normal vector의 각도를 변경함으로써 여유를 회전시킨다.
그리고 바이어스를 조정함으로써 저 경계선을 이동시킨다. 



1.set1.csv를 로드하고 plot 를 그래프로 본다

set1 <- read.csv("set1.csv", header = T , stringsAsFactors = F)
set1

plot(set1)

install.packages("MASS")
library(MASS)
density <- kde2d(set1$food, set1$book, n=400)
image(density, xlab = "food", ylab="book")



설명 : 가운데 평균점 근처에 모여있는 데이터가 보통 사람들의데이터이다.
이들을 분류하기 위하여 어떠한 방법을 쓸수 있는가 .

svm을 이용해서 분류를 해보자


  1. svm 으로 보통사람들(중산층)을 분류
install.packages("e1071")
library(e1071)

m1 <- svm(status ~ food + book + cul + cloth + travel, 
     type ="C-classification", data= set1)

m1 
  1. 이모델이 얼마나 정확한지 기존 훈련 데이터로 평가를 해본다.

predict(m1, set1)

cbind(set1, predict(m1, set1))

  1. 예측한 결과와 실제와의 차이
sum(set1$status != predict(m1, set1)) 

12

88%의 정확도를 가지고 있네여 !

문제228. (점심시간문제) 보스톤 하우징 데이터를 이용해서 
     svm테스트를 하는데 CAT. MEDV가 0과1 로 구분 되는데 
     SVM으로 0과 1의 정확도가 어떻게 나오는지 테스트하시오  !
boston_norm <- as.data.frame(lapply(boston, normalize))

m1 <- svm(CAT..MEDV~ .,  type ="C-classification", data= boston_norm )


cbind(boston_norm$CAT..MEDV+1,predict(m1, boston_norm ))

sum(boston_norm $CAT..MEDV  != predict(m1, boston_norm )) 



m1 <- svm(CAT..MEDV~ .,  type ="C-classification", data= boston_norm )

library(caret)

confusionMatrix(table(boston_norm $CAT..MEDV  , predict(m1,boston_norm )))


 
■ 서포트 벡터 머신 실습
  1. 중산층 분류 실습
  2. 필기체 분류 숫자 
  3. 필기체 분류 영어





install.packages("caret")

install.packages("doParallel")

install.packages("kernlab")

install.packages("ggplot2")

install.packages("lattice")

library(ggplot2)

library(lattice)

library(kernlab)

library(caret)

library(doParallel)


# Enable parallel processing.


cl <- makeCluster(detectCores())

registerDoParallel(cl)


# Load the MNIST digit recognition dataset into R

# http://yann.lecun.com/exdb/mnist/

# assume you have all 4 files and gunzip'd them

# creates train$n, train$x, train$y  and test$n, test$x, test$y

# e.g. train$x is a 60000 x 784 matrix, each row is one digit (28x28)

# call:  show_digit(train$x[5,])   to see a digit.

# brendan o'connor - gist.github.com/39760 - anyall.org


load_mnist <- function() {

  load_image_file <- function(filename) {

    ret = list()

    f = file(filename,'rb')

    readBin(f,'integer',n=1,size=4,endian='big')

    ret$n = readBin(f,'integer',n=1,size=4,endian='big')

    nrow = readBin(f,'integer',n=1,size=4,endian='big')

    ncol = readBin(f,'integer',n=1,size=4,endian='big')

    x = readBin(f,'integer',n=ret$n*nrow*ncol,size=1,signed=F)

    ret$x = matrix(x, ncol=nrow*ncol, byrow=T)

    close(f)

    ret

  }

  load_label_file <- function(filename) {

    f = file(filename,'rb')

    readBin(f,'integer',n=1,size=4,endian='big')

    n = readBin(f,'integer',n=1,size=4,endian='big')

    y = readBin(f,'integer',n=n,size=1,signed=F)

    close(f)

    y

  }

  train <<- load_image_file('train-images.idx3-ubyte')

  test <<- load_image_file('t10k-images.idx3-ubyte')

  

  train$y <<- load_label_file('train-labels.idx1-ubyte')

  test$y <<- load_label_file('t10k-labels.idx1-ubyte')  

}

#필기체의 글씨가 무엇인지 확인하는 함수 

show_digit <- function(arr784, col=gray(12:1/12), ...) {

  image(matrix(arr784, nrow=28)[,28:1], col=col, ...)

}


train <- data.frame()

test <- data.frame()


# Load data.


load_mnist()


# Normalize: X = (X - min) / (max - min) => X = (X - 0) / (255 - 0) => X = X / 255.

#나눠서 정규화 ㅎㅎ

train$x <- train$x / 255


# Setup training data with digit and pixel values with 60/40 split for train/cv.


inTrain = data.frame(y=train$y, train$x)

inTrain$y <- as.factor(inTrain$y)

trainIndex = createDataPartition(inTrain$y, p = 0.60,list=FALSE)

training = inTrain[trainIndex,]

cv = inTrain[-trainIndex,]
# cv 가 테스트 데이터얌 ㅎㅎ

# SVM. 95/94.


fit <- train(y ~ ., data = head(training, 1000), method = 'svmRadial', tuneGrid = data.frame(sigma=0.0107249, C=1))


results <- predict(fit, newdata = head(cv, 1000))
                         ↑
                         모델

results


confusionMatrix(results, head(cv$y, 1000))



show_digit(as.matrix(training[5,2:785]))


# Predict the digit.


predict(fit, newdata = training[5,])


# Check the actual answer for the digit.


training[5,1]




























 


 
 


R 5장. 결정트리

R(알) 2017. 9. 8. 19:27
■ 어제까지 배운 R 수업 복습
  1. R기본수업
  2. R머신러닝 
          - 머신러닝을 이해하기 위한 R 기본문법
          - knn
          - 나이브베이즈 
          - 결정트리 
          - 회귀 (단순,다중) 
          - 신경망
          - 서포트벡터 머신
          - ...

*머신러닝의 종류3가지중에 
1.지도학습: 
      분류: knn, 나이브 베이즈 
      회귀: 

2.비지도 학습
3.강화학습

   P(비아그라|스팸)*P(돈|스팸)*P(식료품|스팸)*P(주소삭제|스팸)*P(스팸)

문제199. 나이가 20대이고 성별이 여자이고 직업이 IT이고 미혼인 여자가 공포영화를 선택할 확률?

P(20대,여자,IT,미혼 | '공포영화' ) =

P(20대 |'공포영화' ) * P(여자 |'공포영화' ) * P(IT |'공포영화' ) * P(미혼|'공포영화' )

이렇게 계산하느게 naive bayes의 전부이다. 

nm <- naiveBayes(movie[1:5], movie$장르, laplace=0)
nm

문제200. 4장의 실습예제인 스팸과 햄 메일을 구분하는 실습을 진행해서 
     아래의 결과를 도출 하시오! 







sms csv파일이 잇는데 이파일은 text(메세지)와 라벨(type)로 구성된 데이터가 있다.
라벨은 ham, spam으로 구분되어있는 라벨이다
          ↓
데이터를 클린징 하는 작업 (데이터 정제 작업) 
          ↓
메일메세지를 단어별로 구분해서 메일별로 단어가 몇번 사용되었는지 빈도수를 표형태로 만든다. 
          ↓
훈련 데이터와 테스트 데이터로 데이터를 나누고 --> 워드 클라우드 그림 
          ↓
훈련 데이터로 나이브 베이즈 모델을 만든다.
          ↓
테스트 데이터로 위에서 만든 모델로 스팸인지 햄인지를 예측 
          ↓
예측을 잘 했는지 확인한다(crosstable) 








## 예제 : 스팸 SMS 메시지 제거 ----
## 2 단계 : 데이터 준비와 살펴보기  ----

# sms 데이터 프레임으로 sms 데이터 읽기
sms_raw <- read.csv("sms_spam.csv", stringsAsFactors = FALSE)

# sms 데이터 구조
str(sms_raw)

# 팩터로 spam/ham으로 변환
sms_raw$type <- factor(sms_raw$type)

# 변수형 확인
str(sms_raw$type)
table(sms_raw$type)

# 텍스트 마이닝(tm) 패키지를 사용하여 말뭉치 생성
install.packages("tm")
library(tm)
sms_corpus <- Corpus(VectorSource(sms_raw$text))

# sms 말뭉치 확인
print(sms_corpus)
inspect(sms_corpus[1:3])
# 로케일을 us(미국)으로 변경해주는 작업을 해줘야 한다. 
Sys.setlocale(category = "LC_ALL", locale = "us")

# tm_map() 사용하여 말뭉치 정리 ( 데이터 정제 작업) 

corpus_clean <- tm_map(sms_corpus, tolower)
# 설명 : 전부 소문자로 바꾸겠다.

corpus_clean <- tm_map(corpus_clean, removeNumbers)
# 설명 : 숫자를 다 제거하겠다.

corpus_clean <- tm_map(corpus_clean, removeWords, stopwords())
# 설명 : to, and, but, or 를 제거한다.

corpus_clean <- tm_map(corpus_clean, removePunctuation)
# 설명 : 마침표(.) 제거한다. 

corpus_clean <- tm_map(corpus_clean, stripWhitespace)
# 설명 : 공백을 제거한다.

# 말뭉치 정리 확인
inspect(sms_corpus[1:3])
inspect(corpus_clean[1:3])

# 문서-용어 희소 매트릭스 생성 ( 책 150페이지의 표와 같은 형태로 변환) 
sms_dtm <- DocumentTermMatrix(corpus_clean)
sms_dtm

# 훈련과 테스트 데이터셋 생성
sms_raw_train <- sms_raw[1:4169, ] # 원래 데이터 (훈련)
sms_raw_test  <- sms_raw[4170:5559, ] # 원래 데이터 (테스트)

sms_dtm_train <- sms_dtm[1:4169, ] # 정제후의 표현태 변경한 데이터(훈련)
sms_dtm_test  <- sms_dtm[4170:5559, ] # 정제후의 표형태 변경한 데이터(테스트) 

sms_corpus_train <- corpus_clean[1:4169] # 정제후의 데이터 (훈련)
sms_corpus_test  <- corpus_clean[4170:5559] # 정제후의 데이터 (테스트)

# 스팸 비율 확인
prop.table(table(sms_raw_train$type)) #훈련데이터의   스팸 : 80%  햄 : 20% 
prop.table(table(sms_raw_test$type))  #테스트데이터의 스팸 : 80%  햄 : 20%

# 단어 클라우드 시각화 (워드 클라우드로 햄의 단어가 무엇이고 
#                    스팸의 단어가 무엇인지 확인하는 작업) 
# R 을 2.15.3(2013-03-01) 로 설치하고 아래 패키지를 install 해야함
install.packages("Rcpp")
install.packages("wordcloud")



library(wordcloud)

wordcloud(sms_corpus_train, min.freq = 30, random.order = FALSE)

# 훈련 데이터를 스팸과 햄으로 구분
spam <- subset(sms_raw_train, type == "spam")
ham  <- subset(sms_raw_train, type == "ham")

wordcloud(spam$text, max.words = 40, scale = c(3, 0.5))
wordcloud(ham$text, max.words = 40, scale = c(3, 0.5))

# 빈번한 단어에 대한 속성 지시자
findFreqTerms(sms_dtm_train, 5) # 5개 이상사용된 단어만 다시 추출
sms_dict <- Dictionary(findFreqTerms(sms_dtm_train, 5))
sms_train <- DocumentTermMatrix(sms_corpus_train, list(dictionary = sms_dict))
sms_test  <- DocumentTermMatrix(sms_corpus_test, list(dictionary = sms_dict))

# 개수를 팩터로 변환 (라벨의 1과 0으로 변경하고 1과 0을 yes와 no로 변경하는 작업) 
convert_counts <- function(x) {
  x <- ifelse(x > 0, 1, 0)
  x <- factor(x, levels = c(0, 1), labels = c("No", "Yes"))
}

# apply() convert_counts()를 사용한 훈련/테스트 데이터 추출
sms_train <- apply(sms_train, MARGIN = 2, convert_counts)
sms_test  <- apply(sms_test, MARGIN = 2, convert_counts)

## 3 단계 : 데이터로 모델 훈련 ----
install.packages("e1071")
library(e1071)
sms_classifier <- naiveBayes(sms_train, sms_raw_train$type)
sms_classifier

## 4 단계 : 모델 성능 평가 ----
sms_test_pred <- predict(sms_classifier, sms_test)

install.packages("gmodels")
library(gmodels)
CrossTable(sms_test_pred, sms_raw_test$type,
           prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,
           dnn = c('predicted', 'actual'))

## 5 단계 : 모델 성능 향상 ----
sms_classifier2 <- naiveBayes(sms_train, sms_raw_train$type, laplace = 1)
sms_test_pred2 <- predict(sms_classifier2, sms_test)
CrossTable(sms_test_pred2, sms_raw_test$type,
           prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,
           dnn = c('predicted', 'actual'))



문제201. mushroom dataset을 활용한 나이브 베이즈 분석을 하시오 ! 



install.packages('rpart')
library(rpart)

tree1 <- rpart(mushroom[,1] ~. , data= mushroom[,-1] , control=rpart.control(minsplit=2) )

plot(tree1, compress = T , uniform = T , margin=0.1)

text(tree1, use.n = T , col = "blue")

□ 5장 . 결정트리 (p164)
  • 머신러닝의 종류 3가지
1.지도학습 : 
     - 분류 : knn, naivebayes, decision tree
     - 회귀 : 회귀(6장)

2.비지도학습
3.강화학습

■ 5장. 목차 
 1.결정트리란?
 2.엔트로피와 정보획득량
 3.결정트리 실습1(은행의 대출 위험 기업 확인) 
 4.결정트리 실습2(배드민턴 데이터와 자동차 평가)

■ 1.결정트리란?

 학습 데이터를 가지고 아래와 같은 트리구조의 학습 모델을 만들어서
 새로운 테스트 데이터에 대한 라벨을 예측하는 알고리즘

 그림 : 5장. 결정트리 이미지 첫번째  


■ 결정트리가 사용되는 곳?
 1.지원자에게 거절된 이유를 명시해야하는 신용등급 모델
      예 : 은행 대출, 회사 인사 채용

 2.변심이 심한 고객이나 고객 만족은 관리하는 부서와 광고부서에서 공유되어야 하는 시장조사
      예: 스킨샵 쿠폰반응

 3.연구 측정, 증상, 매우 드문 질병 진행 과정을 바탕으로한 질병 관찰 
     예: 지방간 

■ 결정트리의 장단점 
 - 장점: 1.모든 문제에 적합한 분류기
        2.결측치, factor, number를 잘 처리할 수 있다.
        3.가장 중요한 속성만 사용
        4.다른 복잡한 모델보다 높은 효율

 - 단점: 1.모델이 쉽게 오버피팅 되거나 언더피팅이 됨
        2.훈련데이터에 약간의 변경이 잇어도 결정트리에 큰 변화를 준다.


■ 최적의 구분 선택 (p170)
  결정트리를 만들때 가장 먼제 해야할 것은 컬럼(변수)들중 가장 중요한 
  컬럼(변수)를 찾는것 이다. 중요한 변수는 정보획득량이 가장 높은 변수를
  말한다.
               ↓
     정보획득량이 높은 변수를 알아내려면 뭘 먼저 알아야 하는가?
               ↓
     엔트로피(entrophy) 함수

■  엔트로피(entrophy) 함수(불확실성)

     "데이터의 불확실성이 얼마나 되는가 ? "

     이 값이 커지면 커질수록 불확실성이 커진다

 예: 1. 확률(p) ====> x 축
     2.엔트로피(불확실성) ----> y 축 (공식 : -p * log(p) ) 

> -0.60 * log2(0.60) - 0.40 * log2(0.40)
[1] 0.9709506
> curve(-x * log2(x) - (1 - x) * log2(1 - x), col="red", xlab = "x", ylab = "Entropy", lwd=4)


설명 : 부자거나(x축 1) 부자가 아니거나 (x축 0)이면 
       불확실성 (엔트로피) y 축이 0이다.

  • 결정트리를 구하려면 ?
          어떤 컬럼을 가장 먼저 물어볼것인가를 결정해야한ㄷ
          정보획득량이 높은 컬럼을 가장 먼저 물어보게해야한다.
      정보획득량 = 분할전 엔트로피 - 분할후 엔트로피

문제202. 아래의 데이터 프레임을 만드시오 ! 


x <- data.frame(
cust_name=c('SCOTT','SMITH','ALLEN','JONES','WARD'),
card_yn=c('Y','Y','N','Y','Y'),
review_yn=c('Y','Y','N','N','Y'),
before_buy_yn=c('Y','Y','Y','N','Y'),
buy_yn=c('Y','Y','N','Y','Y') )


문제203. 위의 구매 데이터의 정보 획득량을 구하시오 

install.packages("FSelector")
library(FSelector)

weights<- information.gain(buy_yn~.,x)
print(weights )
 



문제204. skin.csv를 내려받고 R로 로드한 후에 skin데이터셋 변수들의 
        정보획득량을 구하시오  ~

skin <- read.csv("skin.csv",header = T)
weights<- information.gain(cupon_react~.,skin )
print(weights )



문제205. 위의 정보를 가지고 결정트리를 그리시오 

install.packages('rpart')
library(rpart)

tree1 <- rpart(cupon_react~. , data= skin, control=rpart.control(minsplit=2) )

plot(tree1, compress = T , uniform = T , margin=0.1)

text(tree1, use.n = T , col = "blue")


문제206. 지방간 데이터의 정보획득량을 구하시오 

fatliver<- read.csv("fatliver2.csv",header =T)
weights<- information.gain(FATLIVER~.,fatliver)
print(weights)



tree1 <- rpart(FATLIVER ~. , data= fatliver , control=rpart.control(minsplit=2) )

plot(tree1, compress = T , uniform = T , margin=0.1)

text(tree1, use.n = T , col = "blue")


 




##### 5장 : 결정 트리와 규칙(Decision tree and Rules)을 사용한 분류 -------------------
#### Part 1: 결정 트리 -------------------
## 결정 트리 이해 ----
# 두 부분 분류의 엔트로피 계산
-0.60 * log2(0.60) - 0.40 * log2(0.40)
curve(-x * log2(x) - (1 - x) * log2(1 - x),
      col="red", xlab = "x", ylab = "Entropy", lwd=4)
## 예제 : 위험 은행 대출 식별 ----
## 2 단계 : 데이터 준비와 살펴보기 ----
credit <- read.csv("credit.csv")
str(credit)
# 지원자의 두 특성 확인
table(credit$checking_balance)
table(credit$savings_balance)
# 대출의 두 특성 확인
summary(credit$months_loan_duration)
summary(credit$amount)
# 분류 변수 확인
table(credit$default)
# 훈련과 테스트 데이터에 대한 무작위 샘플 생성
# 예제와 같은 무작위 수열을 사용하기 위해 set.seed 사용
set.seed(12345)
credit_rand <- credit[order(runif(1000)), ]
# credit과 credit_rand 데이터 프레임간 비교
summary(credit$amount)
summary(credit_rand$amount)
head(credit$amount)
head(credit_rand$amount)
# 데이터 프레임 나누기
credit_train <- credit_rand[1:900, ]
credit_test  <- credit_rand[901:1000, ]
# 분류 변수의 비율 확인
prop.table(table(credit_train$default))
prop.table(table(credit_test$default))
## 3 단계 : 데이터로 모델 훈련 ----
# 가장 단순한 결정 트리 생성
library(C50)
credit_model <- C5.0(credit_train[-17], credit_train$default)
# 트리 정보 출력
credit_model
# 트리에 대한 상세 정보 출력
summary(credit_model)
## 4 단계 : 모델 성능 평가 ----
# 테스트 데이터에 대한 예측 팩터 벡터 생성
credit_pred <- predict(credit_model, credit_test)
# 예측과 실제 분류의 교차표
library(gmodels)
CrossTable(credit_test$default, credit_pred,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))
## 5 단계 : 모델 성능 향상 ----
## 결정 트리의 정확성 부스팅
# 10 trials과 부스트드 결정 트리
credit_boost10 <- C5.0(credit_train[-17], credit_train$default,
                       trials = 10)
credit_boost10
summary(credit_boost10)
credit_boost_pred10 <- predict(credit_boost10, credit_test)
CrossTable(credit_test$default, credit_boost_pred10,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))
# 100 trials과 부스트드 결정 트리
credit_boost100 <- C5.0(credit_train[-17], credit_train$default,
                        trials = 100)
credit_boost_pred100 <- predict(credit_boost100, credit_test)
CrossTable(credit_test$default, credit_boost_pred100,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))
## 가중치 매트릭스 생성
# 가중 비용 매트릭스
error_cost <- matrix(c(0, 1, 4, 0), nrow = 2)
error_cost
# 트리에 비용 매트릭스 적용
credit_cost <- C5.0(credit_train[-17], credit_train$default,
                    costs = error_cost)
credit_cost_pred <- predict(credit_cost, credit_test)
CrossTable(credit_test$default, credit_cost_pred,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))
#### Part 2: 규칙 학습기 -------------------


> table(credit$checking_balance)

    < 0 DM   > 200 DM 1 - 200 DM    unknown
       274         63        269        394
> table(credit$savings_balance)

     < 100 DM     > 1000 DM  100 - 500 DM 500 - 1000 DM       unknown
          603            48           103            63           183

설명 : 대출 신청사의 에금계좌와 적금계좌의 예금정도를 확인해서 예금액이 많을 수록 대출이 안전하다고 가정할 수 있다.


> summary(credit$months_loan_duration)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    4.0    12.0    18.0    20.9    24.0    72.0

설명 : 대출 기간이 짧게는 4달에서 기게는 72개월까지 분포가 됨

> summary(credit$amount)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    250    1366    2320    3271    3972   18420 

설명 : 대출 금액은 독일돈으로 205 마르크 ~ 184020 마르크 
     100 마르크가 6~ 7만원 정도 한다

table(credit$default)
#분류 변수 확인 ( default 가 라벨인데 대출금 상환했는지 상환안했는지 ) 
table(credit$default)
no yes
700 300

설명 : 대출자가 협의한 반납기간 안에 대출금을 반납했는지 안했는지 나타냄.
      채무이행자가 300명 , 채무불이행자가 700명

set.seed(12345)
credit_rand <- credit[order(runif(1000)), ]

runif(10)
order(runif(1000))

설명 : runif(10)이라고 하면 0과 1사이의 10개의 숫자가 랜덤으로 출력된다.
order(runif(1000)) 라고 하면 무작위 숫자가 1000개가 출력된다. 
credit[order(runif(1000)),] 하면 행을 무작위로 섞어서 결과를 출력해준다.

서머리는 같지만 잘 섞였음 

#분류 변수의 비율 확인
       no       yes
0.7022222 0.2977778
> prop.table(table(credit_test$default))

  no  yes
0.68 0.32

위의 데이터에 결정트리 기계학습ㅇ르 하려는 목적?

  지금 채무 불이행자가 70% 가 되는데  이 채무 불이행자의 수치를 낮추는것이 (30%로 떨어짐) 이 기계학습의 목표이다.

## 3단계 : 데이터로 모델 훈련
# 가장 단수한 결정 트리 생성
install.packages("C50")
library(C50)
credit_model <- C5.0(credit_train[-17], credit_train$default)
                      

summary(credit_model)


Evaluation on training data (900 cases):

        Decision Tree
      ----------------
      Size      Errors

        66  125(13.9%)   <<

       (a)   (b)    <-classified as
      ----  ----
       609    23    (a): class no
       102   166    (b): class yes
설명: 13.9% 의 오차로 125개를 잘못 분류했다.
     23개는 실제값은 no이지만 yes로 잘못 분류했고 
     102개는 실제값은 yes이지만 no로 잘못분류했다. 

credit_pred <- predict(credit_model, credit_test)
cbind(credit_test, credit_pred)

CrossTable(credit_test$default, credit_pred,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))



               | predicted default
actual default |        no |       yes | Row Total |
---------------|-----------|-----------|-----------|
            no |        57 |        11 |        68 |
               |     0.570 |     0.110 |           |
---------------|-----------|-----------|-----------|
           yes |        16 |        16 |        32 |
               |     0.160 |     0.160 |           |
---------------|-----------|-----------|-----------|
  Column Total |        73 |        27 |       100 |
---------------|-----------|-----------|-----------|

57 + 16 = 73, 11 + 16 = 27
73% 는 정확히 예측 
27% 는 정확히 예측하지 못함 

## 5 단계 : 모델 성능 향상 ----
## 결정 트리의 정확성 부스팅
# 10 trials과 부스트드 결정 트리
credit_boost10 <- C5.0(credit_train[-17], credit_train$default,
                       trials = 10)
credit_boost10
summary(credit_boost10)

Evaluation on training data (900 cases):

Trial        Decision Tree
-----      ----------------
      Size      Errors

   0        66  125(13.9%)
   1        40  205(22.8%)
   2        46  196(21.8%)
   3        45  193(21.4%)
   4        68  163(18.1%)
   5        62  175(19.4%)
   6        56  186(20.7%)
   7        62  188(20.9%)
   8        66  156(17.3%)
   9        49  200(22.2%)
boost             31( 3.4%)   <<

       (a)   (b)    <-classified as
      ----  ----
       626     6    (a): class no
        25   243    (b): class yes

credit_boost_pred10 <- predict(credit_boost10, credit_test)
CrossTable(credit_test$default, credit_boost_pred10,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))
# 100 trials과 부스트드 결정 트리
credit_boost100 <- C5.0(credit_train[-17], credit_train$default,
                        trials = 100)
credit_boost_pred100 <- predict(credit_boost100, credit_test)
CrossTable(credit_test$default, credit_boost_pred100,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))


               | predicted default
actual default |        no |       yes | Row Total |
---------------|-----------|-----------|-----------|
            no |        61 |         7 |        68 |
               |     0.610 |     0.070 |           |
---------------|-----------|-----------|-----------|
           yes |        15 |        17 |        32 |
               |     0.150 |     0.170 |           |
---------------|-----------|-----------|-----------|
  Column Total |        76 |        24 |       100 |
---------------|-----------|-----------|-----------|

## 가중치 매트릭스 생성
# 가중 비용 매트릭스
error_cost <- matrix(c(0, 1, 4, 0), nrow = 2)
error_cost
# 트리에 비용 매트릭스 적용
credit_cost <- C5.0(credit_train[-17], credit_train$default,
                    costs = error_cost)
credit_cost_pred <- predict(credit_cost, credit_test)
CrossTable(credit_test$default, credit_cost_pred,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))
#### Part 2: 규칙 학습기 -------------------






badminton <- read.csv("badminton.csv",header=T)
install.packages("C50")
library(C50)
x <- badminton [1:4]
y <- badminton [,5]
model <- C5.0(x,y) 
model
summary(model)
plot(model)
p <- predict(model,x,type="class")
sum(p==y)/length(p)




문제207. **이가 첫번째로 발표한 차 평가에 관련한 결정트리 실습 코드에 
         예측하는 predict을 추가해서 실제 라벨과 예측 라벨의 
          차이를 한눈에 보여주는 CrossTable결과를 출력하시오 
car_evaluation <- read.csv("car_evaluation.csv",head=T)
head(car_evaluation)

install.packages("C50")
library(C50)
x <- car_evaluation[,2:7]
y <- car_evaluation[,1]     #기준이 되는 컬럼
model <- C50::C5.0(x,y)
model
summary(model)
plot(model)


또는


x <- car_evaluation[,2:7]
build_tree <- C5.0(car_evaluation$buyingprice~.,data=x)
summary(build_tree)
plot(build_tree)


p <- predict(model,x,type="class")
sum(p==y)/length(p)

CrossTable(car_evaluation[,1] ,p)

> CrossTable(car_evaluation[,1] ,p)
Error in CrossTable(car_evaluation[, 1], p) :
  함수 "CrossTable"를 찾을 수 없습니다
> library(gmodels)
경고메시지(들):
패키지 ‘gmodels’는 R 버전 3.4.1에서 작성되었습니다
> CrossTable(car_evaluation[,1] ,p)


   Cell Contents
|-------------------------|
|                       N |
| Chi-square contribution |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|


Total Observations in Table:  1728


                    | p
car_evaluation[, 1] |      high |       low |       med |     vhigh | Row Total |
--------------------|-----------|-----------|-----------|-----------|-----------|
               high |        46 |        13 |        49 |       324 |       432 |
                    |    16.480 |    29.484 |     0.146 |     1.528 |           |
                    |     0.106 |     0.030 |     0.113 |     0.750 |     0.250 |
                    |     0.451 |     0.062 |     0.237 |     0.268 |           |
                    |     0.027 |     0.008 |     0.028 |     0.188 |           |
--------------------|-----------|-----------|-----------|-----------|-----------|
                low |         0 |       121 |        53 |       258 |       432 |
                    |    25.500 |    90.461 |     0.030 |     6.546 |           |
                    |     0.000 |     0.280 |     0.123 |     0.597 |     0.250 |
                    |     0.000 |     0.579 |     0.256 |     0.213 |           |
                    |     0.000 |     0.070 |     0.031 |     0.149 |           |
--------------------|-----------|-----------|-----------|-----------|-----------|
                med |        10 |        75 |        79 |       268 |       432 |
                    |     9.422 |     9.906 |    14.349 |     3.935 |           |
                    |     0.023 |     0.174 |     0.183 |     0.620 |     0.250 |
                    |     0.098 |     0.359 |     0.382 |     0.221 |           |
                    |     0.006 |     0.043 |     0.046 |     0.155 |           |
--------------------|-----------|-----------|-----------|-----------|-----------|
              vhigh |        46 |         0 |        26 |       360 |       432 |
                    |    16.480 |    52.250 |    12.813 |    10.930 |           |
                    |     0.106 |     0.000 |     0.060 |     0.833 |     0.250 |
                    |     0.451 |     0.000 |     0.126 |     0.298 |           |
                    |     0.027 |     0.000 |     0.015 |     0.208 |           |
--------------------|-----------|-----------|-----------|-----------|-----------|
       Column Total |       102 |       209 |       207 |      1210 |      1728 |
                    |     0.059 |     0.121 |     0.120 |     0.700 |           |
--------------------|-----------|-----------|-----------|-----------|-----------|


내일 : 6장. 회귀분석 
      7장 .신경망 (앞부분 까지)






스킨데이터 트리 그리기 !
























 



























 



 


▦ 4장. 나이브 베이즈의 이해
□4장. 목차
     1.나이브 베이즈를 이해하기 위한 기본 통계개념
          - 1.1 확률로 인한 데이터 분류
          - 1.2 확률
          - 1.3 결합확률
          - 1.4 베이즈 이론과 조건부 확률
2.나이브 베이즈 알고리즘 
     - 2.1 나이브 베이즈 분류
     - 2.2 라플라스 추정기

3.나이브 베이즈 실습 예제 
     - 3.1 영화장르
     - 3.2 스팸메일 분류1 (다른 예제)
     - 3.3 스팸메일 분류2 (책)

  1. 나이브베이즈를 이해하기 위한 기본 통계개념 (p128)
-1.1 확률로 인한 데이터 분류
- 기상학자가 날시예보를 할대 일반적으로 '비올확률 70%'
라는 용어를 사용해 예측한다

이 70%는 과거의 사건 데이터를 사용한것인데 과거에 이런 경우 10번중 7번은 비가왔음을 의미하는것이다.
- 베이즈 기법 기반인 분류기는 분류되지 않은 데이터를 분류기가 분류할때 새로운 속성에 대한 가장 유사하나 범주를 예측하기위해 관찰된 확률을 사용하고 이 관찰된 확률은 훈련데이터에 의해 미리 계산되어진다

훈련데이터 -----> 관찰된 확률
실제데이터 -----> 관찰된 확률을 이용해 분류를한다.

무엇을 분류하는 것인가?

  1. 스팸 메일 분류
  2. 컴퓨터 네트워크에 침힙한 이상징후를 분류
  3. 관찰된 증상을 고려한 질병 관찰


스팸 vs 햄

2차 대전때 영국식당에 먹으렉 스팸밖에 없어서 스팸이라는 말을 끊임 없이 써서 희화된 단어 

□ 1.2확률 (p130)
- 사건 
     사건이란 ? 화창하거나 또는 비가 올 날씨 
               동전 던지기에서 동전의 앞면과 뒷면
               스팸 이메일과 햄 이메일이 같이 일어날 수 있는 결과 

1.독립사건 : 두 사건이 서로 전혀 연관되이 않는다면 그건 독립사건 ,동전던지기와 날씨
P(A ∩ B) = P(A) * P(B)
P(A | B) = P(A) B사건은 A에 영향을 주지 않는다. 
==  는 사건B가 일어날때 사건 A의 확률이라고 읽는다. 
P(A | B) = P(A)
== 는 사건A가 일어났을 때 사건 B의 확률

2.종속사건 : 
사건 A가 일어났을 경우와 일어나지 않았을 경우에 따라서
사건B가 일어날 확률이 다를때 B는 A의 종속사건
P(A ∩ B) = P(A) * P(B)
P(A ∩ B) = P(A) * P(A | B)
         = P(B) * P(B | A)
P(A | B) = P(A ∩ B) / P(B)
P(B | A) = P(A ∩ B) / P(A)
3.배반사건
P(A U B) = P(A) + P(B)

문제194. (점심시간문제) 스팸 메일일 확률이 20% 이고 햄 메일일 확률이 80%이면 
스팸이 아닐 확률은 얼마인가?

스팸일 확률 : P(스팸) = 0.2 
햄일 확률   : P(햄) = 0.8
P(~스팸) : 0.8

▩ 1.3 결합확률 
책 131 페이지에 나온것 처럼 일부사건이 흥미로운 사건과 함께 일어났다면 예측하기 위해 흥미로운 사건을 사용할 수 있을것이다. 
모든 메세지의 20% 는 스팸이고 모든 메세지의 5%는 비아그라가 들어있다.

P(스팸) 과 P(비아그라)가 함께 일어날 확률은 ? 

P(스팸 ∩ 비아그라) 로 추정한다 .
P(스팸 ∩ 비아그라) 를 계산하면 (점심시간문제) - 독립사건이라면 ? 
0.01 %

▩ 1.4 베이즈 이론과 조건부 확률 (종속사건) 

사건 B 가 일어날때 사건 A의 확률은 아래와 같이 표시한다. 
P(A | B) = P(A ∩ B) / P(B)

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

            P(A ∩ B)         P(B|A) *  P(B)
P(A | B) = ------------ = ------------------
              P(B)            P(B)

                  P(스팸 ∩ 비아그라)      P(비아그라|스팸) * P(스팸)
P(스팸|비아그라) = ------------------- = -------------------------
                     P(비아그라)                P(비아그라)

설명 : 비아그라가 메일 메세지에 있을 때 스팸일 확률은 ? 

 우도 ? 가능도 (Likelyhood) 

  사건에는 1. 셀 수 있는 사건 ( 가능도 = 확률 )
          예 : 주사위를 던져서 나올 수 있는 숫자 1,2,3,4,5,6
               숫자가 나올 확률이 1/6로 모두 같고 각각의 확률을 합하면 
               확률은 1이 된다. 

          2.연속사건 (가능도 !=  확률) 
          예 : 1에서 6사이의 숫자중에 랜덤으로 아무 숫자를 뽑는다고 할때
               정확히 5가 뽑힐 확률은 얼마인가?

               1
            -------  = 0  <---- 연속사건은 확률이 0으로 계산이 된다.
             무한대
               
               그래서 사건이 일어날 가능성을 비교하는게 불가능하며 
               가능도 (likelyhood)라는 개념을 적용해야 이를 비교할 수 있다.

            우도 * 사전확률
사후 확률 = ----------------- 
              주변우도

  • 내일 시험문제지롱!!!
      비아그라
우도  YES  NO      총합
스팸  4/20 16/20    20
 햄   1/80 79/80    80
     5/100 95/100  100
                  P(비아그라|스팸) * P(스팸)      0.2 * 0.2
P(스팸|비아그라) = -------------------------  =  --------- = 0.8
                    P(비아그라)                    0.05

비아그라가 메세지 단어에 포함되어있으면 스팸일 확률이 80%가 된다.


문제195. 미진누나가 올려준 실습예제1의 메일에서 비아그라가 메세지에 포함되어 있으면 스팸일 확률은 어떻게 되는가?
           

                  P(비아그라|스팸) * P(스팸)      2/3 * 0.3
P(스팸|비아그라) = -------------------------  =  ---------- = 0.5
                    P(비아그라)                     0.4

▩ 2. 나이브 베이즈 알고리즘 (p 135) 

나이브 베이즈 알고리즘은 분류를 위해 베이즈 이론을 사용하는 애플리케이션이다

이름 그대로 순진한 가정을 하는것으로 데이터의 모든 속성을 동등하게 중요하며 독립적이라고 가정한다

장점: 1. 단순하고 빠르며 매우 효과적이다.
     2.결측데이터가 있어도 잘 수행된다.
     3.예측에 대한 추정된 확률을 얻기쉽다. 

단점: 1.모든 속성을 동등하게 중요하고 독립적이라는 알려진 결함에 의존한다. 

▩2.1 나이브 베이즈 분류

이번에는 비아그라라는 단어 하나만 가지고 스팸과 햄을 구분하느 
확률을 구하는게 아니라 다른 단어들도 포함 시켜봅시다.

비아그라 = yes, 돈 = no, 식료품 = no, 주소삭제 = yes 

문제196. 비아그라와 주소삭제는 포함하고 돈과 식료품은 포함하지 않는 
        메세지가 스팸일 확률은 어떻게 되는가. 

¬ : not sign

P(스팸|비아그라 ∩ ¬돈 ∩ ¬식료품  ∩ 주소삭제)  = 


 P( 비아그라 ∩ ¬돈 ∩ ¬식료품  ∩ 주소삭제)  * P(스팸)
-------------------------------------------------
  P( 비아그라 ∩ ¬돈 ∩ ¬식료품  ∩ 주소삭제)
               
                 ↓                             

 P(A ∩ B) = P(A) * P(B) <------- 이 공식을 염두해두고 다시 정리하면 

                 ↓    
                    
   P(비아그라|스팸)*P(¬돈|스팸)*P(¬식료품|스팸)*P(주소삭제|스팸)*P(스팸)
-----------------------------------------------------------------
         P(비아그라) * P(¬돈) * P(¬식료품)  * P(주소삭제)



          비아그라(w1)      돈(w2)         식료품(w3)    주소삭제(w4)
  우도    Yes    No      Yes    No        Yes    No      Yes    No   
  스팸    4/20  16/20   10/20  10/20   0/20  20/20   12/20  8/20        20
  햄      1/80  79/80   14/80  66/80   8/80  71/80   23/80  57/80       80  
  총합  5/100  95/100  24/100 76/100 8/100  9/100 35/100 65/100   100 

스팸의 우도 : (4/20) * (10/20) * (20/20) * (12/20) * (20/100) = 0.012

햄의 우도 : (1/80) * (66/80) * (71/80) * (23/80) * (80/100) = 0.002

                  0.012
스팸일 확률 : ------------------ = 0.85
               0.012 + 0.002
                  0.002
햄일 확률 : ------------------- = 0.1429
               0.012 + 0.002


 위의 해당 단어들을 포함하고 포함하지 않은 메일이 스팸이 될 확률 85% 햄일 확률이 14.2%가 된다. 

 

비아그라(w1)   

돈(w2)    

식료품(w3)  

주소삭제(w4)


우도   
Yes   
No     
Yes   
No     
Yes   
No     
Yes   
No     

스팸   
4/20 
16/20 
10/20
10/20 
0/20 
20/20  
12/20 
8/20 
20
햄     
1/80
79/80
14/80
66/80
8/80 
71/80 
23/80
57/80
80
총합 
5/100 
95/100
24/100
76/100
8/100 
9/100
35/100
65/100  
100


   P(비아그라|스팸)P(¬돈|스팸)*P(¬식료품|스팸)*P(주소삭제|스팸)*P(스팸)
   P(비아그라|햄) P(¬돈|햄 ) *P(¬식료품|햄 ) *P(주소삭제|햄 )*P(햄 )

문제197. 미진누나가 만든 실습예제2 메일 데이터를 보면 비아그라와 쿠폰이라는
        단어가 포함되어 있는 메일 스팸이 될 확률은 어떻게 되는가? 
p(비아그라|스팸) * p(쿠폰|스팸) * p(스팸) = ?
(4/6) * (3/6)* (6/14) = 0.14

p(비아그라|햄) * p(쿠폰|햄) * p(햄) = ?
(3/8) * (1/8) * (8/14) = 0.026
                   0.14
스팸 확률 =  ----------------------- = 0.84
              0.14 + 0.026
   
              0.026
햄 확률 = ----------------- = 0.15
           0.14 + 0.026
결론 : 쿠폰과 비아그라가 메일 메세지에 포함되어있으면 스팸일 확률이 84% 이다. 



       


▩ 2.2 라플라스 추정기 (p139) 

이번에는 비아그라 , 주소삭제, 식료품, 돈이 메일 메세지에 다 포함되어 있다고 했을때 스팸일 확률을 구해보자 


          비아그라(w1)      돈(w2)         식료품(w3)    주소삭제(w4)
  우도    Yes    No      Yes    No        Yes    No      Yes    No   
  스팸    4/20  16/20   10/20  10/20   0/20  20/20   12/20  8/20        20
  햄      1/80  79/80   14/80  66/80   8/80  71/80   23/80  57/80       80  
  총합  5/100  95/100  24/100 76/100 8/100  9/100 35/100 65/100   100 

   P(비아그라|스팸)*P(돈|스팸)*P(식료품|스팸)*P(주소삭제|스팸)*P(스팸)
      4/20  *    10/20 *  0/20 * 12/20 * 20/100                  =0
  P(비아그라|햄 )P(돈|햄 )*P(식료품|햄 )*P(주소삭제|햄 )*P(햄 )
     1/80     *    14/80  *  8/80   *  23/80 *(80/100) =0.0005

                   0
스팸일 확률 : --------------- = 0
               0 + 0.0005
                0.0005
햄일 확률 : ---------------- = 1
               0 + 0.0005
식료품과 돈때문에 햄일 확률이 100% 되어 다른 증거까지 모두 무효로 만들어 버림 .ㅋ.,ㅡ.,


이를 해결하기위해 프랑스의 수학자 피에르 시몬 라플라스가 확률이 0 이 되지 않기 위해서 빈도표의 각 값에 작은 수를 추가했따

각각의 값에 1을 더했다. 



   P(비아그라|스팸)*P(돈|스팸)*P(식료품|스팸)*P(주소삭제|스팸)*P(스팸)
      5/24  *    11/24 *  1/24 * 13/24 * 20/100                  =0.0004
  P(비아그라|햄 )P(돈|햄 )*P(식료품|햄 )*P(주소삭제|햄 )*P(햄 )
     2/84     *    15/84  *  9/84   *  24/84 *(80/100) =0.0001


                  0.0004
스팸일 확률 : ------------------- = 0.8
             0.0004 + 0.0001
햄일 확률 :                      = 0.2

스팸일 확률이 80% 이며 햄일 확률이 20%임을 의미한다. 


쉬운예제 돌려보고 교재있는거 다음에 

▦ 나이브 베이즈 실습 1 (영화장르)

1.데이터 : 카페에 data 게시판 : 선호하는 영화장르 데이터
2.코드   : 아래 실습


movie <- read.csv ( 'movie.csv', header=T)

install.packages("e1071") # 오스트리아 수도 빈 비엔나 기술대학의 통계학과에서 개발함
library(e1071)
movie


 nm <- naiveBayes(movie[1:5],movie$장르 ,laplace=0)


> nm


Naive Bayes Classifier for Discrete Predictors

Call:
naiveBayes.default(x = movie[1:5], y = movie$장르, laplace = 0)

A-priori probabilities:
movie$장르
        SF       공포     로맨틱    로맨틱s       무협     스릴러       액션     코미디
0.12820513 0.12820513 0.20512821 0.02564103 0.12820513 0.12820513 0.12820513 0.12820513

Conditional probabilities:
          나이
movie$장르 10대 10대  20대 30대 40대
   SF       0.0   0.0  0.0  1.0  0.0
   공포     0.0   0.0  0.0  0.0  1.0
   로맨틱   0.5   0.0  0.5  0.0  0.0
   로맨틱s  0.0   0.0  1.0  0.0  0.0
   무협     0.2   0.0  0.2  0.2  0.4
   스릴러   0.0   0.0  0.0  1.0  0.0
   액션     0.2   0.8  0.0  0.0  0.0
   코미디   0.0   0.0  0.4  0.4  0.2

          성별
movie$장르  남  여
   SF      0.4 0.6
   공포    1.0 0.0
   로맨틱  0.0 1.0
   로맨틱s 0.0 1.0
   무협    1.0 0.0
   스릴러  1.0 0.0
   액션    1.0 0.0
   코미디  1.0 0.0

          직업
movie$장르    IT 디자이너  무직  언론  영업 자영업  학생 홍보/마케팅
   SF      1.000    0.000 0.000 0.000 0.000  0.000 0.000       0.000
   공포    0.000    0.000 0.000 0.000 0.200  0.400 0.000       0.400
   로맨틱  0.000    0.375 0.000 0.000 0.000  0.000 0.375       0.250
   로맨틱s 0.000    0.000 0.000 0.000 0.000  0.000 0.000       1.000
   무협    0.000    0.000 1.000 0.000 0.000  0.000 0.000       0.000
   스릴러  0.000    0.000 0.000 1.000 0.000  0.000 0.000       0.000
   액션    0.000    0.000 0.000 0.000 0.000  0.000 1.000       0.000
   코미디  0.000    0.000 0.000 0.000 0.400  0.000 0.400       0.200

          결혼여부
movie$장르    NO   YES
   SF      0.200 0.800
   공포    1.000 0.000
   로맨틱  0.625 0.375
   로맨틱s 0.000 1.000
   무협    1.000 0.000
   스릴러  0.400 0.600
   액션    1.000 0.000
   코미디  1.000 0.000

          이성친구
movie$장르    NO   YES
   SF      0.800 0.200
   공포    1.000 0.000
   로맨틱  0.375 0.625
   로맨틱s 1.000 0.000
   무협    1.000 0.000
   스릴러  0.600 0.400
   액션    1.000 0.000
   코미디  1.000 0.000

result <- predict(nm, movie[1:5])

cbind(movie, result)

sum(movie$장르 != result)

문제198. 오늘 아침에 쪽지시험으로본 zoo 데이터의 100번재 동무링 어떤 종류인지 조류(2)가 맞는지 나이브 베이즈로 확인해보시오 

나이브 베이즈 알고리즘 문제를 풀기 위해서 아래의 zoo2 를 전부 팩터화 하세요 ~

zoo2 <- read.csv("zoo2.csv", stringsAsFactors = FALSE)


zoo2$X1 <- as.factor(zoo2$X1)
zoo2$X0 <- as.factor(zoo2$X0)
zoo2$X0.1 <- as.factor(zoo2$X0.1)
zoo2$X1.1 <- as.factor(zoo2$X1.1)
zoo2$X0.2 <- as.factor(zoo2$X0.2)
zoo2$X0.3 <- as.factor(zoo2$X0.3)
zoo2$X1.2 <- as.factor(zoo2$X1.2)
zoo2$X1.3 <- as.factor(zoo2$X1.3)
zoo2$X1.4 <- as.factor(zoo2$X1.4)
zoo2$X1.5 <- as.factor(zoo2$X1.5)
zoo2$X0.4 <- as.factor(zoo2$X0.4)
zoo2$X0.5 <- as.factor(zoo2$X0.5)
zoo2$X0.6 <- as.factor(zoo2$X0.6)
zoo2$X0.7 <- as.factor(zoo2$X0.7)
zoo2$X1.6 <- as.factor(zoo2$X1.6)
zoo2$X1.7 <- as.factor(zoo2$X1.7)


str(zoo2)


 

 nm <- naiveBayes(zoo2[2:17] ,zoo2[,18] ,laplace=0)
result <- predict(nm, zoo2[2:17] )

cbind(zoo2 , result)

sum(na.omit(zoo2[-100,18])  != result[c(1:99)])

> sum(na.omit(zoo2[-100,18])  != result[c(1:99)])
[1] 22