栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 其他

“名师讲坛”课程资源库使用情况分析

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

“名师讲坛”课程资源库使用情况分析

目录

一、项目背景

二、分析结论

三、分析方法

四、数据说明

五、分析过程

六、计算过程


一、项目背景

        “名师讲坛”课程资源库是我公司资源类产品之一,贵校为该产品正式用户,正在使用的包库含16732套课程视频,其中贵校与我公司合作共建课程124套,发布于贵校平台向师生开放,使用期限至今年底。现对课程资源的使用情况做出分析,以便优化课程内容配置,为课程资源的续费和自建课程的进一步制作给出建议。

二、分析结论

        1、2020学年“名师讲坛”访问量较2019学年有明显增长,访问量增长率在统计的128个数据库中排第7位,高达50%。

        2、2020学年“名师讲坛”访问人次在同类10个数据库中排第2位,且经过课程分类调整后访问人次增长明显,下半学期访问人次占该类数据库总访问人次的20%。

        3、课程整体使用情况良好,可以对课程类型分配做出调整,增加理工、历史、经济、医学类课程,将人文社科类部分课程用相关类型的微课程替换。

        4、自建课程使用情况良好,在接下来课程自建过程中,增加理学、经济学、医学类的课程,增加基础学科课程。对历史和工学类课程的选题、授课、后期制作进行优化,在课程录制和制作中,对课程声音和课件的质量给予关注。

        5、自建课程的制作中,时长、机位数、课程年级、课时数和教室信息等特征会影响课程的受欢迎程度。课时数在20节左右,单节课时长在10分钟以上,在智能多媒体教室采用双机位录制的本科或硕士研究生阶段的课程更受学生用户欢迎。

三、分析方法

        1、运用可视化图表对整体使用情况、不同类别课程的使用情况、自建课程的使用情况进行分析。

        2、运用词云对用户留言进行分析。

        3、运用决策树模型对自建课程特征参数进行分析。

四、数据说明

        时间口径:

        2020学年:2020年7月至2021年6月

        2019学年:2019年7月至2020年6月

本次分析用到7套,共19张表,具体信息如下:

数据库表:正在使用的193个数据库信息及访问增长率

字段

字段说明

类型

数据库的类型,“名师讲坛”属于其中的多媒体数据库

数据库名称

数据库中文名称

数据库类别

所属类别

访问人次增长幅度

2020学年较2019学年的访问增长率。部分数据库采购不满两学年,访问增长率数据缺失

近一年访问数据表:类型为多媒体数据库的10个产品2020学年的访问数据,每个产品一张表,共10张表,格式相同

字段

字段说明

时间

访问数据所属月份,格式为‘年-月’

PV

该月数据库访问人次

课程信息表:16732集课程的相关信息

字段

字段说明

序号

序号

课程名

课程名

课程介绍

课程简介

课程ID

课程在“名师讲坛”资源库中的编号

讲师

讲师姓名

讲师单位

讲师所在单位

职称

讲师职称

讲师简介

讲师简介

模块

此次分析中所有课程均为“课堂”

产品

此次分析中所有课程均为“名师讲坛”

一级分类id

一级分类id

一级分类

含文学、法学、工学等38个分类

二级分类id

二级分类id

二级分类

课程所属一级分类中的二级分类

三级分类id

三级分类id

三级分类

课程所属二级分类中的三级分类

拍摄日期

课程拍摄日期

发行日期

课程上线发行日期

拍摄地点

课程拍摄地点

播放量

2020学年全年课程播放量

播放量增长率

2020学年课程播放量较2019学年增长率

是否为自建课程

由本校师生参与录制并发行的课程为自建课程,本表中自建课程标记为1

评论数据表:2021年7月用户的留言评论

字段

字段说明

课程名称

课程名称

页码

页码

评论

评论内容

日期

评论发布时间,格式为‘年-月-日 时-分‘

用户行为表:2020学年用户行为记录,共3张

字段

字段说明

user_id

用户ID

course_id

课程ID,同课程信息表中课程ID

time

行为发生时间,格式为年-月-日 时-分

action_type

行为类型,1:播放 2:点赞 3:看完 4:收藏 5:留言6:浏览

course_cate

课程分类

课程参数表:课程录制参数等信息

字段

字段说明

course_id

课程ID,同课程信息表中课程ID

course_name

课程名,同课程信息表中课程名

course_cate

课程分类

course_cate2

课程二级分类

teacher_counts

授课老师数量

course_counts

课时数

teacher_title

