We studied a very powerful approach for customer segmentation in the previous post, which is based on the customer’s lifecycle. We used two metrics: frequency and recency. It is also possible and very helpful to add monetary value to our segmentation. If you havecustomer acquisition cost (CAC) and customer lifetime value (CLV), you can easily add these data to the calculations.

We will create the same data sample as in the previous post, but with two added data frames:

  • cac, our expenses for each customer acquisition,
  • gr.margin, gross margin of each product.
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
# loading libraries
library(dplyr)
library(reshape2)
library(ggplot2)
 
# creating data sample
set.seed(10)
data <- data.frame(orderId=sample(c(1:1000), 5000, replace=TRUE),
product=sample(c('NULL','a','b','c'), 5000, replace=TRUE,
prob=c(0.15, 0.65, 0.3, 0.15)))
order <- data.frame(orderId=c(1:1000),
clientId=sample(c(1:300), 1000, replace=TRUE))
gender <- data.frame(clientId=c(1:300),
gender=sample(c('male', 'female'), 300, replace=TRUE, prob=c(0.40, 0.60)))
date <- data.frame(orderId=c(1:1000),
orderdate=sample((1:100), 1000, replace=TRUE))
orders <- merge(data, order, by='orderId')
orders <- merge(orders, gender, by='clientId')
orders <- merge(orders, date, by='orderId')
orders <- orders[orders$product!='NULL', ]
orders$orderdate <- as.Date(orders$orderdate, origin="2012-01-01")
 
# creating data frames with CAC and Gross margin
cac <- data.frame(clientId=unique(orders$clientId), cac=sample(c(10:15), 289, replace=TRUE))
gr.margin <- data.frame(product=c('a', 'b', 'c'), grossmarg=c(1, 2, 3))
 
rm(data, date, order, gender)

Next, we will calculate CLV to date (actual amount that we earned) using gross margin values and orders of the products. We will use the following code:

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
# reporting date
today <- as.Date('2012-04-11', format='%Y-%m-%d')
 
# calculating customer lifetime value
orders <- merge(orders, gr.margin, by='product')
 
clv <- orders %>%
group_by(clientId) %>%
summarise(clv=sum(grossmarg))
 
# processing data
orders <- dcast(orders, orderId + clientId + gender + orderdate ~ product, value.var='product', fun.aggregate=length)
 
orders <- orders %>%
group_by(clientId) %>%
mutate(frequency=n(),
recency=as.numeric(today-orderdate)) %>%
filter(orderdate==max(orderdate)) %>%
filter(orderId==max(orderId))
 
orders.segm <- orders %>%
mutate(segm.freq=ifelse(between(frequency, 1, 1), '1',
ifelse(between(frequency, 2, 2), '2',
ifelse(between(frequency, 3, 3), '3',
ifelse(between(frequency, 4, 4), '4',
ifelse(between(frequency, 5, 5), '5', '>5')))))) %>%
mutate(segm.rec=ifelse(between(recency, 0, 6), '0-6 days',
ifelse(between(recency, 7, 13), '7-13 days',
ifelse(between(recency, 14, 19), '14-19 days',
ifelse(between(recency, 20, 45), '20-45 days',
ifelse(between(recency, 46, 80), '46-80 days', '>80 days')))))) %>%
# creating last cart feature
mutate(cart=paste(ifelse(a!=0, 'a', ''),
ifelse(b!=0, 'b', ''),
ifelse(c!=0, 'c', ''), sep='')) %>%
arrange(clientId)
 
# defining order of boundaries
orders.segm$segm.freq <- factor(orders.segm$segm.freq, levels=c('>5', '5', '4', '3', '2', '1'))
orders.segm$segm.rec <- factor(orders.segm$segm.rec, levels=c('>80 days', '46-80 days', '20-45 days', '14-19 days', '7-13 days', '0-6 days'))

Note: if you prefer to use potential/expected/predicted CLV or total CLV (sum of CLV to date and potential CLV) you can adapt this code or find the example in the next post.

In addition, we need to merge orders.segm with the CAC and CLV data, and combine the data with the segments. We will calculate total CAC and CLV to date, as well as their average with the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
orders.segm <- merge(orders.segm, cac, by='clientId')
orders.segm <- merge(orders.segm, clv, by='clientId')
 
lcg.clv <- orders.segm %>%
group_by(segm.rec, segm.freq) %>%
summarise(quantity=n(),
# calculating cumulative CAC and CLV
cac=sum(cac),
clv=sum(clv)) %>%
ungroup() %>%
# calculating CAC and CLV per client
mutate(cac1=round(cac/quantity, 2),
clv1=round(clv/quantity, 2))
 
lcg.clv <- melt(lcg.clv, id.vars=c('segm.rec', 'segm.freq', 'quantity'))

Ok, let’s plot two charts: the first one representing the totals and the second one representing the averages:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ggplot(lcg.clv[lcg.clv$variable %in% c('clv', 'cac'), ], aes(x=variable, y=value, fill=variable)) +
theme_bw() +
theme(panel.grid = element_blank())+
geom_bar(stat='identity', alpha=0.6, aes(width=quantity/max(quantity))) +
geom_text(aes(y=value, label=value), size=4) +
facet_grid(segm.freq ~ segm.rec) +
ggtitle("LifeCycle Grids - CLV vs CAC (total)")
ggplot(lcg.clv[lcg.clv$variable %in% c('clv1', 'cac1'), ], aes(x=variable, y=value, fill=variable)) +
theme_bw() +
theme(panel.grid = element_blank())+
geom_bar(stat='identity', alpha=0.6, aes(width=quantity/max(quantity))) +
geom_text(aes(y=value, label=value), size=4) +
facet_grid(segm.freq ~ segm.rec) +
ggtitle("LifeCycle Grids - CLV vs CAC (average)")

