ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于K-Means与scikit-learn的学习者行为聚类分析实践

基于K-Means与scikit-learn的学习者行为聚类分析实践 简介这份PDF是基于机器学习的网络学习行为分析论文面向教育技术研究者、数据分析学习者及在线教育从业者。文章以sk-learn为平台围绕学习时长、学习频率、讨论交流、作业、测试等行为数据介绍数据清洗、特征标准化与K-Means聚类建模流程将学习者划分为优秀、良好、合格、较差四类并讨论在线时长、交流互动等因素与学习效果的关系为优化混合式教学提供数据参考。资源为1个PDF文件大小约2.02MB内容包含研究现状、实现步骤、核心代码片段与结果分析适合作为课程设计、论文写作或行为分析项目的参考文献。目前已有237人学习下载可作为快速掌握网络学习行为建模流程的入门资料。1. 学习行为分析为什么要用K-Means聚类一门网络课程结束后平台日志里躺着大量点击、时长、讨论记录但你可能说不清到底是什么行为决定了学习效果。单纯按考试成绩排名只能看到结果看不到过程直接看总时长又会被“挂机党”带偏。这个项目用286条真实学习行为记录把学习时长、学习频率、讨论交流得分、作业得分、测试成绩五个特征交给scikit-learn先标准化再跑K-Means聚类把学习者分成优秀、良好、合格、较差四类再反过来解读每一类人的行为特征。整个过程只依赖pandas和sklearn数据量不大却覆盖了从数据清洗、特征编码、聚类调参到业务解读的完整链路适合做教育数据挖掘、学习分析和学生画像的人照着复现。2. 学习行为特征定义与数据预处理从s_data.csv到标准特征2.1 外显行为特征的选择依据网络学习平台能采集到的原始日志很多但不是所有字段都适合直接进聚类模型。教育心理学把学习行为分成外显和内隐两类外显行为可以通过点击、登录、提交等操作直接观测内隐行为要靠问卷和量表推断。项目里只用了外显行为原因很现实——平台日志最稳定不需要额外发问卷也方便在每学期结束后自动跑批。论文借鉴了数字化学习力问卷的已有成果把行为记录收敛成五个特征具体含义如下表所示。特征字段含义类型Total_Time某一课程累计学习时长连续值Count_Day每天学习次数平均值连续值Discuss_s论坛参与度换算的讨论交流得分连续值Job_work作业提交次数与质量得分连续值Exam课程测试成绩连续值这五个字段分别对应学习投入时长、频率、学习交互讨论和学习产出作业、测试。和只拿考试成绩做评价相比这样的特征组合保留了个体之间不同的“努力结构”有人靠时间堆出成绩有人靠讨论和作业带动理解也有人时间花了很多但产出一般。聚类要捕捉的正是这种结构差异。这里有一个数据工程层面的坑论文正文先定义了学习频率字段Count_Day后面示例代码里又写成Day_count如果按示例代码直接读取CSV会报KeyError。实际处理时先打印students_data.columns核对列名再用rename统一避免后续标准化阶段才暴露问题。这类字段命名不一致在真实平台数据里很常见尤其是多人接手数据导出脚本时。2.2 pandas读取与特征筛选数据整理为s_data.csv共286条记录。读取和筛选特征的代码如下import numpy as np import pandas as pd students_data pd.read_csv(../data/s_data.csv) students_features students_data[[Total_Time, Count_Day, Discuss_s, Job_work, Exam]]students_data存放原始字段students_features只留5个特征。这里不需要划分训练集和测试集因为K-Means是无监督算法不依赖标签做损失计算和泛化验证。真正要检查的是空值和数据类型Discuss_s里的0分是有效记录Total_Time或Exam为空则需要按课程均值填充或者直接剔除。可以使用students_features.isna().sum()快速定位空值位置。如果平台上某些学生没有进入论坛Discuss_s为0是正常的不能把0当缺失处理但如果Total_Time为0且没有任何学习记录说明该样本可能不是有效学习者保留它会干扰聚类。286条数据本身不大删除少量异常行不会改变整体簇结构。2.3 StandardScaler标准化处理K-Means用欧氏距离衡量样本相近程度特征量纲不一致时学习时长几百分钟的数值差异会完全压制讨论得分个位数的差异。标准化是所有基于距离的聚类算法的前置步骤标准化的结果也会直接影响最终簇的边界。from sklearn.preprocessing import StandardScaler scaler StandardScaler() students_scaled scaler.fit_transform(students_features) np.savez(../tmp/students_scale.npz, students_scaled)StandardScaler计算每个特征的均值和标准差然后做(x-mean)/std变换让每个特征变为均值0、方差1。fit_transform在无监督聚类中直接使用即可不用像有监督流程那样拆成fit和transform两段。保存为npz文件是为了让后续聚类脚本直接加载标准化结果避免反复读取CSV产生版本不一致。为什么不用MinMaxScalerMinMax会把数据压缩到[0,1]但如果某个特征存在极端离群点比如某位学生累计学习时长异常高MinMax会把大多数样本压到靠近0的位置削弱区分度StandardScaler虽然同样对离群点敏感但变换后数据更接近标准正态分布在欧氏距离场景下通常更稳定。如果发现时长分布极度偏斜常见做法是先做log1p变换再标准化这个项目里原始数据分布尚可所以保留StandardScaler。提示标准化之前先用students_features.describe()观察取值范围。如果某列方差接近0说明所有学生几乎没有差异删除后能降低聚类噪声。3. K-Means聚类实现学习者分群和K值选择3.1 K-Means算法在学习者分群中的适用性K-Means的核心目标是把n个样本分到k个簇使每个样本到所属簇中心的距离平方和最小。流程是随机初始化k个中心把样本分配到最近的中心重新计算中心再迭代直到中心变化量小于阈值。对学习者分群来说不需要事先知道谁属于优秀还是较差只需要假定同一类人的行为模式在特征空间里靠得比较近。为什么选K-Means而不是层次聚类或者DBSCAN因为这里只有286条记录和5个连续特征K-Means运行快参数少可解释性也直接每个簇的质心就是该类学习者的“平均行为画像”。层次聚类更适合需要树状图辅助决策的数据DBSCAN更擅长发现任意形状簇和离群点但学习行为数据基本是球形簇且没有太多离群点K-Means是性价比最高的选择。sklearn里的K-Means默认使用k-means初始化它会尽量让初始质心彼此分散避免一开始就落到局部最优。配合后面的n_init参数可以在多次随机初始化中挑出最稳定的结果。这一点对教育数据这类边界模糊的数据尤其重要。3.2 基于sklearn的聚类核心代码加载上一步保存的标准化数据并聚类代码如下from sklearn.cluster import KMeans students_scaled np.load(../tmp/students_scale.npz)[arr_0] kmeans_model KMeans(n_clusters4, random_state42, n_init10) kmeans_model.fit(students_scaled) labels kmeans_model.labels_n_clusters4对应优秀、良好、合格、较差四个教学分组这是业务先验random_state42固定随机种子保证复现n_init10表示用10组不同初始质心各跑一遍取惯性最小的那组结果。需要说明的是sklearn较新版本中n_init默认值已经从10调整为auto如果希望行为稳定显式传n_init10仍然是最稳妥的写法。max_iter使用默认300对286条5维数据完全足够。聚类完成后labels是0到3的整数此时簇编号没有语义。需要通过kmeans_model.cluster_centers_查看每个簇的质心向量再结合平均测试成绩排序把簇编号映射为优秀、良好、合格、较差。如果只用labels不排序会出现每次运行簇编号改变但簇内容不变的情况导致后续分析脚本取错类别。3.3 K值选择肘部法则与教学标签映射项目直接采用k4但实际建模时K值最好有依据。常见做法是画肘部图观察簇内误差平方和随K值变化的拐点import matplotlib.pyplot as plt inertia_list [] for k in range(2, 9): km KMeans(n_clustersk, random_state42, n_init10) km.fit(students_scaled) inertia_list.append(km.inertia_) plt.plot(range(2, 9), inertia_list, markero) plt.xlabel(k) plt.ylabel(inertia) plt.show()inertia是每个点到所属簇中心的距离平方和也叫簇内误差平方和。随着K增大inertia必然下降但当K从4继续增大时下降幅度明显变缓这个拐点就是肘部。学习行为数据通常不会出现非常尖锐的拐点所以要把肘部法则和业务需求结合四类分别对应优秀、良好、合格、较差方便教师理解也方便后续做分层教学。聚类结束后把每个簇的特征均值归一化成A-D等级。A代表该特征在四个簇中最大D最小。这个项目得出的特征等级表如下它同时也是第4章分析行为与效果关系的依据。学习者类别学习时长学习频率讨论交流作业测试优秀BCBAB良好AACAB合格CBBCC较差DDDDD要注意这里的等级是相对等级不是绝对分数。比如优秀类的学习频率是C只能说它在四类里相对偏低不代表绝对低。解读时如果说“优秀类频率低”会和常识冲突还会影响后续教学建议的准确性。等级映射这一步建议写成一个小函数自动完成避免手工填表的笔误。4. 学习者行为特征与学习效果的关系分析4.1 聚类结果的特征等级表上一章得到的聚类结果按特征均值转成可读的等级表就是3.3节那张表。它也是所有行为解读的原始依据。为了确认等级映射没有出错这里可以打印标准化后的质心正负数值反映相对高低import pandas as pd cluster_centers pd.DataFrame( kmeans_model.cluster_centers_, columns[Total_Time, Count_Day, Discuss_s, Job_work, Exam] ) cluster_centers[类别] [优秀, 良好, 合格, 较差] print(cluster_centers.round(2))标准化后的质心数值如果大于0表示该特征高于本次分析的总体平均水平小于0则表示低于平均水平。这份输出可以用来检查作业和测试两个维度上的簇排序是否符合教学直觉。如果出现较差类的测试均值反而高于合格类说明簇编号映射顺序错了需要回到cluster_centers重新排序。用这个方式校验后可以再把原始字段按簇分组求均值输出成绩和时长的绝对数值便于写教学分析报告students_data[cluster] kmeans_model.labels_ cluster_summary students_data.groupby(cluster)[ [Total_Time, Count_Day, Discuss_s, Job_work, Exam] ].mean() print(cluster_summary.round(2))groupby按簇编号聚合mean()计算每个簇内各特征的平均值。得到的表格比A-D等级更直观但要注意原始数值受量纲影响不能直接跨特征比较必须回到标准化空间看差异。4.2 在线时长、上网频率、交流活动与学习效果的关系结合特征等级表可以看到三个明确结论。第一个结论是在线时长与学习效果基本正相关优秀和良好的时长等级分别是B和A明显高于合格和较差的C和D。这说明足够的在线学习时间仍然是网络学习效果的基础保障资源数量和内容长度不能太薄。第二个结论是上网频率高不一定效果好。良好类的学习频率达到A是四类里最高的但学习效果没有超过频率只有C的优秀类。合理的解释是高频次、短时长的碎片化学习难以形成持续认知而优秀类单次学习更集中。课程设计时应控制学习单元的粒度既不要太短让学习变成打卡也不要太长超出注意力边界。第三个结论与前两个相互印证交流讨论是优秀和良好的分水岭。良好类在时长和频率上都优于优秀类但讨论交流等级是C优秀类是B。投入了更多时间却没有换来更好的成绩问题就出在缺少论坛答疑、讨论互动等高认知参与行为。教师在组织网络学习时必须把讨论交流设计成有积分、有反馈的正式环节而不是挂一个没人说话的论坛。4.3 从数据分析到教学改进的落地建议基于以上结论教学改进至少有三个抓手。第一在线学习时长要有基本保障但资源要适配移动端和多种网络环境方便学生把整段时间用起来。第二学习单元的内容量和时间长度要控制防止碎片化刷时长。第三把讨论交流纳入评价体系配合作业检查和答疑让线上学习承担一部分线下监督职能实现线上线下结合。这一步的分析没有额外代码因为行为解读属于业务环节。但要注意所有结论都建立在“相对等级”的框架内不能脱离聚类原始数据直接说A比B好多少。如果要在生产环境复用建议把聚类结果和成绩分布图、时长直方图放在一起交叉验证避免单表误读。5. 聚类模型验证与部署中的常见坑5.1 用轮廓系数验证分群质量K-Means不管数据长什么样都会强行分成K组但分成K组不代表分得好。sklearn的silhouette_score能给出量化指标from sklearn.metrics import silhouette_score score silhouette_score(students_scaled, kmeans_model.labels_) print(silhouette_score:, score)轮廓系数范围在-1到1之间越大说明同一簇越紧凑、不同簇越分离。对学习行为数据得分在0.2以下要考虑调整K或换特征0.3到0.5属于可用范围。因为学习行为本来就是连续梯度不能指望像图像分类那样得到0.7以上的高分离度。5.2 小样本数据与字段不一致的排错经验286条数据属于小样本聚类结果可能对随机种子敏感。建议固定random_state并同时跑几个不同种子对比labels的稳定性如果某次聚类把学生归类产生明显跳跃说明簇边界本来就模糊更适合用较弱的教学标签如“待观察”。字段不一致问题也来自这次实现中的Count_Day/Day_count混用处理方式是读取后用columns核对并用rename做统一映射。标准化之后如果出现NaN回头查原始CSV的空值不要急着在模型里找原因。另一个常见问题是保存npz时没有记录列名顺序下次加载后列顺序错位导致质心含义完全错乱。解决方法是同时保存列名列表或者在加载后重新按列名取子集。5.3 后续扩展从单课程到多课程的行为画像把这个流程复制到多门课程时有两点建议。其一是按课程分别标准化别把不同课程的学习时长混在一起归一化否则时长很短但难度很高的课程会被整体压到低分。其二是增加视频完成率、章节点击顺序、重复观看次数等特征让行为画像更细。聚类得到的四类标签只代表当前数据集里的相对模式不要直接当成绩预测模型用更不能作为对学生的最终定性。本文还有配套的精品资源点击获取
返回列表