pacman::p_load(dplyr)


【A】航空公司顧客資料集

A = read.csv('data/AirlinesCluster.csv')
summary(A)
    Balance          QualMiles       BonusMiles       BonusTrans  
 Min.   :      0   Min.   :    0   Min.   :     0   Min.   : 0.0  
 1st Qu.:  18528   1st Qu.:    0   1st Qu.:  1250   1st Qu.: 3.0  
 Median :  43097   Median :    0   Median :  7171   Median :12.0  
 Mean   :  73601   Mean   :  144   Mean   : 17145   Mean   :11.6  
 3rd Qu.:  92404   3rd Qu.:    0   3rd Qu.: 23800   3rd Qu.:17.0  
 Max.   :1704838   Max.   :11148   Max.   :263685   Max.   :86.0  
  FlightMiles     FlightTrans    DaysSinceEnroll
 Min.   :    0   Min.   : 0.00   Min.   :   2   
 1st Qu.:    0   1st Qu.: 0.00   1st Qu.:2330   
 Median :    0   Median : 0.00   Median :4096   
 Mean   :  460   Mean   : 1.37   Mean   :4119   
 3rd Qu.:  311   3rd Qu.: 1.00   3rd Qu.:5790   
 Max.   :30817   Max.   :53.00   Max.   :8296   

欄位定義:
  ■ Balance: 可用里程數
  ■ QualMiles: 可用高級里程數
  ■ BonusMiles: 過去12個月非飛行里程數
  ■ BonusTrans: 過去12個月非飛行交易次數
  ■ FlightMiles: 過去12個月飛行里程數
  ■ FlightTrans: 過去12個月飛行交易次數
  ■ DaysSinceEnroll: 會員年資 (天)

【B】資料標準化

💡 scale(df) 標準化:讓資料框之中每一個欄位的平均值都等於0、標準差都等於1

🗿 Q: 集群分析和尺度縮減之前,為甚麼常要先做資料標準化呢?


AN = scale(A) %>% data.frame
sapply(AN, mean)
                 Balance                QualMiles               BonusMiles 
 0.000000000000000027654  0.000000000000000026507 -0.000000000000000042736 
              BonusTrans              FlightMiles              FlightTrans 
-0.000000000000000071911  0.000000000000000014818  0.000000000000000010741 
         DaysSinceEnroll 
 0.000000000000000055637 
sapply(AN, sd)
        Balance       QualMiles      BonusMiles      BonusTrans     FlightMiles 
              1               1               1               1               1 
    FlightTrans DaysSinceEnroll 
              1               1 



【C】層級式集群分析 Hirarchical Clustering

1.距離矩陣

d = dist(AN, method="euclidean")

2.層級式集群分析

hc = hclust(d, method='ward.D')

3.畫出樹狀圖 Dendrogram

plot(hc)


💡 樹狀圖中的垂直線段高度,代表分群之後,群內各點到族群中心點的平均距離縮短的幅度。

🗿 Q: 如何從樹狀圖決定群數?


4.分割群組、製作分群向量

kg = cutree(hc, k=5)



【D】觀察群組特性

做完分群向量之後,通常要先觀察每一個族群的大小

table(kg)
kg
   1    2    3    4    5 
 776  519  494  868 1342 

然後我們觀察每一個族群、每一個變數的平均值

names(A) = names(AN) =c(
  "里程數","高級里程數","非飛行里程","非飛行交易",
  "飛行里程","飛行交易","會員年資")

sapply(split(A,kg), colMeans) %>% round(2)  # 原始尺度 
                  1         2         3        4        5
里程數     57866.90 110669.27 198191.57 52335.91 36255.91
高級里程數     0.64   1065.98     30.35     4.85     2.51
非飛行里程 10360.12  22881.76  55795.86 20788.77  2264.79
非飛行交易    10.82     18.23     19.66    17.09     2.97
飛行里程      83.18   2613.42    327.68   111.57   119.32
飛行交易       0.30      7.40      1.07     0.34     0.44
會員年資    6235.36   4402.41   5615.71  2840.82  3060.08
sapply(split(AN,kg), colMeans) %>% round(2)  # 標準化尺度 
               1    2     3     4     5
里程數     -0.16 0.37  1.24 -0.21 -0.37
高級里程數 -0.19 1.19 -0.15 -0.18 -0.18
非飛行里程 -0.28 0.24  1.60  0.15 -0.62
非飛行交易 -0.08 0.69  0.84  0.57 -0.90
飛行里程   -0.27 1.54 -0.09 -0.25 -0.24
飛行交易   -0.28 1.59 -0.08 -0.27 -0.25
會員年資    1.03 0.14  0.72 -0.62 -0.51

直條圖

par(cex=0.8)
split(AN,kg) %>% sapply(colMeans) %>% barplot(beside=T,col=rainbow(7))
legend('topright',legend=colnames(A),fill=rainbow(7))


🗿 討論問題:
  ■ 分群平均值的代表什麼? 它們的的商業意義是什麼?
  ■ 「原始尺度」和「標準化尺度」各有什麼優缺點?
  ■ 什麼時候要用原始尺度? 什麼時候要用標準化尺度?


🗿 討論問題:
  ■ 統計上最好的分群也是實務上最好的分群嗎
  ■ 除了考慮群間和群間距離之外,實務上的分群通常還需要考慮那些因數?


🗿 討論問題:
  ■ 請你們為這五個族群各起一個名稱
  ■ 請你們為這五個族群各設計一個行銷策略