계층적 군집분석은 전통적인 군집 방법으로 가장 유사한 개체를 군집해 나가는 과정을 반복하여 원하는 개수의 군집을 형성하는 방법이다.
k-평균 군집분석은 주어진 군집 수(k)로 각 개체를 가까운 초기값에 할당하여 군집을 형성하고, 각 군집의 평균을 계산하여 군집의 중심을 갱신하는 과정을 통해 전체 데이트셋을 상대적으로 유사한 k개의 최종 군집으로 형성한다.
혼합분포 군집분석은 모델 기반의 군집 방법이다
기대값 최대화 알고리즘은 관측되지 않는 잠재변수에 의존하는 확률 모델에서 최대 가능도나 최대 사후 확률을 갖는 모수의 추정값을 찾는 반복적인 알고리즘이다.
계층적 군집 분석은 전통적인 군집 방법으로 가장 유사한 개체를 군집해 나가는 과정을 반복하여 원하는 개수의 군집을 형성하는 방법이다.
계층적 군집을 형성하는 방법에는 병합적방법과 분할적방법이 있다.
병합적 방법은 작은 군집에서 시작하여 군집을 병합해 나가는 방법.
분할적 방법은 큰 군집에서 시작하여 군집을 분리해 나가는 방법.
하나의 개체에서 시작하여 군집을 형성해 나가는 매 단계마다 군집간의 거리르 계산하여 가까운 순으로 병행 또는 분리를 수행한다. 여기서 군집간의 상대적 거리가 가까울수록 유사도가 높다고 말할 수 있다.
군집간의 거리 측정 방법
최단연결법: 두 집군 사이의 거리를 각 군집에서 하나씩 관측값을 뽑았을 때 거리의 최소값으로 측정한다. 고립된 군집을 찾는데 중점을 둔 방법이다.
최장연결법: 두 군집 사이의 거리르 각 군집에서 하나씩 관측값을 뽑았을 때 거리의 최대값으로 측정한다. 군집들의 내부 응집성에 중점을 둔 방법이다.
중심연결법: 두 군집 사이의 중심 간의 거리를 측정한다. 두 군집이 결합 시 새로운 군집의 평균은 가중평균을 이용한다.
평균연결법: 두 군집 사이의 거리르 계산할 때 모든 항목에 대한 거리 평균값으로 측정한다. 불필요하게 계산량이 많아질 수 있다.
와드연결법: 군집내의 오차 제곱합에 기초한 방법이다. 군집 간의 오차 제곱합이 최소화되는 방햐으로 군집화를 진행한다.크기가 비슷한 군집끼리 병향하는 경향이 있다.
계층적 군집의 결과는 덴드로그램의 형태로 표현되고 이를 통해 항목 간의 거리와 군집 간의 거리를 알 수 있고, 군집 내의 항목 간 유사성의 정도를 파악함으로 군집의 견고성을 해석하는 데 도움이 된다.
다음은 stats패키지의 hclust 함수로 USArrests 자료를 이용해 병합적 방법의 계층적 군집분석을 수행하는 예제다.
library(stats)
data("USArrests")
str(USArrests)## 'data.frame': 50 obs. of 4 variables:
## $ Murder : num 13.2 10 8.1 8.8 9 7.9 3.3 5.9 15.4 17.4 ...
## $ Assault : int 236 263 294 190 276 204 110 238 335 211 ...
## $ UrbanPop: int 58 48 80 50 91 78 77 72 80 60 ...
## $ Rape : num 21.2 44.5 31 19.5 40.6 38.7 11.1 15.8 31.9 25.8 ...
USArrests 데이터는 4개 변수와 50개의 관측값이 존재하는 것을 볼 수 있다.
euc.d<-dist(USArrests, method = 'euclidean')avg.h<-hclust(euc.d, method = 'average')plot(avg.h)계층적 군집 결과를 이용한 덴드로그램 분석 결과 유사한 주(50개주)별로 군집화된 것을 볼 수 있다.
library(stats)
groups<-cutree(avg.h, k = 6)
groups## Alabama Alaska Arizona Arkansas California
## 1 1 1 2 1
## Colorado Connecticut Delaware Florida Georgia
## 2 3 1 4 2
## Hawaii Idaho Illinois Indiana Iowa
## 5 3 1 3 5
## Kansas Kentucky Louisiana Maine Maryland
## 3 3 1 5 1
## Massachusetts Michigan Minnesota Mississippi Missouri
## 6 1 5 1 2
## Montana Nebraska Nevada New Hampshire New Jersey
## 3 3 1 5 6
## New Mexico New York North Carolina North Dakota Ohio
## 1 1 4 5 3
## Oklahoma Oregon Pennsylvania Rhode Island South Carolina
## 6 6 3 6 1
## South Dakota Tennessee Texas Utah Vermont
## 5 2 2 3 5
## Virginia Washington West Virginia Wisconsin Wyoming
## 6 6 5 5 6
stats 패키재의 cutree 함수는 계층적 군집 결과를 이용하여 유사한 군집으로 나눌 수 있다. 인자 k = 6는 6개 군집으로 묶는 것을 의미한다.
plot(avg.h)
rect.hclust(avg.h, k =6, border = 'red')cmp.h<-hclust(dist(USArrests), method = 'complete')
plot(cmp.h)
rect.hclust(cmp.h, k = 3, border = 'red')
rect.hclust(cmp.h, h = 50, which = c(1,4), border = 3:4)다음은 cluster 패키지의 agnes함수로 USArrests자료를 이용해 병합적 방법의 계층적 군집분석을 수행하는 예제다 .
library(cluster)cmp.agn<-agnes(daisy(USArrests), diss = TRUE, metric = 'euclidean', method = 'complete')
par(mfrow = c(1,2))
plot(cmp.agn)par(mfrow=c(1,1))agnes() 함수는 계층적 군집 방법 중 병합적 방법을 이용하여 분석한다. daisy() 함수는 관측값 사이의 거리를 계산해주고 자료의 형태가 수치형일 필요가 겂다는 점에서 dist() 함수보다 유연하다. metric 인자는 관측값 간의 비유사성을 계산하는 데 사용하는 거리 함수를 지정하고 여기서는 유클리드 거리 함수로 거리를 계산한다. method 인자는 군집 방법을 지정하고 ’complete’군집을 사용한다.
k-평균 군집 분석은 주어진 군집 수 k 로 각 개체를 가까운 초기값에 할당하여 군집을 형성하고, 각 군집의 평균을 계산하여 군집의 중심을 갱신하는 과정을 통해 전체 데이터셋을 상대적으로 유사한 k 개의 최종 군집으로 형성한다.
first, assign k, and random point.
second, from that point, use euclidean distance divide into k groups.
in each group, take the average and that is the new centroid.
base on the new centroid, divide into k groups again.
the process repeats until the centroid(average point) and the groups do not change.
적정 군집수 k 를 정하는 한 가지 방법으로 군집 수를 k=1 부터 임의의 k 까지를 지정하고 군집 내 동질성과 이질성을 측정한다.여기서 군집 수 k를 늘려가면서 동질성의 증가와 이질성의 감소 기울기의 절감 지점인 엘보우 값으 찾는 방법을 사용할 수 이싿.
k 평균 군집분석 알고리즘의 장, 담점 비교
장점:
알고리즘이 단순하며, 빠르게 수행되어 기법 적용이 용이하다.
계층적 군집보다 많은 양의 자료를 다룰 수 있다.
개체들 간의 거리 측정과 군집 수k, 초기 중심점만 주어지면 바로 분석을 적용할수 있다.
단점:
임의의 조기점 할당으로 인해 최적의 군집을 찾지 못할 수도 있다.
초기 군집 수 에 대한 임의의 판단이 필요하다.
연속형 변수의 거리 측정만 다룰 수 있다.
잡음이나 이상값에 영향을 많이 받는다.
결과 해석이 어렵다.
다음은 rattle 패키지의 kmeans 함수로 wine 자료를 이용해 k-평균 군집분석을 수행한 예제다.
library(rattle)## Loading required package: tibble
## Loading required package: bitops
## Rattle: A free graphical interface for data science with R.
## Version 5.5.1 Copyright (c) 2006-2021 Togaware Pty Ltd.
## Type 'rattle()' to shake, rattle, and roll your data.
data('wine')
str(wine)## 'data.frame': 178 obs. of 14 variables:
## $ Type : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
## $ Alcohol : num 14.2 13.2 13.2 14.4 13.2 ...
## $ Malic : num 1.71 1.78 2.36 1.95 2.59 1.76 1.87 2.15 1.64 1.35 ...
## $ Ash : num 2.43 2.14 2.67 2.5 2.87 2.45 2.45 2.61 2.17 2.27 ...
## $ Alcalinity : num 15.6 11.2 18.6 16.8 21 15.2 14.6 17.6 14 16 ...
## $ Magnesium : int 127 100 101 113 118 112 96 121 97 98 ...
## $ Phenols : num 2.8 2.65 2.8 3.85 2.8 3.27 2.5 2.6 2.8 2.98 ...
## $ Flavanoids : num 3.06 2.76 3.24 3.49 2.69 3.39 2.52 2.51 2.98 3.15 ...
## $ Nonflavanoids : num 0.28 0.26 0.3 0.24 0.39 0.34 0.3 0.31 0.29 0.22 ...
## $ Proanthocyanins: num 2.29 1.28 2.81 2.18 1.82 1.97 1.98 1.25 1.98 1.85 ...
## $ Color : num 5.64 4.38 5.68 7.8 4.32 6.75 5.25 5.05 5.2 7.22 ...
## $ Hue : num 1.04 1.05 1.03 0.86 1.04 1.05 1.02 1.06 1.08 1.01 ...
## $ Dilution : num 3.92 3.4 3.17 3.45 2.93 2.85 3.58 3.58 2.85 3.55 ...
## $ Proline : int 1065 1050 1185 1480 735 1450 1290 1295 1045 1045 ...
dim(wine)## [1] 178 14
table(wine$Type)##
## 1 2 3
## 59 71 48
wine 데이터는 14개 변수와 178개의 관측값이 존재하는 것을 볼 수 있다. wine 자료는 178개 이탈리안 와인을 대상으로 13가지의 화학정 성분을 측정한 자료이다. 반응변수 Type은 1,2,3 세 가지 범주로 분류된다. 반응변수 분할표에서 1은 59개, 2는71개, 3은 48개인 것을 볼 수 있다. 분석 결과 변수의 측정 단위가 다른 것을 알수 있고 반응변수를 빼고 나머지 변수를 표준화를 한다.
wine2<-scale(wine[-1])library(foreach)
nc<-1:15
nc.res<-foreach(i = nc, .combine = rbind) %do%{
with.ss<-sum(kmeans(wine2, centers = i)$withinss)
between.ss<-kmeans(wine2, centers = i)$betweenss
return(data.frame(nc = i, wss = with.ss, bss = between.ss))
}
nc.res## nc wss bss
## 1 1 2301.0000 3.183231e-12
## 2 2 1649.6877 6.513123e+02
## 3 3 1270.7491 1.030251e+03
## 4 4 1197.1284 1.106668e+03
## 5 5 1104.3623 1.202261e+03
## 6 6 1052.1617 1.244871e+03
## 7 7 1000.5914 1.313496e+03
## 8 8 948.1711 1.349811e+03
## 9 9 885.0698 1.410603e+03
## 10 10 862.4752 1.447699e+03
## 11 11 807.5677 1.464479e+03
## 12 12 779.8433 1.482821e+03
## 13 13 776.3919 1.518671e+03
## 14 14 716.4299 1.574965e+03
## 15 15 720.8027 1.573374e+03
plot(nc.res$nc, nc.res$wss, type = 'b', xlab = 'Number of Clusters', ylab = 'Within groups sum of squares')plot(nc.res$nc, nc.res$bss, type = 'b', xlab = 'Number of Clusters', ylab = 'Between-cluster sum of squares')분석 결과 군집 내 제곱합의 경우 감소 폭의 기울기가 급감하는 엘보우 점은 k = 3일 때이고, 군집간 제곱합의 경우도 증가 폭의 기울기가 급감하는 엘보우 점도 k = 3일 때이다. 즉, 군집수 k = 3 이 적당하는 것을 알 수 있다.
library(NbClust)
set.seed(123)
nbc<-NbClust(wine2, min.nc = 2, max.nc = 15, method = 'kmeans')## *** : The Hubert index is a graphical method of determining the number of clusters.
## In the plot of Hubert index, we seek a significant knee that corresponds to a
## significant increase of the value of the measure i.e the significant peak in Hubert
## index second differences plot.
##
## *** : The D index is a graphical method of determining the number of clusters.
## In the plot of D index, we seek a significant knee (the significant peak in Dindex
## second differences plot) that corresponds to a significant increase of the value of
## the measure.
##
## *******************************************************************
## * Among all indices:
## * 2 proposed 2 as the best number of clusters
## * 19 proposed 3 as the best number of clusters
## * 1 proposed 14 as the best number of clusters
## * 1 proposed 15 as the best number of clusters
##
## ***** Conclusion *****
##
## * According to the majority rule, the best number of clusters is 3
##
##
## *******************************************************************
ls(nbc)## [1] "All.CriticalValues" "All.index" "Best.nc"
## [4] "Best.partition"
barplot(table(nbc$Best.nc[1, ]),
xlab = 'Number of Cluster',
ylab = 'Nu,ner of Criteris')분석 결과 군집 수 k = 3 이 15개 지수가 투표되어 최적의 군집 수인 것을 볼 수 있다. NbClust 패키지의 NbClust함수는 최적의 군집 수k 를 찾아준다.
set.seed(123)
km.fit<-kmeans(wine2, centers = 3, nstart = 25)
plot(wine2, col = km.fit$cluster, pch = ifelse(km.fit$cluster ==1, 1, ifelse(km.fit$cluster == 2, 2, 6)),cex = 1)
points(km.fit$centers, col = 1:3, pch = c(1,2,6), cex = 3)ls(km.fit)## [1] "betweenss" "centers" "cluster" "ifault" "iter"
## [6] "size" "tot.withinss" "totss" "withinss"
km.fit$size## [1] 51 62 65
km.fit$cluster## [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [38] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 1 3 3 3 3 3 3 3 3 3 3 3 2
## [75] 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [112] 3 3 3 3 3 3 3 1 3 3 2 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [149] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
round(km.fit$centers, 3)## Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids Nonflavanoids
## 1 0.164 0.869 0.186 0.523 -0.075 -0.977 -1.212 0.724
## 2 0.833 -0.303 0.364 -0.608 0.576 0.883 0.975 -0.561
## 3 -0.923 -0.393 -0.493 0.170 -0.490 -0.076 0.021 -0.033
## Proanthocyanins Color Hue Dilution Proline
## 1 -0.778 0.939 -1.162 -1.289 -0.406
## 2 0.579 0.171 0.473 0.777 1.122
## 3 0.058 -0.899 0.461 0.270 -0.752
속성 $size는 군집에 속할 데이터의 개수이고, 위의 경우 51, 62, 65 이다. 속성 $cluster는 군집 분류 결과이고, 속성 $center는 각 군집의 중심값이다.
aggregate(wine[-1], by = list(cluster = km.fit$cluster), FUN = mean)## cluster Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids
## 1 1 13.13412 3.307255 2.417647 21.24118 98.66667 1.683922 0.8188235
## 2 2 13.67677 1.997903 2.466290 17.46290 107.96774 2.847581 3.0032258
## 3 3 12.25092 1.897385 2.231231 20.06308 92.73846 2.247692 2.0500000
## Nonflavanoids Proanthocyanins Color Hue Dilution Proline
## 1 0.4519608 1.145882 7.234706 0.6919608 1.696667 619.0588
## 2 0.2920968 1.922097 5.453548 1.0654839 3.163387 1100.2258
## 3 0.3576923 1.624154 2.973077 1.0627077 2.803385 510.1692
wine$cluster<-km.fit$cluster
head(wine)## Type Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids Nonflavanoids
## 1 1 14.23 1.71 2.43 15.6 127 2.80 3.06 0.28
## 2 1 13.20 1.78 2.14 11.2 100 2.65 2.76 0.26
## 3 1 13.16 2.36 2.67 18.6 101 2.80 3.24 0.30
## 4 1 14.37 1.95 2.50 16.8 113 3.85 3.49 0.24
## 5 1 13.24 2.59 2.87 21.0 118 2.80 2.69 0.39
## 6 1 14.20 1.76 2.45 15.2 112 3.27 3.39 0.34
## Proanthocyanins Color Hue Dilution Proline cluster
## 1 2.29 5.64 1.04 3.92 1065 2
## 2 1.28 4.38 1.05 3.40 1050 2
## 3 2.81 5.68 1.03 3.17 1185 2
## 4 2.18 7.80 0.86 3.45 1480 2
## 5 1.82 4.32 1.04 2.93 735 2
## 6 1.97 6.75 1.05 2.85 1450 2
table(wine$Type)##
## 1 2 3
## 59 71 48
table(wine$cluster)##
## 1 2 3
## 51 62 65
aggregate(wine, by = list(cluster = wine$cluster, Type = wine$Type), NROW)## cluster Type Type Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids
## 1 2 1 59 59 59 59 59 59 59 59
## 2 1 2 3 3 3 3 3 3 3 3
## 3 2 2 3 3 3 3 3 3 3 3
## 4 3 2 65 65 65 65 65 65 65 65
## 5 1 3 48 48 48 48 48 48 48 48
## Nonflavanoids Proanthocyanins Color Hue Dilution Proline cluster
## 1 59 59 59 59 59 59 59
## 2 3 3 3 3 3 3 3
## 3 3 3 3 3 3 3 3
## 4 65 65 65 65 65 65 65
## 5 48 48 48 48 48 48 48
km.tb<-table(wine$Type, wine$cluster)
km.tb##
## 1 2 3
## 1 0 59 0
## 2 3 3 65
## 3 48 0 0
library(flexclust)## Loading required package: grid
## Loading required package: lattice
## Loading required package: modeltools
## Loading required package: stats4
randIndex(km.tb)## ARI
## 0.897495
분석 결과 수정된 순위지수는 약 0.897로 wine 데이터의 반응변수Type 와 군집 결과의 일치도가 높으것을 볼 수 있다. 수정된 순위지수는 -1(no aggreement) 과 1(perfect agreement)사이의 값을 가진다. flexclust 패키지의 randIndex 함수는 반응변수Type의 범주와 군집 간의 일치도를 나타내는 수정된 순위지수를 계산한다.
다음은 flexclust 패키지의 kcca 함수로 Nclus 자료를 이용해 k-평균 군집분석을 수행한 예제다.
library(flexclust)
data("Nclus")
str(Nclus)## num [1:550, 1:2] -0.208 -0.74 -0.72 0.373 0.954 ...
head(Nclus)## [,1] [,2]
## [1,] -0.20787508 0.4990719
## [2,] -0.74049241 -0.2988594
## [3,] -0.71985109 0.5920086
## [4,] 0.37251818 0.1519670
## [5,] 0.95387726 0.9913636
## [6,] -0.09545011 1.5494850
Nclus 데이터는 550행 2열의 행렬 형식의 데이터인 것을 알 수있다.
plot(Nclus) 산점도 그래프 실행 결과 분포가 4개로 나누어진 것을 볼 수 있다.
kc.fit<-kcca(Nclus, k = 4, family = kccaFamily('kmeans'))
summary(kc.fit)## kcca object of family 'kmeans'
##
## call:
## kcca(x = Nclus, k = 4, family = kccaFamily("kmeans"))
##
## cluster info:
## size av_dist max_dist separation
## 1 291 2.808830 6.533686 3.210227
## 2 85 1.196240 2.952339 1.286494
## 3 109 1.408164 3.183290 3.296170
## 4 65 1.202351 3.178317 1.309621
##
## convergence after 9 iterations
## sum of within cluster distances: 1150.693
image(kc.fit)
points(Nclus)kc.fit@centers## [,1] [,2]
## [1,] 5.4035634 2.6625837
## [2,] -0.9764333 6.1248092
## [3,] 0.2093610 0.1487439
## [4,] -3.3601358 5.9565436
barplot(kc.fit)stripes(kc.fit)자기조직화지도 알고리즘 또는 코호넨 맵이라고 알려져 있는 SOM은 비지도 신경망으로 고차원의 데이터를 이해하기 쉬운 저차원의 뉴런으로 정렬하여 맵의 형태로 형상화한다.
이러한 형상화는 입력변수의 위치관계를 그대로 보존한다는 특징이 있다. 다시말해 실제 공간의 입력변수가 가까이 있으면 맵상에서도 가까운 위치에 있게 된다.
SOM 모델은 두 개의 인공신경망 층으로 구성되어 있다. 입력층은 입력변수의 개수와 동일하게 뉴런수가 존재하고 이 자료는 학습을 통하여 경쟁층에 정렬되는데 이를 맵이라고 부른다.
경쟁층은 2차원 격자로 구성되어 있으며 입력 벡터의 특성에 따라 벡터가 한점으로 클러스터링 되는 층이다.
SOM은 경쟁학습으로 각각의 뉴런이 입력벡터와 얼마나 가까운가를 계산하여 연결 강도를 반복적으로 재조정하여 학습한다. 연결 강도는 입력 패턴과 가장 유사한 경쟁층 뉴런이 승자가 된다.
다음은 kohonen 패키지의 som 함수로 rattle 패키지의 wine 자료를 이용해 SOM 군집분석을 수행하는 예제다.
data(wine, package = 'rattle')
str(wine)## 'data.frame': 178 obs. of 14 variables:
## $ Type : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
## $ Alcohol : num 14.2 13.2 13.2 14.4 13.2 ...
## $ Malic : num 1.71 1.78 2.36 1.95 2.59 1.76 1.87 2.15 1.64 1.35 ...
## $ Ash : num 2.43 2.14 2.67 2.5 2.87 2.45 2.45 2.61 2.17 2.27 ...
## $ Alcalinity : num 15.6 11.2 18.6 16.8 21 15.2 14.6 17.6 14 16 ...
## $ Magnesium : int 127 100 101 113 118 112 96 121 97 98 ...
## $ Phenols : num 2.8 2.65 2.8 3.85 2.8 3.27 2.5 2.6 2.8 2.98 ...
## $ Flavanoids : num 3.06 2.76 3.24 3.49 2.69 3.39 2.52 2.51 2.98 3.15 ...
## $ Nonflavanoids : num 0.28 0.26 0.3 0.24 0.39 0.34 0.3 0.31 0.29 0.22 ...
## $ Proanthocyanins: num 2.29 1.28 2.81 2.18 1.82 1.97 1.98 1.25 1.98 1.85 ...
## $ Color : num 5.64 4.38 5.68 7.8 4.32 6.75 5.25 5.05 5.2 7.22 ...
## $ Hue : num 1.04 1.05 1.03 0.86 1.04 1.05 1.02 1.06 1.08 1.01 ...
## $ Dilution : num 3.92 3.4 3.17 3.45 2.93 2.85 3.58 3.58 2.85 3.55 ...
## $ Proline : int 1065 1050 1185 1480 735 1450 1290 1295 1045 1045 ...
table(wine$Type)##
## 1 2 3
## 59 71 48
wine 데이터는 14개 변수와 178개의 관측값이 존재하는 것을 볼 수 있다. 반응변수 Type는 1,2,3, 세가지 범주로 분류된다. 반응변수 분할표를 보면 1은 59개, 2는 71개, 3은 48개인 것을 볼 수 있다.
library(caret)## Loading required package: ggplot2
parts<-createDataPartition(wine$Type, p = 0.8)
wine.train<-wine[parts$Resample1, ]
wine.test<-wine[-parts$Resample1,]
table(wine.train$Type)##
## 1 2 3
## 48 57 39
table(wine.test$Type)##
## 1 2 3
## 11 14 9
library(kohonen)
set.seed(123)
som.fit<-som(scale(wine.train[-1]),
grid = somgrid(3,1,"hexagonal"),
rlen = 100, # 100번 훈련
alpha = c(0.05, 0.01))
summary(som.fit)## SOM of size 3x1 with a hexagonal topology and a bubble neighbourhood function.
## The number of data layers is 1.
## Distance measure(s) used: sumofsquares.
## Training data included: 144 objects.
## Mean distance to the closest unit in the map: 7.107.
plot(som.fit, type = 'codes')ls(som.fit)## [1] "alpha" "changes" "codes" "data"
## [5] "dist.fcts" "distance.weights" "distances" "grid"
## [9] "maxNA.fraction" "na.rows" "radius" "unit.classif"
## [13] "user.weights" "whatmap"
som.fit$unit.classif## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1
## [38] 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 3 2 2 2 2
## [75] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 1 2 2 2 2 2 2 2 3 3 3 3 3 3
## [112] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
적합된 모델에서 승자 유니트는 $unit.classif 속성값에서 확인할 수 있다.
#100번
som.fit1<-som(scale(wine.train[-1]), grid = somgrid(3,1,'hexagonal'), rlen = 100, alpha =c(0.05, 0.01))
#500번
som.fit2<-som(scale(wine.train[-1]), grid = somgrid(3,1,'hexagonal'), rlen = 500, alpha =c(0.05, 0.01))
par(mfrow = c(1,2))
plot(som.fit1, type = 'changes', main = 'Wine data: SOM (Learning NO. = 100)')
plot(som.fit2, type = 'changes', main = 'Wine data: SOM (Learning NO. = 500)')par(mfrow = c(1,1))우측 그래프가 좀 더 규칙적인 패턴을 보이는 것을 알 수 있다.
pred.som<-predict(som.fit, newdata =scale(wine.test[-1]))설명변수의 측정 단위편차를 없애기 위해 데이터를 표준화하여 적용한다.
wine.test$cluster<-pred.som$unit.classif
table(wine.test$Type)##
## 1 2 3
## 11 14 9
table(wine.test$cluster)##
## 1 2 3
## 13 11 10
# from factor to numeric number
wine.test$Type2<-ifelse(wine.test$Type == '1',1,
ifelse(wine.test$Type == '2',2,3))
som.tb<-table(wine.test$Type2, wine.test$cluster)
som.tb##
## 1 2 3
## 1 11 0 0
## 2 2 11 1
## 3 0 0 9
# Accuracy
mean(wine.test$Type2 == wine.test$cluster)## [1] 0.9117647
# Error rate
(1-sum(diag(som.tb))/sum(som.tb))## [1] 0.08823529
분석 결과 정오분류표를 보면 반응변수 모두 잘 군집된 것을 볼 수 있다. 정분류율은 1 이고, 오분류율은 0 이다.
연관규칙분석은 기업의 데이터 베이스에서 상품구매, 서비스 등 일련의 거래 또는 사건 간의 규칙을 찾아내는 거시며 그래서 흔히 장바구니분석이라고 불린다.
지지도는 전체 거래 중에서 품목 A 와 B가 동시에 포함되는 거래의 비율이다. 즉, 얼마나 빈번하게 나타나는 경우인지를 설명하는 절대적인 값이다.
신뢰도는 품목 A가 포함된 거래 중에서 품목 A, B를 동시에 포함될 확률이다. 이는 연관성의 정도를 파악할 수 있다.
향상도는 품목 A가 구매되지 않았을 때 품목 B를 구매한 고객 대비 품목 A를 구매한 후 품목B를 구매하는 고객에 대한 확률 증가 비율이다.
순차패턴분석은 구매순서가 고려되어 상품 간의 규칙을 찾는 기법이다
고객의 대규모 거래 데이터로부터 함께 구매가 발생하는 규칙 (A제품과 B제품을 동시에 구매하는 경우)을 도출하여 고객이 특정 상품 구매 시 이와 연관성 높은 상품을 추천할 수 있다.
연관성규칙의 일반적인 형태는 if A then B 형태이다. 연관규칙을 파악하면 세트메뉴를 구성하거나 쿠폰을 발행하는 등의 교차판매를 할 때 매우 효과적이다.예로 아메리카노를 마시는 손님 중 약 33%가 치즈케이크를 먹는다 등과 같은 연관규칙을 발견할 수 있다.
연관규칙분석을 통해 도출된 연관규칙이 유의미 한것인지 평가하기 위한 측도에는 지지도, 신뢰도, 향상도 의 측정지표를 활용한다.
지지도: 전체 거래 중에서 품목 A와 B가 동시에 포함되는 거래의 비율이다. A와 B가 동시에 포함된 거래수 / 전체 거래수
신뢰도: 품목 A가 포함된 거래 중에서 품목 A, B 가 동시에 포함될 확률이다. A와 B가 동시에 포함된 거래수 / A를 포함한 거래수 즉, 품목 A 를 구매한 사람이 품목 B도 구매하더라 이다.
향상도: 품목 A가구매되지 않았을 때 품목 B를 구매한 고객 대비 품목 A를 구매한 후 품목B를 구매하는 고객에 대한 확률 증가 비율이다. A와 B를 포함한 거래수 / A 를 포함한 거래수 x B 를 포함한 거래수. 향상도가 1 보다 크거나 작다면 우연적 기회보다 우수함을 의미한다.
Apriori 알고리즘: 연관분석 절차는 최소지지도 보다 큰 집합만을 대상으로 높은 지지도를 갖는 품목집합을 찾는 것이다. 최소지지도 이상을 갖는 품목집합을 빈발품목집합이라고 하는데 여기서 최소지지도 이상의 빈발품목집합을 찾아내는 연관규칙을 계산하는 것이다.
Apriori 절차: 최소지지도를 설정, 개별 품목 중에서 최소지지도를 넘는 모든 품목을 찾음, 그중에서 최소지지도를 넘는 2가지 품목 집합을 찾음, 전에 차은 품목집합을 결합하여 최소지지도를 넘는 3가지 품목집합찾음, 반복적으로 수행.
다음은 arules 패키지의 Epub 자료로 연관규칙분석을 수행하는 예제다.
library(arules)## Loading required package: Matrix
##
## Attaching package: 'Matrix'
## The following object is masked from 'package:bitops':
##
## %&%
##
## Attaching package: 'arules'
## The following object is masked from 'package:flexclust':
##
## info
## The following object is masked from 'package:modeltools':
##
## info
## The following objects are masked from 'package:base':
##
## abbreviate, write
data("Epub")
summary(Epub)## transactions as itemMatrix in sparse format with
## 15729 rows (elements/itemsets/transactions) and
## 936 columns (items) and a density of 0.001758755
##
## most frequent items:
## doc_11d doc_813 doc_4c6 doc_955 doc_698 (Other)
## 356 329 288 282 245 24393
##
## element (itemset/transaction) length distribution:
## sizes
## 1 2 3 4 5 6 7 8 9 10 11 12 13
## 11615 2189 854 409 198 121 93 50 42 34 26 12 10
## 14 15 16 17 18 19 20 21 22 23 24 25 26
## 10 6 8 6 5 8 2 2 3 2 3 4 5
## 27 28 30 34 36 38 41 43 52 58
## 1 1 1 2 1 2 1 1 1 1
##
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.000 1.000 1.000 1.646 2.000 58.000
##
## includes extended item information - examples:
## labels
## 1 doc_11d
## 2 doc_13d
## 3 doc_14c
##
## includes extended transaction information - examples:
## transactionID TimeStamp
## 10792 session_4795 2003-01-02 10:59:00
## 10793 session_4797 2003-01-02 21:46:01
## 10794 session_479a 2003-01-03 00:50:38
Epub 자료는 비엔나 경제 경영 대학교에서의 2003년 ~ 2008년까지 전자책 다운로드 이력, 거래 데이터다.
inspect(Epub[1:10])## items transactionID TimeStamp
## [1] {doc_154} session_4795 2003-01-02 10:59:00
## [2] {doc_3d6} session_4797 2003-01-02 21:46:01
## [3] {doc_16f} session_479a 2003-01-03 00:50:38
## [4] {doc_11d, doc_1a7, doc_f4} session_47b7 2003-01-03 08:55:50
## [5] {doc_83} session_47bb 2003-01-03 11:27:44
## [6] {doc_11d} session_47c2 2003-01-04 00:18:04
## [7] {doc_368} session_47cb 2003-01-04 04:40:57
## [8] {doc_11d, doc_192} session_47d8 2003-01-04 09:00:01
## [9] {doc_364} session_47e2 2003-01-05 02:48:36
## [10] {doc_ec} session_47e7 2003-01-05 05:58:48
itemFrequency(Epub[,1:10])## doc_11d doc_13d doc_14c doc_14e doc_150 doc_151
## 0.0226333524 0.0009536525 0.0024794965 0.0017801513 0.0015894208 0.0007629220
## doc_153 doc_154 doc_155 doc_156
## 0.0006357683 0.0013351135 0.0010808062 0.0031152648
itemFrequencyPlot(Epub, support = 0.01, main = "Item frequency plot above support 1%")itemFrequencyPlot(Epub, topN = 20, main = 'Support top 20 items')Epub.rules<-apriori(data = Epub, parameter = list(support = 0.001, confidence = 0.2, minlen = 2))## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.2 0.1 1 none FALSE TRUE 5 0.001 2
## maxlen target ext
## 10 rules TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 15
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[936 item(s), 15729 transaction(s)] done [0.01s].
## sorting and recoding items ... [481 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 done [0.00s].
## writing ... [65 rule(s)] done [0.00s].
## creating S4 object ... done [0.00s].
Epub.rules## set of 65 rules
분석 결과 65개 규칙으로 구성된 것을 볼 수 있다.
summary(Epub.rules)## set of 65 rules
##
## rule length distribution (lhs + rhs):sizes
## 2 3
## 62 3
##
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2.000 2.000 2.000 2.046 2.000 3.000
##
## summary of quality measures:
## support confidence coverage lift
## Min. :0.001017 Min. :0.2048 Min. :0.001208 Min. : 11.19
## 1st Qu.:0.001081 1st Qu.:0.2388 1st Qu.:0.003115 1st Qu.: 34.02
## Median :0.001208 Median :0.2874 Median :0.004514 Median : 59.47
## Mean :0.001435 Mean :0.3571 Mean :0.004764 Mean :105.16
## 3rd Qu.:0.001526 3rd Qu.:0.3696 3rd Qu.:0.005531 3rd Qu.:100.71
## Max. :0.004069 Max. :0.8947 Max. :0.013033 Max. :454.75
## count
## Min. :16.00
## 1st Qu.:17.00
## Median :19.00
## Mean :22.57
## 3rd Qu.:24.00
## Max. :64.00
##
## mining info:
## data ntransactions support confidence
## Epub 15729 0.001 0.2
## call
## apriori(data = Epub, parameter = list(support = 0.001, confidence = 0.2, minlen = 2))
향상도 최소값이 11.19로서 전반적으로 상당히 높은 것을 볼 수 있다.
inspect(sort(Epub.rules, by = 'lift')[1:10])## lhs rhs support confidence coverage
## [1] {doc_6e7, doc_6e8} => {doc_6e9} 0.001080806 0.8095238 0.001335113
## [2] {doc_6e7, doc_6e9} => {doc_6e8} 0.001080806 0.8500000 0.001271537
## [3] {doc_6e8, doc_6e9} => {doc_6e7} 0.001080806 0.8947368 0.001207960
## [4] {doc_6e9} => {doc_6e8} 0.001207960 0.6785714 0.001780151
## [5] {doc_6e8} => {doc_6e9} 0.001207960 0.5937500 0.002034459
## [6] {doc_6e9} => {doc_6e7} 0.001271537 0.7142857 0.001780151
## [7] {doc_6e7} => {doc_6e9} 0.001271537 0.5714286 0.002225189
## [8] {doc_506} => {doc_507} 0.001207960 0.6551724 0.001843728
## [9] {doc_507} => {doc_506} 0.001207960 0.5588235 0.002161612
## [10] {doc_6e8} => {doc_6e7} 0.001335113 0.6562500 0.002034459
## lift count
## [1] 454.7500 17
## [2] 417.8016 17
## [3] 402.0947 17
## [4] 333.5391 19
## [5] 333.5391 19
## [6] 321.0000 20
## [7] 321.0000 20
## [8] 303.0943 19
## [9] 303.0943 19
## [10] 294.9187 21
향상도 기준으로 내림차순으로 정렬한 후 상위 3개의 규칙을 보면, rhs 의 품목만 구매할 확률에 비해 lhs의 품목을 구매했을 때 rhs품목도 구매할 확률이 400배 이상 높다 (lift > 400). 따라서 rhs 와 lhs 품목들 간 결합상품 할인쿠폰 혹은 품목배치 변경 등을 통한 매출 증대를 꾀할수 있다.
library(arulesViz)
plot(Epub.rules)## To reduce overplotting, jitter is added! Use jitter = 0 to prevent jitter.
분석 결과 신뢰도가 높고, 향상도가 높은 경우 지지도는 낮은 경향이 보이는 것을 알 수 있다.
plot(Epub.rules[1:10], method = 'graph', control = list(type = 'items'), vertex.label.cex = 0.7, edge.arrow.size = 0.3, edge.arrow.width = 2)## Warning: Unknown control parameters: type, vertex.label.cex, edge.arrow.size,
## edge.arrow.width
## Available control parameters (with default values):
## layout = stress
## circular = FALSE
## ggraphdots = NULL
## edges = <environment>
## nodes = <environment>
## nodetext = <environment>
## colors = c("#EE0000FF", "#EEEEEEFF")
## engine = ggplot2
## max = 100
## verbose = FALSE