教育平台的线上课程数据分析

一、项目背景

在线教育一般指基于互联网的线上学习行为,与传统的线下教育机构、培训班、学校相比,在线教育在时间空间上有很多优势。
近年来,随着互联网与通信技术的高速发展,各种在线教育平台和学习应用纷纷涌现,各种网课、慕课、直播课等层出不穷。尤其是 2020 年春季学期,受新冠疫情影响,在教育部**“停课不停学”** 的要求下,网络平台成为“互联网+教育”成果的重要展示阵地
因此, 如何根据教育平台的线上用户信息和学习信息,通过数据分析为教育平台和用户提供精准的课程推荐服务就成为线上教育的热点问题。本项目从数据集给出字段出发,围绕用户登录注册→开始试听课程,免费试学→试听后开始付费学习→结束课程学习→推荐其他课程的完整业务流程,深入到各个阶段,通过数据分析为产品部门、运营部门提供可落地的建议,赋能业务增长。

二、分析目标

  • 用户登录注册阶段:
    分析平台用户活跃情况,地域分布以及登录时间统计;
  • 免费试学阶段:
    用户学习行为路径进行漏斗分析,计算各阶段转化率
    分析拉新效果,计算拉新购课转化率;
  • 付费上课学习阶段:
    用户付费行为分析,计算月度ARPUARPPU
    分析用户学习时长,查看学习时长分布;
  • 课程结束阶段:
    计算每门课程结课率,查看课程完成情况;
    计算课程受欢迎程度,找到最受欢迎的课程TOP10
  • 构建RFM模型,实现用户精细化运营
  • 分析用户流失情况,计算流失率
  • 课程推荐阶段:
    协同过滤算法进行线上课程智能推荐

三、数据探索与预处理

3.1 字段解释


用户信息表

users_data = pd.read_csv('./users.csv',encoding='gbk')
users_data.head()


学习信息表

study_information_data = pd.read_csv('./study_information.csv',encoding='gbk')
study_information_data.head()


登录信息表

login_data = pd.read_csv('./login.csv',encoding='gbk')
login_data.head()

3.2 缺失值处理

  • 用户信息表
# 查看数据的简要信息
users_data.info()

user_id字段和school字段均有缺失值,缺失用户占比少,故直接舍弃;school字段也有缺失值,但是该字段意义不大,故不做处理

users_data.isnull().sum()  #查看缺失值个数
#统计缺失值占比
print(users_data['user_id'].isnull().sum()/users_data.shape[0])

#缺失用户占比少,故直接舍弃;school字段也有缺失值,但是该字段意义不大,故不做处理
users_data.dropna(subset=['user_id'],axis= 0 ,inplace = True)
users_data.shape  #处理后数据大小
# (43916, 7)
  • 学习信息表
study_information_data.info()

price价格字段有缺失值,但缺失数据比较少,直接用0值进行填充

# 用0值进行填充
study_information_data['price'].fillna(0,inplace= True)
  • 登录信息表
login_data.info()

登录信息表无缺失值

3.3 重复值处理

#用户信息表
users_data.duplicated().sum()
#删去重复值
users_data.drop_duplicates('user_id',inplace= True)
# 学习详情表
study_information_data.duplicated().sum()

结果为0

#登录详情表
login_data.duplicated().sum()

结果为0

3.4 异常值处理

users_data数据中 recently_logged 字段存在异常值“–-”,该数据可能为缺失值,也可能是用户注册后不再进行登录,结合后续分析与study_information表格进行联结,对“–”进行分类处理。
对于在 study_information 中出现的选课信息的用户,采用其选课的最后时间来替换“–”;剩余的“–”异常值用注册时间来替换。

users_data[users_data['recently_logged']=='--'].info()

有5375个异常数据

#将course_join_time列进行日期转换
pd.to_datetime(study_information_data['course_join_time'])#找到每个用户加入课程的最近时间
users_recently_select = study_information_data.groupby('user_id')['course_join_time'].max()# 将加入课程最近时间与主表连接
users_study_information =  pd.merge(users_data,users_recently_select,on='user_id',how='left')# 新增course_join_time应与recently_join_time同类型
users_study_information['course_join_time'] = users_study_information['course_join_time'].astype(str)#将'--'填充为最近加入课程的时间
users_study_information['recently_logged'] = users_study_information[['recently_logged','course_join_time']].apply(lambda row:row['course_join_time'] if row['recently_logged']=='--' else row['recently_logged'],axis=1)#检查是否填充成功
users_study_information[users_study_information['recently_logged']=='--'].count()

