pre.sourceCode { color: inherit; background-color: transparent; }

RFM Analysis is to quantify your customer purchasing behaviours in terms of

  • recency of last purchased (RLP)
  • frequency of total purchase(FTP)
  • money spent in totals for a given time span (MST)

To rank customer purchasing behaviours, first is to construct a normalized score for each customer

\[\begin{equation} NScore = \dfrac{W_{a}*RLP +W_{b}* FPT + W_{b}*MST }{(W_{a} + W_{c}+W_{c})} \end{equation}\]

Second is to construct a 11-scale purchasing behavioral classes for each customer

Percentile ScoreCls
0.0 0
0.1 1
0.2 2
0.3 3
0.4 4
0.5 5
0.6 6
0.7 7
0.8 8
0.9 9
1.0 10
library(rfm)
library(lubridate)

Churn Rate is to measure the rate of customers not consumed or purchase your products anymore

\[\begin{equation} Churn Rate = \dfrac{UserNo(t_{1})-UserNo(t_{2})}{UserNo(t_{1})} \end{equation}\]

\[\begin{equation} Retention Rate = \dfrac{UserNo(t_{2})}{UserNo(t_{1})} \end{equation}\]

Load Airline Bonus point dataset

Balance QualMiles BonusMiles BonusTrans FlightMiles FlightTrans DaysSinceEnroll custID
276 1704838 0 17108 32 4823 23 7283 276
221 1302051 2706 90653 32 3050 7 7467 221
489 1199220 2919 3800 19 3300 18 8023 489
482 1125076 0 23046 14 0 0 8107 482
467 1113394 2015 60883 26 2600 9 8228 467
118 969559 0 2500 3 1000 2 7718 118
152 930410 0 211284 18 2250 6 7640 152
511 889456 1024 98959 29 850 4 6652 511
1189 837979 0 18372 15 1450 4 5373 1189
3773 822321 0 138334 26 600 2 3288 3773
319 766419 0 11398 3 398 1 7162 319
824 765738 0 62133 14 0 0 6112 824
630 747983 0 26117 15 50 1 6427 630
472 743745 2066 4100 20 2500 18 8228 472
1116 739476 0 24215 8 322 1 5678 1116
1301 737514 0 43993 40 2150 7 5030 1301
314 714717 0 119162 20 1750 4 7183 314
187 707079 0 57173 40 3450 12 7523 187
2490 704113 0 98119 23 0 0 3082 2490
2657 644881 2600 14350 28 10850 26 2511 2657
summary(kk)[,1:3]
##     Balance          QualMiles         BonusMiles    
##  Min.   :      0   Min.   :    0.0   Min.   :     0  
##  1st Qu.:  18528   1st Qu.:    0.0   1st Qu.:  1250  
##  Median :  43097   Median :    0.0   Median :  7171  
##  Mean   :  73601   Mean   :  144.1   Mean   : 17145  
##  3rd Qu.:  92404   3rd Qu.:    0.0   3rd Qu.: 23801  
##  Max.   :1704838   Max.   :11148.0   Max.   :263685
summary(kk)[,4:7]
##    BonusTrans    FlightMiles       FlightTrans     DaysSinceEnroll
##  Min.   : 0.0   Min.   :    0.0   Min.   : 0.000   Min.   :   2   
##  1st Qu.: 3.0   1st Qu.:    0.0   1st Qu.: 0.000   1st Qu.:2330   
##  Median :12.0   Median :    0.0   Median : 0.000   Median :4096   
##  Mean   :11.6   Mean   :  460.1   Mean   : 1.374   Mean   :4119   
##  3rd Qu.:17.0   3rd Qu.:  311.0   3rd Qu.: 1.000   3rd Qu.:5790   
##  Max.   :86.0   Max.   :30817.0   Max.   :53.000   Max.   :8296
#library(igraph)
library(Hmisc)
library(clusterSim)
library(EnvStats)

create 11-classes of Miles_balance