授课老师职称

PPT

课程是否有PPT,U为无PPT,Y为有PPT,P为影视化课程(非课堂录制)

course_type

课程类型,Y为讲座,N为公开课

class

录制教室信息,Y智能多媒体教室,U普通教室,P300人大教室,R实验室,T报告厅

duration

单节课时长,单位分钟

camera

机位数,A为单机位,B为双机位,C为多机位,U为移动机位

students

是否有学生,0为没有,1为有

course_grade

课程年级,M为本科,S为硕士研究生,U为博士研究生,P为学术报告

subtitle

是否有字幕,0为没有,1为有

interaction

是否有互动,0为没有,1为有,有互动的课程需要在规定时间内完成答题并通过才能继续观看

homework

是否为习题课程,0为不是,1为是

数据字典表:与课程参数表对应,用于课程参数表特征字段汉化

字段

字段说明

变量名

对应课程参数表特征变量英文名

type

数据类型

变量说明

对应课程参数表特征变量中文名

备注

补充说明

五、分析过程

1、整体情况分析

        在128个正在使用的数据库中,大约有一半的数据库访问量较上个学年是增长的。最高的增幅达到了190%,增幅排名前25%的数据库访问量增长率在10%以上。“名师讲坛”的增长率为50.89%,排在第7位。 

        增幅前25%的数据库分布比较分散,涵盖了会议文献库、学位论文库、论文引文库、多媒体数据库、参考工具库、文摘数据库、科技报告库、期刊全文库、电子图书库、成果数据库、报纸文献库、专利文献库、书刊馆藏目录共13个类别。排名前十的数据库中,增幅最高的属于会议文献库,所属类别为学位论文库的占了3个。排在“名师讲坛”前面的数据库所属类型包括会议文献库、学位论文库和论文引文库,都是文献论文相关的,“名师讲坛”增幅高于非文献论文相关的数据库,而且在多媒体数据库类型中,“名师讲坛”增幅也领先于其他同类数据库。由此可知,文献论文相关的数据库与用户学业密切相关,因此访问量增长高,除此之外,“名师讲坛”无论与同类型数据库比,还是与其他类型数据库比,访问量增长都表现不错。 

2、多媒体类数据库分析

        多媒体类数据库共10个,“名师讲坛”访问量排在第2名,访问人次在1、2月经历短暂的减少后,在第二学期上升明显,有赶超第1名的趋势。1、2月由于放寒假,所有数据库的访问人次都下降了,寒假期间,我们对“名师讲坛”的课程分类做了调整,将自建课程单独打包,便于用户查找,这一调整对访问人次的增长产生了积极的影响。

        “名师讲坛”访问人次占同类数据库总访问人次的17.81%,排在第2名。 

        2020学年下学期“名师讲坛”访问人次占同类数据库访问人次总数的比较上学期提升4%左右,可以看出,经过课程分类调整,访问人次增长明显。 

3、整体课程分析

       “名师讲坛”课程资源共38类,其中人文和文学类课程较多,占总课程数的比均在10%以上,通过课程数占比和播放量占比的对比图可以看出,理学、工学、历史学、艺术学、医学、经济学课程表现不错,播放量占比均明显高于课程数占比。而人文、社科、法学、教育等类型的课程播放量占比低于课程数占比,说明课程的数量相对于用户需求来说偏高。此外可以看出用户对于微课程的使用兴趣比较大,尤其像微国学、微心理、微名城、微外语这类偏文科的课程很受欢迎。

        在续费时,可以适当调整不同类型课程数的分配,建议适当增加理工、历史、经济、医学类课程,将人文社科类部分课程用微课程替换,微课程时长短,内容紧凑、精简,满足用户碎片化的学习需求,而人文社科类课程观点鲜明,知识点精炼,结论的呈现无需大量理论铺垫,适合制作成微课程。通过这样的调整,可以满足用户对理工类课程的需求,同时提高人文社科类课程的利用率。

