카테고리 없음

[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means)

연정양 2022. 12. 20.

개요

  diamonds 데이터의 경우 등간척도와 명목척도가 혼재되어 있으며 데이터 양이 많아 (53940 ) 샘플링을 포함한 데이터 전처리 과정이 필요하였다. 데이터는 1000개를 임의 추출하였으며, seed값으로 1234를 부여하였다.

  군집 분석의 경우 범위가 넓은 변수에 영향을 많이 받는 경향이 있어 scale() 함수를 통해 데이터 표준화 과정을 거쳤다. 이상치에도 영향을 많이 받으나 해당 데이터는 실존하는 다이아몬드의 데이터이므로 결측치를 제외한 이상치는 없는 것으로 간주하였다. 결측치 또한 실제로 존재하지 않았다.

  dist()함수로 계산되는 manhattan, maximum, canberra 거리의 경우 명목척도를 제외한 데이터셋으로 계산하였다. 또한, distance() 함수로 계산된 결과값을 hclust()에 직접 입력 시 오류가 발생하여 as.dist() 함수를 통해 dist() 결과값으로 변환 후 사용하였다.

  계산된 데이터를 기반으로 NbClust() 함수를 통해 최적 군집수를 확인하였고, 2개의 군집으로 분류하는 것이 가장 적절할 것이라는 결론을 내렸다. 비계층적 군집 분석에 앞서 변수간 상관관계를 확인하였고, 가장 높은 상관계수를 가지는 price carat 데이터로 군집 분석을 실시하였다.

 

분석 목적

  다이아몬드의 가격과 나머지 변수들의 연관성 분석 및 군집 분석을 통하여 관련이 깊은 변수를 찾아내고, 군집의 존재 여부와 군집을 구분하는 기준을 분석하기 위하여 해당 분석을 진행하고자 한다.

 

 

데이터 정의

사용 데이터: ggplot2 패키지 내 diamonds 데이터

컬럼명 의미
price 가격 ($326 ~ $18,823)
carat 무게 (0.2 ~ 5.01)
cut cut 컷팅의 가치 (Fair, Good, Very Good, Premium, Ideal)
colour 다이아몬드 색상 (J(가장 나쁜)에서 D(가장 좋은)까지)
clarity 깨끗함 (I1 (가장 나쁜), SI1, SI2, VS1, VS2, VVS1, VVS2, IF(가장 좋은))
x 길이 (0 ~ 10.74mm)
y 너비 (0 ~ 58.9mm)
z 깊이 (0~31.8mm)
depth 깊이 비율 = z / mean(x, y)
table 가장 넓은 부분의 너비 대비 다이아몬드 꼭대기의 너비 (43 ~ 95)
(비율(%)로 추정됨)

  diamonds 데이터는 총 10개의 변수로 이루어져 있으며,  53,940개의 컷팅된 다이아몬드에 대한 정보를 갖고 있다. depth 계산식에 x, y, z가 포함되므로 연관성 분석에서 제외하였으며, 명목척도인 cut, colour, clarity 또한 분석에서 제외하여 price, carat, depth, table변수에 대해 집중적으로 분석하였다.

 

계층적 군집 분석(hierarchical clustering)

1) library 호출

library(ggplot2)
library(philentropy)
library(cluster)
library(NbClust)
library(corrgram)

2) 데이터 샘플링

data(diamonds)
str(diamonds)
head(diamonds)
set.seed(1234)

idx <- sample(1:nrow(diamonds), 1000)
head(idx)

t <- diamonds[idx, ]
d <- t[, -c(2:4, 8:10)]
dia <- scale(d)

head(dia)
length(dia$carat)

  diamonds 데이터 중 임의의 데이터 1000개를 추출하여 사용하였으며, 명목 척도와 분석에 사용하지 않는 변수를 제거한 후 데이터 표준화를 진행하였다.

 

3) 거리 계산

getDistMethods()
man <- dist(dia, method = 'manhattan')
max <- dist(dia, method = 'maximum')
can <- dist(dia, method = 'canberra')
이름 공식 및 설명
maximum 최대 거리. 두 점의 차의 절대값의 최대값. chebyshev 거리와 같다.

