数据加载
Discover实现客户流失预警分析
流失预警对于大多数企业而言具有重要的作用,可以帮助企业在早期预测未来即将流失的重要客户,从而及时进行相应的营销活动,挽回客户,提高客户价值。
本文将以某机构的用户交易记录作为分析案例,构建流失预警模型的分析思路,探索用户流失原因,建立用户流失预警模型,并预测用户流失的概率,同时讲解如何用Discover提供的函数去实现上述流程。
首先在Discover Notebook中指定采用R为解释器。
然后加载discoverR中内置的示例流失预警数据集losingWarn。该数据集共包括三列,用于记录某机构中用户交易情况。
第一列为交易时间trade_time,形如“2014-01-01 14:41:44”。
第二列记录交易用户user_id。
第三列是交易金额consume_amt。
接着加载R包并初始化SparkSession:
library(discoverR) library(ggplot2) discover.init() |
将本地的losingWarn数据集转换成分布式数据集,便于后续分布式处理:
data("losingWarn") df_losingWarn <- createDataFrame(losingWarn) |
数据处理与分析
为了按月对用户是否流失进行预测,我们将数据中的交易时间转换成月,并取出2014全年交易数据进行分析:
df_losingWarn <- df_losingWarn %>% mutate(trade_month = month(df_losingWarn$trade_time)) %>% mutate(trade_year = year(df_losingWarn$trade_time)) df_losingWarn <- df_losingWarn %>% filter("trade_year == 2014") |
统计和查看每个人在每个月的交易次数和交易金额,便于后续对于用户的特征提取:
colName <- c("user_id", "trade_month", "consume_amt") df_user_summary <- select(df_losingWarn, as.list(colName)) %>% groupBy("user_id", "trade_month") %>% summarize(trade_num = n(df_losingWarn$user_id), trade_amt = sum(df_losingWarn$consume_amt)) |
统计和查看每个月总的交易次数和交易金额:
colName <- c("trade_month", "trade_num", "trade_amt") df_trade_summary <- select(df_user_summary, as.list(colName)) %>% groupBy("trade_month") %>% summarize(sum_trade_num = sum(df_user_summary$trade_num), sum_trade_amt = sum(df_user_summary$trade_amt)) |
查看每个月的交易金额,并绘制出对应箱线图。由于交易金额相差比较大,我们对交易金额进行了对数处理,从图中可以看出每个月的交易金额的中位数相差不大,说明每个月的交易金额比较平稳。
df_user_summary_local <- collect(df_user_summary) df_user_summary_local$trade_month <- as.factor(df_user_summary_local$trade_month) p_trade_amt <- ggplot(data = df_user_summary_local, aes(trade_month, log(trade_amt))) p_trade_amt + geom_boxplot(aes(fill = trade_month)) + ggtitle("Transaction Amount Distribution") + theme(plot.title = element_text(hjust = 0.5)) |
接着查看每个月的交易用户个数,从年初二月份到年末,交易用户的个数基本呈现稳步上升的趋势。
ggplot(data = df_user_summary_local, aes(trade_month)) + geom_bar(aes(fill = trade_month)) + ggtitle("Customer Number Trend") + theme(plot.title = element_text(hjust = 0.5)) |
为了分析用户交易数可能受哪些因素影响,接下来查看每个月的总的交易次数分布情况:
df_trade_summary_local <- collect(df_trade_summary) df_trade_summary_local$trade_month <- as.factor(df_trade_summary_local$trade_month) ggplot(data = df_trade_summary_local, aes(x = trade_month, y = sum_trade_num, fill = trade_month)) + geom_bar(stat = 'identity') + ggtitle("Transaction Amount Distribution") + theme(plot.title = element_text(hjust = 0.5)) |
以及每个月交易金额的分布情况:
ggplot(data = df_trade_summary_local, aes(x = trade_month, y = sum_trade_amt, fill = trade_month)) + geom_bar(stat = 'identity') + ggtitle("Transaction Times Distribution") + theme(plot.title = element_text(hjust = 0.5)) |
从上面的交易次数与交易金额分析图以及每个月的交易用户个数图可以看出,每个月总的交易次数分布与交易用户个数分布基本相似,因此推断用户的交易次数对用户的流失影响可能比较大。交易金额在年末相对较高,年中相对比较平稳。
特征提取
基于以上分析,下面我们对用户进行特征提取。为了有效的反映一个用户在一段时间的用户行为,需要限定一个时间窗口,从而提取出用户在指定段时间内的特征。
定义一个GetFeature函数用来获取特征,GetFeature接受三个参数,其中data是原始的输入数据,startMonth指起始月,endMonth指结束月。该函数涉及用户特征主要包括:最后一次交易时间lastTradeMonth,最大交易金额maxAMT, 最大交易数目maxNum,训练时间窗口内的交易金额总和sumAMT,交易次数总和sumNum,训练时间窗口内的平均交易金额averageAMT以及平均交易次数。
GetFeature <- function(data, startMonth, endMonth) { result <- data %>% filter(paste("trade_month >=", startMonth, "and trade_month <=", endMonth)) month <- as.integer(endMonth) - as.integer(startMonth) + 1 out <- result %>% groupBy("user_id") %>% summarize(lastTradeMonth = max(result$trade_month), maxAMT = max(result$trade_amt), maxNum = max(result$trade_num), sumAMT = sum(result$trade_amt), sumNum = sum(result$trade_num)) out %>% mutate(averageAMT = out$sumAMT / month, averageNum = out$sumNum / as.integer(month)) } |
类别标注
获得训练数据的特征之后,需要对训练数据打标签,从而才能进行模型训练。这里需要对用户流失行为进行定义。我们对于该案例给出的定义是:给定一个观察窗口,如果用户在观察窗口内总的交易次数为0,说明此用户已经流失,需要给这个用户打上“losing”标签。反之,则给用户打上“remain”标签,表示该用户留存。
为用户做标签标记的函数如下所示:
GetLabel <- function(data, startMonth, endMonth) { out <- data %>% filter(paste("trade_month >=", startMonth, "and trade_month <=", endMonth)) %>% group_by("user_id") %>% summarize(sumNum = sum(data$trade_num)) out <- out %>% mutate(label = ifelse(out$sumNum > 0, "remain", "losing")) %>% select(as.list(c("user_id", "label"))) names(out) <- c("id", "label") out } |
模型构建
完成训练数据和标签之后,下面开始着手建立流失预警模型。这里采用6月到9月为训练时间窗口,提取该时间段的用户行为特征,然后以10月到11月为观察窗口,根据用户行为决定所打标签。然后利用随机森林模型进行建模,用于预测分类。我们可以直接使用Discover提供的txRandomForest函数实现随机森林算法,具体的代码如下所示:
GetModelData <- function(data, startMonth, endMonth, observeSize) { feature <- GetFeature(data, startMonth, endMonth) labelStartMonth <- endMonth + 1 labelEndMonth <- endMonth + observeSize label <- GetLabel(data, labelStartMonth, labelEndMonth) out <- join(feature, label, feature$user_id == label$id, "left_outer") %>% drop("id") out %>% mutate(label = ifelse(out$label == "remain", "remain", "losing")) } training_data <- GetModelData(df_user_summary, 6, 9, 2) rf_model <- txRandomForest(data = training_data, formula = label ~ lastTradeMonth + maxAMT + maxNum + sumAMT + sumNum + averageAMT + averageNum, type = "classification") |
模型预测
利用随机森林得到用户流失预警模型后,就可以开始对用户行为进行预测。这里采用7月到10月为测试数据的时间窗口。利用Discover中的predict函数,通过训练得到的模型进行预测。
test_data <- GetModelData(df_user_summary, 7, 10, 2) result <- predict(rf_model, test_data) |
之后用showDF函数查看预测结果。
showDF(result) |
模型评估
得到预测结果后,需要根据预测结果对模型进行评估,Discover实现了txBinaryClassificationEvaluator函数方便结果评估。我们在此处采用ROC为评估指标,通过特异性和敏感度的关系反映预测准确度。
areaUnderROC <- txBinaryClassificationEvaluator(result, metricName = "areaUnderROC", probabilityCol = "probability", labelCol = "label", labels = summary(rf_model)$labels) areaUnderROC |
另外还可以利用importance函数查看训练特征的重要性,来验证我们之前在数据探索过程中的猜想。
variable_importance <- importance(rf_model) variable_importance |
从特征重要性分析结果可以看出占比最大的是averageNum和sumNum两个特征,说明用户的在一段时间内的平均交易次数和总的交易次数对用户在机构中的留存影响比较大,正好验证了上述我们从每个月交易次数分布图中做出的猜想。
总结
本案例提供了建立流失预警模型的主要分析思路,以及在Discover中的实现方式。可以看出Discover预置了多种丰富函数,有效实现算法建模与评估。使用Discover将极大的降低客户流失预测的难度,实现便捷的流失分析,帮助企业在必要的时间,采用正确的营销手段,提升商业价值。
往期原创文章
Sophon+Slipstream实现流式KMeans聚类预测
Guardian 5.0全新架构解析:大数据安全防御之盾(二)
Guardian 5.0全新架构解析:大数据安全防御之盾(一)
近实时的ETL工具--Transwarp Transporter
混合负载下的资源调度神器--Inceptor Scheduler
你应该知道的工作流调度平台——Transwarp Workflow
OLAP Cube可视化设计工具—Transwarp Rubik
TDH荣获TPC官方测试(TPCx-HS@10TB)最佳性能
大数据开放实验室由星环信息科技(上海)有限公司运营,专门致力于大数据技术的研究和传播。若转载请在文章开头明显注明“文章来源于微信订阅号——大数据开放实验室”,并保留作者和账号介绍。