4、自建课程分析

        将自建课程筛选出来,自建课程涵盖法学、历史学、工学等10大分类。计算可知,自建课程中理学、经济学的播放量占比明显高于课程数占比,说明用户需求大。人文、文学、法学的播放量占比低于课程数占比,说明课程的数量相对于用户需求来说偏高。这两点与前面对所有课程的分析结果一致。值得注意的是,在整体课程分析时发现历史和工学课程的播放量占比是明显高于课程数占比的,说明用户对于这两类课程存在较大需求,但是在自建课程中,用户却没有表现出对这两类课程的热情,因此在将来课程自建的过程中,需要对这两类课程的选题、授课、后期制作做进一步分析,提高课程质量。

        加大与理学院、经济学院的合作,制作更多的自建课程,对历史和工学课程做进一步分析,提高课程质量。

        从播放量和播放增长率的维度,绘制自建课程的波士顿矩阵,对播放量和播放量增长率用第三四分位数线进行分割,对照课程信息表中的课程ID,可以看出836:高等代数、1143:化工原理、4068:金融学、3230:数学物理方法(1)、10052:人民币汇率与中国经济结构扭曲、8656:国际商务谈判实务、4154:病理学、1781:概率论、16909586:能源经济学、4206:生物化学等课程播放量高且播放量增长率高,主要还是集中在理工、经济金融类,值得关注的是,自建课程中医学类只有病理学一门课程,其播放量和增长率表现都不错,可以考虑增加医学类课程的制作。而538:数学分析、5118:基础物理、1348:民商法探析等课程表现也不错,有较高的播放量,可以看出课程多属于基础学科内容。 

        对自建课程2021年7月的评论数据进行分析。通过高频词整理,可以看出在出现频率前30的词里,有计算机、线性代数、高数、C语言、音乐、力学这些学科名字,这些学科的内容应该是学生用户比较关心的科目,主要也是理学、工学的课程,可以增加课程建设。关于考试的词出现的频率也比较高,一方面由于我们所统计的7月为考试月,另一方面也反映了学生用户对考试的关注程度。

        此外,可以发现,频率前30词汇中还出现了声音、课件这样的词,根据经验可知,此类词汇的出现通常反应在这方面存在问题,在后期课程自建过程中,需要对声音和课件多加关注,比如现场收声、课程课件制作与上传方面的问题,避免影响听课体验。

5、优质课程特征分析

        在所有课程中,有接近一半的课程为会议类课程,这类课程对我们自建课程参考意义不大,我们将非会议类课程取出,共8464套,并取得这些课程在2020学年的用户使用数据。

        利用决策树模型挖掘优质课程的特征,为自建课程提供指导。首先将优质课程找出,用户信息表的action_type字段中记录了用户的6个行为特征,分别是:1播放完成、2回复、3点赞、4分享、5收藏、6浏览。自定义三个指标,分别从互动情况、结课情况、喜爱情况3个维度对课程质量做出衡量,3个维度的计算公式如下:

I(Interaction) 互动=留言数/播放数

F(Finish) 结课=播放完成数/播放数

L(Like) 喜爱=(点赞*1+收藏*2+分享*3)/播放数

        定义3个指标得分全部位于前50%的课程为优质课程,共1524套,添加label特征,将优质课程标记为1,用于后续建模的标签。

        根据经验,从课程制作参数中选出相关的17个特征值,分别为课程ID、课程名、一级分类、二级分类、教师数、课时数、教师职称、是否有PPT、课程类型、教室信息、时长、机位数、是否有学生、课程年级、字幕、互动、随堂作业。对特征进行探索,并对数据进行清洗。删除课程ID、课程名、一级分类和二级分类特征,对是否有PPT、课程类型、教室信息、机位数、课程年级进行哑变量转码,对是否有学生、字幕、互动、随堂作业特征进行0-1转码,把数据划分为训练集和测试集,将课程类型、教室信息、机位数、课程年级的空值用众数替换。

        建立决策树模型,通过网格搜索找到最优参数('criterion': 'entropy', 'max_depth': 7, 'min_samples_leaf': 6, 'splitter': 'best'),计算模型得分,准确率0.874,精确率0.885,召回率0.592。生成决策树如下:​​​​​​​

        可以看出,影响课程质量的几个关键特征为时长、机位数、课程年级、课时数和教室信息。课时数在20节左右,单节课时长在10分钟以上,在智能多媒体教室采用双机位录制的本科或硕士研究生阶段的课程更受学生用户欢迎。 

六、计算过程
import os
import glob
import re
import numpy as np
import pandas as pd
import datetime as dt
import seaborn as sns
from matplotlib import pyplot as plt
import jieba
import jieba.analyse
import imageio
from wordcloud import WordCloud
from sklearn.preprocessing import OrdinalEncoder
from sklearn.model_selection import train_test_split
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import roc_curve
import graphviz

plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
from matplotlib.font_manager import FontProperties
myfont = FontProperties(fname=r'/Library/Fonts/AdobeKaitiStd-Regular.otf', size=14)
sns.set(font=myfont.get_name())

