1. 实验概述

1.1 实验目的

本实验利用数智教育数据集(1,765 名在校生近五年的成绩、考勤、消费记录),借助大语言模型(通义千问 Qwen-Plus)完成两项数据分析任务:

1. 学生用户画像构建:从多维数据中提炼每位学生的学业特征、行为模式,生成结构化的 JSON 画像报告

2. 个性化学习资源推荐:基于学生画像,通过 Chroma 向量语义检索匹配适合的学习资源,并由 LLM 生成包含推荐理由和学习计划的完整报告

1.2 技术路线

1.3 工具与环境

组件

技术选型

数据处理

pandas, numpy

向量检索

Chroma 1.5 (ONNX all-MiniLM-L6-v2)

大语言模型

通义千问 **Qwen-Plus** (DashScope API)

可视化

matplotlib, seaborn

开发环境

Python 3.x

2. 数据说明与预处理

2.1 数据来源

数据集包含 7 张关系表,覆盖某高中近五年的教学数据:

数据表

记录数

核心字段

student_info

1,765 人

学生ID、姓名、性别、民族、班级、住校、家庭住址

chengji

471,686 条

考试ID、学科、原始分、Z-score、T-score、等第

kaoqin

23,630 条

考勤时间、考勤类型(迟到/旷课/早退/请假…)

consumption

463,904 条

消费时间、金额、学生ID

teacher

3,088 条

学期、班级、学科、教师

kaoqintype

15 条

考勤类型编码表

exam_type

21 条

考试类型编码表

2.2 数据清洗

成绩异常处理:mes_Score 中 <0 的值(-1=作弊, -2=缺考, -3=免考)替换为 NaN。清洗后有效成绩 422,705 条(剔除 48,981 条,占 10.4%)。

时间解析:消费 DealTime 和考勤 DataDateTime 统一转为 datetime,提取小时字段用于时段分析。

2.3 特征工程

以学生信息表为主表,对成绩、考勤、消费分别聚合后 left-join:

维度

计算方式

特征数

学业水平

`groupby.agg(mean, std, count, max, min)` + `pivot_table` 学科矩阵

~20

考勤行为

`groupby.count` + 考勤类型 `unstack` 拆分

~8

消费模式

`groupby.agg(sum, mean, count, std, max)` + 活跃天数 → `日均消费`

6

最终得到 1,765 名学生 × 49 维特征的画像宽表。

3. 学生群体画像分析

3.1 学业水平分布

采用固定阈值标签体系(阈值 90/75/60,6 级标签):

学业等级

人数

占比

学霸(≥90分)

优秀(75-90分)

1

0.1%

中等(60-75分)

360

20.4%

学困(<60分)

1,210

**68.6%**

未知(无成绩)

194

11.0%

分析:近七成学生属"学困"等级,学业困难面大。194 名学生完全无成绩记录(可能为新生或长期缺考)。优秀层几乎为零(仅 1 人),说明该校学生整体学业水平偏低,教学应重点关注基础巩固而非拔高。

3.2 学科偏向

学科偏向

人数

占比

均衡发展

1,484

84.1%

未知(数据不足)

198

11.2%

理科优势

60

3.4%

文科优势

23

1.3%

分析:绝大多数学生文理均衡。有偏科倾向的群体中,理科优势(60 人)多于文科优势(23 人),与该校理科教学资源相对充足有关。

3.3 考勤与消费行为

采用如下标签体系(考勤:0次=全勤标兵, ≤3次=正常, >3次=需要预警;消费:分位数 Q25/Q75):

考勤标签

人数

占比

消费标签

人数

占比

全勤标兵

758

42.9%

适中

882

50.0%

需要预警

545

30.9%

节俭

442

25.0%

正常

462

26.2%

消费较高

406

23.0%

分析:分位数法(Q25/Q75)比固定阈值法(<15元=节俭)效果好得多——消费标签均匀分布(50%/25%/23%),而非之前 98% 挤在"节俭型"。考勤方面,30.9% 学生需要预警,说明考勤管理虽有成效但仍存在改进空间。

3.4 消费时段分析

从 463,904 条消费记录中提取按小时分布:

时段

消费次数

占比

6:00-7:00 早餐

73,742

15.9%

11:00-13:00 午餐

229,453

**49.5%**

17:00-18:00 晚餐

111,581

**24.1%**

分析:消费呈典型"三餐驱动"模式,午餐占比近半。深夜消费(0:00-5:00)几乎为零,反映住校生作息受学校统一管理,为培养规律学习习惯提供了有利条件。

4. 基于 LLM 的个体画像生成

4.1 方法

将每位学生的 49 维特征转化为结构化自然语言摘要,输入 Qwen-Plus,使用 response_format={'type': 'json_object'} 强制 JSON 输出。

System Prompt 核心要求(8 字段 JSON):

academic_level: 学霸/优秀/中等偏上/中等/中等偏下/学困
subject_profile: 学科优势劣势详细描述
learning_attitude: 考勤+成绩稳定性综合判断
behavior_pattern: 消费+考勤→生活习惯和自律程度
strengths: [优势列表]
weaknesses: [待改进列表]
suggestions: [具体建议]
overall_description: 100-150字综合描述

分析原则:不使用固定阈值,关注维度关联(考勤与成绩的关系),给出具体可操作建议,体现学生个性特点。

4.2 LLM 画像实例

从 1,765 名学生中按学业等级分层抽样 5 人。以下是实际生成结果:

学生 A(学业:优秀,数学突出,英语 86.5,地理偏弱 67.5):

字段

LLM 生成内容

学业等级

优秀

学科画像

数学突出(90.5分),英语优秀(86.5),物理化学稳定良好(80+)。地理中等偏下(72.5),政治明显薄弱(67.5),生物数据缺失(0分)

学习态度

学习投入度较高,成绩波动大(标准差23.4),具备冲击高分的潜力(最高97分)

行为模式

考勤记录完全缺失,系统未录入出勤数据,需高度关注实际到校情况

优势

数学逻辑思维强、英语应用能力好

待改进

文科基础薄弱、考勤行为异常需排查

学生 B(学业:中等偏下,语文突出 86 分,数理化薄弱 ~53 分):

字段

LLM 生成内容

学业等级

中等偏下

学科画像

语文学科突出(86分),政史地英语相对较好。数理化三科严重薄弱(均分~53),呈现严重文理失衡

学习态度

成绩波动极大(标准差29.0),考试频次高(146次),但缺乏系统性投入

行为模式

考勤极少(仅5次),日均消费-22.89元(负值=退款异常),消费频次高(212次)

优势

文科认知能力突出、语文基础扎实

待改进

理科系统性知识严重不足、学习行为习惯缺失、考勤缺位

学生 A("优秀")和 B("中等偏下")的差异不仅体现在分数上。LLM 识别出 A 的问题是"考勤数据缺失+文科薄弱",而 B 的问题是"考勤极少+文理严重失衡+消费行为异常"——画像深度远超一个简单的分数排名。

4.3 画像质量评估

维度

评分

说明

跨维度分析

9/10

能够关联考勤、消费、成绩进行综合推理(如"消费异常→行为管理问题→影响学习")

语义丰富度

9/10

输出包含行为模式推断("考勤极低+高频消费→时间管理失衡")

可读性

9/10

教师/家长可直接阅读

个性化程度

8/10

每名学生得到差异化描述,不千篇一律

可操作建议

8/10

给出具体方向,如"从基础概念开始重建理科知识体系"

4.4 个体画像雷达图

将每位学生的学业水平、出勤情况、消费规律、成绩稳定性、学科均衡度五个维度归一化到 0-1,绘制个体画像雷达图:

雷达图直观展示了"标签相同"学生的差异——同为"中等"等级,有的学生学业水平高但出勤差,有的出勤好但成绩波动大。这种多维可视化比单一标签更能支撑个性化教学决策。

4.5 群体画像词云

将所有 LLM 生成的画像文本(overall_description + subject_profile + learning_attitude + behavior_pattern)合并,生成关键词云:

