在线教育BD推广效果复盘分析

项目介绍

为了拓展高阶课的用户销量,目前通过BD与周边学校合作,开展四节体验课促销活动,并且会在第三节体验课后开展“高阶课程讲座”并开启高阶课的报名通道,目前项目已经完结,请根据已有的数据源分析并提出优化方案。

项目流程

  1. 用户行为路径轨迹
  • 1.1 分析一般在线产品用户行为路径,并结合真实体验过程,绘制流程图
  • 1.2 对数据源进行特征转换(将“是”,“否”转换为“1”,“0”),方便统计绘制漏斗图
  • 1.3 漏斗图绘制
  1. 案例复盘
  • 2.1 数据观察(去重、查看缺失值、查看数据大小及类型)
  • 2.2 清洗数据(清洗杂乱学校名称字段、拆分课程报名情况)
  • 2.3 数据合并(合并报名信息和上课情况表)
  • 2.4 数据分析(从用户路径、学校、年级、推广渠道等维度展开分析)

1.用户行为路径轨迹

1.1 用户路径

用户体验产品路径一般为:渠道曝光->产生兴趣->信息采集->体验->完成

由于本文仅针对BD推广后,通过注册app,绘制用户体验流程图如下:

1.2 特征转换

为了方便读取数据以及统计各阶段人数,将数据第三列之后根据是、否进行特征转换为1,0
读取原始数据

# 读取excel文件
# 查看excel文件表格
wb = openpyxl.load_workbook("数据.xlsx")
wb.sheetnames
# 读取数据
df2 = pd.read_excel("数据.xlsx",sheet_name="上课数据")

特征转换:

dic = {"是":1,"否":0}
i = 0
for index in df2.columns:
    i += 1
    if i > 3:
        df2[index] = df2[index].map(dic)

处理结果:
  • 文章一共有973条数据

1.3 绘制漏斗图

导入pyecharts绘制互动性可视化漏斗图

from pyecharts import options as opts
from pyecharts.charts import Funnel

c = ["总人数",'绑定微信','绑定手机号','添加老师','登录APP','第一节课完课',
     '第一节课作业完成','第二节课完课','第二节课作业完成', '第三节课完课','第三节课作业完成',
     '高阶课程点击数','高阶课程报名数','第四节课完课','第四节课作业完成']
c1 = [df2.ID.count(),df2["绑定微信"].sum(),df2["绑定手机"].sum(),df2["添加老师"].sum(),df2["登录APP"].sum(),
      df2["第一节课是否完课"].sum() , df2["第一节课是否完成作业"].sum(),df2["第二节课是否完课"].sum() , df2["第二节课是否完成作业"].sum(),
      df2["第三节课是否完课"].sum() , df2["第三节课是否完成作业"].sum(),df2["高阶课报名情况"].value_counts()["点击未报名"],df2["高阶课报名情况"].value_counts()["点击已报名"],
      df2["第四节课是否完课"].sum() , df2["第四节课是否完成作业"].sum()]
c1 = [round(int(i)/973*100,2) for i in c1]
c = (
    Funnel()
    .add(
        "转换率",
        [list(z) for z in zip(c,c1)],
        sort_="none",
        label_opts=opts.LabelOpts(is_show=True, position="inside"),
        tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b} : {c}%"),
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="流程转化",subtitle="计算方式:人数/总人数"),
                    legend_opts=opts.LegendOpts(pos_left='right',pos_top="90%"))

)
c.render_notebook()

2. 案例复盘

2.1 观察数据

检验缺失值:df1.info()
去重:df1.drop_duplicates()

# 检查是否缺失
df1.info()
# 判断是否有重复值
df1 = df1.drop_duplicates("id")

结果:删除2条重复字段后,共有968条数据,无缺失值

2.2 字段清洗

由于表单为自主填写,存在许多杂乱数据,需要进行清洗区分
2.2.1 学校字段:

df1.学校.unique()

经由业务部门沟通,先将学校分为以下7所:

  • 邳州春田花花实验小学
  • 十堰东风八零学校
  • 北大附属西瓜小学
  • 简阳春田花花小学
  • 三亚第九小学
  • 郑州第九十八中小学
  • 肇庆第九小学
    以下字段出现混淆:
  • 【江苏邳州市春田花花、】【简阳市春田花花小学】以及【春田花花小学】
  • 【三亚第九小学】、【肇庆第九小学】以及【第九小学】
    在数据清洗中,由于数据维度不够,将春田花花实验小学划为江苏邳州春田花花实验小学 ,不包含实验小学字样的划成简阳市春田花花小学。
    将包含三亚的统一划为三亚第九小学 , 不包含三亚但是包含九小的划为肇庆市第九小学