You can find in the grid that the width of bars depends on the number of customers. I think these visualizations are very helpful. You can see the difference between CLV to dateand CAC and make decisions about on paid campaigns or initiatives like:

  • does it make sense to spend extra money to reactivate some customers (e.g. those who are in the “1 order / >80 days“ grid or those who are in the “>5 orders / 20-45 days“ grid)?,
  • how much money is appropriate to spend?,
  • and so on.

Therefore, we have got a very interesting visualization. We can analyze and make decisions based on the three customer lifecycle metrics: recency, frequency andmonetary value.

Thank you for reading this!

转自:http://analyzecore.com/2015/02/19/customer-segmentation-lifecycle-grids-clv-and-cac-with-r/

Customer segmentation – LifeCycle Grids, CLV and CAC with R(转)的更多相关文章

  1. Customer segmentation – LifeCycle Grids with R(转)

    I want to share a very powerful approach for customer segmentation in this post. It is based on cust ...

  2. Cohort Analysis and LifeCycle Grids mixed segmentation with R(转)

    This is the third post about LifeCycle Grids. You can find the first post about the sense of LifeCyc ...

  3. Appboy 基于 MongoDB 的数据密集型实践

    摘要:Appboy 正在过手机等新兴渠道尝试一种新的方法,让机构可以与顾客建立更好的关系,可以说是市场自动化产业的一个前沿探索者.在移动端探索上,该公司已经取得了一定的成功,知名产品有 iHeartM ...

  4. ML.NET教程之客户细分(聚类问题)

    理解问题 客户细分需要解决的问题是按照客户之间的相似特征区分不同客户群体.这个问题的先决条件中没有可供使用的客户分类列表,只有客户的人物画像. 数据集 已有的数据是公司的历史商业活动记录以及客户的购买 ...

  5. CRM 建设方案(01):CRM基础

    CRM 客户关系管理系统基础 客户关系管理简称CRM(Customer Relationship Management).CRM概念引入中国已有数年,其字面意思是客户关系管理,但其深层的内涵却有着许多 ...

  6. python excel 文件合并

    Combining Data From Multiple Excel Files Introduction A common task for python and pandas is to auto ...

  7. Ninject之旅之六:Ninject约定

    摘要 在小的应用系统中一个一个注册一些服务类型不怎么困难.但是,如果是一个实际的有上百个服务的应用程序呢?约定配置允许我们使用约定绑定一组服务,而不用一个一个分别绑定. 要使用约定配置,需要添加Nin ...

  8. 沈阳润才教育CRM

    一.CRM初始 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...

  9. python 全栈开发,Day107(CRM初始,权限组件之权限控制,权限系统表设计)

    一.CRM初始 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...

随机推荐

  1. linux awk 命令详解

    awk是一个非常棒的数字处理工具.相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分为数个"字段"来处理.运行效率高,而且代码简单,对格式化的文本处理能力超强.先来一个 ...

  2. JavaScript运算符优先级

    图片引用自:http://www.cnblogs.com/xxcanghai/p/5189353.html

  3. 简单 fibonacci 函数

    public static int fibonacci(int n){  if(n<=1) return 1;  else {     return fibonacci(n-1)+fibonac ...

  4. .NET程序员也学Node.js——初识Node.js

    清明在石门休了八天假,一眨眼,4月又到中旬了...看到.NET在天朝彻底沦陷而又无能为力,我开始尝试去学习一些新的东西来充实自己,我自然是打死不会去学java的,没有为什么,于是乎,最近开始学习一些前 ...

  5. java代码开发完成后,代码走查规范

    代码走查注意事项: 1.不变的值,尽量写个常量类 2.尽量使用if{}else,不要一直if去判断 3.减少循环调用方法查询数据库 4.dao层尽量不要用逻辑,尽量在service里写业务逻辑 5.金 ...

  6. ios 苹果手机硬件摘要

    IPhone4 * 2010年发布. * A4单核处理器. * 3.5英寸Retina显示屏(视网膜屏幕),960x640像素分辨率. * 后置摄像头500万像素. * 前置摄像头30万像素. IPh ...

  7. 你不得不知的逻辑或(||)与(&&)非(!)

    最近重新翻开原生JS,又得到很多不同的体会,虽然现在开发框架那么多,但很多思想都还是离不开原生的基础.今天呢,我就根据自己的学习总结一下逻辑与(&&)和(逻辑或(||)和逻辑非(!). ...

  8. 4 安装MPush

    cnblogs-DOC 1.服务器环境 2.安装Redis3.安装Zookeeper4.安装MPush5.安装Alloc服务6.完整测试7.常见问题 一.Linux安装Mpush [root@loca ...

  9. C#小知识点记录(QQ交流群的一个小问题)Linq提取数据

    请教 这里 LINQ想 找到 最后的 4条 记录 然后放在 这里这个 List Linq查找怎么写呀? 解答:写了一个小例子作为解答. namespace C_Sharp { class Progra ...

  10. JavaScript中的数据结构及实战系列(1):队列

    开题 张三丰教无忌太极剑法: 还记得吗? 全都记得. 现在呢? 已经忘却了一小半. 啊,已经忘了一大半. 不坏不坏,忘得真快,那么现在呢? 已经全都忘了,忘得干干净净. 好了,你上吧. 长时间写前端代 ...