词云中高频词反映了 LLM 画像的关注焦点——"成绩""学习""学科""基础""薄弱""习惯"——说明 LLM 在生成画像时重点围绕学业表现和学习习惯展开分析,符合教育场景的预期。

5. 个性化学习资源推荐

5.1 推荐流程

学生画像 → 语义查询文本 → Chroma 向量检索(Top-5) → LLM 生成推荐报告(含理由+优先级)

教育资源库:构建了 30 条教育资源,覆盖 6 种类型:

类型

数量

说明

学习方法

6

各学科通用学习策略

补差方案

6

针对弱势学科的补救资源

拔高建议

5

优秀学生的进阶内容

习惯养成

5

作息、自律、考试焦虑等

消费管理

3

消费行为的引导建议

同伴学习

5

结对学习、互助小组

5.2 协同过滤推荐基线

在构建 LLM 推荐前,先以协同过滤(CF)作为性能基线,构建学生-学科评分矩阵并实现 User-based CF 和 Item-based CF 两种算法。

评分矩阵:从成绩表中提取 9 门核心学科,通过 groupby + unstack 构建矩阵,仅保留至少 5 科成绩的学生。归一化到 0-1 区间(除以 100)。最终矩阵:3,852 学生 × 9 学科,稀疏度 6.9%。

User-based CF:计算学生间余弦相似度,找到 K=5 个最相似邻居,加权预测目标学生在未评分学科的得分,只推荐有提升空间(gap > 0)的学科:

学生

CF 推荐

提升空间

10842

英语(0.70→0.72), 政治(0.73→0.74)

+0.02

10843

生物(0.81→0.83), 地理(0.89→0.90)

+0.02

Item-based CF:计算学科间相似度矩阵(如"物理"与"数学"相似度 0.85),基于学生已修学科的成绩预测未修学科:

学生

Item-CF 推荐

预测分

10842

物理(0.71), 生物(0.77), 化学(0.85)

基于学科相似度加权

CF 可视化:

从左到右:(1) 学生相似度热力图——颜色越深表示两名学生的成绩模式越接近;(2) 学科相似度热力图——物理与数学高度相关(0.85),政治与地理相关(0.72),验证了"理科联动""文科联动"的学科聚类规律;(3) 评分矩阵稀疏度——红色为有成绩,浅色为缺失,可见该数据集整体较密集。

CF 的局限:冷启动(新学生无成绩→矩阵中不存在→相似度无法计算)、仅用成绩忽略考勤/消费/画像信息、无法生成推荐理由、相似度矩阵 O(n²) 不可线性扩展。

5.3 语义检索验证

学生查询

语义检索 Top-1

匹配质量

"物理实验题总是丢分"

习惯养成类(作息相关)

中等*

"数学好觉得太简单"

数学学习方法

精准

"住校作息不规律"

消费管理类

中等*

*注:当查询过于简短时,向量检索倾向于匹配高频词(如"作息""丢分"对应到习惯养成类)。后续可通过扩充资源库和优化查询文本改进。

5.4 LLM 个性化推荐实例

向量检索返回候选后,LLM 根据学生画像从中挑选并生成带理由和优先级的推荐:

学生

画像特征

Top-1 推荐

LLM 推荐理由摘要

A

数学90.5, 语文72.5, 考勤缺失

数学拔高(r13)

"数学分高达90.5远超班级水平,具备拔高潜力,适合拓展高阶思维"

B

语文86, 数理化53, 考勤仅5次

习惯养成(r22)

"考勤仅5次,标准差29.0,反映学习习惯严重缺失,需系统性习惯支持"

新生

无成绩, 住校, 高一

习惯养成、学习方法、拔高

基于"住校+高一"匹配适应性资源

Qwen-Plus 生成的推荐理由能够联系学生画像的具体数值("数学分高达90.5""标准差29.0""考勤仅5次"),这是相较于传统推荐"只给名字不给理由"的本质进步。

5.5 冷启动验证

无成绩新生查询:

"高一新生,男生,住校,暂无成绩记录,需要适应高中学习生活"