四、 用户登录阶段

4.1 用户地域分布分析

对用户的登录信息,尤其是地理位置信息的分析,能够帮助我们了解使用我们产品的用户集中分布在哪些省份、哪些城市,为运营部门指定推广计划,进行广告精准投放指明方向。

# 构建省份变量
province = ['新疆','西藏', '青海', '甘肃', '四川','云南','宁夏','内蒙古','黑龙江','吉林','辽宁','河北','北京','天津','陕西','山西','山东','河南','重庆','湖北','安徽','江苏','上海','贵州','广西', '湖南', '江西', '浙江', '福建','广东', '海南','台湾','澳门', '香港']def get_provice(x):'''提取省份数据param x:用户登录地址'''for i in province:if i in x:return i
#调用函数提取省份
login_data['province'] = login_data['login_place'].apply(get_provice)
login_data['province'].head()

#查看省份缺失数据占原始数据的比重
len1 = login_data['province'].isnull().sum()
len2 = login_data.shape[0]
print('省份缺失数据占原始数据的比重:',len1/len2)

# 构建城市变量
def get_city(x):'''提取城市数据param x:用户登录地址'''# 两个特殊的三个字符的省份if (x[2:5]=='黑龙江') or (x[2:5]=='内蒙古'):return x[5:]else:return x[4:]
login_data['city'] = login_data['login_place'].apply(get_city)
login_data['city']

#将直辖市与行政区的省份名与城市名进行替换
ind = login_data['province'].str.contains('北京|上海|重庆|天津|澳门|香港')
login_data.loc[ind,'city'] = login_data.loc[ind,'province']
#查看城市空数据占原始数据的比重
len1 = (login_data['city']=='').sum()
len2 = login_data.shape[0]
print('城市缺失数据占原始数据的比重:',len1/len2)

城市缺失数据占原始数据的比重: 0.17364718657505146

# 将省份字段后加上省/市字段
def province(province):provinces = ["北京市", "天津市", "河北省", "山西省", "内蒙古自治区", "辽宁省", "吉林省", "黑龙江省", "上海市", "江苏省", "浙江省", "安徽省", "福建省", "江西省","山东省", "河南省", "湖北省", "湖南省", "广东省", "广西壮族自治区", "海南省", "重庆市", "四川省", "贵州省", "云南省", "西藏自治区", "陕西省", "甘肃省","青海省", "宁夏回族自治区", "新疆维吾尔自治区", "台湾省", "香港特别行政区", "澳门特别行政区"]for p in provinces:if province in p:return pbreak
​
login_data['province'] = login_data['province'].apply(province)
# 统计各省份的平台登录次数
pro_count = login_data['province'].value_counts()
# 绘图
(Map()   #实例化类.add(series_name='',data_pair=[(i,j)for i,j in zip(pro_count.index,pro_count)])    #添加数据,series_name系列名称.set_global_opts(visualmap_opts=opts.VisualMapOpts(max_=20000),title_opts = opts.TitleOpts('各省份登录次数热力图'))    #视觉配置项
).render_notebook()    #图表显示

从图中可以看出,红色区域的广东省、贵州省、湖北省和湖南省是用户登录最密集的省份。

# 统计各城市的平台登录次数
city_count = login_data['city'].value_counts()
# 绘图
geo = Geo()  #实例化类
geo.add_schema(maptype='china')   # 选择地图类型
for i in range(len(city_count)):try:geo.add(series_name='',data_pair=[(city_count.index.tolist()[i],city_count.tolist()[i])],symbol_size =7)except:pass   #忽略错误geo.set_global_opts(visualmap_opts=opts.VisualMapOpts(max_=3000),title_opts = opts.TitleOpts('各城市登录次数热力图'))    #视觉配置项
geo.set_series_opts(label_opts = opts.LabelOpts(is_show=False))   #设置不显示标签
geo.render_notebook()  #图标显示


对用户登录次数最多的四个省份分析各个城市的登录情况,如下图所示:

4.2 用户登录时间分布

对用户登录时间的分析能够帮助我们了解到工作日与非工作日一天各个时间段用户出现的频率,方便安排课程直播上课时间,满足不部分用户的时间需求。

# 对登录时间转换成日期格式
login_data.loc[:,'login_time'] = pd.to_datetime(login_data.loc[:,'login_time'].astype(str), format='%Y-%m-%d %H:%M')
#创建一列登录日期列,计算消费时间是星期几,Monday是1,Sunday是7
login_data['login_week'] = login_data['login_time'].dt.dayofweek + 1
login_data.head()
user_id login_time  login_place province    city    login_week

# 以周一至周五为工作日,周六日作为非工作日,拆分为两组数据
work_day_data = login_data[login_data['login_week']<=5]
unwork_day_data = login_data[login_data['login_week']>5]
#计算工作日消费时间对应的各时间的登录次数
work_day_times = []
for i in range(24):work_day_times.append(work_day_data['login_time'].apply(str).str.contains(' {:02d}:'.format(i)).sum())
# 计算非工作日消费时间对应的各时间的登录次数
unwork_day_times = []
for i in range(24):unwork_day_times.append(unwork_day_data['login_time'].apply(str).str.contains(' {:02d}:'.format(i)).sum())


可以看到

  • 工作日与非工作日用户的登录时间段整体分布大致契合;
  • 工作日登录高峰出现在上午10点,非工作日除了上午10点,在下午3点,晚上8点也出现了小高峰,原因是休息日大家的时间较工作日更加灵活。

4.3 每月活跃用户情况

考虑到有些课程是周期性,有季节的需求,比如说求职课程,在金三银四,金九银十的月份会备受关注,因此分析各个月份的用户活跃情况是十分必要的。

# 查看每月用户的活跃数
#提取月份
users_study_information['month'] = pd.to_datetime(users_study_information['recently_logged']).dt.month
#按月份分组求和
month_count = users_study_information.groupby('month')[['user_id']].count()
df_12 = {"月份":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",],"用户访问数":[1451,3638,6038,8095,5683,4868,1056,1099,1308,2233,1756,1313]}
df_12_table  = pd.DataFrame(df_12)#转换为表格
df_12_table.head()


可以看到

  • 用户在4月份登录量达到了峰值,并且上半年的登录情况要比下半年整体要好,推测原因可能是上半年广告推广更多,达到了今年的目标,下半年在推广方面有所懈怠。

五、 免费试学阶段

通过计算从用户登录注册→开始试听课程,免费试学→试听后开始付费学习→结束课程学习的各阶段的转化率,能够及时发现哪个环节出现了问题,从而精准定位需要重点优化的环节。

5.1 用户学习行为漏斗分析

# 对learn_process列进行处理
study_information_data['learn_process'] = study_information_data['learn_process'].apply(lambda x:int(x.split(':')[1].split('%')[0]))
# 1.注册用户数
register_num  = users_data['user_id'].count()
register_num

43716

# 2.加入课程学生人数
course_join_num = len(study_information_data['user_id'].unique())
course_join_num

40807

# 3. 开始学习学生人数
course_start_num = len(study_information_data[study_information_data['learn_process']>0]['user_id'].unique())
course_start_num

27605

# 4. 结课学生人数
course_finish_num = len(study_information_data[study_information_data['learn_process']>90]['user_id'].unique())
course_finish_num

8798

可以看到

  • 用户注册到点击课程,用户的课程点击率为92%,平台课程种类能够很好的覆盖多样的用户,吸引用户进入课程学习
  • 从点入课程到没有跳出,课程的点进率为68%,课程内容能够留存超过半数的用户
  • 完整看完课程的结课率为32%,用户流失较为严重,因为在线教育获客成本相对较高,而获客之后的老用户的再次购买也较多,因此要想办法加强用户粘性。影响结课的因素不仅与课程本身有关,可以增加一些陪伴学习打卡等运营活动等等避免用户流失

5.2 试听课程转化率分析

教育平台为了激发用户兴趣,会有课程拉新活动,推出一些免费的试听课程,便于用户了解授课教师授课方式以及课程大纲。拉新客户引流来的新用户能都在试学阶段结束后,产生购课行为是衡量拉新效果的重要指标。

# 拉新人数:参与免费课程的用户数
user_new = len(study_information_data[study_information_data['price']==0]['user_id'].unique())
user_new

32930

# 参加免费课程又参加其他课程并付费的人数
data1 = study_information_data[study_information_data['price']==0]
data2 = pd.merge(study_information_data,data1,on='user_id',how='inner')
data3 = data2.groupby('user_id')['price_x'].sum()
data3 = pd.DataFrame({'user_id':data3.index,'price_sum':data3.values})
user_pay = data3[data3['price_sum']>0].count()[0]
user_pay

9686

# 转化率
rate = user_pay/user_new
rate

0.29413908290312785

可以看到

  • 拉新转化率为30%,用户参与免费课程后又对其他课程进行购买,说明用户建立了与平台的信任关系。

六、付费上课阶段

用户在试听课程之后,进而选择感兴趣的课程进一步学习,ARPU是每用户平均收入,能看出所有用户为课程创造的收入,是评估课程变现有效性的指标,ARPU越高,就代表用户在这段时间内为课程带来的变现收入就越多。
ARPPU考核的是某时间段内平均每个付费用户为课程创造的收入,能够反映付费用户为课程带来了多少收益,显示出一个忠诚付费用户实际上愿意支付的金额。

6.1 用户付费行为分析

# 将提取月份信息
study_information_data['min_course_join_time'] = study_information_data['course_join_time'].apply(lambda x:x[0:7])
def distinct_num(x):return len(x.unique())
# 按月份统计所有用户的信息
all_user = study_information_data.groupby('min_course_join_time').agg({'user_id':distinct_num,'price':'sum'})
all_user['ARPU'] = all_user['price']/all_user['user_id']
all_user.head()

# 筛选出有付费行为的用户数据
pay_user = study_information_data.groupby('user_id')['price'].sum()
pay_user = pd.DataFrame({'user_id':pay_user.index,'price_sum':pay_user.values})
pay_user = pay_user[pay_user['price_sum']>0]
# 按月份统计付费用户的信息
pay_user =  pd.merge(pay_user,study_information_data,on='user_id',how='left')
pay_user = pay_user.groupby('min_course_join_time').agg({'user_id':distinct_num,'price':'sum'})
pay_user['ARPPU'] = pay_user['price']/pay_user['user_id']
pay_user.head()


可以看到

  • ARPPU显著高于ARPU,说明课程还是存在大量的流量,获客率仍有提升的空间;
  • ARPU和ARPPU从2019年12月份开始上涨,在2020年4月份达到了最高峰,这段时间正好是新冠疫情刚刚爆发的时间点,这也印证了疫情影响给教育行业带来了红利。

6.2 用户学习时长分析

用户在平台上学习课程的时长侧面反映了课程的质量,对用户的吸引力,好的课程应该引起用户继续学习的兴趣。

def convert_func(x):if x.find(',')== 1:return x.replace(',','')elif x.find(',') == 2:return x.replace(',','')else:return x
users_data['learn_time'] = users_data['learn_time'].apply(lambda x:convert_func(x))
users_data['learn_time'] = users_data['learn_time'].astype('float')
learn_time = users_data.groupby('user_id')['learn_time'].sum()
learn_time = pd.DataFrame({'user_id':learn_time.index,'learn_time_sum':learn_time.values})
learn_time

learn_time['learn_time_sum'].quantile([0.25,0.5,0.75,0.9])

count_0 = learn_time[learn_time['learn_time_sum']==0].count()[0]
count_0

10961

count_1 = learn_time[(learn_time['learn_time_sum']> 0) &(learn_time['learn_time_sum']<= 30)].count()[0]
count_1

10542

count_2 = learn_time[(learn_time['learn_time_sum']> 30) &(learn_time['learn_time_sum']<= 480)].count()[0]
count_2

11338

count_3 = learn_time[(learn_time['learn_time_sum']> 480) &(learn_time['learn_time_sum']<=1920 )].count()[0]
count_3

6465

count_4 = learn_time[learn_time['learn_time_sum']>1920].count()[0]
count_4

4410

可以看到

  • 有一部分用户的学习时长为0,分析这部分用户应该只是看到了免费课程,点击进去,但是并没有继续观看,这部分用户没有引流成功;
  • 观看时长在半小时以内的客户也占了不小的比例,说明用户并没有对课程产生兴趣,可以对这些学习时长较少的用户发信息或者打电话调研;

七、结课阶段

7.1 课程结课率分析

结课率这个指标通常用于录播课程,可以衡量在线教育平台的教学质量,结课率较高代表课程质量较高,可以吸引用户完成课程的学习。

# 按照课程列对用户进行分组统计
course_join_number =  study_information_data.groupby('course_id')['user_id'].count()
course_join_number = pd.DataFrame({'course_id':course_join_number.index,'join_num':course_join_number.values})

course_finish_num = study_information_data[study_information_data['learn_process']>90].groupby('course_id')['user_id'].count()
course_finish_num = pd.DataFrame({'course_id':course_finish_num.index,'finish_num':course_finish_num.values})

# 联结连两个表
data =  pd.merge(course_join_number,course_finish_num,on='course_id',how='left')
# 对空值字段用0填充
data['finish_num'] = data['finish_num'].replace(np.NaN,0)
data['rate'] = data['finish_num']/data['join_num']
data = data[data['rate']>0]
data.head()


可以看到

  • 教育平台目前一共有164门在线课程,课程完成率过渡到20%是一个艰难的过程,需要对这部分学生建立学生画像分析他们不再学习的原因;
  • 结课率超过50%的课程一共有19门,其中结课率最高的一门课程是课程89,可以着重分析这门课程完成率较高的原因,例如老师的授课方式、课程讲解内容等方面,对其他课程进行优化。

7.2 最受欢迎的课程统计

找到最受欢迎的课程,可以分析这些课程的模式,有哪些共同点,方便进行课程统计。

# 统计每门课程的参与人数
course_count = study_information_data['course_id'].value_counts()
# 平台上所有课程中参与人数最多/最少的课程所对应的人数
course_count_max = course_count.max()
course_count_min = course_count.min()
# 计算每门课程受欢迎程度
course_pop = course_count.apply(lambda x:(x-course_count_min)/(course_count_max-course_count_min))
​
# 最受欢迎的前10门课程
course_pop_top10 = course_pop.sort_values(ascending = False)[:10]
course_pop_top10

八、用户精细化运营

用户精细化运营通过深入了解用户的行为、需求和习惯,将其划分成不同的类别和群体,有针对地进行营销。对于在线教育行业,可以通过用户的购课种类,频次和金额等信息分为不同的类别,然后针对不同的用户特点进行阶段性用户服务,如发放优惠券、精准推荐课程,提供定制化服务

  1. 对R、F、M进行定义
  • R(Recency):某用户最近一次消费距离2020-07-01日的天数;
  • F(Frequency):某用户在平台购课次数;
  • M(Money):某用户在平台的消费金额
  1. 统计R、F、M值
study_information_data.head()
data = pd.read_excel('./RFM_data.xls')
data.head()

  1. 给R、F、M值进行打分
  • R值打分:一般来说,用户在3天内发生购买,课程上新周期为2周左右,课程一般在45天内更新完毕,授课周期是3-4个月,以这几个时间作为节点。
  • F值打分:数据最小值是1,中位数为1,将最少消费一次作为一个节点;全平台用户平均数是5,这是一个节点;根据二八法则,20%的用户提供80%的利润,80%分位数的用户订单数是6单,这是最后一个节点。
data['purchase_num'].describe()

data['purchase_num'].quantile(0.8)

  • M值打分:中位数是0,即免费试听用户占到了一半以上,因此选择40%,60%,80%分位数分值。
data['purchase_money'].describe()

data['purchase_money'].quantile([0.4,0.6,0.8])


综上,打分规则如下:

# 给diff_time最近一次上课时间打分
def func1(x):if x <= 34:return 4 elif x>34 and x<=62 :return 3elif x>62 and x<128:return 2else:return 1
​
data['R分'] = data['diff_time'].apply(lambda x:func1(x))
# 给purchase_num购课次数打分
def func2(x):if x >6:return 4 elif x>5 and x<=6 :return 3elif x>1 and x<=5:return 2else:return 1
data['F分'] = data['purchase_num'].apply(lambda x:func2(x))
# 给purchase_miney购课金额打分
def func3(x):if x >1096:return 4 elif x>109 and x<=1096 :return 3elif x>0 and x<=109:return 2else:return 1 data['M分'] = data['purchase_money'].apply(lambda x:func2(x))
data.head()

打分结果如下:

  1. 用户细分
# 根据RFM打分值计算均值,高于均值为“高”,记为1,低于均值为低,记为“0”
R_mean = data['R分'].mean()
F_mean = data['F分'].mean()
M_mean = data['M分'].mean()
​
data['R'] =  data['R分'].apply(lambda x: 1 if x>R_mean else 0)
data['F'] =  data['F分'].apply(lambda x: 1 if x>F_mean else 0)
data['M'] =  data['M分'].apply(lambda x: 1 if x>M_mean else 0)
data.head()

data['R'] = data['R'].astype('str')
data['F'] = data['F'].astype('str')
data['M'] = data['M'].astype('str')
data['Label'] = data['R'].str.cat(data['F']).str.cat(data['M'])
# 用户细分规则
def label(x):d = {'111':'重要价值客户','011':'重要保持客户','101':'重要发展客户','001':'重要挽留用户','110':'潜力用户','100':'新用户','010':'一般维持用户','000':'流失用户'}return d[x]
​
data['Label'] = data['Label'].map(label)
data.head()


可以看到

  • 流失用户最多,新客数量相对较低,需要对流失用户进行分析,提高课程试听的转化率和吸引力;
  • 重要价值客户和重要发展客户数量较多,重要挽留客户较少,说明老客户对课程的认可度较高,有一定的客户粘性。

通过分类后,每个用户都有其对应的价值标签,这就可以针对不同的用户指定不同的运营策略。具体的策略描述如下:

  • 重要价值客户:投入更多资源做好个性化推荐服务VIP专享服务等,增加续费率和更多销售机会;
  • 重要发展客户:消费频次少,因此推荐多样性的课程,提高消费频率;
  • 重要保持客户:消费时间间隔久,课程顾问老师要加强联系增加用户粘性
  • 重要挽留客户:消费金额很高,但是消费时间间隔久,频次低,课程顾问老师要加强联系,推荐高价值的课程,提高留存
  • 潜力客户:推荐性价比高的课程,促进购买;
  • 新客户:采取学习打卡留言评论积分等学习陪伴服务,保持用户活跃促进购课;
  • 一般保持客户:发放一定的优惠券等,保持用户对平台的关注
  • 流失客户:采取信息推送电话回访等低成本的用户维护手段与用户保持接触,询问用户离开平台原因,进而改进。

九、 流失用户分析

用户最后一次登录的时间距离当前分析日的时间越久,用户越有可能流失。通过挖掘数据,追踪流失用户的流失原因,能帮助我们发现产品存在的问题,进而优化产品挽留客户

#计算最后登录时间与截止时间的时间差
# 截至日期
end_day = '2020-07-01 23:00:00'users_study_information['diff_day'] = (pd.to_datetime(end_day) - pd.to_datetime(users_study_information['recently_logged'])).dt.days
users_study_information['diff_day']

# 总登录人数
login_sum = users_study_information.shape[0]
login_sum

43908

# 查看用户流失人数,未访问天数>90 ==> 流失
loss_users = users_study_information.loc[users_study_information['diff_day']>90]
loss_users_num = loss_users.shape[0]
loss_users_num

27465

# 用户流失率=总流失用户数/总用户数
loss_users_rate = loss_users_num/login_sum
loss_users_rate

0.6255124350915551

可以看到,流失用户的比例高达60%,说明有大部分用户长时间没有登录学习,查看这些用户情况,看这些用户是参加课程后流失的,还是没有加入过课程。


流失用户中,未参加过课程的人数占大多数,分析这部分用户的学习时长记录,学习时长能反映出用户对平台上课程的感兴趣程度。

# 查看没参加课程的用户是否有学习记录
loss_users_learn_time = loss_users[loss_users['number_of_classes_join']==0]
loss_users_learn_time.describe()

可以看出

  • 未参加课程的人里至少有50%的人数学习时长少于10分钟,说明用户并没有对课程产生兴趣,没有继续学习。
# 查看参加了课程还是流失的用户比例
loss_join_rate = loss_users_join_class_num/loss_users.shape[0]
loss_join_rate

0.19206262515929365

# 查看退出课程的人数比例
loss_users_out_class = loss_users[loss_users['number_of_classes_out'] > 0]
loss_users_out_class_num = loss_users_out_class.shape[0]
loss_users_out_class_num

262

# 查看参加课程后退出的人数比例
loss_out_rate = loss_users_out_class_num/loss_users_join_class_num
loss_out_rate

0.04966824644549763

可以看到

  • 有将近5%的用户在加入班级后退出了班级,一般来说,学员不会主动退班级,这种情况可以视为用户不满意课程,进行了退课操作。

十、课程智能推荐

协同过滤算法,是基于用户的协同过滤推荐和基于物品的协调过滤推荐。首先需要收集好用户的偏好,再找到相似的用户或物品,最后进行推荐。

基于用户的协同过滤算法:该算法是通过用户的历史行为数据发现用户对商品或内容的喜欢〈如商品购买,收藏,内容评论或分享),并对这些喜好进行度量和打分。根据不同用户对相同商品或内容的态度和偏好程度计算用户之间的关系。在有相同喜好的用户间进行商品推荐。

基于物品的协同过滤算法与基于用户的协同过滤算法很像,将商品和用户互换。通过计算不同用户对不同物品的评分获得物品间的关系。基于物品间的关系对用户进行相似物品的推荐。这里的评分代表用户对商品的态度和偏好。简单来说就是如果用户A同时购买了商品1和商品2,那么说明商品1和商品2的相关度较高。当用户B也购买了商品1时,可以推断他也有购买商品2的需求。

  • 创建用户-物品矩阵
# 创建用户-物品矩阵
study_information_data['score'] = 1
# 数据透视表,构建用户课程矩阵
user_course = pd.pivot_table(study_information_data,index='user_id',columns='course_id',values='score',fill_value=0)
user_course

  • 计算课程之间的相似度
# 计算课程之间的相似度
def simlarity(x):'''计算物品之间的相似度param x:用户-物品矩阵'''sim = pd.DataFrame(columns = x.columns,index=x.columns)for i in x.columns:for j in x.columns:matv = np.mat(user_course[[i,j]]).Tsim.loc[i,j] = 1 - dist.pdist(matv,'jaccard')[0]return sim#调用自定义函数构建课程相似度矩阵
sim = simlarity(user_course)
sim

课程总学习进度前5名的学员id

# 统计各用户学习进度
learn_count = study_information_data.groupby('user_id').agg({'learn_process':'sum'})# 筛选总学习进度前5的数据
learn_count_top5 = learn_count.sort_values(by = 'learn_process',ascending = False)[:5]
learn_count_top5

  • 提取学习总进度前5的用户及其对应课程