# 找到表格所在路径,打开数据库表。因同一个数据库可能在不同分类中出现,所以需要将重复数据删除。部分数据库使用不足两学年,故将增长率为空的数据删除,最终删选出128条数据。根据'访问人次增长幅度'做降序排列后,将索引重置。
os.chdir('/Users/stefanie/desktop/Project/整体数据')
data = pd.read_excel('数据库.xlsx')
data.shape

data.info()

 

data.drop_duplicates(subset='数据库名称', keep='first', inplace=True)
data.info()

 

data.dropna(axis=0, subset=['访问人次增长幅度'], inplace=True)
data.shape

 

data.reset_index(drop=True, inplace=True)
data.describe()

 

data.sort_values(by='访问人次增长幅度', ascending=False, inplace=True)
data.reset_index(drop=True, inplace=True)
data.head()

 

# 将各数据库访问人次增长幅度绘图,并将“名师讲坛”的数据用红色标出。
data[data['数据库名称']=='名师讲坛'].index
 
color = ['tab:red' if (i == '名师讲坛') else 'tab:gray' for i in data.数据库名称]
y = data[data['数据库名称']=='名师讲坛']['访问人次增长幅度'].item()
plt.rcParams['axes.facecolor'] = 'none'
plt.figure(figsize=(12,4), dpi=500)
plt.bar(x=data['数据库名称'], height=data['访问人次增长幅度'], color=color)
plt.text(x=7, y=y, s=y, ha='left', va='bottom', size=10, color='tab:red')
plt.xlabel('数据库名称')
plt.ylabel('访问人次增长幅度')
plt.xticks(rotation=90, size=4)
plt.axhline(0.249400, color='tab:olive', linestyle='--', label='第三四分位数')
plt.title('各数据库2021年度访问人次较2020年度增长情况', size=16)
plt.legend(loc='best', frameon=False)
plt.show()

 

# 将增幅前25%的数据库找出,将增长率绘图,并将不同分类用不同颜色标出。
data = data[data['访问人次增长幅度']>=data['访问人次增长幅度'].quantile(0.75)]
data.类型.unique()

 

colors = ('tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan', '#8C8C00','#FFB5B5','#FF0000')
trancolor = dict(zip(data.类型.unique(),colors))
plt.rcParams['axes.facecolor'] = 'none'
plt.figure(figsize=(6,2), dpi=500)
plt.bar(x=data['数据库名称'], height=data['访问人次增长幅度'], color=data.类型.map(trancolor))
plt.xlabel('数据库名称', size=7)
plt.ylabel('访问人次增长幅度', size=7)
plt.xticks(rotation=90, size=4)
plt.yticks(size=4)
plt.xlim(-0.5, 31.5)
plt.vlines(10.5, 0, 0.8, color='black', label='top10', linestyle='--', lw=0.5)
plt.title('前25%数据库2021年度访问人次较2020年度增长情况', size=6)
plt.legend(loc='best', frameon=False, fontsize=4)
plt.show()

# 读取多媒体数据库分类下的数据库近一年访问数据,把10张表的数据合并到一张表里,将各数据库近一年访问人次绘图。
filenames = glob.glob('*近一年访问数据.xlsx')
filenames

def load_xlsx(filename):
    colname = re.search(r'.*(?=近一年)', filename).group()
    df = pd.read_excel(filename)
    if df['时间'].dtypes == 'int64':
        df['时间'] = pd.to_datetime(df['时间'], unit='D', origin=pd.Timestamp('1899-12-30'))
    df.iloc[:,1].astype('int')
    df.rename(columns={df.columns[1]:colname}, inplace=True)
    df = df.set_index('时间')
    return df
data02 = pd.concat(([load_xlsx(i) for i in filenames]), axis=1)
data02.head()

 

data02.info()

 

fig, ax = plt.subplots(figsize=(2,1.5), dpi=500)
plt.rcParams['axes.facecolor'] = 'none'
plt.plot(data02, label=data02.columns, linewidth=1)
plt.ylabel('访问人次', fontdict={'size' : 5})
plt.xlabel('日期', fontdict={'size' : 5})
plt.yticks(fontproperties = 'Times New Roman', size = 4, rotation=45) 
plt.xticks(fontproperties = 'Times New Roman', size = 4, rotation=45)
plt.ylim(0,130000)
plt.legend(loc='best', fontsize=3, frameon=False, ncol=2)
plt.title('近一年各资源库产品访问人次', size=5, pad=5)
plt.show()

 

