Quiet Time

■ apriori 알고리즘
  1. apriori 알고리즘 이무엇인지?
  2. apriori 알고리즘 실습 1 ( 맥주와 기저귀)
  3. apriori 알고리즘 실습 2 (상가 건물 데이터)
  4. apriori 알고리즘 실습 3 ( 책 : 야채와 우유 데이터) 
■ 1.apriori 알고리즘이 무엇인지?

맥주와 기저귀와의 관계를 알아낸 대표적인 기계학습 방법

시리얼 ----------------> 우유 

쉽게 말해 이 규칙은 시리얼을 사면 우유도 함께 구매한다는 것을 알아내는 알고리즘 

  • apriori 알고리즘 공식(p312)
                count(x)  <- x 아이템의 거래건수
support(x) = ---------------
     ↑              N  <- 데이터베이스의 전체 거래 건수
아이템 x에 대한 지지도 
                              support(x,y)           
     confidence (x -> y) = ----------------
                              support(x) 

연관 관계의 계산은 아이템들의 출현 빈도를 이용하여 계산을 하게 된다.

신뢰도(기저귀 ---> 맥주) ? 항목 기저귀를 포함하는 건수에서 기저귀와 맥주를 모두
                         포함하는 건수의 비를 구한다.

     다시 말하면 ?
         
     아이템 기저귀가 출현될 때 또 다른 아이템 맥주가 포함되어있을 경우의 조건부 확률

지지도(우유 ---> 시리얼) : 우유와 시리얼을 동시에 구매할 확률
신뢰도(우유 ---> 시리얼) : 우유를 구매할때 시리얼도 같이 구매할 확률

예 : 90%의 사람이 시리얼 구매할 때 우유를 같이 구매한다.
     라는 연관 규칙을 발견하려 한다. 
 
  거래번호        구매물품          (p311)
     1          우유, 버터,시리얼
     2          우유, 시리얼
     3          우유, 빵
     4          버터, 맥주, 오징어

문제232. 전체 아이템에서 우유와 시리얼이 동시에 출현할 확률은? 
 
2/4 

문제233. 우유를 샀을때 시리얼 살 조건부 확률

2/3 

문제234. 이와는 반대로 시리얼을 샀을때 우유를 동시에 구매할 확률

100% 

이를 간단히 표현하면 다음과 같다 

우유 ---> 시리얼( 50%, 66%)
시리얼 --> 우유 (50%, 100%)

시리얼을 샀을때 우유를 사게되는 지지도는 50%이고 신뢰도는 100% 이다.

우리가 찾고자 하는 연관 규칙은 지지도와 신뢰도가 둘다 최소한도보다 
높은것이다. 

보통은 최소 지지도를 정하여 그 이하는 모두 버리고 그중에 신뢰도가 어느정도 높은것들만 가져오는 
방법을 쓴다. 

x와 y라는 항목의 조합의 수도 너무나도 다양하기 때문에 모든 경우의 수를 다 계산한다면 시간이 오래 걸린다.

최소 지지도 이상의 데이터를 찾는다 어떻게 하면 찾을 수 있는지 연습해보자 

       거래번호        아이템
          1          A C D
          2          B C E
          3          A B C E 
          4          B E 

문제235. 위으 각각의 아이템에 대해서 지지도를 산정해보시오! 
     원래 지지도는 "구매건수/전체구매건수" 로 계산 할 수 있지만
     여기서는 단순하게 아이템의 갯수로 처리하시오 

아이템   지지도 
  A     2          
  B     3
  C     3
  D     1
  E     3

문제236. 이것에 대해서 지지도가1이상인것만 추출하여 다시 정리하시오 

아이템   지지도 
  A     2          
  B     3
  C     3
  E     3

문제237. 이제 아이템들간의 연관규칙을 알아야하므로 다시 아이템들간의      
     조합으로 재구성하고 지지도를 다시 구하시오 

아이템 목록     지지도          거래번호   아이템 
A  B          1                   1    A C D
A  C          2                   2    B C E
A  E          1                   3    A B C E
B  C          2                   4    B E
B  E          3
C  E          2

그리고 지지도가 1인것은 제외한다.

아이템 목록     지지도
A  C          2
B  C          2
B  E          3
C  E          2 

문제238. 이제 각각의 아이템 목록에서 첫번째 아이템을 기준으로 
          동일한것을 찾아보시오!

B 가 발생하면 이 B에 대해서 각각의 두번재 키를 조합한다. 
B 에 대해서 C, E가 조합된다.

아이템 목록      지지도
B C E           2

             처음상태 -------------------------------------> 발견된 연관규칙 
       거래번호        아이템                             아이템 목록    지지도 
          1          A C D                              B C E           2
          2          B C E
          3          A B C E 
          4          B E 


문제239. 맥주와 기저귀 판매 목록 데이터를 가지고 
        기저귀를 사면 맥주를 산다라는 연관규칙을 발견하시오 !
 

 


x <- data.frame(

beer=c(0,1,1,1,0),

bread=c(1,1,0,1,1),

cola=c(0,0,1,0,1),

diapers=c(0,1,1,1,1),

eggs=c(0,1,0,0,0),

milk=c(1,0,1,1,1) )


install.packages("arules")
library(arules) 

trans <- as.matrix(x, "Transaction")
trans


rules1 <- apriori(trans, parameter = list(supp=0.2, conf=0.6, target="rules"))
rules1

inspect(sort(rules1))


                            지지도  신뢰도
5  {beer}    => {diapers}     0.6  1.0000000 1.2500000
6  {diapers} => {beer}        0.6  0.7500000 1.2500000
7  {milk}    => {bread}       0.6  0.7500000 0.9375000
8  {bread}   => {milk}        0.6  0.7500000 0.9375000

문제240. 건물 상가에 서로 연관이 있는 업종은 무엇인가?
          (병원 ---> 약국) data 게시판에 건물 상가 데이터 
 
install.packages("arules")
library(arules)

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

build[is.na(build)]<- 0
build <- build[-1]
trans <- as.matrix(build, "Transaction")

rules1 <- apriori(trans, parameter = list(supp=0.2, conf=0.6, target="rules"))
rules1
inspect(sort(rules1))

   lhs                 rhs              support confidence     lift
1  {일반음식점}     => {패밀리레스토랑}    0.40  1.0000000 2.222222
2  {패밀리레스토랑} => {일반음식점}        0.40  0.8888889 2.222222
3  {약국}           => {휴대폰매장}        0.25  1.0000000 3.333333
4  {휴대폰매장}     => {약국}              0.25  0.8333333 3.333333
5  {약국}           => {병원}              0.25  1.0000000 3.333333
6  {병원}           => {약국}              0.25  0.8333333 3.333333
7  {휴대폰매장}     => {병원}              0.25  0.8333333 2.777778

결론 :  일반 음식점과 패밀리 레스토랑이 같은 건물에 있는 경향이 높고 약국과 병원, 휴대폰 판매점이 같은 건물에 있는 경향이 있다.

문제241. 보습학원이 있는 건물에는 어떤 업종의 매장이 있는지 알아내시오 (연관이 높은지 알아내시오 ) 

30 {보습학원,    은행}       => {카페}              0.20  1.0000000 4.000000
31 {카페,    보습학원}       => {은행}              0.20  1.0000000 5.000000

보습학원 있으면 아주 높은 확률로 그 건물에 은행이나 카페가 있네여 ! 

  1. apriori 알고리즘 실습 3 (책: 야채와 우유 데이터 ) 
[ 경원형 발표 ]
groceries <- read.transactions("groceries.csv",sep=",")

groceries


summary(groceries)
# 9835행은 저장된 거래와 169개 열은 사람들의 장바구니에 있을 수 있는 169개 제품에 대한 속성이다.
# 매트릭스의 각 칸은 거래에서 구매한 제품이면 1, 그렇지 않으면 0이 된다.
# 밀도값 0.02609146은 매트릭스에서 0이 아닌 칸의 비율을 뜻한다.
# 9835 * 169 = 1,662,115개가 매트릭스에 있기 때문에 상점의 영업시간동안
# 총 1662115 * 0.02609146 = 43,367개의 제품이 거래됏음을 계산 할 수 있다.
# 평균 한번의 거래에서 43367 / 9835 = 4.409개의 다른 제품이 구매됏다.
# whole milk 의 2513 / 9835 = 0.2555이기 때문에 거래의 25.6%에서 whole milk가 나타난다.
# whole milk 말고도 나머지도 일반적인 제품이다.
# element (itemset/transaction) length distribution를 보면
# 2159 거래는 하나의 제품을 포함하고 있고 1개 거래가 32개 제품을 포함한다.
# mean이 4.409로 43367 / 9835 = 4.409 이 계산과 맞아 떨어진다.

# 희소 매트릭스의 내용을 보기 위해 벡터 연산의 조합과 inspect() 함수를 사용한다.

# 첫 5개의 거래를 볼수 있다.
# csv 파일과 같다
inspect(groceries[1:5])