# 提取总学习进度前5的用户及其对应课程
ind = study_information_data['user_id'].isin(learn_count_top5.index)
rem = study_information_data.loc[ind,['user_id','course_id']]
rem

  • 课程推荐
# 课程推荐
for i in rem.index:course = rem.loc[i,'course_id']      #所看课程ind = sim.columns != course # 剔除掉要推荐的课程rem.loc[i,'rem'] = sim.loc[course,ind].astype('float').idxmax()  # 相似度最高的课程名称rem.loc[i,'score'] = sim.loc[course,ind].max()
  • 选择推荐相似度排在前3的课程作为推荐结果
# 用户推荐相似度排在前3的课程
recommend_list = []
# learn_count_top5.index是用户名
for i in learn_count_top5.index:rem_user = rem[rem['user_id'] == i]tui = rem_user.sort_values(by = 'score',ascending = False)['rem'].drop_duplicates()   # 所有推荐课程tui = [i for i in tui if i not in rem_user['course_id'].tolist()]    # 剔除掉用户已经观看过的课程dic = {}dic['user_id'] = i    # 用户dic['course_id'] = rem_user['course_id'].tolist()   # 已经看过的课程dic['rem'] = tui[:3]  # 推荐相似度排在前3的课程recommend_list.append(dic)recommend_list  = pd.DataFrame(recommend_list)
recommend_list

结论及建议

产品部门:

  • 大部分用户的学习时长在半小时以内甚至是0,说明课程没有对用户产生吸引力,需要进一步分析是哪些类型的课程,如何设计课程界面和课程介绍内容能提高留存率
  • 分析最受欢迎的前10门课程的共性,这反映了用户的需求,可以多产出这些主题的课程,交付兼具用户价值商业价值的产品;

运营部门:

  • 用户登录地址集中的省份,如广东省、贵州省、湖北省和河南省,以及对应的城市进行重点推广;
  • 广告投放时间尽量选择工作日的上午10点左右,休息日的上午10点,下午三点和晚上8点,这些时间段用户登录平台几率大;
  • 通过免费试学课程来拉新用户阶段的转化率是30%,说明用户对平台建立了一定的信任关系,但可以对未进行转化的用户多沟通,了解其犹豫未购买的原因,可以通过发放优惠券等手段来刺激购买;
  • 教研部门反馈结课率较低的课程,课程89的结课率最高,可详细分析其课程内容,教师风格,作为课程模板供其他教师参考;
  • 流失用户较多,且大部分用户在登陆后并没有开始学习,课堂助手应勤与用户接触,提醒其上课时间,促进用户激活

教育平台线上课程数据分析相关推荐

  1. 教育平台线上课程用户行为分析

    教育平台线上课程用户行为分析 一. 分析的背景和目的 因为新冠疫情的影响,越来越多的教育平台开启了线上课程.线上课程相较于传统的线下课程,不论时间还是地点都更加的灵活,人们开始更加倾向于选择线上学习. ...

  2. 某教育平台线上课程用户行为数据分析报告

    目录 项目背景 分析思路 1.链路分析 2.指标拆解 探索数据(EDA) 数据处理 用户活跃度分析 1.区域维度 2.时间维度 用户流失分析 流失预警模型 1.流失用户定义 2.特征工程 3.特征筛选 ...

  3. Python数据分析实践项目 教育平台的线上课程智能推荐

    嗨喽! 大家好,我是"流水不争先,争的是滔滔不绝"的翀,欢迎大家来交流学习,一起入坑数据分析,希望我们一起好好学习,天天向上,目前在社会毒打中~~ 文章目录 摘要 关键词:数据分析 ...

  4. 教育平台的线上课程智能推荐策略

    题目来自:http://www.tipdm.org 一. 背景 近年来,随着互联网与通信技术的高速发展,学习资源的建设与共享呈现出 新的发展趋势,各种网课.慕课.直播课等层出不穷,各种在线教育平台和学 ...

  5. 教育平台的线上课程推荐策略——课程分级

    文章列表 篇1:<在线教育平台的数据分析--用户精细化运营> 篇2:<在线教育平台的数据分析--课程分级> 篇3:<在线教育平台的数据分析--业务流程指标的计算> ...

  6. 教育平台的线上课程智能推荐策略-Python

    1 背景 近年来,随着互联网与通信技术的高速发展,学习资源共享与建设呈现出新的发展趋势,多样化的线上教育平台如雨后春笋般争相涌入大众视野.尤其是自2020年初,受新冠肺炎疫情的冲击,学生返校进行线下 ...

  7. 如何在 LearnDash 线上教育平台网站上构建和管理大型课程

    以课程的形式在 LearnDash 线上教育平台网站上上传大量内容.你的课程长度是否让学生不知所措? 这一切都是为了确保您的课程结构正确, 从而使您更容易管理内容.学生进度和参与度. 目录 隐藏 划分 ...

  8. 线上课程直播平台做推广的方式有哪几种?

    随着移动互联网时代的到来,在线教育平台如雨后春笋一般出现.根据相关数据的预测,2020年在线教育市场规模将会达到4330亿.然而线上课程直播平台的竞争是很激烈的,想要在这局面中脱颖而出,教育机构只能花 ...

  9. 零基础学python免费网课-零基础学Python量化投资,超值线上课程反复回看

    原标题:零基础学Python量化投资,超值线上课程反复回看 超值网络课程 量化投资是一种严谨.系统化的投资方式,相比起传统投资,量化投资风险低回报高,但是它要求投资者使用数据处理分析.计算机编程技术. ...

