K-means演算法原理以及應用(R)
K-means是一種無監督學習演算法,是聚類演算法中最簡單的一種了。不同與一些分類的監督學習演算法,比如邏輯迴歸、SVM、隨機森林等,k-means聚類無需給定Y變數,只有特徵X。下面是k-means演算法原理及思想。
K-means演算法是將樣本聚類成k個簇(cluster),具體演算法描述如下:
1、 隨機選取k個聚類質心點(cluster centroids)為。 2、 重複下面過程直到收斂 { 對於每一個樣例i,計算其應該屬於的類 對於每一個類j,重新計算該類的質心 } |
K是我們事先給定的聚類數,代表樣例i與k個類中距離最近的那個類,的值是1到k中的一個。質心代表我們對屬於同一個類的樣本中心點的猜測,拿星團模型來解釋就是要將所有的星星聚成k個星團,首先隨機選取k個宇宙中的點(或者k個星星)作為k個星團的質心,然後第一步對於每一個星星計算其到k個質心中每一個的距離,然後選取距離最近的那個星團作為,這樣經過第一步每一個星星都有了所屬的星團;第二步對於每一個星團,重新計算它的質心(對裡面所有的星星座標求平均)。重複迭代第一步和第二步直到質心不變或者變化很小。
下圖展示了對n個樣本點進行K-means聚類的效果,這裡k取2。
K-means面對的第一個問題是如何保證收斂,前面的演算法中強調結束條件就是收斂,可以證明的是K-means完全可以保證收斂性。下面我們定性的描述一下收斂性,我們定義畸變函式(distortion function)如下:
J函式表示每個樣本點到其質心的距離平方和。K-means是要將J調整到最小。假設當前J沒有達到最小值,那麼首先可以固定每個類的質心,調整每個樣例的所屬的類別來讓J函式減少,同樣,固定,調整每個類的質心也可以使J減小。這兩個過程就是內迴圈中使J單調遞減的過程。當J遞減到最小時,和c也同時收斂。(在理論上,可以有多組不同的和c值能夠使得J取得最小值,但這種現象實際上很少見)。
由於畸變函式J是非凸函式,意味著我們不能保證取得的最小值是全域性最小值,也就是說k-means對質心初始位置的選取比較感冒,但一般情況下k-means達到的區域性最優已經滿足需求。但如果你怕陷入區域性最優,那麼可以選取不同的初始值跑多遍k-means,然後取其中最小的J對應的和c輸出。
kmeans的演算法和思想弄懂之後,就開始要知道如何使用它,以及在什麼場合適用,有什麼優點和缺點。下面我來用示例來展示:下面是一家航空公司的一部分客戶資料:
屬性名稱 |
屬性說明 |
|
客戶基本資訊 |
MEMBER_NO |
會員卡號 |
FFP_DATE |
入會時間 |
|
FIRST_FLIGHT_DATE |
第一次飛行日期 |
|
GENDER |
性別 |
|
FFP_TIER |
會員卡級別 |
|
WORK_CITY |
工作地城市 |
|
WORK_PROVINCE |
工作地所在省份 |
|
WORK_COUNTRY |
工作地所在國家 |
|
AGE |
年齡 |
|
乘機資訊 |
FLIGHT_COUNT |
觀測視窗內的飛行次數 |
LOAD_TIME |
觀測視窗的結束時間 |
|
LAST_TO_END |
最後一次乘機時間至觀測視窗結束時長 |
|
AVG_DISCOUNT |
平均折扣率 |
|
SUM_YR |
觀測視窗的票價收入 |
|
SEG_KM_SUM |
觀測視窗的總飛行公里數 |
|
LAST_FLIGHT_DATE |
末次飛行日期 |
|
AVG_INTERVAL |
平均乘機時間間隔 |
|
MAX_INTERVAL |
最大乘機間隔 |
|
積分資訊 |
EXCHANGE_COUNT |
積分兌換次數 |
EP_SUM |
總精英積分 |
|
PROMOPTIVE_SUM |
促銷積分 |
|
PARTNER_SUM |
合作伙伴積分 |
|
POINTS_SUM |
總累計積分 |
|
POINT_NOTFLIGHT |
非乘機的積分變動次數 |
|
BP_SUM |
總基本積分 |
*觀測視窗:以過去某個時間點為結束時間,某一時間長度作為寬度,得到歷史時間範圍內的一個時間段。
目標:對客戶精準個性化營銷,提升航空公司收益。思路:
1.選取特徵變數;
在經典RFM模型上加上兩個業務緊密相關指標,總共5個特徵變數。
模型 |
L |
R |
F |
M |
C |
航空公司LRFMC模型 |
會員入會時間距觀測視窗結束的月數 |
客戶最近一次乘坐公司飛機距觀測視窗結束的月數 |
客戶在觀測視窗內乘坐公司飛機的次數 |
客戶在觀測視窗內累計的飛行里程 |
客戶在觀測視窗內乘坐艙位所對應的折扣係數的平均值 |
2.採用k-means進行聚類(K=5);
3.對聚類使用者進行特徵分析;
4.對不同聚類群體客戶特徵進行個性化營銷服務。
summary(datafile)
## MEMBER_NO FFP_DATE FIRST_FLIGHT_DATE GENDER
## Min. : 1 2011/1/13 : 184 2013/2/16: 96 : 3
## 1st Qu.:15748 2013/1/1 : 165 2012/9/30: 85 男:48134
## Median :31495 2013/3/1 : 100 2013/2/15: 84 女:14851
## Mean :31495 2010/11/17: 99 2005/9/9 : 78
## 3rd Qu.:47241 2011/1/14 : 95 2012/4/21: 70
## Max. :62988 2012/9/19 : 88 2012/4/27: 70
## (Other) :62257 (Other) :62505
## FFP_TIER WORK_CITY WORK_PROVINCE WORK_COUNTRY
## Min. :4.000 廣州 : 9385 廣東 :17507 CN :57748
## 1st Qu.:4.000 北京 : 7843 北京 : 8014 HK : 991
## Median :4.000 上海 : 4995 上海 : 4994 JP : 875
## Mean :4.102 深圳 : 3604 遼寧 : 4182 KR : 790
## 3rd Qu.:4.000 : 2268 : 3244 US : 575
## Max. :6.000 大連 : 1978 新疆 : 2512 (Other): 2008
## (Other):32915 (Other):22535 NA's : 1
## AGE LOAD_TIME FLIGHT_COUNT BP_SUM
## Min. : 6.00 2014/3/31:62988 Min. : 2.00 Min. : 0
## 1st Qu.: 35.00 1st Qu.: 3.00 1st Qu.: 2518
## Median : 41.00 Median : 7.00 Median : 5700
## Mean : 42.48 Mean : 11.84 Mean : 10925
## 3rd Qu.: 48.00 3rd Qu.: 15.00 3rd Qu.: 12831
## Max. :110.00 Max. :213.00 Max. :505308
## NA's :420
## EP_SUM_YR_1 EP_SUM_YR_2 SUM_YR_1 SUM_YR_2
## Min. :0 Min. : 0.0 Min. : 0 Min. : 0
## 1st Qu.:0 1st Qu.: 0.0 1st Qu.: 1003 1st Qu.: 780
## Median :0 Median : 0.0 Median : 2800 Median : 2773
## Mean :0 Mean : 265.7 Mean : 5355 Mean : 5604
## 3rd Qu.:0 3rd Qu.: 0.0 3rd Qu.: 6574 3rd Qu.: 6846
## Max. :0 Max. :74460.0 Max. :239560 Max. :234188
## NA's :551 NA's :138
## SEG_KM_SUM WEIGHTED_SEG_KM LAST_FLIGHT_DATE AVG_FLIGHT_COUNT
## Min. : 368 Min. : 0 2014/3/31: 959 Min. : 0.2500
## 1st Qu.: 4747 1st Qu.: 3219 2014/3/30: 933 1st Qu.: 0.4286
## Median : 9994 Median : 6978 2014/3/28: 924 Median : 0.8750
## Mean : 17124 Mean : 12777 2014/3/29: 779 Mean : 1.5422
## 3rd Qu.: 21271 3rd Qu.: 15300 2014/3/27: 767 3rd Qu.: 1.8750
## Max. :580717 Max. :558440 2014/3/26: 728 Max. :26.6250
## (Other) :57898
## AVG_BP_SUM BEGIN_TO_FIRST LAST_TO_END AVG_INTERVAL
## Min. : 0.0 Min. : 0.0 Min. : 1.0 Min. : 0.00
## 1st Qu.: 336.0 1st Qu.: 9.0 1st Qu.: 29.0 1st Qu.: 23.37
## Median : 752.4 Median : 50.0 Median :108.0 Median : 44.67
## Mean : 1421.4 Mean :120.1 Mean :176.1 Mean : 67.75
## 3rd Qu.: 1690.3 3rd Qu.:166.0 3rd Qu.:268.0 3rd Qu.: 82.00
## Max. :63163.5 Max. :729.0 Max. :731.0 Max. :728.00
##
## MAX_INTERVAL ADD_POINTS_SUM_YR_1 ADD_POINTS_SUM_YR_2 EXCHANGE_COUNT
## Min. : 0 Min. : 0.0 Min. : 0.0 Min. : 0.0000
## 1st Qu.: 79 1st Qu.: 0.0 1st Qu.: 0.0 1st Qu.: 0.0000
## Median :143 Median : 0.0 Median : 0.0 Median : 0.0000
## Mean :166 Mean : 540.3 Mean : 814.7 Mean : 0.3198
## 3rd Qu.:228 3rd Qu.: 0.0 3rd Qu.: 0.0 3rd Qu.: 0.0000
## Max. :728 Max. :600000.0 Max. :728282.0 Max. :46.0000
##
## avg_discount P1Y_Flight_Count L1Y_Flight_Count P1Y_BP_SUM
## Min. :0.0000 Min. : 0.000 Min. : 0.000 Min. : 0
## 1st Qu.:0.6120 1st Qu.: 2.000 1st Qu.: 1.000 1st Qu.: 946
## Median :0.7119 Median : 3.000 Median : 3.000 Median : 2692
## Mean :0.7216 Mean : 5.766 Mean : 6.073 Mean : 5367
## 3rd Qu.:0.8095 3rd Qu.: 7.000 3rd Qu.: 8.000 3rd Qu.: 6485
## Max. :1.5000 Max. :118.000 Max. :111.000 Max. :246197
##
## L1Y_BP_SUM EP_SUM ADD_Point_SUM Eli_Add_Point_Sum
## Min. : 0 Min. : 0.0 Min. : 0 Min. : 0
## 1st Qu.: 545 1st Qu.: 0.0 1st Qu.: 0 1st Qu.: 0
## Median : 2547 Median : 0.0 Median : 0 Median : 0
## Mean : 5558 Mean : 265.7 Mean : 1355 Mean : 1621
## 3rd Qu.: 6619 3rd Qu.: 0.0 3rd Qu.: 0 3rd Qu.: 345
## Max. :259111 Max. :74460.0 Max. :984938 Max. :984938
##
## L1Y_ELi_Add_Points Points_Sum L1Y_Points_Sum
## Min. : 0 Min. : 0 Min. : 0
## 1st Qu.: 0 1st Qu.: 2775 1st Qu.: 700
## Median : 0 Median : 6328 Median : 2860
## Mean : 1080 Mean : 12546 Mean : 6639
## 3rd Qu.: 0 3rd Qu.: 14302 3rd Qu.: 7500
## Max. :728282 Max. :985572 Max. :728282
##
## Ration_L1Y_Flight_Count Ration_P1Y_Flight_Count Ration_P1Y_BPS
## Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.2500 1st Qu.:0.2889 1st Qu.:0.2582
## Median :0.5000 Median :0.5000 Median :0.5143
## Mean :0.4864 Mean :0.5136 Mean :0.5223
## 3rd Qu.:0.7111 3rd Qu.:0.7500 3rd Qu.:0.8151
## Max. :1.0000 Max. :1.0000 Max. :1.0000
##
## Ration_L1Y_BPS Point_NotFlight
## Min. :0.0000 Min. : 0.000
## 1st Qu.:0.1680 1st Qu.: 0.000
## Median :0.4767 Median : 0.000
## Mean :0.4684 Mean : 2.728
## 3rd Qu.:0.7284 3rd Qu.: 1.000
## Max. :1.0000 Max. :140.000
##
head(datafile)
## MEMBER_NO FFP_DATE FIRST_FLIGHT_DATE GENDER FFP_TIER WORK_CITY
## 1 54993 2006/11/2 2008/12/24 男 6 .
## 2 28065 2007/2/19 2007/8/3 男 6
## 3 55106 2007/2/1 2007/8/30 男 6 .
## 4 21189 2008/8/22 2008/8/23 男 5 Los Angeles
## 5 39546 2009/4/10 2009/4/15 男 6 貴陽
## 6 56972 2008/2/10 2009/9/29 男 6 廣州
## WORK_PROVINCE WORK_COUNTRY AGE LOAD_TIME FLIGHT_COUNT BP_SUM EP_SUM_YR_1
## 1 北京 CN 31 2014/3/31 210 505308 0
## 2 北京 CN 42 2014/3/31 140 362480 0
## 3 北京 CN 40 2014/3/31 135 351159 0
## 4 CA US 64 2014/3/31 23 337314 0
## 5 貴州 CN 48 2014/3/31 152 273844 0
## 6 廣東 CN 64 2014/3/31 92 313338 0
## EP_SUM_YR_2 SUM_YR_1 SUM_YR_2 SEG_KM_SUM WEIGHTED_SEG_KM
## 1 74460 239560 234188 580717 558440.1
## 2 41288 171483 167434 293678 367777.2
## 3 39711 163618 164982 283712 355966.5
## 4 34890 116350 125500 281336 306900.9
## 5 42265 124560 130702 309928 300834.1
## 6 27323 112364 76946 294585 285067.7
## LAST_FLIGHT_DATE AVG_FLIGHT_COUNT AVG_BP_SUM BEGIN_TO_FIRST LAST_TO_END
## 1 2014/3/31 26.250 63163.50 2 1
## 2 2014/3/25 17.500 45310.00 2 7
## 3 2014/3/21 16.875 43894.88 10 11
## 4 2013/12/26 2.875 42164.25 21 97
## 5 2014/3/27 19.000 34230.50 3 5
## 6 2014/1/13 11.500 39167.25 11 79
## AVG_INTERVAL MAX_INTERVAL ADD_POINTS_SUM_YR_1 ADD_POINTS_SUM_YR_2
## 1 3.483254 18 3352 36640
## 2 5.194245 17 0 12000
## 3 5.298507 18 3491 12000
## 4 27.863636 73 0 0
## 5 4.788079 47 0 22704
## 6 7.043956 52 0 2460
## EXCHANGE_COUNT avg_discount P1Y_Flight_Count L1Y_Flight_Count P1Y_BP_SUM
## 1 34 0.9616390 103 107 246197
## 2 29 1.2523144 68 72 177358
## 3 20 1.2546755 65 70 169072
## 4 11 1.0908696 13 10 186104
## 5 27 0.9706579 71 81 128448
## 6 10 0.9676925 50 42 190583
## L1Y_BP_SUM EP_SUM ADD_Point_SUM Eli_Add_Point_Sum L1Y_ELi_Add_Points
## 1 259111 74460 39992 114452 111100
## 2 185122 41288 12000 53288 53288
## 3 182087 39711 15491 55202 51711
## 4 151210 34890 0 34890 34890
## 5 145396 42265 22704 64969 64969
## 6 122755 27323 2460 29783 29783
## Points_Sum L1Y_Points_Sum Ration_L1Y_Flight_Count
## 1 619760 370211 0.5095238
## 2 415768 238410 0.5142857
## 3 406361 233798 0.5185185
## 4 372204 186100 0.4347826
## 5 338813 210365 0.5328947
## 6 343121 152538 0.4565217
## Ration_P1Y_Flight_Count Ration_P1Y_BPS Ration_L1Y_BPS Point_NotFlight
## 1 0.4904762 0.4872207 0.5127773 50
## 2 0.4857143 0.4892891 0.5107081 33
## 3 0.4814815 0.4814671 0.5185300 26
## 4 0.5652174 0.5517217 0.4482754 12
## 5 0.4671053 0.4690537 0.5309427 39
## 6 0.5434783 0.6082326 0.3917642 15
#確定要探索分析的變數
col=c(15:18,20:29)#去掉日期型變數
#輸出變數最值、缺失情況
summary(datafile[,col])
## SUM_YR_1 SUM_YR_2 SEG_KM_SUM WEIGHTED_SEG_KM
## Min. : 0 Min. : 0 Min. : 368 Min. : 0
## 1st Qu.: 1003 1st Qu.: 780 1st Qu.: 4747 1st Qu.: 3219
## Median : 2800 Median : 2773 Median : 9994 Median : 6978
## Mean : 5355 Mean : 5604 Mean : 17124 Mean : 12777
## 3rd Qu.: 6574 3rd Qu.: 6846 3rd Qu.: 21271 3rd Qu.: 15300
## Max. :239560 Max. :234188 Max. :580717 Max. :558440
## NA's :551 NA's :138
## AVG_FLIGHT_COUNT AVG_BP_SUM BEGIN_TO_FIRST LAST_TO_END
## Min. : 0.2500 Min. : 0.0 Min. : 0.0 Min. : 1.0
## 1st Qu.: 0.4286 1st Qu.: 336.0 1st Qu.: 9.0 1st Qu.: 29.0
## Median : 0.8750 Median : 752.4 Median : 50.0 Median :108.0
## Mean : 1.5422 Mean : 1421.4 Mean :120.1 Mean :176.1
## 3rd Qu.: 1.8750 3rd Qu.: 1690.3 3rd Qu.:166.0 3rd Qu.:268.0
## Max. :26.6250 Max. :63163.5 Max. :729.0 Max. :731.0
##
## AVG_INTERVAL MAX_INTERVAL ADD_POINTS_SUM_YR_1 ADD_POINTS_SUM_YR_2
## Min. : 0.00 Min. : 0 Min. : 0.0 Min. : 0.0
## 1st Qu.: 23.37 1st Qu.: 79 1st Qu.: 0.0 1st Qu.: 0.0
## Median : 44.67 Median :143 Median : 0.0 Median : 0.0
## Mean : 67.75 Mean :166 Mean : 540.3 Mean : 814.7
## 3rd Qu.: 82.00 3rd Qu.:228 3rd Qu.: 0.0 3rd Qu.: 0.0
## Max. :728.00 Max. :728 Max. :600000.0 Max. :728282.0
##
## EXCHANGE_COUNT avg_discount
## Min. : 0.0000 Min. :0.0000
## 1st Qu.: 0.0000 1st Qu.:0.6120
## Median : 0.0000 Median :0.7119
## Mean : 0.3198 Mean :0.7216
## 3rd Qu.: 0.0000 3rd Qu.:0.8095
## Max. :46.0000 Max. :1.5000
##
head(datafile[,col])
## SUM_YR_1 SUM_YR_2 SEG_KM_SUM WEIGHTED_SEG_KM AVG_FLIGHT_COUNT AVG_BP_SUM
## 1 239560 234188 580717 558440.1 26.250 63163.50
## 2 171483 167434 293678 367777.2 17.500 45310.00
## 3 163618 164982 283712 355966.5 16.875 43894.88
## 4 116350 125500 281336 306900.9 2.875 42164.25
## 5 124560 130702 309928 300834.1 19.000 34230.50
## 6 112364 76946 294585 285067.7 11.500 39167.25
## BEGIN_TO_FIRST LAST_TO_END AVG_INTERVAL MAX_INTERVAL ADD_POINTS_SUM_YR_1
## 1 2 1 3.483254 18 3352
## 2 2 7 5.194245 17 0
## 3 10 11 5.298507 18 3491
## 4 21 97 27.863636 73 0
## 5 3 5 4.788079 47 0
## 6 11 79 7.043956 52 0
## ADD_POINTS_SUM_YR_2 EXCHANGE_COUNT avg_discount
## 1 36640 34 0.9616390
## 2 12000 29 1.2523144
## 3 12000 20 1.2546755
## 4 0 11 1.0908696
## 5 22704 27 0.9706579
## 6 2460 10 0.9676925
#丟棄票價為空的記錄
delet_na = datafile[-which(is.na(datafile$SUM_YR_1) |
is.na(datafile$SUM_YR_2)),]
#丟棄票價為0、平均折扣率不為0、總飛行公里數大於0的記錄
index = ((delet_na$SUM_YR_1 == 0 & delet_na$SUM_YR_2 == 0)
* (delet_na$avg_discount != 0)
* (delet_na$SEG_KM_SUM > 0))
newdata = delet_na[-which(index == 1),]
datascore <- data.frame(L=as.numeric(difftime(newdata$LOAD_TIME,newdata$FFP_DATE,units = "days"))/30,
R=newdata$LAST_TO_END,
F=newdata$FLIGHT_COUNT,
M=newdata$SEG_KM_SUM,
C=newdata$avg_discount)
head(datascore)
## L R F M C
## 1 90.20000 1 210 580717 0.9616390
## 2 86.56667 7 140 293678 1.2523144
## 3 87.16667 11 135 283712 1.2546755
## 4 68.23333 97 23 281336 1.0908696
## 5 60.53333 5 152 309928 0.9706579
## 6 74.70000 79 92 294585 0.9676925
#各個特徵資料分佈情況
library(ggplot2)
ggplot(datascore, aes(x=L)) +
geom_histogram(aes(y=..density..),bins = 30,colour="black", fill="white") +
geom_density(alpha=.2, fill="1")
ggplot(datascore, aes(x=R)) +
geom_histogram(aes(y=..density..),bins = 30,colour="black", fill="white") +
geom_density(alpha=.2, fill="2")
ggplot(datascore, aes(x=F)) +
geom_histogram(aes(y=..density..),bins = 30,colour="black", fill="white") +
geom_density(alpha=.2, fill="3")
ggplot(datascore, aes(x=M)) +
geom_histogram(aes(y=..density..),bins = 30,colour="black", fill="white") +
geom_density(alpha=.2, fill="4")
ggplot(datascore, aes(x=C)) +
geom_histogram(aes(y=..density..),bins = 30,colour="black", fill="white") +
geom_density(alpha=.2, fill="5")
#資料標準化
zdatascore=scale(datascore)
colnames(zdatascore)=c("ZL","ZR","ZF","ZM","ZC")
head(zdatascore)
## ZL ZR ZF ZM ZC
## [1,] 1.4357472 -0.9449977 14.0345098 26.76211 1.294939
## [2,] 1.3071924 -0.9119453 9.0735594 13.12737 2.866311
## [3,] 1.3284216 -0.8899103 8.7192058 12.65397 2.879075
## [4,] 0.6585213 -0.4161590 0.7816852 12.54111 1.993551
## [5,] 0.3860794 -0.9229628 9.9240081 13.89927 1.343695
## [6,] 0.8873253 -0.5153163 5.6717649 13.17045 1.327664
#聚類分析
result=kmeans(zdatascore,5)
#說明一下,這裡聚類中心K=5,由於初始點隨機,所以每次聚類的結果可能會有不同。經我多次重複實驗後,發現最終的雷達圖(見下下圖)都是基本相同的,說明聚類的結果大致還是一樣的,所以可以採用此聚類結果,對此聚類使用者進行群體特徵分析,並進行個性化營銷。實際中,個人建議也多跑幾次,檢測聚類結果是否都相同。
#結果輸出
head(result$cluster)
## [1] 5 5 5 5 5 5
result$centers#聚類中心
## ZL ZR ZF ZM ZC
## 1 0.2696816 -0.7186760 1.2558097 1.1945424 0.32514159
## 2 -0.7170713 -0.3611278 -0.2769407 -0.2718581 -0.18322244
## 3 -0.3272473 1.7114570 -0.5727285 -0.5354953 0.02241081
## 4 1.1545411 -0.2933660 -0.2427147 -0.2446185 0.03465997
## 5 0.6922035 -0.8496275 3.8695212 3.8514378 0.50455875