# itemFrequency() 함수는 제품이 포함한 거래의 비율을 볼 수 있게 한다.
# 예를 들어 식료품 데이터 3개 제품에 대해 지지도 레벨(support level)을 볼 수 있다.
itemFrequency(groceries[,1:3])

# 데이터에서 적어도 0.1(10%)의 지지도 이상인 8개 제품을 보여준다.
itemFrequencyPlot(groceries , support=0.1)

# groceries 데이터에서 상위 20개 제품에 대한 다이어그램이다.
itemFrequencyPlot(groceries, topN=20)


image(groceries[1:5])

# 100개의 행과 169개의 열로 구성된 매트릭스 다이어그램을 생성한다.
image(sample(groceries,100))

## 3단계 : 데이터로 모델 훈련
apriori(groceries)

# 하루에 두번씩(약 60번) 구매되는 제품이라면 지지도 레벨을 계산하는데 쓸 수 있다.
# 총 9835에서 60은 0.006이기 때문에 지지도를 0.006으로 한다.
# 결과에 포함되기 위해서 적어도 25% 정확도의 규칙을 뜻하는 0.25인 신뢰도 경계 값으로 시작한다.
# 두 제품보다 적게 포함되는 규칙을 제거하기 위한 minlen을 2로 설정한다.
groceryrules <- apriori(groceries, parameter=list(support = 0.006, confidence=0.25, minlen=2))
# 463개의 연관 규칙을 포함하고 있다. 규칙이 사용할 만한지 결정하기 위해 좀 더 살펴봐야 한다.
groceryrules

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

# rule length distribution 이부분을 살펴보면
# 150개의 규칙이 2개의 제품을 갖고 있는 반면, 297개의 규칙은 3개, 16개의 규칙은 4개 제품을 가지고 있다
# 세번째 열인 리프트(lift)는 지금까지 고려하지 않은 메트릭이다. 다른 물품을 구매한 것을 고려해
# 전형적인 구매 비율과 상대적으로 물푸이 얼마나 구매됏는지 측정한다. 이는 다음 식으로 정의 된다.
#                confidence(X->Y)
# lift(X->Y) = -------------------
#                 support(Y)
# mining info 부분은 얼마나 규칙을 선택할 수 있는지 알려준다.
# 9835건의 거래를 포함한 groceries 데이터는 최소 지지도인 0.006과 최소 신뢰도인 0.25로 규칙을 만든것을 확인할 수 있다.
summary(groceryrules)

# lhs는 규칙을 작동시키기 위해 충족해야할 조건이고 rhs는 충족된 조건의 결과로 예상되는 값이다.
# 첫번째 규칙은 소비자가 potted plants(화분 식물)을 사면 whole milk(전유)도 산다는 의미이다
# 약 0.007의 지지도와 0.4의 신뢰도를 가지고 있고 이 규칙은 약 0.7%의 거래를 이룬다.
inspect(groceryrules[1:3])

## 5단계 : 모델 성능 향상
# 리프트 통계를 따르는  최상상의 5개 규칙은 다음과 같다.
# 리프트가 3.956477인 첫번째 규칙은 허브를 산 구매자는 일반적으로 근채류 구매가 4배에 가깝다고 나온다.
# 두번째 규칙은 딸기를 구매한 소비자는 일반 소비자보다 3배 더 많이 거품크림을 구매한다.
inspect(sort(groceryrules,by="lift")[1:5])

# subset() 함수는 거래,제품,규칙의 부분집합을 찾는 기법을 제공한다.
# 딸기 홍보광고를 만들기 위해서 딸기가 포함된 규칙을 저장한다.
berryrules <- subset(groceryrules,items %in% "berries")
inspect(berryrules)

# 장바구니 분석 결과를 공유하기 위해 write함수로 csv파일에 저장할 수 있다.
write(groceryrules, file="groceryrules.csv",sep=",", quote=TRUE, row.names=FALSE)

# 규칙을 데이터 프레임으로 변환하는것이 편리하다. as() 함수를 이용해서 만들수 있다.
groceryrules_df <- as(groceryrules, "data.frame")
# 수치가 가장 높은 순으로 정렬
install.packages("doBy")
library(doBy)
head(orderBy(~-lift,groceryrules_df))
head(orderBy(~-support,groceryrules_df))
head(orderBy(~-confidence,groceryrules_df))
str(groceryrules_df)




문제242. (점심시간 문제) 다음 데이터에서 가장 연관성이 높은 항목을 찾으시오