最新文章

  1. 18.16 gcc-3.4.5编译错误及解决方法集锦
  2. python小程序-第一个python小程序——即时动态时钟(代码解读)
  3. SAStruts リンク記述におけるs:linkとhtml:linkの比較
  4. 读懂 Redis 源码,我总结了这7点心得
  5. 控件设置相对位置_惊人的Divi转换控件!
  6. ifconfig route 手动设置网卡route路由 示例
  7. Logistics模型预测银行贷款违约
  8. mysql列的数值型,字符型,日期型
  9. javascript window location
  10. 电力、输电、变电、配电(转)
  11. 21天Jmeter打卡Day17 后置处理器_JSON_正则表达式_边界提取器_完成删除场景模拟测试
  12. 我们自己搞了个数据库设计工具(客户端)
  13. 服务器系统影子系统,影子系统安装教程
  14. 基于Java+SpringBoot+vue+element实现校园疫情防控系统详细设计和实现
  15. 1183 电力(点的双连通分量--求解割点)
  16. 派对屋3000效果器怎样调试_音响效果器的调试和使用技巧
  17. PAT(甲)1124 Raffle for Weibo Followers——未完成
  18. python基础教程: 利用turtle库绘制笑脸和哭脸的例子
  19. 数据结构实训——运动会分数统计
  20. web项目打war包方法 两步解决(极其简单方便)

热门文章

  1. vulnhub之CH4INRULZ渗透测试实战
  2. java随机数生成函数
  3. http 协议 查看ie http的版本
  4. 为什么要使用框架,你听过最好的答案是什么?
  5. uniapp h5直播拉流的几种方法 flv.js, video.js, 阿里播放器sdk,video标签
  6. redis主从同步概念及配置
  7. 进程退出后占用的内存都去哪儿了?
  8. 【维生素C语言】第十八章 - C语言程序环境
  9. 什么是anaconda
  10. c语言中10 1是什么意思,维生素c1十是什么意思