def clean_school(b):
    matchObj_baling = re.search( r'八零', b, re.M|re.I)
    matchObj_xigua = re.search( r'西瓜', b, re.M|re.I)
    matchObj_jiushiba = re.search( r'九十八', b, re.M|re.I)
    matchObj_sanya = re.search( r'三亚', b, re.M|re.I)
    matchObj_shiyan = re.search( r'实', b, re.M|re.I)
    matchObj_chuntian = re.search( r'春田花花', b, re.M|re.I)
    matchObj_jiuxiao = re.search( r'九小', b, re.M|re.I)
    
    if matchObj_baling:
        b = '湖北省十堰市东风八零学校'
    elif matchObj_xigua:
        b = '北大西瓜小学'
    elif matchObj_jiushiba:
        b = '郑州市第九十八中小学部'
    elif matchObj_sanya:
        b = '三亚市第九小学'
    elif matchObj_shiyan:
        b = '邳州市春田花花实验小学'
    elif matchObj_shiyan == None and matchObj_chuntian:  # 如果“邳州市春田花花实验小学”匹配失败,则进行简阳春天花花匹配
        b = '简阳市春田花花小学'
    elif matchObj_sanya == None and matchObj_jiuxiao:
        b = '肇庆市第九小学'
    return b
# 清洗
df1["学校"] = df1['学校'].map(clean_school)


2.2.2 其他字段

df1["年级"].unique()
df1["班级"].unique()
df1["三级渠道"].unique()
df2.高阶课报名情况.value_counts()
  • 根据显示结果,发现均无异常字段,无需清洗

2.2.3 字段拆分


高阶课报名情况中,存在三种数据,“未点击进入”,“点击未报名”,“点击已报名”,为方便区分,利用pd.get_dummies将三种数据进行特征提取。

df2 = pd.concat([df2,pd.get_dummies(df2["高阶课报名情况"])],axis=1)
df2.drop("高阶课报名情况",axis = 1,inplace = True)
2.3 数据合并

将用户来源及信息表与用户上课信息表通过"ID"合并

  • 注意:用户来源表中字段名称为“id”,上课信息表中字段名称为“ID”
data = pd.merge(df1,df2,left_on="id",right_on="ID")
# 空值检查
data.isnull().sum().sum()
# 删除多余字段
data.drop(["ID","电话号码","序号"],axis = 1,inplace = True)
2.4 数据分析

2.4.1 漏斗图绘制
参照开始流程,使用pyecharts进行漏斗图绘制

from pyecharts import options as opts
from pyecharts.charts import Funnel

c = ["总人数",'绑定微信','绑定手机号','添加老师','登录APP','第一节课完课',
     '第一节课作业完成','第二节课完课','第二节课作业完成', '第三节课完课','第三节课作业完成',
     '高阶课程点击数','高阶课程报名数','第四节课完课','第四节课作业完成']
c1 = [df2.ID.count(),df2["绑定微信"].sum(),df2["绑定手机"].sum(),df2["添加老师"].sum(),df2["登录APP"].sum(),
      df2["第一节课是否完课"].sum() , df2["第一节课是否完成作业"].sum(),df2["第二节课是否完课"].sum() , df2["第二节课是否完成作业"].sum(),
      df2["第三节课是否完课"].sum() , df2["第三节课是否完成作业"].sum(),df2["点击未报名"].sum(),df2["点击已报名"].sum(),
      df2["第四节课是否完课"].sum() , df2["第四节课是否完成作业"].sum()]
c1 = [round(int(i)/973*100,2) for i in c1]
c = (
    Funnel()
    .add(
        "转换率",
        [list(z) for z in zip(c,c1)],
        sort_="none",
        label_opts=opts.LabelOpts(is_show=True, position="inside"),
        tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b} : {c}%"),
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="流程转化",subtitle="计算方式:人数/总人数"),
                    legend_opts=opts.LegendOpts(pos_left='right',pos_top="90%"))

)
c.render_notebook()


结果:

  • 从漏斗图得知,整体符合流程转换规则,不过登录APP到第一节课完课转换率较低
  • 但在第四节课完课处开始出现异常,第四节课完课率比高阶课程报名数还要高,根据用户链路,没有报名的用户是不能开始第四节课的,这里可能出现数据错误,需要相关部门进行检查重新埋点
  • 第二节课、第三节课作业完成率均比相应完课率较高,一部分同学没有听课直接做作业,推测可能是难度较低,可以适当提升难度
  • 转换率在报名处最低,符合规则,但同样,需要调研用户原因,查看是什么原因导致报名数较低,价格原因还是其他原因

2.4.2 多维度统计分析
(1)整体:


(2)学校