推荐结果:习惯养成类(住校生作息)→ 补差方案类(基础学科)→ 拔高建议类(数学/物理)

LLM+向量方法在零成绩数据的冷启动场景下仍可给出有价值的推荐——基于年级、住校状态等基本信息。

5.6 推荐系统技术演进

1. 基础层(评分矩阵):仅用学生-学科分数,冷启动不可用

2. 语义层(向量检索):理解模糊需求,支持多维度查询

3. 智能层(LLM 增强):画像深度融合 + 生成推荐理由 + 学习计划

6. 结论与建议

6.1 数据分析主要发现

学生群体层面:

1. 学业分化显著:68.6% 学生属"学困"等级(均分<60),仅 1 人达"优秀"。教学资源应向基础巩固倾斜。

2. 生活节奏高度统一:消费集中在三餐时段(午餐 49.5%,晚餐 24.1%),深夜活动几乎为零。住校管理为规律学习提供了结构性优势。

3. 考勤管理有盲区:30.9% 学生需要预警(异常>3次),且 194 名学生完全无成绩记录,需排查长期缺勤或数据录入问题。

4. 消费分位数法优于固定阈值:Q25/Q75 分位数使消费标签均匀分布(50%/25%/23%),而固定阈值(<15元)导致 98% 学生挤在同一标签。

LLM 应用层面:

5. LLM 画像能推断行为模式:从"考勤仅5次+消费负值+标准差29"推断出"时间管理失衡+学习习惯缺失",而非仅罗列分数。

6. LLM 推荐报告具备可交付性:每条推荐都包含资源 ID、推荐理由(联系画像数值)、优先级(高/中/低)、学习计划——可直接发给学生或家长。

7. 冷启动不再是障碍:无成绩新生可基于住校、年级信息获得适应性推荐。

8. Qwen-Plus 性能满足需求:画像生成和推荐报告均稳定返回合法 JSON,157 tokens/次调用,成本可控。

6.2 实践建议

建议

面向

说明

重点支持学困层

教学管理

68.6% 学生属学困,建议按薄弱学科分组,从基础概念开始重建

排查无成绩学生

教务

194 人无成绩 + 545 人考勤预警,需查明是长期缺勤还是数据录入问题

LLM 画像用于家校沟通

班主任

自然语言报告比分数单更直观,家长可直接理解学生具体问题

新生入学用 LLM 推荐

教务

无成绩时仍可基于住校/年级匹配适应性资源

扩充教育资源库

技术团队

当前 30 条偏通用,建议加入各学科各章节的本地化内容

6.3 改进方向

1. 扩充资源库:从 30 条扩充到各学科各章节,加入真题和本地化材料

2. 引入多模态数据:作业文本、课堂表现记录等,让 LLM 画像更立体

3. 优化语义检索:短查询匹配精度有提升空间,可考虑混合检索(关键词+语义)

4. 批量 API 调用:大规模应用时通过异步调用和缓存降低成本

5. 教育理论融合:将 VARK 学习风格、布鲁姆认知层次融入 Prompt 设计

附录:核心代码

A. 特征聚合

# 学科矩阵 — pivot_table 构建
subject_scores = df_chengji.pivot_table(
    index='mes_StudentID', columns='mes_sub_name',
    values='mes_Score', aggfunc='mean'
).reset_index()
subject_scores.rename(columns={'mes_StudentID': 'bf_StudentID'}, inplace=True)
# 给学科列加前缀 subj_
for c in subject_scores.columns:
    if c != 'bf_StudentID':
        subject_scores.rename(columns={c: f'subj_{c}'}, inplace=True)

# 考勤类型拆分 (unstack)
kaoqin_pivot = df_kaoqin.groupby(['bf_studentID', 'controler_name']) \
    .size().unstack(fill_value=0).reset_index()

# 日均消费
consumption_days = df_consumption.groupby('bf_StudentID')['DealTime'] \
    .apply(lambda x: x.dt.date.nunique())
student_consumption['daily_avg'] = total_spending / consumption_days