# 求每个数据库年访问总人次,计算2020学年上下两个学期每个数据库访问量占多媒体数据库总访问量的比。
data02.loc['近一年访问人次合计'] = data02.apply(lambda x: x.sum())
data02.loc['2021上半年合计'] = data02.iloc[:12,:].apply(lambda x: x.sum())
data02.loc['2020下半年合计'] = data02.iloc[12:-2,:].apply(lambda x: x.sum())
data02.loc['2021上半年'] = data02.iloc[-2,:].div(data02.loc['2021上半年合计'].sum())
data02.loc['2020下半年'] = data02.iloc[-2,:].div(data02.loc['2020下半年合计'].sum())
data02.iloc[-4:,:]

 

colors = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
explode = [0,0,0,0,0,0,0,0,0,0.1]
plt.figure(dpi=500)
plt.pie(data02.loc['近一年访问人次合计'],
        explode=explode,
        labels=data02.columns,
        autopct='%3.2f%%',
        startangle=45,
        textprops={'fontsize':6},
        colors=colors)
plt.title('近一年多媒体数据库中各数据库访问人次占比', size=8)
plt.show()

 

data02.loc[['2020下半年','2021上半年']].plot(kind='bar', stacked=True, figsize=(6,8), colormap='tab10')
for a,b in zip(range(len(data02.loc[['2020下半年','2021上半年']])), data02.loc[['2020下半年','2021上半年']]['名师讲坛']):
    plt.text(a,1-b/2,f'{b*100:.2f}%', ha='center',va='bottom',size=12,color='white')
plt.xlabel('')
plt.ylabel('访问量占比', size=16)
plt.xticks(rotation=0, size=16)
plt.ylim(0,1.3)
plt.legend(loc='best', fontsize=9, frameon=False, ncol=2)
plt.title('各数据库访问量占多媒体数据库总访问量的比', size=18, pad=10)
plt.show()

 

# 读取课程数据表,统计一级分类下的课程数量。
os.chdir('/Users/stefanie/desktop/Project/课程数据')
data03 = pd.read_excel('课程信息.xlsx')
data03.head()

 

data03.shape

 

data03.columns

 

data03.一级分类.unique()

 

def coursecounts(data):
    coursecounts = data['课程名'].groupby(by=data['一级分类']).count()
    coursecounts.sort_values(ascending=False, inplace=True)
    plt.figure(figsize=(10,4), dpi=500)
    p = plt.bar(x=coursecounts.index, height=coursecounts, color='tab:olive', label=coursecounts)
    plt.xticks(rotation=90)
    plt.yticks(size=8)
    plt.xlim(-0.5,38.5)
    plt.xlabel('课程分类')
    plt.ylabel('课程数量')
    plt.title('各类课程数量')
    plt.bar_label(p, size=6)
    plt.show()
coursecounts(data03)

 

# 统计不同类课程近一年的播放量。
def category(data):
    category = data['播放量'].groupby(by=data['一级分类']).sum()
    category.sort_values(ascending=False, inplace=True)
    plt.figure(figsize=(10,4), dpi=500)
    plt.bar(x=category.index, height=category, color='tab:olive')
    plt.xticks(rotation=90)
    plt.yticks(size=8)
    plt.xlim(-0.5,38.5)
    plt.xlabel('课程分类')
    plt.ylabel('播放量')
    plt.title('各类课程近一年播放量')
    plt.show()
category(data03)

 

# 计算不同类型课程的课程数占总课程数的比和播放量占总播放量的比。
def contribution(data):
    contribution = pd.Dataframe(data=data['课程名'].groupby(by=data['一级分类']).count())
    contribution['播放量'] = data['播放量'].groupby(by=data['一级分类']).sum()
    contribution['课程数占比'] = contribution['课程名']/contribution['课程名'].sum()
    contribution['播放量占比'] = contribution['播放量']/contribution['播放量'].sum()
    contribution.sort_values(by='课程名', ascending=False, inplace=True)
    plt.figure(figsize=(15,4), dpi=500)
    ax = contribution.plot(y='播放量占比',linestyle='-',marker='o')
    contribution.plot(y='课程数占比',kind='bar',color='tab:olive',ax=ax, figsize=(15,4))
    plt.xticks(size=15)
    plt.xlabel('一级分类', size=15)
    plt.ylim(0,0.2)
    plt.legend(loc='best', fontsize=18, frameon=False)
    plt.title('各类课程数和播放量占比', size=26)
    plt.show()