grouped_school = data.groupby("学校").count()["id"].reset_index()
# 绘图
bar = (Bar()
      .add_xaxis(list(grouped_school.学校))
      .add_yaxis("参与人数",[int(i) for i in grouped_school.id.values])
      .set_global_opts(title_opts=opts.TitleOpts(title = "各学校参与人数"),
                      xaxis_opts=opts.AxisOpts(name = "学校",axislabel_opts=opts.LabelOpts(rotate = 20)))
      )
bar.render_notebook()
  • 春田花花实验小学人数最多,东风八零次之
    (3)三级渠道
grouped_bd_sc = data.groupby(["三级渠道","学校"]).count()["id"].reset_index()

数据导入PowerBI绘制桑基图
  • 主要渠道来源为周氏集团、武汉力公司、每日优鲜效果最好,河南公司和科技公司最次;
  • 其中周氏集团和每日优鲜能够覆盖两所学校;
  • 东风八零学校、春田花花实验学校的生源最多。

(4)年级与完课率

grouped_nianji = pd.concat([data.groupby("年级").sum().iloc[:,5:9],data.groupby("年级").sum()["点击已报名"]],axis = 1)
# 绘图
bar = (Bar()
      .add_xaxis(grouped_nianji.columns.tolist())
      .add_yaxis("幼儿园小班", grouped_nianji.loc['幼儿园小班'].tolist(), stack="stack1")
      .add_yaxis("小学一年级", grouped_nianji.loc['小学一年级'].tolist(), stack="stack1")
      .add_yaxis("小学二年级", grouped_nianji.loc['小学二年级'].tolist(), stack="stack1")
      .add_yaxis("小学三年级", grouped_nianji.loc['小学三年级'].tolist(), stack="stack1")
      .add_yaxis("小学四年级", grouped_nianji.loc['小学四年级'].tolist(), stack="stack1")
      .add_yaxis("小学五年级", grouped_nianji.loc['小学五年级'].tolist(), stack="stack1")
      .add_yaxis("小学六年级", grouped_nianji.loc['小学六年级'].tolist(), stack="stack1")
      .add_yaxis("初中一年级",grouped_nianji.loc['初中一年级'].tolist(), stack="stack1")
       .set_series_opts(label_opts=opts.LabelOpts(is_show=False),
                    axis_opts = opts.AxisOpts(
                        interval = None,
                        
                    ),
                    )
    .set_global_opts(title_opts=opts.TitleOpts(title="完\n成\n课\n程\n及\n作\n业\n学\n员\n年\n级\n分\n布"
                    ,padding = [150,100,5,10]),
                     xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
      )
      )
bar.render_notebook()
  • 每节课均是小学五年级占比最多,其次是小学三年级、小学四年级
  • 幼儿园以及小学五年级以上,几乎没有人参与活动以及报名,推测可能是没有向这些年级的学生推广(幼儿园太小、六年级学生太忙等等)

2.4.3 特征工程处理
使用sklearn对于学校、年级、三级渠道字段进行特征处理,将至转换为数值型

from sklearn.preprocessing import LabelEncoder 
le = LabelEncoder()
data['学校'] = le.fit_transform(data['学校'])
data['年级'] = le.fit_transform(data['年级'])
data['三级渠道'] = le.fit_transform(data['三级渠道'])


正相关部分:第三节课是否完成作业与第四节课是否完成作业表现出强相关 ,高达0.87。第一次课程到第四次课程,可以看出他们关联性较大,可谓是环环相扣,呈现出了方块形状。
负相关部分:学校与三级渠道达到-0.35。

结论:

  • 从登录APP到第一节课完课 ,用户流失较严重,需要对该部分用户进行调研 ,看是难度太大还是课程不能引起他们的兴趣。

  • 第三节课作业完成到高阶课程报名这一过程 , 也出现数据异常,占比从60.8%下降到8%,但是第四节课的作业完成率与第四节课作业完成率都达到了百分之五十,甚至作业完成率高于完课率,这里要和产品部门沟通,对这里的用户浏览轨迹进行专项复盘,是不是数据埋点需要重新进行设计。

  • 完成作业及课程的学员大多分布在小学三、四、五年级,幼儿园及小学六年级、初中一年级几乎没有,根据二八法则,建议花更多时间在小学三四五年级身上,进行高阶课程拓展。

  • 逆转集团、河南公司、科技公司的投放效果有限,周氏集团与每日优鲜的覆盖效果较好,可以覆盖两个学校。建议后期选择周氏集团与每日优鲜。

  • 根据真实体验情况,建议相关助教部门将发出的大量网址链接及视频教程,以小程序或者H5表单形式呈现,以及视频添加相关视频说明。减少一般用户对网址链接的抗拒感,增加品牌认知度。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容