# 0 简介
今天学长向大家介绍一个适合作为毕设的项目
毕设分享 决策树算法的学生行为数据分析(源码分享)
项目获取:
https://gitee.com/assistant-a/project-sharing
基于决策树算法的学生学习行为数据分析
一、 背景
近年来,受学习理论发展和技术进步的影响,学习环境已经开始从线下转移到线上。尤其像今年这种情形,一些不可抗拒的外界因素,使得学校不得部在线教学,这让学生和教学工作者切身体会了线上教学的便利和优点,同时也找到了克服其缺陷的办法。因此,即使这场灾难过去后,线上教学也将紧密的与线下教学的模式相结合在一起。学生在网上学习将产生大量的学习行为数据,这些数据无论是对于学生还是教育工作者来说,都是一个巨大的“宝藏”。
通过机器学习算法进行数据分析,无疑是对这个“宝藏”最佳的开采方式。利用学生在网上的学习行为数据,感受学生的学习状态,预测学生的课程成绩。虽然学生是学习的主体,但是在学习过程中,难免会有过度自信或过分自卑的情况,学习行为数据没有任何感情的掺杂,可以给出一个理性、合理的评测。教师也可以根据预测情况,对学生个性化教学,因材施教,提交学生成绩。毫无疑问,对学习行为数据的分析是一个必然趋势趋势,是势在必行的。
本设计基于决策树算法从多角度对某学校网上平台的学生行为数据进行分析,将根据学生的综合成绩将学生划分为三类:优秀(80分 – 100分)、良好(60分 – 79)、差(0分 – 59分)。这些数据包括到课率、预习率、习题正确率、综合成绩,数据量达千余条。通过已有数据建立决策树模型,供该平台未来的使用者进行预测,起到教学预警的作用。
二、 目的
以学生的历史学习行为数据训练决策树,通过该决策树预测学生期末成绩处于哪一个档次(优秀、良好、差),使学生可以清晰的知道自己当前学习属于一个什么样的状态,一遍调整学习策略,取得更好的成绩。
三、 原理
1、 数据分析三步骤
a) 数据预处理(数据清洗)
大数据的来源和数据形式丰富多样,分析数据源可能存在许多脏数据,比如噪音数据、不完整数据、不一致数据。如果不对其进行合理的处理,会影响整个数据分析的结果,所以对数据进行预处理是一个非常重要的环节。
数据预处理的方法重要有数据清洗、数据集成、数据变换、数据归约等,本设计中所进行的主要是数据清洗。数据清洗技术是通过清理数据中的异常数据,纠正数据中存在的错误,清除重复多余的数据,从而使数据格式标准化。常用的处理方法包括填写缺失值、光滑噪声数据、识别或删除孤立点等。
本设计所分析数据源存在的脏数据情况主要是数据缺失,处理缺失数据的方法有很多种,比如忽略元组、手动填入空缺值、全局常量填充法、平均值填充法等。经过对比各种方法的优略性质及适用场景,本设计选择了平均值填充法进行数据预处理。
b) 构建模型
模型构建是根据数据形式及分析目标,选择最合适的技术和模型。模型的选择是整个数据分析中最为构建的一步,决定了数据分析的准确性。
本设计所研究的问题属于分类问题,因此选择分类算法中的决策树算法。在实现上,本设计基于 Python 的第三方库 sklearn 进行实现。scikit-learn(sklean)是机器学习中经典的专用库,涵盖了几乎所有主流机器学习算法,包括分类、聚类、回归、降维等,还包括了特征值提取、数据处理和模型评估三大模块。
c) 数据可视化
数据可视化是对视觉表现形式做出科学技术的研究,是将复杂信息数据清晰表达出来的一种工具形式。数据可视化有利于实现数据与数据背后用户的互动,帮助决策者对用户做出分析并为用户提供针对性的服务。
Python 在数据可视化方面有很多第三方库,比如 Matplotlib、Seaborn、ggplot、Bokeh、Mayavi、Plotly、pygal、geoplotlib、missingno 等,本设计选择 Matplotlib 来实现可视化,该库可以绘制柱形图、散点图、气泡图、堆积图、树地图、雷达图、热力图、组合图等众多图表,功能非常强大。
2、 决策树原理
a) 决策树构建三步骤
i. 特征值选择
特征选择决定了使用哪些特征来做判断。在训练数据集中,每个样本的属性可能有很多个,不同属性的作用有大有小。因此,特征选择的作用就是筛选与分类结果相关性较高的特征,也就是分类能力较强的特征。依据不同的特征选择,有如下三种经典的决策树算法:
算法名称 | 特征选择依据 |
---|---|
ID3 | 信息增益 |
C4.5 | 信息增益率 |
CART | 基尼系数 |
ii. 决策树生成
特征选择好后,从根节点出发,对节点计算所得的特征选择依据值(信息增益、信息增益率、基尼系数),选择值最大的特征作为节点特征,根据该特征的不同取值建立子节点;对每个子节点使用相同的方法生成新的子节点,直到特征选择依据值很小或者没有特征可以选择为止。
iii. 决策剪枝
剪枝的目的是为了对抗过拟合,通过主动去掉分支来降低拟合过度发风险。
b) 算法的对比及选择
i. 3 种经典决策树算法对比
算法 | 特征选择 | 树类型 | 特征类型 | 缺失 | 剪枝 | 任务 |
---|---|---|---|---|---|---|
ID3 | 信息增益 | 多叉 | 离散 | No | 无剪枝 | 分类 |
C4.5 | 信息增益率 | 多叉 | 离散/连续 | Yes | 有剪枝 | 分类 |
CART | 基尼系数 | 二叉 | 离散/连续 | Yes | 有剪枝 | 分类/回归 |
ii. 算法选择
本设计所用数据源的特征是:树类型为多叉树,特征值是离散值,目标是分来。所以,选择 C4.5 算法实现。
c) 决策树算法流程图
四、 实验环境
PyCharm Community Edition 2020.1.2 x64
Python 3.8.1
五、 实验方法及步骤
主函数:
if __name__ == '__main__':
# 加载数据
data = pd.read_csv('student_data.csv')
# 数据预处理
feature,label = data_preprocessing(data)
# 构造模型
mytree = structural_model(feature,label)
# 可视化训练好的决策树
tree_visualise(mytree)
# 计算预测正确率
feature_train, feature_test, label_train, label_test = train_test_split(feature, label, test_size=0.3)
rate = np.sum(mytree.predict(feature_test) == label_test) / mytree.predict(feature_test).size
print('训练集数量:',label_train.size)
print('测试集数量:',label_test.size)
print('正确率:',rate)
1、 数据预处理
def data_preprocessing(data):
# 数据清洗,采用用平均值填充空缺值
for column in list(data.columns[data.isnull().sum() > 0]):
mean_val = data[column].mean()
data[column].fillna(mean_val, inplace=True)
data = np.array(data.values)
feature = data[:,0:3]
label = data[:,3]
for i in range(np.size(label)):
if label[i]<60:
label[i] = 3
elif label[i]<80 and label[i]>59:
label[i] = 2
else:
label[i] = 1
return feature,label
2、 构建模型
a) 数据集划分
# 数据集划分,70%训练数据,30%测试数据
feature_train, feature_test, label_train, label_test = train_test_split(feature, label, test_size=0.3)
b) 调参
i. 调最 max_depth
# 选取最合适的深度
max_depths = []
for max_depth in range(10):
clf = tree.DecisionTreeClassifier(max_depth=max_depth+1)
clf.fit(feature_train, label_train) # 拟合
score = clf.score(feature_test,label_test)
max_depths.append(score)
best_depth = max_depths.index(max(max_depths))+1
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(range(1, 11), max_depths)
plt.xlabel('max depth')
plt.ylabel('evaluate score')
plt.show();
ii. 调 min_samples_leaf
# 选取最合适的最小叶子树
min_samples = []
for min_sample in range(30):
clf = tree.DecisionTreeClassifier(max_depth=best_depth,min_samples_leaf=min_sample+5)
clf.fit(feature_train, label_train) # 拟合
score = clf.score(feature_test, label_test)
min_samples.append(score)
best_min_samples_leaf = min_samples.index(max(min_samples))+5
print(best_min_samples_leaf)
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(range(4, 34), min_samples)
plt.xlabel('min samples leaf')
plt.ylabel('evaluate score')
plt.show();
c) 根据调好的测试构建模型
# 根据最合适的参数构建模型
mytree = tree.DecisionTreeClassifier(max_depth=best_depth,min_samples_leaf=best_min_samples_leaf)
mytree.fit(feature_train,label_train)
return mytree
3、 可视化
a) 安装 graphviz、pydotplus 插件
更多操作
b) 可视化生成的决策树
def tree_visualise(mytree):
# 可视化
dot_data = tree.export_graphviz(mytree, out_file=None,\
feature_names=["Attendance","Preview","Job"],\
class_names=["excellent","good","poor"],\
rounded=True)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf("dtree.pdf")
六、 实验结果及分析
数据量及预测正确率如下图:
七、 总结与展望
本文所训练的数据量只有 1852 条,其中用于训练模型的只有 1296 条,数据量相对较小,正确率只达到了 62.3%。随着教学的继续,网络平台上会积累更多的学生学习数据,随着数据量的增长,模型也会训练的越来越好,预测精确率越来越高。
有于时间关系,本设计并没有把模型做到最优。在日后的改进中,可以从 3 个方面进行改进:数据预处理方面,根据数据特点选择更好的方法清洗脏数据,本文选择的是平均值填入法,并不是最优的;算法选择方面,选择多种算法进行预测,挑选预测了最高的进行使用;算法参数调优方面,选择更好的评价标准。
在进行本文的代码实现部分时,我最先是自己编码实现决策树算法,但是后面改变了策略,选择了直接调人家写好的包来实现。也许有些人会觉得自己实现岂不是更好,而我不予苟同,像我这般低水平的编程者,先不说写出来的代码的效率,代码的正确性都可能是个问题。另外,我们应该专注于解决问题,本文的目的是实现通过学生行为数据来预测学生期末成绩的类别,应该先将其实现,再考虑算法的优化。我认为,借助别人的成果来解决自己的问题,而不是把时间花在重复造轮子上,这是最明智的选择。因为,只有站在巨人的肩膀上,我们才能看的更远。
最后
项目分享: