基于多源校园数据的学生画像构建:特征聚合、KMeans 分群与可视化解读
摘要
大家好,这篇文章描述一套从学籍、成绩、考勤与一卡通消费数据构建学生画像的流程:在清洗阶段统一学号并完成学生级汇总;在分析阶段衍生偏科与成绩稳定性等指标,采用标准化后的 KMeans(k=5)划分群体,并基于簇特征与分位数规则生成可读的群体命名;进一步输出规则化标签与风险评分
1 引言
这篇文章记录了一套从学籍、成绩、考勤与一卡通消费数据构建学生画像的完整流程。
工程实现分为两段脚本:
clean.py:负责数据清洗、学号统一、多表连接,生成学生级宽表student_profile.csv。analysis.py:负责特征衍生、KMeans 聚类、可视化、及画像卡与风险评分生成。
阅读本文,你可以获得一个可运行的、从原始 CSV 到学生群体画像的端到端方案。
免责声明:本文使用的数据均为经过脱敏处理的模拟数据,不包含任何真实学生隐私信息。文中出现的“班级”、“姓名”等字段仅为结构示意。
环境与依赖: 建议使用 Python 3.10+(本文在 Python 3.11 下调试);核心第三方库为 pandas(数据清洗与聚合)、NumPy(数值计算)、scikit-learn(StandardScaler、KMeans)、matplotlib(可视化)。
2 数据与目录约定
| 路径 | 说明 |
|---|---|
| data/ | 原始 CSV |
| outputs/cleaned/ | 清洗结果,主文件 student_profile.csv |
| outputs/analysis/ | 分析结果(表格、图像) |
3 清洗阶段:学生级画像表
清洗阶段是整个工程的基石。我们在这一步完成:
- 文件编码兼容与列名规范化。
- 关键操作:所有表映射到统一主键
bf_StudentID,这是后续多源数据聚合的灵魂。 - 成绩数值化与缺考处理(缺考不计入平均分)。
- 考勤规则统计、消费金额符号统一。
核心聚合逻辑类似于:
# 多表合并示意student_profile=pd.merge(students_info,grades_agg,on='bf_StudentID',how='left')student_profile=pd.merge(student_profile,attendance_agg,on='bf_StudentID',how='left')student_profile=pd.merge(student_profile,consumption_agg,on='bf_StudentID',how='left')student_profile.to_csv('outputs/cleaned/student_profile.csv',index=False)最终形成一人一行的宽表。
4 分析阶段:衍生特征与 KMeans 群体划分
4.1 学业相关特征
从行为数据中挖掘出两个不易直接获取的特征:
- 偏科指数(
subject_std):将学生各科平均分展开成宽表,按行计算各科均值的标准差。数值越大,科目间差异越显著。 - 成绩稳定性(
score_std):学生历次成绩的标准差,反映其成绩的波动程度。
4.2 聚类划分逻辑
我们选取了五个维度组成特征向量:
avg_score, score_std, total_spend, late_count, subject_std处理步骤如下:
- 缺失值以0填充后,使用
StandardScaler标准化。 - 调用 KMeans 算法,固定随机种子以保证可复现。
fromsklearn.preprocessingimportStandardScalerfromsklearn.clusterimportKMeans# 五维特征:成绩均值、成绩波动、总消费、迟到次数、偏科指数(缺失用 0 参与聚类)features=profile[["avg_score","score_std","total_spend","late_count","subject_std"]].fillna(0)# 标准化:消除量纲,避免某一维数值特别大支配距离scaler=StandardScaler()X_scaled=scaler.fit_transform(features)# KMeans:固定簇数与随机种子,保证同一数据下结果可复现kmeans=KMeans(n_clusters=5,# 学生群体分为 5 类,可按需求调整random_state=42,# 复现用;改数据/改 k 后簇编号含义需重新解读n_init="auto",# sklearn 较新版本推荐初始化策略)profile["cluster"]=kmeans.fit_predict(X_scaled)4.3 群体命名规则(业务可读标签 cluster_name)
命名不针对单个学生,而是针对每个簇在各维度上的簇内均值,与全校四个维度的 75% 分位数比较:
| 条件(簇内均值相对全校) | 标签片段 |
|---|---|
| 平均成绩 ≥ 成绩的全局 75% 分位 | 高绩效 |
| 总消费 ≥ 总消费的全局 75% 分位 | 高消费 |
| 迟到次数 ≥ 迟到的全局 75% 分位 | 高迟到 |
| 偏科指数 ≥ 偏科的全局 75% 分位 | 偏科明显 |
若命中多项,以「 / 」连接;若四项均未达到上述阈值,则记为 综合平稳。该规则保证图中「群体名称」与簇中心统计一致,便于文字叙述与图例对照。
4.4 本批次结果中簇 0~4 的含义(结合统计表解读)
下表基于 outputs/analysis/student_profile_enriched.csv 按 cluster 分组统计得到(人数、cluster_name 众数、簇内均值)。撰写论文或博客时,若重新跑分析,应重新生成该表以保持与图表一致。
| cluster | cluster_name(众数) | 人数 n | 簇内平均成绩(约) | 簇内平均总消费(约) | 簇内平均迟到次数(约) | 简要解读 |
|---|---|---|---|---|---|---|
| 0 | 高消费 | 506 | 55.53 | 3167 | 0.53 | 总消费维度的簇均值处于全校高位,命名为「高消费」;成绩与迟到在簇均值上接近中等水平。 |
| 1 | 综合平稳 | 769 | 56.69 | 2081 | 0.68 | 人数最多;簇均值未达到四条「高×」命名阈值,属中间型群体。 |
| 2 | 综合平稳 | 268 | 53.77 | 976 | 0.55 | 与簇 1 同为「综合平稳」,但平均总消费明显更低、平均成绩略低,可叙述为「消费总额偏低、学业略低的中间群体」。 |
| 3 | 高迟到 | 198 | 8.72 | 2068 | 1.13 | 命名上侧重迟到相对突出的一组;簇内平均成绩极低,建议核查缺考、记录缺失或样本量极少的成绩记录,避免误读。 |
| 4 | 高迟到 | 24 | 57.57 | 2406 | 13.29 | 人数很少但簇内平均迟到次数很高,属于「迟到行为极端」的典型小群体。 |
关于「综合平稳」出现两次: 命名规则只看簇均值是否越过全局 75% 阈值;簇 1 与簇 2 在多维空间中的位置不同(例如消费总额差异大),KMeans 仍将它们分为两簇。写作时应用上表数值区分二者,而不能仅依赖四字标签。
5 图表 placement、图注与结果分析
集中展示以下图表,形成从宏观到微观的证据链。
5.1 portrait_cluster_radar.png(学生群体画像雷达图)
图注示例: 「图 1 五类学生群体在平均成绩、总消费、迟到次数、偏科指数上的簇内均值轮廓(已对簇内均值做 min-max 归一化以便形状对比;同一图上不同簇可不直接比较原始量纲)。」
分析要点: 雷达图用于对比五类群体的相对强项与弱项(哪一维隆起或凹陷)。阅读时配合 §4.4 表格中的簇编号与 cluster_name,例如「高消费」簇是否在消费维度突出,「高迟到」簇是否在迟到维度突出。
5.2 cluster_sizes.png(各学生群体人数分布)
图注示例: 「图 2 各簇学生人数分布(簇编号 0~4 与 §4.4 群体含义表对应)。」
这张图把学生分成了 5 个群体,每个群体在「平均成绩、总消费、迟到次数、偏科指数」四个维度上有明显差异:
5.3 score_by_cluster.png(各群体平均成绩分布)
图注示例: 「图 3 各簇学生平均成绩的箱线图分布。」
图3显示,簇3的成绩分布与其他四簇明显分离,其中位数仅为5分左右,箱体极度压缩,远低于全校平均水平,且无任何上须延伸。这一异常形态与表4.4中簇3平均成绩8.72分相符,但中位数更低,暗示该群存在大量近乎零分的记录。结合本分析中缺考编码已被剔除,该现象仍需核查原始成绩表是否存在大量补考未录入、缓考数据缺失或学生已休退学等数据质量问题。
5.4 consumption_distribution.png(学生总消费分布与参考线)
图注示例: 「图 4 学生总消费直方图及参考竖线;须注意横轴为总消费,与月均口径在文字中区分。」
这张图展示了学生月消费的分布,并以15% 分位值 = 1370.5作为 “贫困线” 参考:
消费分布呈明显的单峰形态,峰值在 2000 元左右,说明大部分学生的月消费集中在 1500~4000 元区间。
红色虚线左侧(消费≤1370.5元)的学生数量极少,说明绝大多数学生的消费都远高于贫困线水平,整体经济条件较好
5.5 late_vs_score.png(迟到次数与平均成绩散点图)
图注示例: 「图 5 迟到次数与平均成绩散点(按簇着色)。」
相对于群体 0 1 2 3 ,群体4迟到率比较高,成绩无明显区别。
5.6 subject_bias_dist.png(偏科指数分布)
- 图注示例: 「图 6 偏科指数(各科均分标准差)的直方图及经验参考线。」
整体情况:超半数学生偏科指数≥15,偏科是普遍问题。
群体关联:
「高消费 / 综合平稳」群体:偏科指数低,成绩均衡。
「高迟到」群体:偏科指数高,成绩分化严重。
干预重点:盯紧临界线附近的学生,防止滑向偏科;重点帮扶迟到、偏科双高的学生。### 5.7 individual_radar_.png 与 individual_labels_.txt(个人微观画像示例)
5.7 individual_radar_.png 与 individual_labels_.txt(个人微观画像示例)
图注示例: 「图 7 某学生各科成绩与全校均分对比(雷达图)」
分析要点: 体现从「群体」到「个人」的下钻;强调示例为随机抽取,完整结论应以 student_portrait_cards.csv 为准。
6. 画像卡:标签与风险评分
我们设计了两套互补的输出来描述学生,解决“描述”与“排序”两种不同需求:
portrait_tags(规则标签):像一张便签,用几句话描述学生概况,适合快速浏览。- 风险评分与原因:一个 0-100 的量化分数,用于全校范围内排序筛查,并附上可解释的原因。
6.1 portrait_tags:标签生成规则
程序基于全校分位数,为每个学生贴上由以下五个维度组合而成的标签:
- 成绩:全校平均分的 20% 和 80% 分位为界,分为
成绩优秀、成绩中等、成绩待提升。 - 偏科:偏科指数 ≤ 15 为
学科均衡,否则为偏科明显(注:此阈值与聚类命名的“偏科明显”规则不同,可能会有一致或不一致的个案,属正常现象)。 - 消费:有月均消费数据时,与全校比较,分为
低消费、消费适中、高消费。若无月均数据,则跳过此段。 - 考勤:迟到次数达到全校高段位,标为
迟到偏多,否则出勤较好。 - 成绩稳定性:成绩波动大则标为
成绩波动大,否则成绩较稳定。
最终将命中的标签用顿号连接,如:“成绩优秀、学科均衡、消费适中、出勤较好、成绩波动大”。
6.2 风险评分体系
四个分数都是 0~100,数值越高,代表在数据上越值得关注(非品行鉴定)。
- 学业风险(academic_risk_score):综合均分偏低、偏科程度、成绩波动三者,经分位数映射后合成。
- 消费风险(consumption_risk_score):考察消费的两端(过高或过低)及刷卡频次异常,优先使用月均消费计算。
- 考勤风险(attendance_risk_score):由迟到、早退加权得到,迟到权重更大。
- 综合风险(overall_risk_score):默认为
学业*0.5 + 考勤*0.3 + 消费*0.2,侧重学业与出勤。
6.3 风险等级与原因
- 风险等级(risk_level):按综合分切为
低/中/高,用于快速过滤,不作为最终定性。 - 风险原因(risk_reasons / risk_reasons_top3):通过 if 规则生成解释(如“成绩落入全校后20%”、“迟到次数过多”等),用分号连接。
top3字段只取最靠前的三条,适合打印成报表。
提醒:可能出现“分数较高但文字原因较少”的情况,这是设计上允许的。因为评分是加权连续值,原因则是离散规则触发。二者互补,而非完全一一对应。
7 主要输出文件
| 文件 | 谁来看 | 内容要点 |
|---|---|---|
student_portrait_cards.csv | 数据分析师 | 每人一行,含标签、四类风险分、等级、原因全貌 |
high_risk_students_top100.csv | 学生工作者 | 综合风险排序前100,列全,用于建立关注名单 |
high_risk_students_explanations.csv | 班主任/汇报 | 姓名班级+分+原因前三条,简洁,方便沟通 |
poor_student_candidates.csv | 资助工作 | 低消费候选,用于辅助分析 |
*.png | 所有人 | 论文、报告所需的各种可视化图表 |
8 合规与边界
- 公开发表的 CSV 或图片必须对学号、姓名等彻底脱敏。
- 所有风险评分和标签都是基于有限数据的辅助分析工具,不能替代正式认定和综合评价。
- 涉及资助、处分等实际工作,请务必遵守学校规定与个人信息保护法。
9 结语
本文提供了一套特征工程→聚类→命名→画像卡输出的完整管道。你可以在替换数据后,一键重跑脚本刷新所有表格和图像,快速得到属于你这批数据的结论。
- 对技术同学:这是一个融合了数据清洗、无监督学习、特征分箱和结果可视化的经典毕设/项目参考。
- 对业务老师:这套输出可以帮你从几千行原始表格中解放出来,看到一个“活”的学生概览图谱。