contribution(data03)

 

# 将自建课程筛选出来,代入上面自定义的函数,对不同分类下的课程数量,播放量,课程数量占比和播放量占比进行统计。
data04 = data03[data03.是否为自建课程==1]
data04.shape

 

coursecounts(data04)

 

category(data04)

 

contribution(data04)

 

# 提取播放量和播放增长率字段,绘图查看自建课程表现。
def highqualitycourse(data, q1=0.75, q2=0.75):
    highqualitycourse = data.loc[:,['课程ID', '播放量', '播放量增长率']]
    plt.figure(figsize=(6,4), dpi=200)
    sns.scatterplot(x=highqualitycourse['播放量'], y=highqualitycourse['播放量增长率'],
                    size=highqualitycourse['播放量'], sizes=(1,200), color='tab:cyan', data=highqualitycourse)
    #给所有的点加行索引,索引为课程ID
    for i in range(len(highqualitycourse)):
        plt.text(highqualitycourse.iloc[i,1], highqualitycourse.iloc[i,2],highqualitycourse.iloc[i,0])
    plt.axvline(highqualitycourse['播放量'].quantile(q1), color='tab:olive', linestyle='--')#垂线
    plt.axhline(highqualitycourse['播放量增长率'].quantile(q2), color='tab:olive', linestyle='--')#水平线
    plt.xlabel('播放量', size=10)
    plt.ylabel('播放量增长率', size=10)
    plt.xticks(size=6)
    plt.yticks(size=6)
    plt.title('播放量和播放增长率关系', size=10, pad=20)
    plt.legend('', frameon=False)
plt.show()

 

# 读取2021年7月的评论数据,对评论数据进行清洗,去掉重复信息,去掉非中英字符、标点符号和停用词,分词后做出词云图,并统计各个词出现频率。
os.chdir('/Users/stefanie/desktop/Project/行为数据')
data05 = pd.read_excel('评论数据.xlsx')
data05.head()

 

data05.drop_duplicates(subset='评论', keep='first', inplace=True)
data05.shape

 

comment = list(data05['评论'])
comment

 

comment = [re.sub(r'[^a-zu4E00-u9Fa5]+', ' ', i, flags=re.I) for i in comment]
comment

 

stopwords = list(pd.read_csv('/Users/stefanie/desktop/Project/行为数据/百度停用词表.txt', names=['stopwords'])['stopwords']) #指定列名转化为列表
stopwords.extend([' ']) #把空格也去掉
stopwords

 

comment02 = []
for i in comment:
    seg1 = pd.Series(jieba.lcut(i))
    ind1 = pd.Series([len(j) for j in seg1])>1
    seg2 = seg1[ind1]
    ind2 = ~seg2.isin(pd.Series(stopwords))
    seg3 = list(seg2[ind2].unique())
    if len(seg3)>0:
        comment02.append(seg3)
comment03 = [y for x in comment02 for y in x]
comment04 = ' '.join(comment03)
comment04

 

mask = imageio.imread(r'/Users/stefanie/desktop/Project/行为数据/earth.jpg')
font = r'/Users/stefanie/desktop/Project/行为数据/SimHei.ttf'
wc = WordCloud(background_color='white',mask=mask,
                       font_path=font).generate(comment04)
plt.figure(figsize=(8,8),dpi=500)
plt.imshow(wc)
plt.axis('off')
plt.show()

 

jieba.analyse.extract_tags(comment04,30,True)

 

# 读取用户行为数据,自定义函数对表中各个特征进行查看,将action_type特征通过数据透视表展示,由播放、点赞、看完、收藏、留言、浏览这6个维度,通过自定义的公式给各个课程打分,计算出互动、结课、喜爱3个分数指标,添加label特征,将3个分数指标分别位于前50%的课程标为1,用做后面决策树建模的标签。
os.chdir('/Users/stefanie/desktop/Project/行为数据')
filenames_action = glob.glob('*Action*.csv')
filenames

 

action = pd.concat(([pd.read_csv(i) for i in filenames_action]), axis=0)
action.info()

 

def describe(x):
    for i in x.columns:
        print('特征名:',i)
        print('---------------------')
        print('特征类型:',x[i].dtype)
        print('---------------------')
        print('空值个数:',x[i].isnull().sum())
        print('---------------------')
        print('特征频数:',x[i].value_counts())
        print('++++++++++++++++++++++++++++++++++++++++++++')
describe(action)

 

 

action = action[['course_id', 'action_type', 'course_cate']]
action = pd.pivot_table(action, index='course_id', columns='action_type', values='course_cate', aggfunc='count')
action.columns = ['finish', 'reply', 'like', 'share', 'collect', 'play']
action.reset_index(inplace=True)
action.fillna(0, inplace=True)

 

action['I_score'] = action['reply']/action['play']
action['F_score'] = action['finish']/action['play']
action['L_score'] = (action['like']+action['collect']*2+action['share']*3)/action['play']

action_ = action[(action['I_score'] > action['I_score'].quantile(0.5))
                 &(action['F_score'] > action['F_score'].quantile(0.5))
                 &(action['L_score'] > action['L_score'].quantile(0.5))]

action['label'] = action['course_id'].isin(action_['course_id'])
action['label'] = action['label'].map(lambda x: 1 if x else 0)

 

# 导入课程数据文件和课程数据字典文件
os.chdir('/Users/stefanie/desktop/Project/课程数据')
course = pd.read_csv('course.csv')

 

course_dict = pd.read_csv('course_dict.csv')

describe(course)

 

# 将course表和action表通过course_id条件连接,并将action表中除label之外的特征删除
course= course.merge(action,on='course_id')
course.columns

 

course.drop(columns=['finish', 'reply', 'like', 'share', 'collect', 'play', 'I_score', 'F_score', 'L_score'], inplace=True)

# 自定义函数,将课程数据文件特征名替换为数据字典中的变量说明,方便阅读,查看课程数据文件特征名和数据字典变量名是否对应。将最后一列名称改为label。
np.setxor1d(course, course_dict.变量名)
dic = {k:v for k, v in course_dict[['变量名', '变量说明']].values.reshape(-1,2)}
def tran(x):
    x.columns = pd.Series(x.columns).map(dic)
    return x
tran(course)

 

course.rename(columns={course.columns[-1]:'label'}, inplace=True)
course.info()

 

# 自定义临时0-1转码函数,把教师数之后的特征值转换成0,1,2……,画出相关性热力图,看数据之间的相关性。
def zero_one(x):
    for i in x.columns:
        if x[i].dtype == 'object':
            dic0_1 = dict(zip(list(x[i].value_counts().index), range(x[i].nunique())))
            x[i] = x[i].map(dic0_1)
    return x
zero_one(course.iloc[:,4:-1]).corr()

 

sns.heatmap(zero_one(course.iloc[:,4:-1]).corr(),cmap='Blues')

 

# 从热力图上看相关性表现还不错,自定义函数把相关性大于0.6的找出来
def high_corr(x,y=0.6):
    a = []
    data_corr = x.corr() > y
    for i in data_corr.columns:
        if data_corr[i].sum() >= 2:
            a.append(i)
    return a
high_corr(course.iloc[:,4:-1])

# 调用自定义的函数查看每个特征的信息,对特征进行筛选。
describe(course)

 

# 删除:
课程ID;
课程名;
二级分类
# 哑变量转码:
是否有PPT:U无PPT,Y有PPT,P影视化课程;
课程类型:Y讲座,N公开课;
教室信息:Y智能多媒体教室,U普通教室,P300人大教室,R实验室,T报告厅;
机位数:U移动机位,C多机位,B双机位,A单机位;
课程年级:M本科,S硕士研究生,U博士研究生,P学术报告
# 0-1转码:
是否有学生;
是否有字幕;
是否有互动;
是否为习题课
# 替换:
课程类型8个空值,用众数替换;
教室信息10个空值,用众数替换;
机位数11个空值,用众数替换;
课程年级7个空值,众数替换

# 数据清洗
course.drop(columns=['时长', '课程ID', '课程名', '二级分类'], inplace=True) #删除特征
course.drop_duplicates() #删除重复值

# 划分训练集和测试集
from sklearn.model_selection import train_test_split
y = course.pop('label') #标签
x = course #特征
Xtrain, Xtest, Ytrain, Ytest = train_test_split(x, y, test_size=0.3, random_state=100)
# 备份
Xtrain_01 = Xtrain.copy()
Xtest_01 = Xtest.copy()
Ytrain_01 = Ytrain.copy()
Ytest_01 = Ytest.copy()

# 对训练集的缺失值进行填充
# 填充众数
mod = ['课程类型', '教室信息', '机位数', '课程年级']
dic_mod = dict(zip(Xtrain_01[mod].mode().columns, Xtrain_01[mod].iloc[0,:]))
Xtrain_01 = Xtrain_01.fillna(dic_mod)
# 验证
Xtrain_01.isnull().sum()[Xtrain_01.isnull().sum() != 0]

 

