现状
某社交游戏公司有一款游戏本月的销售额相比上月有所下滑,需要我们分析下滑的原因,并提升销售额。这个游戏的销售额之前一直保持增长,而这个月却下降了。从市场环境和游戏本身的状态来看,不太可能由于游戏本身内容导致,于是我们需要找出哪些用户产生差异导致销售额下降。
近两个月销售额数据
发现问题
首先,我们需要知道本月和上月相比有哪些点不同。我们尝试进行下述假设。销售额减少的原因可能有以下两点:
1. 在营销宣传上存在问题
2. 每月开展的游戏活动存在问题
提出假设后我们需要检验假设是否正确,最简单的方式是询问相关部门。通过咨询是市场部和游戏开发部,得到以下信息:
1. 由于营销预算有限,本月相比上月并没有开展那么多宣传活动
2. 游戏活动主题和内容相比上月几乎没有变动
从上面信息可以发现销售额减少可能由于宣传活动减少,导致公司产品在用户纳新方面不足,现在我们需要通过数据确认新用户数量减少和销售额下降是否存在关系。
数据收集和处理
通过跟技术部沟通分析需求的数据支持,收集到如下数据:
1. DAU(Daily Active User,每天至少来访 1 次的用户数据)
2. DPU(Daily Payment User,每天至少消费 1 元的用户数据)
3. Install(记录每个用户首次玩这个游戏的时间的数据)
DAU
数据字段
数据类型
数据名称
log_date
string
访问时间
app_name
string
应用名称
user_id
int
用户ID
DPU
数据字段
数据类型
数据名称
log_date
string
消费日期
app_name
string
应用名称
user_id
int
用户ID
payment
int
消费金额
Install
数据字段
数据类型
数据名称
install_date
string
首次使用时间
app_name
string
应用名称
user_id
int
用户ID
读取数据文件
本例的数据都是以csv文件存储,使用Pandas库可以将csv文件读取成DataFrame数据,方便后续进行数据处理。具体代码如下:
# 导入相关库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 读取csv数据
dau = pd.read_csv('data/dau.csv')
dpu = pd.read_csv('data/dpu.csv')
install = pd.read_csv('data/install.csv')
注:%matplotlib inline是我因为使用jupyter notebook进行编辑,为了显示图表需要添加此行。
查看读取的数据
head方法可以显示数据头五行。
dau.head()
dau
dpu.head()
dpu
install.head()
install
数据合并
merge函数可以将两份数据进行合并,类似SQL里面的join,但功能要更加强大。首先将DAU和install的数据进行合并,合并的数据能计算当月新用户和已有用户。再将得到的数据与用户消费信息数据DPU合并,这样可以计算用户当月的消费金额情况。
# 合并DAU和install数据
dau_install = pd.merge(dau, install, on=['user_id', 'app_name'])
# 合并上述数据和DPU数据
dau_install_payment = pd.merge(dau_install, dpu, how='left', on=['log_date', 'app_name', 'user_id'])
dau_install.head()
dau_install
dau_install_payment.head()
dau_install_payment
查看最终合并后的数据发现消费金额payment显示NaN即该值为空,这是因为只有产品消费行为的用户才有消费金额,否则就没有数据,缺失的数据在合并后会显示NaN。
实际上有消费金额的数据和NaN混合在一起,这里只查看了前五行数据全显示为NaN,所以我们还无法确定消费金额数据是否与之前的数据正确合并。为了查看消费金额非空的数据,需要进行一下操作:
# 查看payment不为空数据
dau_install_payment[dau_install_payment['payment'].notnull()].head()
看到不为NaN数据有实际的值,即payment正确合并在一起。
数据处理
前面我们合并用户的消费数据,但未消费用户的消费金额为NaN值,因为payment需要参与到后续计算,NaN值则不是最好的标识,所以需要将这些值设置为零。
# 将未消费用户的消费金额设置为零
dau_install_payment['payment'] = dau_install_payment['payment'].fillna(0)
dau_install_payment
数据探索分析
按月统计
现在得到的分析数据日期都是年月日类型,如要要按月统计则需重新生成月份的列来表示。利用lambda函数从日期中提取第1到7个字符,使用日期log_date和首次使用日期install_date都需要进行处理。为了观察上月与本月的差别,数据将按照月份进行统计用户信息。
# 增加两列表示月份
dau_install_payment['log_month'] = dau_install_payment['log_date'].map(lambda x: x[0: 7])
dau_install_payment['install_month'] = dau_install_payment['install_date'].map(lambda x: x[0: 7])
# 按使用月份、用户ID和首次使用月份分组汇总消费金额合计
mau_payment = dau_install_payment.groupby(['log_month', 'user_id', 'install_month'])['payment'].sum().to_frame().reset_index()
mau_payment.head()
mau_payment
区分新用户和已有用户
如果用户的使用月份和首次使用月份一致,则该用户为新用户,否则为已有的用户,下面我们将对用户类型进行区分。
# 增加识别新用户和已有用户
mau_payment['user_type'] = np.where(mau_payment['log_month'] == mau_payment['install_month'], 'install', 'existing')
mau_payment.head()
mau_payment
为了确认新用户是否减少了,按月统计不同用户类型的消费额,对比发现7月相比6月新用户大幅减少。
# 按月份和用户类型分组求消费金额合计
mau_paymnet_summary = mau_payment.groupby(['log_month', 'user_type'])['payment'].sum().to_frame().reset_index()
Paste_Image.png
数据可视化
通过前面的汇总数据可以发现本月与上月之间的差异,但不是特别直观,所以我们用可视化图表来表示两者的差异情况。如下图,本月相比上月消费额减少,但已有用户的消费金额并没有明显变化,新用户消费金额减少明显。
# 按使用月份和用户类型分组汇总消费金额绘制叠加柱状图
mau_payment.groupby(['log_month', 'user_type'])['payment'].sum().unstack().plot(kind='bar', stacked=True, alpha=0.8, rot=True)
plt.ylabel('total_payment')
plt.legend()
plt.show()
两个月的消费额分布比较
从上面的初步分析结果可以验证我们之前的假设,即新用户数减少导致销售额下降。那么具体是哪个消费层级的消费额减少?
先抽取新用户的消费数据,将两个月份的数据分别绘制直方图并重叠对比。横坐标表示该月的消费金额总计,纵坐标表示相应的用户数。通过可视化图表可以看出消费额2000以下的用户减少了。在社交游戏中,用户可以用金钱来购买劳动。由于大部分用户消费得很少,所以你只需要花不多的钱就可以让自己的排名大幅上升。然而,如果你想占据排行榜的顶端,那么所要花费的金额马上就会上涨。这也是人们的竞争心理结构在数据分布上的表现。
# 对比不同月份消费金额分布
install_payment = mau_payment[(mau_payment['payment'] > 0) & (mau_payment['user_type'] == 'install')]
data1 = install_payment[install_payment['log_month'] == '2013-06']['payment']
data2 = install_payment[install_payment['log_month'] == '2013-07']['payment']
bins = np.arange(0, 13000, 1000)
data1.hist(bins=bins, alpha=0.7, label='2013-06')
data2.hist(bins=bins, alpha=0.8, label='2013-07')
plt.ylabel('payment')
plt.legend()
plt.show()
解决方案
基于前面的分析结果,我们可以采取以下解决方案来提高销售额。
1. 公司恢复之前营销宣传的活动水平,提高潜在用户对公司产品的认知度
2. 打包小额游戏促销包,提高小额消费新用户数量