sixLevel_Bal = cut2(ABP_df$Balance,g=11)  
levels(sixLevel_Bal)
##  [1] "[     0,   7388)" "[  7388,  13873)" "[ 13873,  20603)"
##  [4] "[ 20603,  27905)" "[ 27905,  37348)" "[ 37348,  49280)"
##  [7] "[ 49280,  64153)" "[ 64153,  85751)" "[ 85751, 118177)"
## [10] "[118177, 175344)" "[175344,1704838]"
levels(sixLevel_Bal)  =c("BalC00","BalC01","BalC02","BalC03","BalC04","BalC05", "BalC06", "BalC07","BalC08","BalC09", "BalC10")
ABP_df["BalCls"] = sixLevel_Bal
Balance QualMiles BonusMiles BonusTrans FlightMiles FlightTrans DaysSinceEnroll custID BalCls
28143 0 174 1 0 0 7000 1 BalC04
19244 0 215 2 0 0 6968 2 BalC02
41354 0 4123 4 0 0 7034 3 BalC05
14776 0 500 1 0 0 6952 4 BalC02
97752 0 43300 26 2077 4 6935 5 BalC08
16420 0 0 0 0 0 6942 6 BalC02
84914 0 27482 25 0 0 6994 7 BalC07
20856 0 5250 4 250 1 6938 8 BalC03
443003 0 1753 43 3850 12 6948 9 BalC10
104860 0 28426 28 1150 3 6931 10 BalC08
40091 0 7278 10 0 0 6959 11 BalC05
96522 0 61105 19 0 0 6924 12 BalC08
43382 0 11150 20 0 0 6924 13 BalC05
43097 0 3258 6 0 0 6918 14 BalC05
17648 0 0 0 0 0 6912 15 BalC02
28495 0 49442 15 0 0 6912 16 BalC04
51890 0 48963 16 0 0 6910 17 BalC06
13958 0 4291 5 0 0 6905 18 BalC02
91473 0 27408 17 0 0 6903 19 BalC08
23354 0 10447 5 0 0 6896 20 BalC03

RFM Analysis : air mileage consumer behaviour

Recency = list()
for(i in 1:dim(ABP_df)[1]){Recency[i] = ABP_df$DaysSinceEnroll[i]/(ABP_df$FlightTrans[i] + ABP_df$BonusTrans[i])}
N_Recency   = data.Normalization((1/as.numeric(matrix(Recency)) ),  type = "n4")
NN_Recency  = N_Recency*100 /sum(N_Recency )
sum(NN_Recency)
## [1] 100
N_Retention = 1-N_Recency
NN_Retention  = N_Retention*100 /sum(N_Retention )
sum(NN_Retention)
## [1] 100
FrePurchase = list()
for(i in 1:dim(ABP_df)[1]){FrePurchase[i] = (ABP_df$FlightTrans[i] + ABP_df$BonusTrans[i])}
N_FrePurchase  = data.Normalization((as.numeric(matrix(FrePurchase)) ),  type = "n4")
NN_FrePurchase  = N_FrePurchase*100 /sum(N_FrePurchase )
sum(NN_FrePurchase)
## [1] 100
TMonSpent = ABP_df$Balance
N_TMonSpent   = data.Normalization((as.numeric(matrix(TMonSpent)) ),  type = "n4")
NN_TMonSpent = N_TMonSpent*100 /sum(N_TMonSpent )
sum(NN_TMonSpent) 
## [1] 100
rfm_metric = cbind(NN_Recency, NN_FrePurchase, NN_TMonSpent)

NNScore100 = ((NN_Recency *0.2 )  +  (NN_FrePurchase*0.5) + (NN_TMonSpent*0.3) )
sum(NNScore100)
## [1] 100
NScore = round(quantile(NNScore100 , c(0.1, 0.2, 0.3, 0.4,0.5, 0.6,0.7, 0.8,0.9, 1), 10 )*100, 3)
NScore_df = data.frame(NScore)
NScore
10% 0.266
20% 0.679
30% 1.205
40% 1.759
50% 2.210
60% 2.604
70% 3.068
80% 3.669
90% 4.831
100% 27.254

NScore customer behavorial airflight tickets purchased : Skewed Distribution

plot.ecdf(NN_Recency, xlab = "recency to buy flight ticket")

plot.ecdf(NN_FrePurchase, xlab = "Frequency to buy flight ticket")

plot.ecdf(NN_TMonSpent, xlab = "Total money Spent to buy flight ticket")