# 合并 — 1,765 × 49
df_profile = df_student.merge(student_score).merge(subject_scores) \
    .merge(student_kaoqin).merge(kaoqin_pivot).merge(student_consumption)

B. 画像标签

# 学业: 90/75/60
def assign_academic_label_v1(avg):
    if pd.isna(avg): return '未知'
    if avg >= 90: return '学霸'
    elif avg >= 75: return '优秀'
    elif avg >= 60: return '中等'
    else: return '学困'

# 考勤: 0/3
def assign_attendance_label(total):
    if total == 0: return '全勤标兵'
    elif total <= 3: return '正常'
    else: return '需要预警'

# 消费: Q25/Q75 分位数
q25, q75 = df_profile['daily_avg'].quantile([0.25, 0.75])
def assign_consumption_label(daily):
    if daily > q75: return '消费较高'
    elif daily > q25: return '适中'
    else: return '节俭'

C. LLM 画像生成

SYSTEM_PROMPT = """你是资深教育数据分析师。请输出严格JSON格式的画像报告:
{
  "academic_level": "学霸/优秀/中等偏上/中等/中等偏下/学困",
  "subject_profile": "学科优劣势详细描述",
  "learning_attitude": "考勤+成绩稳定性综合判断",
  "behavior_pattern": "消费+考勤→生活习惯和自律程度",
  "strengths": ["优势1","优势2"],
  "weaknesses": ["待改进1","待改进2"],
  "suggestions": ["建议1","建议2"],
  "overall_description": "100-150字综合描述"
}
原则: 不固定阈值,关注维度关联,具体可操作,体现个性特点"""

response = client.chat.completions.create(
    model='qwen-plus',
    messages=[{'role':'system','content':SYSTEM_PROMPT},
              {'role':'user','content':f"请分析:\n{student_summary}"}],
    temperature=0.3,
    response_format={'type': 'json_object'}  # 强制JSON
)
return json.loads(response.choices[0].message.content)

D. 协同过滤

# 评分矩阵 (groupby + unstack)
student_subject_scores = df_chengji[
    df_chengji['mes_sub_name'].isin(cf_subjects) & df_chengji['mes_Score'].notna()
].groupby(['mes_StudentID', 'mes_sub_name'])['mes_Score'].mean().unstack()

valid_mask = student_subject_scores.notna().sum(axis=1) >= 5  # 至少5科
rating_matrix = (student_subject_scores[valid_mask] / 100.0).clip(0, 1)

# User-CF (推荐有提升空间的学科)
def user_based_cf_recommend(target_id, k=5, n=3):
    target_scores = rating_matrix.loc[target_id]
    top_k = similarity_df.loc[target_id].drop(target_id).nlargest(k)
    for subject in rating_matrix.columns:
        pred = weighted_avg(top_k, subject)
        gap = pred - target_scores[subject]
        if gap > 0:  # 只推荐有提升空间的
            recommendations[subject] = {'predicted': pred, 'current': ..., 'gap': gap}
    return sorted(recommendations, key=lambda x: -x[1]['gap'])[:n]

E. 向量检索 + LLM 推荐

# Chroma 向量库
collection = chroma_client.create_collection(name='edu_resources')
collection.add(
    documents=[r['text'] for r in education_resources],  # 30条
    metadatas=[{'title':f"[{r['type']}]{r['subject']}", ...}],
    ids=[r['id'] for r in education_resources]
)

# 语义检索
candidates = collection.query(query_texts=[query], n_results=5)

# LLM 推荐报告生成
RECOMMEND_PROMPT = """输出JSON:
{"recommended_resources": [{"resource_id":"...","reason":"...","priority":"高/中/低"}],
 "learning_plan":"50-80字学习计划",
 "peer_suggestion":"同伴学习建议",
 "overall_recommendation":"100-150字总体推荐"}"""

response = client.chat.completions.create(
    model='qwen-plus',
    messages=[{'role':'system','content':RECOMMEND_PROMPT},
              {'role':'user','content':f"画像:\n{profile}\n候选:\n{candidates}"}],
    temperature=0.3,
    response_format={'type': 'json_object'}
)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