《数据分析实战》–用R做逻辑回归分析
本文参考的是《数据分析实战》的第七章。
背景:针对某公司的一个产品,发现其用户量不断的减少。
当时该产品发布的时候智能手机还并未普及,随后智能手机的市场不断的扩大,该产品也增加了账户迁移功能,即在智能手机上继续使用过去非智能手机中的游戏账号。该功能上线后,智能手机的用户稳步上升,然而最近总用户量却不断的减少,发现是产品的非智能手机用户大量减少。
现状:智能手机用户的增加量比非智能手机用户的减少量要少。
预期:智能手机用户量的增加要能够弥补非智能手机用户量的减少。
明确问题:是否是 “账号迁移设定失败” 导致智能手机用户量增加量较少?
读取数据
在读取数据之前,要明确的一点是:用户自然流失和账号迁移设定失败导致的用户流失有何不同?
自然流失的用户的访问天数是在逐渐减少的,而因游戏账号迁转设定失败而流失的用户是在某天后就突然不再访问了。
这个假设虽然不是来自于问卷调查或访谈,但也符合我们自身使用的感觉和开发者的亲身体会,因此具有较高的可信度。
读入数据:
> dau <- read.csv('section7-dau.csv',header = T,stringsAsFactors = F)
> head(dau)
region_month region_day app_name user_id device
1 2013-01 2013-01-01 game-02 10061580 FP
2 2013-01 2013-01-01 game-02 10154440 FP
3 2013-01 2013-01-01 game-02 10164762 SP
4 2013-01 2013-01-01 game-02 10165615 FP
5 2013-01 2013-01-01 game-02 10321356 FP
6 2013-01 2013-01-01 game-02 10406653 SP
在此数据中,我们最想知道的 “在智能手机上将旧的游戏账号迁转设定失败” 的这种情况的相关数据无法获得。
也就是说,用户“自然流失”和“因游戏账号迁转设定失败而流失”这两种情况在数据上无法区分,我们无法获得所需的包含正解的数据。
基于不包含正解的数据进行建模,这在学术界属于一个被NG 的问题。然而在商业领域里,建模所需的数据不一定要局限于包含正解的完美数据。像本案例这样,在无法获得包含正解的数据的情况下还必须得出某些结论的情况并不少见。
根据用户的访问情况,,如果“因游戏账号迁转设定失败而流失”的用户在所有流失用户中所占比例较高的话,那么流失用户我们也就无法基于访问数量构筑判别模型。反之,如果因游戏账号迁转设定失败而流失的用户较少的话,那么访问次数的差异就会比较显著,也就能够顺利地构筑判别模型。
在本例中,如果能构筑判别模型,就意味着令人畏惧的游戏账号迁转设定的复杂性并未产生影响。
在本例中,使用简单的方法尽快得出结果,于是本例中我们决定使用逻辑回归分析。
逻辑回归分析特别适合因变量是“买/ 不买”这种二值的情况,是用来简单把握数据大致倾向的最合适的方法。
数据处理
1.我们先整理出从非智能手机更换到智能手机并进行了账号迁转设定的用户数据。
其中:FP为非智能手机用户,SP为智能手机用户
> mau <- unique(dau[,c("region_month","device","user_id")])
> fp_mau <- unique(dau[dau$device=="FP",c("region_month","device","user_id")])
> sp_mau <- unique(dau[dau$device=="SP",c("region_month","device","user_id")])
分别获取1月份和2月份的数据:
> fp_mau1 <- fp_mau[fp_mau$region_month=="2013-01",]
> fp_mau2 <- fp_mau[fp_mau$region_month=="2013-02",]
> sp_mau1 <- sp_mau[sp_mau$region_month=="2013-01",]
> sp_mau2 <- sp_mau[sp_mau$region_month=="2013-02",]
1月份的非智能手机用户在2月份的访问情况:
用0和1作为判断:
> fp_mau1 <- merge(fp_mau1,mau[mau$region_month == "2013-02",c("user_id","is_access")],
+ by="user_id",all.x = T)
> fp_mau1$is_access[is.na(fp_mau1$is_access)] <- 0
> head(fp_mau1)
user_id region_month device is_access
1 397286 2013-01 FP 1
2 471341 2013-01 FP 1
3 503874 2013-01 FP 0
4 512250 2013-01 FP 1
5 513811 2013-01 FP 1
6 638688 2013-01 FP 1
1月份访问过游戏的非智能手机用户在2月份是否是继续通过非智能手机来访问的
> fp_mau2$is_fp <- 1
> fp_mau1 <- merge(fp_mau1,fp_mau2[,c("user_id","is_fp")],by="user_id",all.x = T)
> fp_mau1$is_fp[is.na(fp_mau1$is_fp)] <- 0
> head(fp_mau1)
user_id region_month device is_access is_fp
1 397286 2013-01 FP 1 1
2 471341 2013-01 FP 0 0
3 503874 2013-01 FP 0 0
4 512250 2013-01 FP 1 1
5 513811 2013-01 FP 1 1
6 638688 2013-01 FP 1 1
然后,我们区分出那些在1 月份通过非智能手机访问而在2 月份变成通过智能手机来访问的用户。
> sp_mau2$is_sp <- 1
> fp_mau1 <- merge(fp_mau1,sp_mau2[,c("user_id","is_sp")],by="user_id",all.x = T)
> fp_mau1$is_sp[is.na(fp_mau1$is_sp)] <- 0
> head(fp_mau1)
user_id region_month device is_access is_fp is_sp
1 397286 2013-01 FP 1 1 0
2 471341 2013-01 FP 0 0 1
3 503874 2013-01 FP 0 0 0
4 512250 2013-01 FP 1 1 0
5 513811 2013-01 FP 1 1 0
6 638688 2013-01 FP 1 1 0
接着我们要从这份数据中提取出逻辑回归分析所需要的数据。我们从上一步得到的fp.mau1 数据中提取出is_access==0(2 月份没有访问的用户)或者is_sp==1(2 月份通过智能手机访问的用户)的部分。
> fp_mau1 <- fp_mau1[fp_mau1$is_access==0 | fp_mau1$is_sp == 1,]
> head(fp_mau1)
user_id region_month device is_access is_fp is_sp
2 471341 2013-01 FP 1 0 1
3 503874 2013-01 FP 0 0 0
11 1073544 2013-01 FP 0 0 0
12 1073864 2013-01 FP 0 0 0
14 1163733 2013-01 FP 1 0 1
15 1454629 2013-01 FP 0 0 0
数据分析
- 关于是否每天访问游戏的数据的整理
> library(reshape2)
> fp_dau1_cast <- dau[dau$device == "FP" & dau$region_month == "2013-01",]
> fp_dau1_cast$is_access <- 1
> fp_dau1_cast <- dcast(fp_dau1_cast, user_id~region_day,
+ value.var = "is_access",
+ function(x) as.character(length(x)))
> names(fp_dau1_cast)[-1] <- paste0("x",1:31,"day")
> head(fp_dau1_cast)
user_id x1day x2day x3day x4day x5day x6day x7day x8day x9day ... x31day
1 397286 1 1 1 1 1 1 1 1 1 ... 1
2 471341 1 1 1 1 0 0 0 0 0 ... 0
3 503874 1 0 0 0 0 0 0 0 0 ... 0
4 512250 1 1 1 1 1 1 1 1 1 ... 1
5 513811 0 0 0 0 0 0 0 0 0 ... 1
6 638688 1 1 1 1 1 1 1 1 1 ... 1
我们将这个数据和之前得到的用户访问数据fp_mau1 合并起来。
> fp_dau1_cast <- merge(fp_dau1_cast,fp_mau1[,c("user_id","is_sp")],by="user_id")
> head(fp_dau1_cast)
user_id x1day x2day x3day x4day x5day x6day x7day x8day .... x31day is_sp
1 471341 1 1 1 1 0 0 0 0 .... 0 1
2 503874 1 0 0 0 0 0 0 0 .... 0 0
3 1073544 0 0 0 0 0 0 0 0 .... 0 0
4 1073864 0 0 0 0 0 0 0 0 .... 0 0
5 1163733 1 1 0 0 0 0 0 0 .... 0 1
6 1454629 0 0 0 0 0 0 0 0 .... 0 0
> table(fp_dau1_cast$is_sp)
0 1
190 62
通过table 函数,我们可以统计出符合要求的数据。
经确认,标记为“0”的用户有190 名,标记为“1”的用户有62 名,共计252 名。
1月份非智能手机用户,在2月份有190名没有登陆(即流失),有62名完成账号迁移。
2.基于逻辑回归分析建立模型
> fit_logit <- step(glm(is_sp ~ .,data = fp_dau1_cast[,-1],
+ family = binomial))
> summary(fit_logit)
Call:
glm(formula = is_sp ~ x1day + x4day + x5day + x7day + x10day +
x13day + x22day + x29day + x31day, family = binomial, data = fp_dau1_cast[,
-1])
Deviance Residuals:
Min 1Q Median 3Q Max
-1.95538 -0.45175 -0.23178 -0.06122 2.69461
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.6036 0.4269 -8.441 < 2e-16 ***
x1day1 1.5334 0.5720 2.681 0.00735 **
x4day1 1.7753 0.6424 2.764 0.00572 **
x5day1 -1.0353 0.7622 -1.358 0.17437
x7day1 1.7002 0.7109 2.392 0.01678 *
x10day1 -2.6753 0.9418 -2.841 0.00450 **
x13day1 1.3726 0.7547 1.819 0.06893 .
x22day1 1.6233 0.6382 2.543 0.01098 *
x29day1 2.0012 0.6480 3.088 0.00201 **
x31day1 1.7310 0.8143 2.126 0.03352 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 281.20 on 251 degrees of freedom
Residual deviance: 126.73 on 242 degrees of freedom
AIC: 146.73
Number of Fisher Scoring iterations: 6
我们使用glm 函数来进行逻辑回归分析。在该函数的使用过程中,需要将选项family 设为binomial,才能顺利进行逻辑回归分析。
另外,我们还使用了step 函数。step 函数以赤池信息量准则(AIC)为标准,能够对模型中自变量的增减进行自动的探寻和选择。在本次的逻辑回归分析中,我们就使用了step 函数来建立模型。
3.利用生成的模型来进行预测
> fp_dau1_cast$prob <- round(fitted(fit_logit),2)
> fp_dau1_cast$pred <- ifelse(fp_dau1_cast$prob > 0.5,1,0)
> table(fp_dau1_cast[,c("is_sp","pred")])
pred
is_sp 0 1
0 180 10
1 20 42
可以看出,模型预测为“流失”的用户有180 名,而这180 名用户确实不再来了,模型预测“账号迁转”的42 名用户也确实迁转了账号。
预测的准确率为 (180 + 42) / (180 + 10 + 20 + 42) = 88%。这个准确率比较高,基本可以认为我们得到了一个值得信赖的预测模型。
通过上述内容可以看出,本例中建立的模型的可信度较高,也就是说,当初设立的假设“账号迁转设定失败而导致用户流失”的影响较小,从实际人数上来看也只有10 名用户。
我们的假设是“在智能手机上游戏账号迁转设定失败导致流失的用户很多”,而根据分析的结果,因账号迁转设定失败而流失的用户占整体流失用户的比例很小。因此,我们决定改进面向智能手机新用户的商业宣传,提升用户数量。
至此数据分析结束~