作者简介
HeoiJin:立志透过数据看清世界的产品策划,专注爬虫、数据分析、产品策划领域。
万物皆营销 | 资本永不眠 | 数据恒真理
CSDN:https://me.csdn.net/weixin_40679090
数据分析师们经常会收到“我这里有一份数据,你帮我分析分析呗”这类没有明确需求的任务,往往经过在我们一顿自认为是金牌讲师的操作之后,得到的反馈却是一个又一个的灵魂拷问:
其中的本质原因,就是我们只站在统计学的角度去分析,迷恋数值的游戏,而不是从业务的角色出发,通过数据解决业务问题。下面将用一个实战案例,与大家共同探讨如何撰写一份有业务价值的分析报告。
PS.
介于篇幅问题,本文着重讲解分析思路,代码仅展示核心知识点
完整代码和数据集请移步至文末链接或阅读原文
本次样本数据集来自“天池”的婴儿用品信息,包含两个表trade(商品交易记录)和babyinfo(婴儿信息)
trade表:29972行*7列
babyinfo表:945行*3列
这一步骤其实非常重要,梳理好指标的层级关系(结果指标、过程指标:串行/并行),我们才能知道哪些指标是面,哪些指标是点,才会有由面到点的深入分析。
结果指标:
维度:
注意:此数据集的分析文章,大都会以最基础的1-7岁对婴儿年龄划分为7个组别。但实际上,针对不同年龄段的婴儿,婴幼儿奶粉分为4个阶段:
这里凸显出一个问题:数据分析师习惯性以统计学含义理解指标,而不是找指标背后的业务含义
销量数据的异常值是整一个分析当中影响最大的,数据录入错误或运营的刷单等行为,会让个别时间段的销量猛增,严重影响趋势的判断,因此先剔除销量中的异常值。
利用四分位和方差对销量数据情况进行了解,确定异常值范围。站在统计学的角度,把超过平均值3倍标准差的销量(即2.54+64*3=194.54罐)作为异常值是常规的做法,但站在业务的角度则不合理。
通过奶粉产品的净含量和各年龄段婴幼儿奶粉推荐食用量的估算,我们可以得到以下理论值数据:
(1段、2段食用量分别参考自美赞臣蓝臻婴儿配方奶粉 1段/2段,3段和4段的喂食频率改为每天1次,每次食用量依据为2段的单次用量)
从上表中可以看出,用量最大的4段全年龄段理论上最多食用110罐400g的奶粉,一次性购买194罐以上才算异常值明显不合理。另外翻查2014年婴幼儿奶粉相关调研报告,400g的奶粉产品均价在250元左右,一次性购买100罐400g奶粉需要2万5千元,对于任何家庭来说,都是不合理支出结构。
因此,衡量异常值,不能仅通过统计学意义,还需要结合业务的实际情况。
在没有内部业务数据支撑下,以行业报告作为补充对异常值进行划分。根据国双2018年本土婴幼儿奶粉电商消费研究的数据,在电商平台购买婴幼儿奶粉的消费者年均购买次数约为27次,“双十一”、“618”两个购物节是囤货高峰。
婴幼儿在0-1岁时,理论上一共需要81罐400g奶粉,假设用户除“双十一”、“618”外其他时间每次只购买1罐,那么两个购物节平均需要承担27罐奶粉,向上取整后,以单笔销量超过30罐奶粉作异常值处理。
df.drop(index=df[df['buy_mount']>30].index,inplace=True)
本次数据集,没有过程指标,结果指标只有销量一个。接下来的分析都将围绕销量情况如何,导致目前状况的原因是什么以及提升空间在什么地方进行分析。
通常我们会抛出这样的问题:现在的销量状况不好,要提高!!!(数据分析师日常用语)
在这个问题当中,有3个非常关键的词:现在、不好、高,分别对应了5w2h里面的when(需要分析的时间段),what(标准)以及How much(改进效果)
首先要确定的是经常会被混淆的名词/副词部分,即Who、Where、When部分。这里将时间范围锁定为2015年1月1日至2015年2月5日。
第二步就是要解决标准的问题。数据分析报告常常被批没屁用,缺乏标准是原罪。“环比下降3%”是日报和周报里面经常出现的废话之一(有被冒犯到,谢谢),但如果给3%加上一个标准或者业务含义,比如这周是双十一,但销量环比下降3%,就变成很严重的业务问题了。
因此,与利益相关人统一标准口径,对于数据分析至关重要,有了标准才能评判好坏优劣。在没有任何指标的情况下,可以采用趋势分析来确定指标,这里的标准定为当月同比增速必须高于上年同期同比增速或上年整体同比增速。
def YOY_2014(df):
df=df.groupby(pd.Grouper(key='day',freq='Y')).sum()
# .pct_change()常用于求同比增速度,默认向上一位找分母
# 相似的api还有.diff(),可以用于求相邻两项的差值
df['年同比增速']=df['buy_mount'].pct_change()
print(df['buy_mount'])
print(df['年同比增速'])
通过简单的计算,我们得知,2014年的同比增速为50.54%。那么这里可以把假定的问题翻译成具体的:2015年至今,销量同比增速低于目标的50.54%,需要将销量增速提至50.54%以上。
在准备这次分析的过程中,也研究了几份相同数据集不同分析角度的文章,其中一篇开头看到15年整体的销量断崖式下降后,在没有进一步锁定问题爆发的具体时间点的情况下,便假设是某个用户群体的复购下降而导致。结果分析一轮回到月的时间维度上,才发现是因为数据记录不全而导致的销量骤降,做了不少无用功。
多维度的分析,应该是一个金字塔式的分析路径:从一个维度的整体到局部,再引入另外一个维度的整体再到局部,而不是在多个维度间反复横跳。
初步规划的分析路径如下:
如果你按捺不住手中的ESP(Excel、SQL、Python)直奔2015年1-2月的数据,那么我只能说你只看到了第二层(老千层饼了)
观察上图,假设我们分析的目标时间段是e-f,两图的e-f都由15跌到13.5,但两种数据走势反映出的问题点是不一样的。左边是断崖式下降,要分析e-f之间出现了什么变化,而右边则是持续下降,只是e-f下降幅度较大,但关键的问题点在c-d-e。
因此先对整体数据的走势有了印象,才能更好地把握住问题的关键点,避免管中窥豹。
实现思路:
# 分组聚合+降采样方法一:
df=df.groupby(pd.Grouper(key='day', freq='m')).sum()
# 分组聚合+降采样方法二:
df_1=df.groupby('day').sum().resample('m').sum()
观察数据可知,14年的销量走势与13年类似,并没有出现持续性下降的问题,因此可以把分析聚焦到各年度的1-2月数据进行分析。
除了15年2月销量由于数据不全而出现骤降外,2013年的2月也同样出现了环比骤降的情况,第一反应是春节导致的下降。翻查13年-15年的春节(初一到初七)时间如下:
可以得知,15年的春节时间与13年类似,都是完整分布在2月,可初步推出,15年2月的销量数据应该与13年类似。如果把15年2月的目标定为同比增长50%显然不尽合理,因此我们将时间线修改为春节前30天。
调用往年春节前30日的销量情况,确认目前销量是否良好,并推测未来14日的走势如何,是否需要进一步准备推广计划。
实现思路:
def situation_2015_2(df):
df=df.groupby(by=pd.Grouper(key=('day'),freq='D')).sum()['buy_mount']
_y_2013=df['2013-1-10':'2013-2-15']
_y_2014=df['2014-1-1':'2014-2-6']
_y_2015=df['2015-1':'2015-2'][:-17:-1][::-1]
df_1=pd.DataFrame(
{
'2013':_y_2013[:16].sum(),
'2014':_y_2014[:16].sum(),
'2015':_y_2015.sum(),
}
)
df_1=pd.concat([df_1,df_1.pct_change(axis=1)])
由左图可以看到14年闰月初一到十五,同比增速为49.9%,而15年同时间段增速为43.2%,低于最低目标49.9%,销量状况不佳。
进一步计算2014年春节前30日的总销量为1057,同比增速57.06%,得到2015年春节前30日目标销量为1057*1.499=1584罐,而目前总销量为1080罐,还有504罐的缺口,平均每天36罐。
确定了现状及一级问题后,就要先着手分析问题的原因。但目前的问题是针对所有产品,人人都负责意味着没人负责,因此要进一步确认是那一条产品线出现问题。
观察可知,50008168大类(后称168大类)、50014815大类(后称815大类)都是销量在前茅但增长幅度都非常的低,是主要的问题点。而122650008大类(后称08大类)的增速接近目标值,且销量占比低,是次要的问题点。
这时候我们就可以拿着问题去跟这三条业务线相关负责人对线,把他们认为的原因作为新的假设,梳理成逻辑树的形式,再进行逐点通过分析数据验证,找到核心原因。这里的逻辑树采用营销中的两个经典模型:PEST和4P理论,但由于没有数据进一步支撑,不再进一步深挖原因。
在真实的商业场景中,我们可以根据上一步中找到的核心原因,再基于ROI(投入产出比)去作进一步的资源调配。但在这个案例当中,并没有更多的数据进行支撑,不过我们可以基于上一年的的数据,对今年未来14天的走势做基本预测,发掘可能挽救销售量的机会。
同样需要先了解整体销量走势,对比往年走势情况,才能预测出未来的销量走势会怎么样。
从往期销售曲线可以看到,接下来的销量会逐步下降,且年廿十开始,每日销量降至20以下。假设年廿四到年三十日均销量为15,那么接下来一周日均销量要达到57罐。因此,需要在接下来的一周之内,作出1-2轮的推广计划,年廿四或廿五作为保底冲刺节点。
确定了推广计划的时间节点后,再考虑资源如何分配到不同的大类进行推广。这里需要分开不同产品来看销售曲线。
实现思路:
def marketing_plan_2015(df):
df=df.groupby(by=[pd.Grouper(key=('day'),freq='D'),'cat1']).sum()['buy_mount']
# .unstack()方法将复合索引的series转化为dataframe
# 此方法也可以用于dataframe的行列转换
df_2013=df.loc['2013-1-10':'2013-2-15'].unstack()
df_2014=df.loc['2014-1-1':'2014-2-6'].unstack()
df_2015=df.loc['2015-1-21':].unstack()
查看以日维度的销量数据,波动幅度会非常大,我们要知其然,更要知其所以然。因此要与相关业务部门确认上年同期的详细推广时间、内容、渠道等数据,才能准确地判断出,是自然增长还是推广带来的增长,从而给出更贴合实际的建议。
每当作总结报告的时候,数分们都会焦头烂额地四处找模板来弥补建议空洞的窘境,核心的问题是仅站在统计学的角度去分析,就数论数,没有把业务含义和业务逻辑融入分析当中。只要分析过程中,进一步深挖数据的业务含义,总结与建议便是一件水到渠成的事,只需把分析过程的结论按一定逻辑框架展现出即可。
回顾整篇分析报告思路,有两点是突破结论只有环比下降3%的关键:
希望这篇文章能够给到正在为分析报告发愁的小伙伴一点启发。如果各位小伙伴有什么想法或者建议,欢迎在评论区留言~我是HeoiJin,我们下次分享再会。
完整代码及相关数据集:https://github.com/heoijin/BAproject
参考资料: