Description for Cluster Analysis using Package mlr
k-means의 장점
k-means의 단점
실습 자료 : “USArrests” 데이터셋은 1973년 미국의 50개 주별로 살인(Murder), 폭행(Assault) 그리고 강간(Rape) 범죄의 10만명당 체포 건수와 도시 인구 비율을 포함하고 있다.
Contents
pacman::p_load("data.table",
"tidyverse",
"dplyr",
"caret",
"GGally", # For ggpairs
"mlr",
"clue",
"parallelMap", # For parallelStartSocket
"parallel") # For detectCores
data("USArrests") # 데이터 불러오기
USArrests %>%
as_tibble
# A tibble: 50 × 4
Murder Assault UrbanPop Rape
<dbl> <int> <int> <dbl>
1 13.2 236 58 21.2
2 10 263 48 44.5
3 8.1 294 80 31
4 8.8 190 50 19.5
5 9 276 91 40.6
6 7.9 204 78 38.7
7 3.3 110 77 11.1
8 5.9 238 72 15.8
9 15.4 335 80 31.9
10 17.4 211 60 25.8
# ℹ 40 more rows
# 상관계수 그래프
ggcorr(USArrests, # 데이터
label = TRUE, # 라벨 명시 여부
label_round = 3, # 상관계수 소숫점 이하 자릿수
label_size = 3, # 상관계수 글자 크기
low = "steelblue", # 상관계수가 음수일 때 색깔
mid = "white", # 상관계수가 0에 가까울 때 색깔
high = "darkred") # 상관계수가 양수일 때 색깔
# Standardization
preProcValues <- preProcess(USArrests.trd,
method = c("center", "scale")) # Standardization 정의 -> Training Dataset에 대한 평균과 표준편차 계산
USArrests.trd <- predict(preProcValues, USArrests.trd) # Standardization for Training Dataset
USArrests.ted <- predict(preProcValues, USArrests.ted) # Standardization for Test Dataset
glimpse(USArrests.trd) # 데이터 구조 확인
Rows: 40
Columns: 4
$ Murder <dbl> -0.28335915, -0.82987994, 1.64134450, -1.13878299, …
$ Assault <dbl> -0.66262772, -0.20320584, 1.37532065, -1.06314937, …
$ UrbanPop <dbl> 0.56553882, 0.63579209, -1.12053964, 0.14401920, 1.…
$ Rape <dbl> -0.62276898, 0.61022086, 0.20649852, -0.62276898, 2…
glimpse(USArrests.ted) # 데이터 구조 확인
Rows: 10
Columns: 4
$ Murder <dbl> 0.5958265, 1.8789622, 2.3541977, -1.1625448, 0.6908…
$ Assault <dbl> 1.1868399, 2.0350034, 0.5742774, -0.4977070, 1.0219…
$ UrbanPop <dbl> -1.1205396, 1.1275650, -0.2775004, -0.6990200, 1.33…
$ Rape <dbl> 2.6070097, 1.2321715, 0.5665752, -0.6991489, 0.3701…
문제 유형 | 함수 |
회귀 문제 | makeRegrTask() |
이진 또는 다중 클래스 분류 문제 | makeClassifTask() |
생존분석 | makeSurvTask() |
군집분석 | makeClusterTask() |
다중 라벨 분류 문제 | makeMultilabelTask() |
비용 민감 분류 문제 | makeCostSensTask() |
## k-means : 군집분석
USArrests.Task <- makeClusterTask(data = USArrests.trd) # Training Dataset
USArrests.Task
Unsupervised task: USArrests.trd
Type: cluster
Observations: 40
Features:
numerics factors ordered functionals
4 0 0 0
Missings: FALSE
Has weights: FALSE
Has blocking: FALSE
Has coordinates: FALSE
makeLearner()
를 이용하여 정의한다.makeLearner()
의 첫 번째 인자 cl
에는 사용하고자 하는 머신러닝 알고리듬을 문제 유형.알고리듬과 관련된 R 함수 이름
형태로 입력한다.
"regr.알고리듬과 관련된 R 함수 이름"
"classif.알고리듬과 관련된 R 함수 이름"
"surv.알고리듬과 관련된 R 함수 이름"
"cluster.알고리듬과 관련된 R 함수 이름"
"multilabel.알고리듬과 관련된 R 함수 이름"
"mlr"
에서 사용할 수 있는 알고리듬은 여기를 통해서 확인할 수 있다.# 초모수 집합
getParamSet("cluster.kmeans") # cluster.kmeans : Clustering based on "kmeans" function
Type len Def
centers untyped - -
iter.max integer - 10
nstart integer - 1
algorithm discrete - Hartigan-Wong
trace logical - -
Constr Req Tunable Trafo
centers - - TRUE -
iter.max 1 to Inf - TRUE -
nstart 1 to Inf - TRUE -
algorithm Hartigan-Wong,Lloyd,Forgy,MacQueen - TRUE -
trace - - FALSE -
Caution!
특정 머신러닝 알고리듬이 가지고 있는 초모수는 함수 getParamSet()
를 이용하여 확인할 수 있다.
USArrests.Learner <- makeLearner(cl = "cluster.kmeans", # 함수 kmeans를 이용하여 군집분석 수행
par.vals = list(iter.max = 100, # 최대 반복 수
nstart = 25)) # 수행 횟수
USArrests.Learner
Learner cluster.kmeans from package stats,clue
Type: cluster
Name: K-Means; Short name: kmeans
Class: cluster.kmeans
Properties: numerics,prob
Predict-Type: response
Hyperparameters: centers=2,iter.max=100,nstart=25
Caution!
함수 makeLearner()
의 인자 par.vals
에 함수 kmeans()
의 옵션을 입력할 수 있다. iter.max
에는 최대 반복 수를, nstart
에는 k-means 수행 횟수를 지정할 수 있다. k-means는 초기 중심값을 랜덤하게 선택하기 때문에 이 과정에서 다양한 결과가 나타날 수 있다. 그래서 옵션 nstart
를 이용하여 수행 횟수를 늘려 최대한 다양한 초기 중심값에 대해 k-means를 수행하고 최적의 결과를 찾을 수 있다.
makeDiscreteParam()
또는 makeNumericParam()
을 이용하여 초모수의 검색 범위를 정의한다.
makeDiscreteParam()
: 검색 범위를 특정값으로 정의하는 경우 사용makeNumericParam()
: 검색 범위를 구간으로 정의하는 경우 사용makeParamSet()
를 이용하여 정의한 검색 범위을 ParamSet
객체로 만든다.# 초모수 "centers" (군집 수)와 알고리듬의 검색 범위 정의
tune.hyper <- makeParamSet(
makeDiscreteParam("centers", # 군집 수
values = 3:7), # 군집 수에 대한 검색 범위
makeDiscreteParam("algorithm", # k-means 알고리듬
values = c("Lloyd", "MacQueen", "Hartigan-Wong"))) # 알고리듬에 대한 검색 범위
tune.hyper
Type len Def Constr Req Tunable
centers discrete - - 3,4,5,6,7 - TRUE
algorithm discrete - - Lloyd,MacQueen,Hartigan-Wong - TRUE
Trafo
centers -
algorithm -
Caution!
k-means를 수행하기 위해 “Lloyd”, “MacQueen” 그리고 “Hartigan-Wong” 알고리듬을 검색 범위로 정의하였다. 각 알고리듬의 수행 절차는 다음과 같다.
makeTuneControlGrid()
와 makeTuneControlRandom()
을 이용하여 정의할 수 있다.gridSearch <- makeTuneControlGrid() # 그리드 검색
gridSearch
Tune control: TuneControlGrid
Same resampling instance: TRUE
Imputation value: <worst>
Start: <NULL>
Tune threshold: FALSE
Further arguments: resolution=10
Result!
함수 makeTuneControlGrid()
를 이용하여 위에서 정의한 초모수 “centers”와 알고리듬의 검색 범위에 해당하는 모든 조합을 후보 초모수 조합으로 설정한다.
kFold <- makeResampleDesc("CV", iters = 5) # 5-Fold Cross Validation
kFold
Resample description: cross-validation with 5 iterations.
Predict: test
Stratification: FALSE
tuneParams()
를 이용한다.parallelStartSocket(cpus = detectCores()) # 병렬 처리
set.seed(100)
tunedK <- tuneParams(task = USArrests.Task, # Defined Task in 5-1-1
learner = USArrests.Learner, # Defined Learner in 5-1-2
par.set = tune.hyper, # Defined Search Space in 5-1-3
control = gridSearch, # Defined Tuning Method in 5-1-4
resampling = kFold, # Defined Resampling Strategy in 5-1-5
measures = list(silhouette)) # Silhouette Index
tunedK
Tune result:
Op. pars: centers=4; algorithm=Lloyd
silhouette.test.mean=0.4363971
Result!
최적의 초모수 조합을 찾기 위해 “Silhouette Index”를 사용하였다. “Silhouette Index”는 다른 군집과 비교하여 case가 현재 속한 군집과 얼마나 유사한지를 나타내는 척도로 값이 높을수록 군집화가 잘 되었다는 것을 의미한다.
tunedK$x$centers # 최적의 군집 수
[1] 4
tunedK$x$algorithm # 최적의 알고리듬
[1] "Lloyd"
# 튜닝 과정 시각화
kMeansTuningData <- generateHyperParsEffectData(tunedK) # Extract Hyperparameter Effect from Tuning Result
kMeansTuningData$data
centers algorithm silhouette.test.mean iteration exec.time
1 3 Lloyd 0.38410327 1 0.48
2 4 Lloyd 0.43639711 2 0.47
3 5 Lloyd 0.28880857 3 0.47
4 6 Lloyd 0.16298416 4 0.50
5 7 Lloyd 0.14641453 5 0.48
6 3 MacQueen 0.38012986 6 0.46
7 4 MacQueen 0.42428022 7 0.06
8 5 MacQueen 0.34982859 8 0.06
9 6 MacQueen 0.18721157 9 0.09
10 7 MacQueen 0.08485767 10 0.10
11 3 Hartigan-Wong 0.38012986 11 0.08
12 4 Hartigan-Wong 0.42428022 12 0.07
13 5 Hartigan-Wong 0.31448170 13 0.09
14 6 Hartigan-Wong 0.17279832 14 0.09
15 7 Hartigan-Wong 0.12861509 15 0.06
# 데이터 구조 변환
TuningData <- pivot_longer(kMeansTuningData$data,
cols = -c(centers, iteration, algorithm, exec.time),
names_to = "Metric",
values_to = "Value")
TuningData %>%
as_tibble
# A tibble: 15 × 6
centers algorithm iteration exec.time Metric Value
<int> <chr> <int> <dbl> <chr> <dbl>
1 3 Lloyd 1 0.480 silhouette.test.m… 0.384
2 4 Lloyd 2 0.470 silhouette.test.m… 0.436
3 5 Lloyd 3 0.470 silhouette.test.m… 0.289
4 6 Lloyd 4 0.5 silhouette.test.m… 0.163
5 7 Lloyd 5 0.480 silhouette.test.m… 0.146
6 3 MacQueen 6 0.460 silhouette.test.m… 0.380
7 4 MacQueen 7 0.0600 silhouette.test.m… 0.424
8 5 MacQueen 8 0.0600 silhouette.test.m… 0.350
9 6 MacQueen 9 0.0900 silhouette.test.m… 0.187
10 7 MacQueen 10 0.100 silhouette.test.m… 0.0849
11 3 Hartigan-Wong 11 0.0800 silhouette.test.m… 0.380
12 4 Hartigan-Wong 12 0.0700 silhouette.test.m… 0.424
13 5 Hartigan-Wong 13 0.0900 silhouette.test.m… 0.314
14 6 Hartigan-Wong 14 0.0900 silhouette.test.m… 0.173
15 7 Hartigan-Wong 15 0.0600 silhouette.test.m… 0.129
ggplot(TuningData, aes(centers, Value, col = algorithm)) +
facet_wrap(~ Metric, scales = "free_y") +
geom_line() +
geom_point() +
theme_bw()
Result!
초모수 “centers = 4”이고 알고리듬이 “Lloyd”일 때 “Silhouette Index”값이 가장 높다는 것을 알 수 있다.
# Redefine Learner with 최적의 초모수 조합
tunedKMeans <- setHyperPars(USArrests.Learner, # Defined Learner in 5-1-2
par.vals = list(centers = tunedK$x$centers, # 최적의 군집 수
algorithm = tunedK$x$algorithm)) # 최적의 알고리듬
tunedKMeans
Learner cluster.kmeans from package stats,clue
Type: cluster
Name: K-Means; Short name: kmeans
Class: cluster.kmeans
Properties: numerics,prob
Predict-Type: response
Hyperparameters: centers=4,iter.max=100,nstart=25,algorithm=Lloyd
tunedKMeansModel <- train(tunedKMeans, # Defined Learner in 5-2-1
USArrests.Task) # Defined Task in 5-1-1
tunedKMeansModel
Model for learner.id=cluster.kmeans; learner.class=cluster.kmeans
Trained on: task.id = USArrests.trd; obs = 40; features = 4
Hyperparameters: centers=4,iter.max=100,nstart=25,algorithm=Lloyd
kMeanModel <- getLearnerModel(tunedKMeansModel) # 예측 모형 추출
kMeanModel
K-means clustering with 4 clusters of sizes 15, 7, 8, 10
Cluster means:
Murder Assault UrbanPop Rape
1 -0.4544439 -0.3736239 0.5280704 -0.1441216
2 1.4139104 1.0135049 -0.7793095 0.0194457
3 0.7354269 1.1323572 0.9607135 1.5267797
4 -0.8964129 -1.0549033 -1.0151597 -1.0188533
Clustering vector:
Pennsylvania Washington South Carolina Minnesota
1 1 2 1
Nevada Utah Montana Louisiana
3 1 4 2
Nebraska Tennessee Mississippi Maryland
1 2 2 3
South Dakota Delaware Oklahoma New Mexico
4 1 1 3
Colorado New Jersey Wisconsin Virginia
3 1 4 1
North Dakota Arizona Hawaii New Hampshire
4 3 1 4
California Alabama Michigan Ohio
3 2 3 1
Oregon Connecticut Texas Arkansas
1 1 3 2
North Carolina Maine Indiana Wyoming
2 4 1 1
Kentucky Iowa Vermont West Virginia
4 4 4 4
Within cluster sum of squares by cluster:
[1] 14.857404 7.103948 8.774396 9.673065
(between_SS / total_SS = 74.1 %)
Available components:
[1] "cluster" "centers" "totss" "withinss"
[5] "tot.withinss" "betweenss" "size" "iter"
[9] "ifault"
# Training Dataset의 각 군집별 특징 시각화
USArrests.trd.clus <- mutate(USArrests.trd,
kMeansCluster = as.factor(kMeanModel$cluster)) # 예측 모형에 의한 군집 결과
USArrests.trd.clus %>%
as_tibble
# A tibble: 40 × 5
Murder Assault UrbanPop Rape kMeansCluster
<dbl> <dbl> <dbl> <dbl> <fct>
1 -0.283 -0.663 0.566 -0.623 1
2 -0.830 -0.203 0.636 0.610 1
3 1.64 1.38 -1.12 0.206 2
4 -1.14 -1.06 0.144 -0.623 1
5 1.12 1.06 1.20 2.77 3
6 -1.02 -0.498 1.13 0.250 1
7 -0.355 -0.627 -0.769 -0.459 4
8 1.88 1.02 0.144 0.174 2
9 -0.759 -0.710 -0.137 -0.448 1
10 1.36 0.303 -0.348 0.687 2
# ℹ 30 more rows
ggpairs(USArrests.trd.clus, aes(col = kMeansCluster),
upper = list(continuous = "density")) +
theme_bw()
# 예측 군집 생성
Pred <- predict(tunedKMeansModel,
newdata = USArrests.ted) # predict(Trained Model, Test Dataset)
Pred %>%
as_tibble
# A tibble: 10 × 1
response
<int>
1 3
2 3
3 2
4 4
5 3
6 1
7 1
8 3
9 3
10 1
Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".