x <- data.frame(
  영화=c(0,1,1,1,0,1,1,1,0,1,1,1,1),
  오징어=c(1,0,1,1,1,1,0,0,0,1,0,0,1),
  맥주=c(0,0,1,0,1,0,0,0,1,1,0,0,1),
  음료=c(1,1,0,1,1,0,0,1,0,0,1,1,0),
  스낵=c(0,1,0,0,0,0,0,0,0,1,1,0,0),
  팝콘=c(0,1,1,1,1,1,1,1,0,1,1,0,1))

trans <- as.matrix(x, "Transaction")
trans


rules1 <- apriori(trans, parameter = list(supp=0.2, conf=0.6, target="rules"))
rules1

inspect(sort(rules1))


> inspect(sort(rules1))
   lhs         rhs        support confidence      lift
1  {}       => {영화}   0.7692308  0.7692308 1.0000000
2  {}       => {팝콘}   0.7692308  0.7692308 1.0000000
3  {영화}   => {팝콘}   0.6923077  0.9000000 1.1700000
4  {팝콘}   => {영화}   0.6923077  0.9000000 1.1700000
5  {오징어} => {팝콘}   0.4615385  0.8571429 1.1142857
6  {팝콘}   => {오징어} 0.4615385  0.6000000 1.1142857
7  {음료}   => {영화}   0.3846154  0.7142857 0.9285714




x <- data.frame(
  영화=c(0,1,1,1,0,1,1,1,0,1,1,1,1),
  오징어=c(1,0,1,1,1,1,0,0,0,1,0,0,1),
  맥주=c(0,0,1,0,1,0,0,0,1,1,0,0,1),
  음료=c(1,1,0,1,1,0,0,1,0,0,1,1,0),
  스낵=c(0,1,0,0,0,0,0,0,0,1,1,0,0),
  팝콘=c(0,1,1,1,1,1,1,1,0,1,1,0,1))

trans <- as.matrix(x, "Transaction")
trans
rules1 <- apriori(trans, parameter = list(supp=0.2, conf=0.6, target="rules"))
a <- as(rules1, "data.frame")
head(orderBy(~-lift,a))














 

▣ R 를 활용한 기계학습 7장. 블랙박스 기법 : 신경망과 서포트 벡터 머신 신경망 (p286)

■  서포트 벡터 머신이란(Support Vector Machine: SVM)?
서포트 벡터 머신이란 간단히 말해 이진 분류기이다. 
 SVM 목적은 초평면(hyperplane) 기준으로 한쪽 면으로 동일한 데이터가 놓이게 평평한 경계를 만드는 것이다.



 
  • 초평면 (hyperplane)?
SVM 보통 범주 값을 유사한 데이터들로 그룹짓기 위해 초평면(hyperplane )이라는 경계를 사용하는데

hyperplane은 n-1차원의 subspace를 의미하는 것이며, 3차원의 경우 hyperplane은 2차원의 면이 되고, 2차원의 경우는 hyperplane은 1차원의 선이된다








 ■  Kernel Tricks 기법: 선형분리가 불가능한 데이터나
비선형 data들을 차원 높여서 분리하는 방법

이렇게 1차원 데이터를 2차원으로 높이게 되면 분리가 가능하다.

그림을 보면 왼쪽 평면에 있는 sample들이 오른쪽과 같이 변형되었는데, 이것은 sample들이 있는 공간을 kernel 함수를 이용하여 공간을 3차원 공간으로 변형시켜주었기 때문이다. 그런 다음 3차원 공간에서 hyperplane을 이용하면 cancer와 normal 샘플들을 좀 더 쉽게 구별할 수 있게 된다.
 



 
왼쪽 그림에서는 대각선 방향의 직선이 최대 여백 초평면(Maximum Margin Hyperplane) 해당한다. 그리고 직선과 가장 가까운 분류에 속한 점들을 서포트 벡터 라고한다.























■  실습1 : 붓꽃 데이터 분류--- 1. Data set : 기본제공(iris)
data(iris)
install.packages("ggplot2")
library(ggplot2)
gplot(Petal.Length, Petal.Width, data=iris, color = Species) #실제 데이터를 확인
library(e1071)
s<-sample(150,100)       # 1 ~ 150 까지 중복되지 않는 랜덤수를 100개 생성
col<- c("Petal.Length", "Petal.Width", "Species")    # 컬럼명 지정 꽃잎 길이 , 꽃잎 폭, 종류
iris_train <- iris[s,col]      # 랜덤으로 뽑은 100개의 트레이닝 셋
iris_test <- iris[-s,col]       # 나머지 테스트 셋

