Cluster Analysis using Package mlr

Data Mining

Description for Cluster Analysis using Package mlr

Yeongeun Jeon , Jung In Seo
2023-07-10

k-means의 장점


k-means의 단점

실습 자료 : “USArrests” 데이터셋은 1973년 미국의 50개 주별로 살인(Murder), 폭행(Assault) 그리고 강간(Rape) 범죄의 10만명당 체포 건수와 도시 인구 비율을 포함하고 있다.





Contents


1. 데이터 불러오기

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

2. 데이터 탐색

ggpairs(USArrests,
        upper = list(continuous = "density"),
        lower = list(continuous = wrap("points", size = 0.5)),
        diag = list(continuous = "densityDiag")) +
  theme_bw()

# 상관계수 그래프
ggcorr(USArrests,               # 데이터
       label = TRUE,            # 라벨 명시 여부
       label_round = 3,         # 상관계수 소숫점 이하 자릿수
       label_size = 3,          # 상관계수 글자 크기
       low = "steelblue",       # 상관계수가 음수일 때 색깔
       mid = "white",           # 상관계수가 0에 가까울 때 색깔
       high = "darkred")        # 상관계수가 양수일 때 색깔


3. 데이터 분할

# Partition (Training Dataset : Test Dataset = 8:2)
set.seed(200)
ind <- sample(1:nrow(USArrests), 0.8*nrow(USArrests))       # Index를 이용하여 8:2로 분할

USArrests.trd <- USArrests[ind,]                            # Training Dataset
USArrests.ted <- USArrests[-ind,]                           # Test Dataset

4. 데이터 전처리

# 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…

5. 모형 훈련


5-1. Resampling을 이용한 최적의 초모수 조합 찾기

5-1-1. Define Task

문제 유형 함수
회귀 문제 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

5-1-2. Define Learner

# 초모수 집합
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를 수행하고 최적의 결과를 찾을 수 있다.


5-1-3. Define Search Space

# 초모수 "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” 알고리듬을 검색 범위로 정의하였다. 각 알고리듬의 수행 절차는 다음과 같다.


5-1-4. Define Tuning Method

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”와 알고리듬의 검색 범위에 해당하는 모든 조합을 후보 초모수 조합으로 설정한다.


5-1-5. Define Resampling Strategy

kFold <- makeResampleDesc("CV", iters = 5)                             # 5-Fold Cross Validation
kFold
Resample description: cross-validation with 5 iterations.
Predict: test
Stratification: FALSE

5-1-6. Perform Tuning

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”값이 가장 높다는 것을 알 수 있다.


5-2. 최적의 초모수 조합과 함께 모형 훈련

5-2-1. Redefine Learner

# 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

5-2-2. Train Model

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()


6. 예측

# 예측 군집 생성
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

Reuse

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 ...".