ABP_df["NRecency"] = NN_Recency 
ABP_df["NFrePurc"] = NN_FrePurchase 
ABP_df["NTMonSpt"] = NN_TMonSpent 
ABP_df["NScor100"] = NNScore100
sixLevel_NScore = cut2(NNScore100,g=6)  
levels(sixLevel_NScore)
## [1] "[2.03e-05,0.00556)" "[5.56e-03,0.01403)" "[1.40e-02,0.02211)"
## [4] "[2.21e-02,0.02879)" "[2.88e-02,0.03953)" "[3.95e-02,0.27254]"
levels(sixLevel_NScore)  =c("NSCC01","NSCC02","NSCC03","NSCC04","NSCC05","NSCC06")
ABP_df["NSCls"] = sixLevel_NScore

ABPrfm_df = ABP_df[, c(-2,-3,-5, -9)]
Balance BonusTrans FlightTrans DaysSinceEnroll custID NRecency NFrePurc NTMonSpt NScor100 NSCls
28143 1 0 7000 1 0.0008627 0.0019272 0.0095617 0.0040046 NSCC01
19244 2 0 6968 2 0.0017334 0.0038544 0.0065382 0.0042353 NSCC01
41354 4 0 7034 3 0.0034342 0.0077088 0.0140501 0.0087563 NSCC02
14776 1 0 6952 4 0.0008687 0.0019272 0.0050202 0.0026434 NSCC01
97752 26 4 6935 5 0.0261241 0.0578157 0.0332115 0.0440961 NSCC06
16420 0 0 6942 6 0.0000000 0.0000000 0.0055787 0.0016736 NSCC01
84914 25 0 6994 7 0.0215865 0.0481798 0.0288498 0.0370621 NSCC05
20856 4 1 6938 8 0.0043521 0.0096360 0.0070859 0.0078142 NSCC02
443003 43 12 6948 9 0.0478046 0.1059955 0.1505115 0.1077121 NSCC06
104860 28 3 6931 10 0.0270105 0.0597429 0.0356265 0.0459615 NSCC06
40091 10 0 6959 11 0.0086780 0.0192719 0.0136210 0.0154579 NSCC03
96522 19 0 6924 12 0.0165716 0.0366166 0.0327936 0.0314607 NSCC05
43382 20 0 6924 13 0.0174437 0.0385438 0.0147392 0.0271824 NSCC04
43097 6 0 6918 14 0.0052377 0.0115631 0.0146423 0.0112218 NSCC02
17648 0 0 6912 15 0.0000000 0.0000000 0.0059960 0.0017988 NSCC01
28495 15 0 6912 16 0.0131055 0.0289079 0.0096813 0.0199794 NSCC03
51890 16 0 6910 17 0.0139833 0.0308351 0.0176298 0.0235031 NSCC04
13958 5 0 6905 18 0.0043729 0.0096360 0.0047423 0.0071152 NSCC02
91473 17 0 6903 19 0.0148723 0.0327622 0.0310782 0.0286790 NSCC04
23354 5 0 6896 20 0.0043786 0.0096360 0.0079346 0.0080741 NSCC02
Flight Transaction by NScore
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31 36 45 46 53
NSCC01 640 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC02 495 89 49 25 7 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC03 503 63 33 27 21 13 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC04 467 90 43 20 16 8 11 4 4 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC05 400 109 55 32 14 15 10 4 6 11 5 4 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC06 218 91 62 28 39 21 16 21 21 19 11 14 15 6 7 9 11 8 8 2 4 1 1 7 4 1 5 1 4 5 1 1 1 1 2
Bonus Transaction by NScore
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 49 50 51 52 53 55 58 65 68 86
NSCC01 434 138 48 40 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC02 32 59 51 165 124 72 56 43 28 20 13 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC03 5 7 4 28 45 29 35 32 41 52 58 52 72 90 57 37 19 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC04 1 4 0 10 10 16 16 11 18 7 12 29 44 88 125 84 74 48 35 17 10 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC05 2 2 0 5 3 6 5 2 6 9 14 21 23 39 61 65 67 62 59 48 41 33 31 11 12 11 11 7 6 1 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NSCC06 1 2 1 2 1 3 3 0 7 3 0 3 9 14 19 26 29 27 30 32 34 31 30 24 29 23 30 25 22 22 17 21 22 8 15 11 6 11 10 12 4 7 7 3 5 2 3 2 3 4 1 4 1 1 2 1 1