# 리니어 커널방식으로 트레이닝 셋을 종류별로 모델링한다.
iris_svm <- svm(Species ~. , data=iris_train, cost=1,kernel ="linear")
plot(iris_svm, iris_train[,col])

# svm로 훈련된 모델과 테스트데이터로 결과예측
p<- predict(iris_svm,iris_test[,col],type="class")
plot(p)
table(p, iris_test[,3])
mean( p == iris_test[,3])







■  실습2 : 광학식 문자 인식 ---- 1. Data set : letterdata.csv
# 각 글자모양의 속성들을 수치화 한 데이터
# 데이터 읽기와 구조
letters <- read.csv("letterdata.csv")
str(letters)

# 훈련 데이터와 테스터 데이터 구분
letters_train <- letters[1:16000, ]
letters_test  <- letters[16001:20000, ]
## 3단계 : 데이터로 모델 훈련 ----
# 단순 선형 SVM을 훈련으로 시작
install.packages(“kernlab”)
library(kernlab)
letter_classifier <- ksvm(letter ~ ., data = letters_train, kernel = "vanilladot")
# 모델에 대한 기본 정보 확인
letter_classifier


## 4단계 : 모델 성능 평가 ----
# 테스트 데이터셋에 대한 예측
letter_predictions <- predict(letter_classifier, letters_test)

head(letter_predictions)

table(letter_predictions, letters_test$letter)

# 일치/불일치 예측을 표시하는 TRUE/FALSE 벡터 생성
agreement <- letter_predictions == letters_test$letter
table(agreement)
prop.table(table(agreement))

## 5단계 : 커널을 바꿔서 모델 성능을 향상시켜보자 ----
## 가우시안 RBF 커널을 사용
##  RBF ? 링크 -> [Radial Basis Function(방사 기저 함수)]
letter_classifier_rbf <- ksvm(letter ~ ., data = letters_train, kernel = "rbfdot")
letter_predictions_rbf <- predict(letter_classifier_rbf, letters_test)

agreement_rbf <- letter_predictions_rbf == letters_test$letter
table(agreement_rbf)
prop.table(table(agreement_rbf))
prop.table(table(agreement))


향상 됐음!

■  실습3 : 산불데이터 forestfires.csv
install.packages("dplyr")
install.packages("kernlab")
install.packages("ROCR")
install.packages("caret")
install.packages("e1071")
library(dplyr)
library(kernlab)
library(ROCR)
library(caret)
library(e1071)

mydata <- read.csv('forestfires.csv',header =T)
hist(mydata$area)
rug(mydata$area)

# area값들을 분석하기 쉽게 변경 log값을 씌워서 y컬럼으로 추가한다.
mydata <- mutate(mydata, y = log(area + 1))

normalise <- function(x) {  #정규화함수
  return((x - min(x)) / (max(x) - min(x))) }
 
#분석할 값들을 정규화한다.
mydata$temp <- normalise(mydata$temp)
mydata$rain <- normalise(mydata$rain)
mydata$RH <- normalise(mydata$RH)
mydata$wind <- normalise(mydata$wind)

#산불 넓이가 5헥타르 이상인 것을 large 아니면 small로 놓고 분석한다.
mydata$size <- factor(ifelse(mydata$y< 2, 1, 0),
                       labels = c("large", "small"))
#tail(mydata[, c("size", "area")]) 
train <- sample(x = nrow(mydata), size = 400, replace = FALSE)
# 각 커널 방식 비교
# polydot커널 방식으로 svm
m.poly <- ksvm(size ~ temp + RH + wind + rain,
          data = mydata[train, ],
          kernel = "polydot", C = 1)

pred <- predict(m.poly, newdata = mydata[-train, ], type = "response")
 
table(pred, mydata[-train, "size"])
mean(pred == mydata[-train, "size"])


# tanhdot 커널 방식으로 svm
m.tan <- ksvm(size ~ temp + RH + wind + rain,
          data = mydata[train, ],
          kernel = "tanhdot", C = 1)

pred <- predict(m.tan, newdata = mydata[-train, ], type = "response")
 
table(pred, mydata[-train, "size"])
mean(pred == mydata[-train, "size"])


# rbfdot 커널 방식으로 svm
m.rad <- ksvm(size ~ temp + RH + wind + rain,
          data = mydata[train, ],
          kernel = "rbfdot", C = 1)
pred <- predict(m.rad, newdata = mydata[-train, ], type = "response")
 
table(pred, mydata[-train, "size"])
mean(pred == mydata[-train, "size"])

공부한 내용을 정리한 블로그 입니다.