# 对测试集的缺失值进行填充
# 填充众数
mod = ['课程类型', '教室信息', '机位数', '课程年级']
dic_mod = dict(zip(Xtest_01[mod].mode().columns, Xtest_01[mod].iloc[0,:]))
Xtest_01 = Xtest_01.fillna(dic_mod)
# 验证
Xtest_01.isnull().sum()[Xtest_01.isnull().sum() != 0]

 

# 对训练集的特征进行转码
# 0-1转码
z_o_list = ['是否有学生', '字幕', '互动', '随堂作业']
Xtrain_02 = Xtrain_01[z_o_list]
new_z_o_list_train = OrdinalEncoder().fit_transform(Xtrain_02)
new_df_train = pd.Dataframe(data=new_z_o_list_train, columns=Xtrain_02.columns, index=Xtrain_02.index)
Xtrain_01[z_o_list] = new_df_train[z_o_list]

# 哑变量
o_h_list = ['是否有PPT', '课程类型', '教室信息', '机位数', '课程年级']
Xtrain_03 = Xtrain_01.copy()
Xtrain_03 = pd.get_dummies(Xtrain_03[o_h_list])
# 将原特征删除,把转好的特征放进去
Xtrain_04 = Xtrain_01.copy()
Xtrain_04 = Xtrain_04.drop(columns=['是否有PPT', '课程类型', '教室信息', '机位数', '课程年级'])
# 合并Xtrain_03,Xtrain_04
Xtrain_05 = pd.concat([Xtrain_03,Xtrain_04],axis=1)
Xtrain_05

 

# 对测试集的特征进行转码
# 0-1转码
Xtest_02 = Xtest_01[z_o_list]
new_z_o_list_test = OrdinalEncoder().fit_transform(Xtest_02)
new_df_test = pd.Dataframe(data=new_z_o_list_test, columns=Xtest_02.columns, index=Xtest_02.index)
Xtest_01[z_o_list] = new_df_test[z_o_list]

# 哑变量
Xtest_03 = Xtest_01.copy()
Xtest_03 = pd.get_dummies(Xtest_03[o_h_list])

# 将原特征删除,把转好的特征放进去
Xtest_04 = Xtest_01.copy()
Xtest_04 = Xtest_04.drop(columns=['是否有PPT', '课程类型', '教室信息', '机位数', '课程年级'])

# 合并Xtest_03,Xtest_04
Xtest_05 = pd.concat([Xtest_03,Xtest_04],axis=1)
Xtest_05

 

# 初步建模
clf = DecisionTreeClassifier(random_state=420, class_weight='balanced')
cross_val_score(clf, Xtrain_05, Ytrain_01)

 

# 测试参数
param_test = {
    'splitter':('best','random'),
    'criterion':('gini','entropy'),
    'max_depth':range(3,10),
    'min_samples_leaf':range(1,50,5)
}

gsearch = GridSearchCV(
            estimator=clf, #对应模型
            param_grid=param_test, #要找的最优参数
            scoring='roc_auc', #准确度评估标准
            n_jobs=-1, #并行数个数,-1与CPU核数一致
            cv=5, #折数
            verbose=2 #输出训练过程
            )

gsearch.fit(Xtrain_05, Ytrain_01)

 

gsearch.best_score_

  

gsearch.best_score_

 

gsearch.best_params_

 

Ypred = gsearch.predict(Xtest_05)
accuracy_score(Ypred, Ytest_01)

 

precision_score(Ypred, Ytest_01)

 

recall_score(Ypred, Ytest_01)

 

fpr, tpr, thresholds = roc_curve(Ypred, Ytest_01)

plt.plot(fpr, tpr, c='b', label='ROC曲线')
plt.plot(fpr, fpr, c='r', ls='--')

 

# 最优参数 {'criterion': 'entropy', 'max_depth': 7, 'min_samples_leaf': 6, 'splitter': 'best'}

# 将最优参数放到分类器里
clf_ = DecisionTreeClassifier(criterion='entropy', max_depth=7, splitter='best', min_samples_leaf = 6)
clf_ = clf_.fit(Xtrain_05, Ytrain_01)
features = Xtrain_05.columns
data = tree.export_graphviz(clf_,
                    feature_names=features,
                    class_names=['普通','优质'],
                    filled=True,
                    rounded=True,
                    leaves_parallel=False
                    )
graph = graphviz.Source(data)
graph

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/279587.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号