概要
RによるRFM分析をご紹介します。
RFM分析
とは、顧客を以下の3つの側面から分析する手法です。
R
(Recency, 最近購買しているかどうか, 購買日付)F
(Frequency, 頻繁に購買しているかどうか, 購買頻度)M
(Monetary, 高額に購買しているかどうか, 購買金額)
まず、最近、頻繁に、高額商品を購入していれば、優良顧客と言えます。
逆に、最近購入していない、または、頻繁に購入していない、または、高額に購入していない、
のいずれか、またはその組み合わせの場合は、優良顧客とは言えず、
改善していく施策を打つ必要があります。
準備
データ
まず、以下のような売上データを準備します。
# 顧客ID,売上金額,日付 custID,sales,date 1289,2599,2012/1/1 1925,110,2012/1/1 1498,75,2012/1/1
実装
まず、売上データを読み込みます。
rfmdata <- read.csv("~/Downloads/idposdata.csv", header = T) str(rfmdata) 'data.frame': 10000 obs. of 3 variables: $ custID: int 1289 1925 1498 1535 1886 1773 1422 1219 1215 1500 ... $ sales : int 2599 110 75 99 2485 3828 191 3901 266 58 ... $ date : Factor w/ 360 levels "2012/1/1","2012/1/10",..: 1 1 1 1 1 1 1 1 1 1 ... summary(rfmdata) custID sales date Min. :1000 Min. : 1.0 2012/4/16 : 42 1st Qu.:1251 1st Qu.: 66.0 2012/11/17: 41 Median :1498 Median : 197.0 2012/7/15 : 41 Mean :1498 Mean : 610.8 2012/10/17: 40 3rd Qu.:1749 3rd Qu.: 587.0 2012/8/12 : 40 Max. :1999 Max. :9998.0 2012/8/17 : 40 (Other) :9756
まず、Recency
を算出するため、datediff
列に新しく基準日と購買日の差分日数を格納します。
rfmdata$datediff<- round(as.numeric(difftime("2013-01-01",rfmdata$date,units="days"))) str(rfmdata) 'data.frame': 10000 obs. of 4 variables: $ custID : int 1289 1925 1498 1535 1886 1773 1422 1219 1215 1500 ... $ sales : int 2599 110 75 99 2485 3828 191 3901 266 58 ... $ date : Factor w/ 360 levels "2012/1/1","2012/1/10",..: 1 1 1 1 1 1 1 1 1 1 ... $ datediff: num 366 366 366 366 366 366 366 366 366 366 ...
cf. もし基準日を"2013-01-01"
ではなく、実行日を基準にする場合は、Sys.Date()
に置き換えます。
Sys.Date() [1] "2019-02-17"
差分日数を算出したら、Recency
を計算します。
Recency <- aggregate(rfmdata$datediff,list(rfmdata$custID),min) names(Recency) <- c("custID","Recency") str(Recency) 'data.frame': 1000 obs. of 2 variables: $ custID : int 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ... $ Recency: num 13 8 74 26 33 20 9 33 9 16 ...
次に、顧客IDをキーにして、購買頻度Frequency
を集計します。
Frequency <- aggregate(rfmdata$sales,list(rfmdata$custID),length) names(Frequency) <- c("custID","Frequency") str(Frequency) 'data.frame': 1000 obs. of 2 variables: $ custID : int 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ... $ Frequency: int 9 11 6 8 10 14 15 5 15 14 ...
そして、購買金額Monetary
も算出します。
Monetary <- aggregate(rfmdata$sales,list(rfmdata$custID),sum) names(Monetary) <- c("custID","Monetary") str(Monetary) 'data.frame': 1000 obs. of 2 variables: $ custID : int 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ... $ Monetary: int 1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...
最後に、各変数を結合します。
temp <- merge(Frequency,Monetary,"custID") customerRFM <- merge(temp,Recency,"custID") str(customerRFM) 'data.frame': 1000 obs. of 4 variables: $ custID : int 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ... $ Frequency: int 9 11 6 8 10 14 15 5 15 14 ... $ Monetary : int 1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ... $ Recency : num 13 8 74 26 33 20 9 33 9 16 ...
各RFMデータが集計されましたので、それぞれランクづけを5段階にしてみます。
customerRFM$rankR <- cut(customerRFM$Recency,quantile(customerRFM$Recency,(0:5)/5,na.rm=TRUE),label=FALSE,include.lowest=TRUE) customerRFM$rankF <- cut(customerRFM$Frequency,quantile(customerRFM$Frequency,(0:5)/5,na.rm=TRUE),label=FALSE,include.lowest=TRUE) customerRFM$rankM <- cut(customerRFM$Monetary,quantile(customerRFM$Monetary,(0:5)/5,na.rm=TRUE),label=FALSE,include.lowest=TRUE)
なお、Recencyだけは、小さい方が良いので、反転しておきます。
customerRFM$rankR <- 6-customerRFM$rankR
ランクづけしたデータを参照します。
str(customerRFM) 'data.frame': 1000 obs. of 7 variables: $ custID : int 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ... $ Frequency: int 9 11 6 8 10 14 15 5 15 14 ... $ Monetary : int 1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ... $ Recency : num 13 8 74 26 33 20 9 33 9 16 ... $ rankR : num 5 5 1 3 3 4 5 3 5 4 ... $ rankF : int 2 3 1 2 3 5 5 1 5 5 ... $ rankM : int 1 4 4 2 5 5 4 1 3 5 ...
ランクづけしたデータを表形式で参照します。
// 5列目rankR, 6列目rankFの組み合わせ table(customerRFM[,5:6]) rankF rankR 1 2 3 4 5 1 78 59 34 21 7 2 47 57 41 28 25 3 35 42 57 32 26 4 31 55 41 38 43 5 24 41 55 44 39 // 6列目rankF, 7列目rankMの組み合わせ table(customerRFM[,6:7]) rankM rankF 1 2 3 4 5 1 99 46 29 25 16 2 64 66 56 42 26 3 28 58 42 57 43 4 8 24 44 43 44 5 1 6 29 33 71 // 各rankMと、他のrankR/rankFとの組み合わせ table(customerRFM[,5:7]) , , rankM = 1 rankF rankR 1 2 3 4 5 1 43 11 3 0 0 2 23 17 6 3 0 3 17 13 8 1 0 4 10 12 3 3 0 5 6 11 8 1 1 , , rankM = 2 rankF rankR 1 2 3 4 5 1 15 17 8 2 0 2 9 17 6 4 2 3 8 12 13 6 0 4 4 13 10 3 1 5 10 7 21 9 3 , , rankM = 3 rankF rankR 1 2 3 4 5 1 8 15 7 7 2 2 4 12 8 6 8 3 4 7 10 11 5 4 10 11 7 8 7 5 3 11 10 12 7 , , rankM = 4 rankF rankR 1 2 3 4 5 1 8 10 7 6 1 2 5 6 12 8 2 3 4 8 17 5 9 4 5 13 13 14 11 5 3 5 8 10 10 , , rankM = 5 rankF rankR 1 2 3 4 5 1 4 6 9 6 4 2 6 5 9 7 13 3 2 2 9 9 12 4 2 6 8 10 24 5 2 7 8 12 18
最後に、高いランクだけファイルに出力する場合は以下のようにきじゅつします
subset(customerRFM, customerRFM$rankM==5 & customerRFM$rankF==5 & customerRFM$rankR==5) RFMgoodcustomers <- subset(customerRFM, customerRFM$rankM==5 & customerRFM$rankF==5 & customerRFM$rankR==5) write.csv(RFMgoodcustomers, "~/Downloads/RFMgoodcustomers.csv", quote=F, row.names=F)
以上、RによるRFM分析でした。