pre.sourceCode { color: inherit; background-color: transparent; }
RFM Analysis is to quantify your customer purchasing behaviours in terms of
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 |
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 |
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 |