資料彙整流程
1. 交易項目計錄:Z
rm(list=ls(all=T))
Sys.setlocale("LC_ALL","C")
library(dplyr)
library(ggplot2)
library(caTools)
1.1 The do.call-rbind-lapply Combo
Z = do.call(rbind, lapply(
dir('data/TaFengDataSet','.*csv$',full.names=T),
read.csv, header=F)
) %>%
setNames(c("date","cust","age","area","cat","prod","qty","cost","price"))
nrow(Z)
Data Convresion
Z$date = as.Date(as.character(Z$date))
summary(Z)
- 將date變成文字型態
- 利用summary查看原始資料之敘述統計量
Quantile of Variables
sapply(Z[,7:9], quantile, prob=c(.99, .999, .9995))
Get rid of Outliers
Z = subset(Z, qty<=24 & cost<=3800 & price<=4000)
nrow(Z)
- 就算有一大筆資料,只要有一筆離群值,就可能造成估計上的偏差
- 找出並過濾掉離群值
Assign Transaction ID
Z$tid = group_indices(Z, date, cust)
No. Customers, Categories, Product Items & Transactions
sapply(Z[,c("cust","cat","prod","tid")], n_distinct)
- 總共有32256位不同的顧客、2007種不同產品…等
Summary of Item Records
summary(Z)
2. 交易計錄:X
交易資料彙整
X = group_by(Z, tid) %>% summarise(
date = first(date), # 交易日期
cust = first(cust), # 顧客 ID
age = first(age), # 顧客 年齡級別
area = first(area), # 顧客 居住區別
items = n(), # 交易項目(總)數
pieces = sum(qty), # 產品(總)件數
total = sum(price), # 交易(總)金額
gross = sum(price - cost) # 毛利
) %>% data.frame # 119422
Check Quantile & Remove Outliers
sapply(X[,6:9], quantile, prob=c(.999, .9995, .9999))
X = subset(X, items<=62 & pieces<95 & total<16000) # 119328
Weekly Transactions
par(cex=0.8)
hist(X$date, "weeks", freq=T, border='lightgray', col='darkcyan',
las=2, main="No. Transaction per Week")
- 由直方圖看每周交易筆數差異
- 可看見聖誕節當周交易量特別低,同學可以想想其背後商業意涵唷
3. 顧客資料:A
顧客資料彙整
d0 = max(X$date)
A = group_by(X, cust) %>% summarise(
r = 1 + as.integer(difftime(d0, max(date), units="days")), # recency
s = 1 + as.integer(difftime(d0, min(date), units="days")), # seniority
f = n(), # frquency
m = mean(total), # monetary
rev = sum(total), # total revenue contribution
raw = sum(gross), # total gross profit contribution
age = first(age), # age group
area = first(area), # area code
) %>% data.frame # 33241
- 由顧客資料依照rfm分析製作新變數,rfm分析介紹請看:
- rfm分析: 從交易記錄到顧客產品矩陣
- r: 距今最近一次購買
- s: 顧客第一次購買
- f: 顧客購買頻率
- m: 平均交易金額
顧客摘要
summary(A)
par(mfrow=c(3,2), mar=c(3,3,4,2))
for(x in c('r','s','f','m'))
hist(A[,x],freq=T,main=x,xlab="",ylab="",cex.main=2)
hist(pmin(A$f,10),0:10,freq=T,xlab="",ylab="",cex.main=2)
hist(log(A$m,10),freq=T,xlab="",ylab="",cex.main=2)
Dupliate & Save
A0 = A; X0 = X; Z0 = Z
save(Z0, X0, A0, file="data/tf0.rdata")
4. Objective of the Contest
range(X$date)
使用一月底(含2001-01-31)以前的資料,建立模型來預測每一位顧客:
- 她在2月份(2001-02-01 ~ 2001-02-28)會不會來買?
- 如果她來買的話,會買多少錢?
The Basic Questions of Analysis
【Q】 What are the Unit of Analysis?
【Q】 What are the Target of Analysis? Should we model for every customers in the dataset? Why not?
【Q】 How to make the Training/Testing Data Split?
【Q】 What are the Predicting and Targeted Variables?
The Target of Analysis
Screen out the new customers (who arrive after 2001-02-01)
A = filter(A0, s > 28) # 28584
The Baseline Probability
mean(A$r <= 28)
Spliting Factor and Spliting Ratio
library(caTools)
set.seed(1234); spl = sample.split(A$r <= 28, SplitRatio=0.75)
cid1 = subset(A, spl)$cust # 21438
cid2 = subset(A, !spl)$cust # 7146
cid1/cid2 are the customers ids in the training/testing data. But, …
【Q】 What are the Predicting (X) and Targeted Variables (Y)?
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyMjIOizh+aWmeW9meaVtOa1geeoiw0KDQo8Y2VudGVyPg0KDQoNCg0KPC9jZW50ZXI+DQoNCjxocj4NCg0KIyMjIDEuIOS6pOaYk+mgheebruioiOmMhO+8mmBaYA0KDQpgYGB7ciBlY2hvPVQsIG1lc3NhZ2U9RiwgY2FjaGU9Riwgd2FybmluZz1GfQ0Kcm0obGlzdD1scyhhbGw9VCkpDQpTeXMuc2V0bG9jYWxlKCJMQ19BTEwiLCJDIikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGNhVG9vbHMpDQpgYGANCg0KIyMjIyMgMS4xIFRoZSBgZG8uY2FsbC1yYmluZC1sYXBwbHlgIENvbWJvDQpgYGB7cn0NClogPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoDQogICAgZGlyKCdkYXRhL1RhRmVuZ0RhdGFTZXQnLCcuKmNzdiQnLGZ1bGwubmFtZXM9VCksDQogICAgcmVhZC5jc3YsIGhlYWRlcj1GKSANCiAgKSAlPiUgDQogIHNldE5hbWVzKGMoImRhdGUiLCJjdXN0IiwiYWdlIiwiYXJlYSIsImNhdCIsInByb2QiLCJxdHkiLCJjb3N0IiwicHJpY2UiKSkNCm5yb3coWikNCmBgYA0KDQojIyMjIyBEYXRhIENvbnZyZXNpb24NCmBgYHtyfQ0KWiRkYXRlID0gYXMuRGF0ZShhcy5jaGFyYWN0ZXIoWiRkYXRlKSkNCnN1bW1hcnkoWikNCmBgYA0KDQorIOWwh2RhdGXorormiJDmloflrZflnovmhYsNCisg5Yip55Soc3VtbWFyeeafpeeci+WOn+Wni+izh+aWmeS5i+aVmOi/sOe1seioiOmHjw0KDQojIyMjIyBRdWFudGlsZSBvZiBWYXJpYWJsZXMNCmBgYHtyfQ0Kc2FwcGx5KFpbLDc6OV0sIHF1YW50aWxlLCBwcm9iPWMoLjk5LCAuOTk5LCAuOTk5NSkpDQpgYGANCg0KIyMjIyMgR2V0IHJpZCBvZiBPdXRsaWVycw0KYGBge3J9DQpaID0gc3Vic2V0KFosIHF0eTw9MjQgJiBjb3N0PD0zODAwICYgcHJpY2U8PTQwMDApIA0KbnJvdyhaKSAgDQpgYGANCg0KKyDlsLHnrpfmnInkuIDlpKfnrYbos4fmlpnvvIzlj6ropoHmnInkuIDnrYbpm6LnvqTlgLzvvIzlsLHlj6/og73pgKDmiJDkvLDoqIjkuIrnmoTlgY/lt64NCisg5om+5Ye65Lim6YGO5r++5o6J6Zui576k5YC8DQoNCiMjIyMjIEFzc2lnbiBUcmFuc2FjdGlvbiBJRA0KYGBge3J9DQpaJHRpZCA9IGdyb3VwX2luZGljZXMoWiwgZGF0ZSwgY3VzdCkNCmBgYA0KDQojIyMjIyBOby4gQ3VzdG9tZXJzLCBDYXRlZ29yaWVzLCBQcm9kdWN0IEl0ZW1zICYgVHJhbnNhY3Rpb25zDQpgYGB7cn0NCnNhcHBseShaWyxjKCJjdXN0IiwiY2F0IiwicHJvZCIsInRpZCIpXSwgbl9kaXN0aW5jdCkNCmBgYA0KDQorIOe4veWFseaciTMyMjU25L2N5LiN5ZCM55qE6aGn5a6i44CBMjAwN+eoruS4jeWQjOeUouWTgS4uLuetiQ0KDQojIyMjIyBTdW1tYXJ5IG9mIEl0ZW0gUmVjb3Jkcw0KYGBge3J9DQpzdW1tYXJ5KFopDQpgYGANCg0KKyDlho3nnIvkuIDmrKHljrvmjonpm6LnvqTlgLzlvoznmoTmlZjov7DntbHoqIgNCg0KPGJyPjxocj4NCg0KDQoNCiMjIyAyLiDkuqTmmJPoqIjpjITvvJpgWGANCg0KIyMjIyMg5Lqk5piT6LOH5paZ5b2Z5pW0DQpgYGB7cn0NClggPSBncm91cF9ieShaLCB0aWQpICU+JSBzdW1tYXJpc2UoDQogIGRhdGUgPSBmaXJzdChkYXRlKSwgICMg5Lqk5piT5pel5pyfDQogIGN1c3QgPSBmaXJzdChjdXN0KSwgICMg6aGn5a6iIElEDQogIGFnZSA9IGZpcnN0KGFnZSksICAgICMg6aGn5a6iIOW5tOm9oee0muWIpQ0KICBhcmVhID0gZmlyc3QoYXJlYSksICAjIOmhp+WuoiDlsYXkvY/ljYDliKUNCiAgaXRlbXMgPSBuKCksICAgICAgICAgICAgICAgICMg5Lqk5piT6aCF55uuKOe4vSnmlbgNCiAgcGllY2VzID0gc3VtKHF0eSksICAgICAgICAgICMg55Si5ZOBKOe4vSnku7bmlbgNCiAgdG90YWwgPSBzdW0ocHJpY2UpLCAgICAgICAgICMg5Lqk5piTKOe4vSnph5HpoY0NCiAgZ3Jvc3MgPSBzdW0ocHJpY2UgLSBjb3N0KSAgICMg5q+b5YipDQogICkgJT4lIGRhdGEuZnJhbWUgICMgMTE5NDIyDQpgYGANCg0KKyDlsIfkuqTmmJPos4fmlpnkvp3mk5rkuqTmmJNJROaOkuW6jz8/DQoNCiMjIyMjIOS6pOaYk+aRmOimgQ0KYGBge3J9DQpzdW1tYXJ5KFgpICAgIA0KYGBgDQoNCisgWOiIh1rkuYtzdW1tYXJ557WQ5p6c54K65L2V5LiN5ZCMPw0KDQojIyMjIyBDaGVjayBRdWFudGlsZSAmIFJlbW92ZSBPdXRsaWVycw0KYGBge3J9DQpzYXBwbHkoWFssNjo5XSwgcXVhbnRpbGUsIHByb2I9YyguOTk5LCAuOTk5NSwgLjk5OTkpKQ0KYGBgDQoNCmBgYHtyfQ0KWCA9IHN1YnNldChYLCBpdGVtczw9NjIgJiBwaWVjZXM8OTUgJiB0b3RhbDwxNjAwMCkgIyAxMTkzMjgNCmBgYA0KDQorIOWOu+mZpOmboue+pOWAvA0KDQojIyMjIyBXZWVrbHkgVHJhbnNhY3Rpb25zDQpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD03fQ0KcGFyKGNleD0wLjgpDQpoaXN0KFgkZGF0ZSwgIndlZWtzIiwgZnJlcT1ULCBib3JkZXI9J2xpZ2h0Z3JheScsIGNvbD0nZGFya2N5YW4nLCANCiAgICAgbGFzPTIsIG1haW49Ik5vLiBUcmFuc2FjdGlvbiBwZXIgV2VlayIpDQpgYGANCg0KKyDnlLHnm7TmlrnlnJbnnIvmr4/lkajkuqTmmJPnrYbmlbjlt67nlbANCisg5Y+v55yL6KaL6IGW6KqV56+A55W25ZGo5Lqk5piT6YeP54m55Yil5L2O77yM5ZCM5a245Y+v5Lul5oOz5oOz5YW26IOM5b6M5ZWG5qWt5oSP5ra15ZS3DQoNCjxicj48aHI+DQoNCg0KDQojIyMgMy4g6aGn5a6i6LOH5paZ77yaYEFgDQoNCiMjIyMjIOmhp+Wuouizh+aWmeW9meaVtA0KYGBge3J9DQpkMCA9IG1heChYJGRhdGUpDQpBID0gZ3JvdXBfYnkoWCwgY3VzdCkgJT4lIHN1bW1hcmlzZSgNCiAgciA9IDEgKyBhcy5pbnRlZ2VyKGRpZmZ0aW1lKGQwLCBtYXgoZGF0ZSksIHVuaXRzPSJkYXlzIikpLCAjIHJlY2VuY3kNCiAgcyA9IDEgKyBhcy5pbnRlZ2VyKGRpZmZ0aW1lKGQwLCBtaW4oZGF0ZSksIHVuaXRzPSJkYXlzIikpLCAjIHNlbmlvcml0eQ0KICBmID0gbigpLCAgICAgICAgICAgICMgZnJxdWVuY3kNCiAgbSA9IG1lYW4odG90YWwpLCAgICAjIG1vbmV0YXJ5DQogIHJldiA9IHN1bSh0b3RhbCksICAgIyB0b3RhbCByZXZlbnVlIGNvbnRyaWJ1dGlvbg0KICByYXcgPSBzdW0oZ3Jvc3MpLCAgICMgdG90YWwgZ3Jvc3MgcHJvZml0IGNvbnRyaWJ1dGlvbg0KICBhZ2UgPSBmaXJzdChhZ2UpLCAgICMgYWdlIGdyb3VwDQogIGFyZWEgPSBmaXJzdChhcmVhKSwgIyBhcmVhIGNvZGUNCiAgKSAlPiUgZGF0YS5mcmFtZSAgICAjIDMzMjQxDQpgYGANCg0KKyDnlLHpoaflrqLos4fmlpnkvp3nhadyZm3liIbmnpDoo73kvZzmlrDorormlbjvvIxyZm3liIbmnpDku4vntLnoq4vnnIs6IA0KKyByZm3liIbmnpA6IOW+nuS6pOaYk+iomOmMhOWIsOmhp+WuoueUouWTgeefqemZow0KKyByOiDot53ku4rmnIDov5HkuIDmrKHos7zosrcNCisgczog6aGn5a6i56ys5LiA5qyh6LO86LK3DQorIGY6IOmhp+WuouizvOiyt+mgu+eOhw0KKyBtOiDlubPlnYfkuqTmmJPph5HpoY0NCg0KIyMjIyMg6aGn5a6i5pGY6KaBDQpgYGB7cn0NCnN1bW1hcnkoQSkgDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD04fQ0KcGFyKG1mcm93PWMoMywyKSwgbWFyPWMoMywzLDQsMikpDQpmb3IoeCBpbiBjKCdyJywncycsJ2YnLCdtJykpIA0KICBoaXN0KEFbLHhdLGZyZXE9VCxtYWluPXgseGxhYj0iIix5bGFiPSIiLGNleC5tYWluPTIpDQpoaXN0KHBtaW4oQSRmLDEwKSwwOjEwLGZyZXE9VCx4bGFiPSIiLHlsYWI9IiIsY2V4Lm1haW49MikNCmhpc3QobG9nKEEkbSwxMCksZnJlcT1ULHhsYWI9IiIseWxhYj0iIixjZXgubWFpbj0yKQ0KYGBgDQoNCisg6JeJ55Sx55u05pa55ZyW77yM5bCHcmZt562J6K6K5pW46KaW6Ka65YyW77yM55yL5ZyW6Kqq5pWF5LqLDQoNCiMjIyMjIER1cGxpYXRlICYgU2F2ZQ0KYGBge3J9DQpBMCA9IEE7IFgwID0gWDsgWjAgPSBaDQpzYXZlKFowLCBYMCwgQTAsIGZpbGU9ImRhdGEvdGYwLnJkYXRhIikNCmBgYA0KPGJyPjxocj4NCg0KDQoNCiMjIyA0LiBPYmplY3RpdmUgb2YgdGhlIENvbnRlc3QgDQoNCmBgYHtyfQ0KcmFuZ2UoWCRkYXRlKQ0KYGBgDQoNCioq5L2/55So5LiA5pyI5bqVKOWQqzIwMDEtMDEtMzEp5Lul5YmN55qE6LOH5paZ77yM5bu656uL5qih5Z6L5L6G6aCQ5ris5q+P5LiA5L2N6aGn5a6i77yaKioNCg0KYS4gKirlpbnlnKgy5pyI5Lu9KDIwMDEtMDItMDEgfiAyMDAxLTAyLTI4Keacg+S4jeacg+S+huiyt++8nyoqDQpiLiAqKuWmguaenOWlueS+huiyt+eahOipse+8jOacg+iyt+WkmuWwkemMou+8nyoqDQoNCjxicj4NCg0KIyMjIyMgVGhlIEJhc2ljIFF1ZXN0aW9ucyBvZiBBbmFseXNpcw0KDQoqKuOAkFHjgJEqKiBfV2hhdCBhcmUgdGhlIFVuaXQgb2YgQW5hbHlzaXM/XyANCg0KKw0KKw0KDQoqKuOAkFHjgJEqKiBfV2hhdCBhcmUgdGhlIFRhcmdldCBvZiBBbmFseXNpcz9fIA0KX1Nob3VsZCB3ZSBtb2RlbCBmb3IgZXZlcnkgY3VzdG9tZXJzIGluIHRoZSBkYXRhc2V0P18gDQpfV2h5IG5vdD9fDQoNCisNCisNCg0KKirjgJBR44CRKiogX0hvdyB0byBtYWtlIHRoZSBUcmFpbmluZy9UZXN0aW5nIERhdGEgU3BsaXQ/Xw0KDQorDQorDQoNCioq44CQUeOAkSoqIF9XaGF0IGFyZSB0aGUgUHJlZGljdGluZyBhbmQgVGFyZ2V0ZWQgVmFyaWFibGVzP18NCg0KKw0KKw0KDQojIyMjIyBUaGUgVGFyZ2V0IG9mIEFuYWx5c2lzDQoNCg0KU2NyZWVuIG91dCB0aGUgbmV3IGN1c3RvbWVycyAod2hvIGFycml2ZSBhZnRlciAyMDAxLTAyLTAxKQ0KYGBge3J9DQpBID0gZmlsdGVyKEEwLCBzID4gMjgpICAjIDI4NTg0DQpgYGANCg0KIyMjIyMgVGhlIEJhc2VsaW5lIFByb2JhYmlsaXR5DQpgYGB7cn0NCm1lYW4oQSRyIDw9IDI4KQ0KYGBgDQoNCiMjIyMjIFNwbGl0aW5nIEZhY3RvciBhbmQgU3BsaXRpbmcgUmF0aW8NCmBgYHtyfQ0KbGlicmFyeShjYVRvb2xzKQ0Kc2V0LnNlZWQoMTIzNCk7IHNwbCA9IHNhbXBsZS5zcGxpdChBJHIgPD0gMjgsIFNwbGl0UmF0aW89MC43NSkNCmNpZDEgPSBzdWJzZXQoQSwgc3BsKSRjdXN0ICAgICMgMjE0MzgNCmNpZDIgPSBzdWJzZXQoQSwgIXNwbCkkY3VzdCAgICMgNzE0Ng0KYGBgDQpgY2lkMWAvYGNpZDJgIGFyZSB0aGUgY3VzdG9tZXJzIGlkcyBpbiB0aGUgdHJhaW5pbmcvdGVzdGluZyBkYXRhLiBCdXQsIC4uLg0KDQoqKuOAkFHjgJEqKiBfV2hhdCBhcmUgdGhlIFByZWRpY3RpbmcgKFgpIGFuZCBUYXJnZXRlZCBWYXJpYWJsZXMgKFkpP18NCg0KKw0KKw0KDQo8YnI+PGJyPjxicj48YnI+PGhyPjxicj48YnI+PGJyPg0KDQo8c3R5bGU+DQoNCi5jYXB0aW9uIHsNCiAgY29sb3I6ICM3Nzc7DQogIG1hcmdpbi10b3A6IDEwcHg7DQp9DQpwIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnByZSB7DQogIHdvcmQtYnJlYWs6IG5vcm1hbDsNCiAgd29yZC13cmFwOiBub3JtYWw7DQogIGxpbmUtaGVpZ2h0OiAxOw0KfQ0KcHJlIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnAsbGkgew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KLnJ7DQogIGxpbmUtaGVpZ2h0OiAxLjI7DQp9DQoNCi5xaXogew0KICBsaW5lLWhlaWdodDogMS43NTsNCiAgYmFja2dyb3VuZDogI2YwZjBmMDsNCiAgYm9yZGVyLWxlZnQ6IDEycHggc29saWQgI2NjZmZjYzsNCiAgcGFkZGluZzogNHB4Ow0KICBwYWRkaW5nLWxlZnQ6IDEwcHg7DQogIGNvbG9yOiAjMDA5OTAwOw0KfQ0KDQp0aXRsZXsNCiAgY29sb3I6ICNjYzAwMDA7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpib2R5ew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KaDEsaDIsaDMsaDQsaDV7DQogIGNvbG9yOiAjMDA2NmZmOw0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KDQpoM3sNCiAgY29sb3I6ICMwMDg4MDA7DQogIGJhY2tncm91bmQ6ICNlNmZmZTY7DQogIGxpbmUtaGVpZ2h0OiAyOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDV7DQogIGNvbG9yOiAjMDA2MDAwOw0KICBiYWNrZ3JvdW5kOiAjZjhmOGY4Ow0KICBsaW5lLWhlaWdodDogMS41Ow0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KPC9zdHlsZT4NCg0K