[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 계층적 군집 분석(hierarchical clustering)
manhattan 맨해튼 거리. 두 점의 차의 절대값의 총 합.

[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 계층적 군집 분석(hierarchical clustering)
canberra 캔버라 거리. 두 점의 차의 절대값을 두 점의 합으로 나눈 값의 총 합.
[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 계층적 군집 분석(hierarchical clustering)

4) 계층적 군집 분석과 덴드로이드 시각화 (일부)

man_hc1 <- hclust(man, method = 'average')

NbClust(dia, distance = 'manhattan', method = 'average')

  모든 연결법에 대해 NbClust()를 진행하였으며, 최적 군집수는 아래와 같이 확인되었다.

  average single complete centroid ward.D mcquitty median
manhattan 2 2 2 2 2 2 2
maximum 2 2 2, 10 2 3 2 2
canberra 2 2 3 2 2, 3 2 2

 NbClust() 결과 2개의 군집으로 분류하는 것이 적절함을 알 수 있었다. 추가로 덴드로이드를 시각화하여 적절한 군집 수를 확인해 보았으며, 그 중 canberramaximumaverage 연결법 시각화 결과는 아래와 같다.

 

[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 계층적 군집 분석(hierarchical clustering)
canberra distance : average
[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 계층적 군집 분석(hierarchical clustering)
maximum distance : average

   덴드로그램 상에서 군집을 나누는 경우 군집 간 높이 차이가 큰 군집의 개수를 선택하여야 군집 간 이질성이 큰 군집이 되므로 이를 활용하고자 하였으나, 데이터 수가 많아 유의미한 군집을 찾기 어려운 경우가 많았다. 이와 같은 경우를 제외한 분기점이 눈에 띄는 데이터의 경우 대부분 2개의 군집으로 나누는 것이 적절할 것으로 확인되었다.

NbClust() 결과 데이터와 덴드로그램 분석 결과를 바탕으로 2개의 군집으로 군집분석을 진행했다.

 

비계층적 군집 분석(k-means clustering)

1) 상관계수 확인

corrgram(dia, upper.panel = panel.conf)
corrgram(dia1, upper.panel = panel.conf)

  계층적 군집 분석 결과를 통해 2개의 군집으로 데이터를 분류하는 것이 적절할 것으로 확인하여 kmeans() 함수를 통해 비계층적 군집 분석을 실행하였다. 분석 대상으로는 price 와 상관계수가 0.92로 가장 높은 carat 데이터로 지정하였다. 상관계수표는 다음과 같다.

[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 비계층적 군집 분석(k-means clustering)
명목척도를 제외한 데이터셋의 상관계수표(carat, depth, table, price)

2) k-means 군집분석 및 시각화

kmeans <- kmeans(d, 2)

X11()
plot(d[c('carat', 'price')], col = kmeans$cluster,
     pch = 21, bg = kmeans$cluster)
points(kmeans$centers[, c('carat', 'price')],
       col = 3:4, pch = 23, cex = 3, bg = 3:4)

[R/실습] Diamonds 데이터 군집분석(hierarchical/k-means) - undefined - 비계층적 군집 분석(k-means clustering)

  k-means 군집 분석 시각화 결과 price 7000 근처에서 확연한 구분선이 보이지만 carat 값으로는 명확한 구분선이 보이지 않으며, 군집 간의 거리도 상당히 가까운 것으로 보아 데이터가 유의미한 군집을 형성하고 있지 않다고 결론지을 수 있다.

 

결론

  diamonds 데이터를 대상으로 다양한 거리 계산법과 연결법을 적용하여 분석해 보았으나 대부분의 경우에서 계층적 군집분석 결과는 해당 데이터가 2개의 군집으로 이루어져 있는 것으로 유사하게 나타나 유의미한 차이를 보이지 않았다. 이 데이터를 바탕으로 비계층적 군집 분석을 실시하였으나 군집 간의 경계가 모호한 것으로 보아 군집 간 이질성이 떨어지는 것으로 판단되어 해당 데이터가 군집성이 있다고 보기 어려웠다.

 

소스 코드

library(ggplot2)
library(philentropy)
library(cluster)
library(NbClust)
library(corrgram)

# (1)
#install.packages("ggplot2")
data(diamonds)
str(diamonds)
head(diamonds)
set.seed(1234)
idx <- sample(1:nrow(diamonds), 1000)
head(idx)
t <- diamonds[idx, ]
d <- t[, -c(2:4, 8:10)]
dia <- scale(d)
head(dia)
length(dia$carat)


# (2)
getDistMethods()
man <- dist(dia, method = 'manhattan')
max <- dist(dia, method = 'maximum')
can <- dist(dia, method = 'canberra')
help(dist)

# (3)
#install.packages('cluster')
help(hclust)

man_hc1 <- hclust(man, method = 'average')
max_hc1 <- hclust(max, method = 'average')
can_hc1 <- hclust(can, method = 'average')
help("NbClust")
NbClust(dia, distance = 'manhattan', method = 'average')


# (4)
X11()
par(mfrow = c(1, 2))
plot(man_hc1, hang = -1)
rect.hclust(man_hc1, k=2)
plot(max_hc1, hang = -1)
rect.hclust(max_hc1, k=2)
plot(can_hc1, hang = -1)
rect.hclust(can_hc1, k=2)


# (5)
corrgram(dia, upper.panel = panel.conf)
kmeans <- kmeans(d, 2)


# (6)
X11()
plot(d[c('carat', 'price')], col = kmeans$cluster,
     pch = 21, bg = kmeans$cluster)
points(kmeans$centers[, c('carat', 'price')],
       col = 3:4, pch = 23, cex = 3, bg = 3:4)

댓글