青少年心理状态识别与干预

技术栈:Python 3.10 · scikit-learn · XGBoost · pyswarms · Streamlit · SQLite · Plotly


目录

  1. 项目概述
  2. 数据集详解
  3. 目标变量构建
  4. 数据预处理流程
  5. 特征选择算法详解
    • 5.1 粒子群优化 PSO
    • 5.2 随机森林特征重要性
    • 5.3 SelectKBest 互信息
    • 5.4 递归特征消除 RFE
    • 5.5 四种方法对比分析
  6. 分类模型详解
    • 6.1 随机森林
    • 6.2 XGBoost
    • 6.3 逻辑回归
    • 6.4 支持向量机
    • 6.5 K 近邻
  7. 模型训练与评估
  8. 系统架构设计
  9. 数据库设计
  10. 项目目录结构
  11. 系统界面功能详解
  12. 技术栈原理详解

1. 项目概述

本系统面向青少年学生群体,通过心理健康问卷数据自动识别个体的心理风险等级(高风险 / 中风险 / 低风险),并提供个性化的干预建议和档案跟踪功能。

1.1 核心目标

目标 说明
心理状态分类 将学生的心理健康状态分为高风险、中风险、低风险三类
特征优化 使用 PSO 等方法从 18 个特征中筛选最关键的心理健康指标
模型对比仿真 训练并对比 5 种机器学习模型,选择最优模型
系统化管理 提供在线问卷、风险预警、干预建议、档案管理全流程支持

1.2 系统功能模块

┌─────────────────────────────────────────────────────┐
│              青少年心理健康识别与干预系统              │
├──────────┬──────────┬──────────┬──────────┬─────────┤
│ 问卷录入  │ 状态识别  │ 高危预警  │ 干预建议  │ 档案管理 │
│ 在线填写  │ 模型预测  │ 风险监控  │ 分级方案  │ 历史查询 │
│ 文件导入  │ 维度分析  │ 列表标记  │ 报告生成  │ 趋势图表 │
└──────────┴──────────┴──────────┴──────────┴─────────┘

2. 数据集详解

2.1 数据来源

数据集来源:Kaggle — Student Mental Health and Burnout Dataset

属性
样本总量 150,000 条
特征数量 18 个输入特征 + 1 个原始标签
类别数量 3 类(High / Medium / Low)
数据类型 数值型 + 类别型混合
缺失值

2.2 特征说明

序号 特征名称 中文含义 数据类型 取值范围
1 age 年龄 整型 18–30
2 gender 性别 类别 Male / Female
3 course 专业 类别 BTech / BCA / BSc 等
4 year 年级 类别 1st / 2nd / 3rd / 4th
5 daily_study_hours 每日学习时长(小时) 浮点 0–16
6 daily_sleep_hours 每日睡眠时长(小时) 浮点 0–12
7 screen_time_hours 每日屏幕时间(小时) 浮点 0–16
8 stress_level 压力等级 类别 Low / Medium / High
9 anxiety_score 焦虑评分 整型 1–10
10 depression_score 抑郁评分 整型 1–10
11 academic_pressure_score 学业压力评分 整型 1–10
12 financial_stress_score 经济压力评分 整型 1–10
13 social_support_score 社会支持评分 整型 1–10
14 physical_activity_hours 每周体育锻炼时长(小时) 浮点 0–8
15 sleep_quality 睡眠质量 类别 Good / Average / Poor
16 attendance_percentage 出勤率(%) 浮点 0–100
17 cgpa 学业绩点 浮点 0–10
18 internet_quality 网络质量 类别 Good / Average / Poor

2.3 探索性数据分析(EDA)

下图展示了数据集的整体分布情况,包括目标变量分布、各心理指标箱线图、压力与风险等级关系、GPA 分布及学习睡眠散点图:

在这里插入图片描述

图表解读:

  • 左上(目标分布):三类风险标签分布较为均衡,各约 5 万条,保证了模型训练的公平性。
  • 中上(焦虑评分箱线图):高风险组焦虑评分显著高于低风险组(均值 7.33 vs 3.66),说明焦虑评分是重要的判别特征。
  • 右上(抑郁评分箱线图):规律与焦虑相同,高风险组抑郁均值达 7.35,三组差异显著。
  • 左下(压力等级对比):高压力等级与高风险等级高度相关,低压力学生主要集中在低风险类别。
  • 中下(GPA 分布):三组 GPA 分布相近,说明学业成绩并非主要的心理风险判别因子。
  • 右下(学习-睡眠散点):学习时间与睡眠时间呈一定分散分布,颜色标记展示了不同风险等级的空间分布特征。

下图展示了各数值型特征之间的 Pearson 相关系数热力图:

在这里插入图片描述

图表解读:

  • anxiety_scoredepression_score 相关系数接近 0.5,表明焦虑与抑郁倾向存在共线性,但不完全重叠。
  • social_support_score 与多个压力指标呈负相关,说明社会支持具有心理保护作用。
  • cgpaattendance_percentage 与心理指标相关性较弱,主要反映学业行为而非心理状态。
  • 整体相关性中等,说明特征之间信息互补,适合多特征联合建模。

3. 目标变量构建——复合心理健康风险标签

3.1 问题背景

原始数据集中的 burnout_level(高/中/低倦怠)字段经验证为随机生成,与所有特征的皮尔逊相关系数均接近 0.001,无法作为有效目标变量:

特征 与 burnout_level 的相关系数
anxiety_score 0.0012
depression_score 0.0010
academic_pressure_score -0.0042
stress_level(编码后) 0.0003

因此,本项目根据心理学量表理论,从原始特征中构建具有临床意义的复合心理健康风险评分

3.2 复合风险评分公式

R = 2 ⋅ A + 2 ⋅ D + P a c a d + P f i n + 3 ⋅ S s t r e s s + 2 ⋅ Q s l e e p − S s o c i a l + 1.5 ⋅ max ⁡ ( 0 ,   7 − h s l e e p ) R = 2 \cdot A + 2 \cdot D + P_{acad} + P_{fin} + 3 \cdot S_{stress} + 2 \cdot Q_{sleep} - S_{social} + 1.5 \cdot \max(0,\ 7 - h_{sleep}) R=2A+2D+Pacad+Pfin+3Sstress+2QsleepSsocial+1.5max(0, 7hsleep)

其中各变量含义如下:

符号 含义 编码方式
A A A 焦虑评分(anxiety_score 原值 1–10
D D D 抑郁倾向(depression_score 原值 1–10
P a c a d P_{acad} Pacad 学业压力(academic_pressure_score 原值 1–10
P f i n P_{fin} Pfin 经济压力(financial_stress_score 原值 1–10
S s t r e s s S_{stress} Sstress 压力等级(stress_level High=3, Medium=2, Low=1
Q s l e e p Q_{sleep} Qsleep 睡眠质量(sleep_quality Poor=2, Average=1, Good=0
S s o c i a l S_{social} Ssocial 社会支持(social_support_score,保护因子) 原值 1–10,取负号
h s l e e p h_{sleep} hsleep 每日睡眠时长(daily_sleep_hours 不足 7 小时则计入惩罚

权重设计依据:

  • 焦虑与抑郁权重×2:这两项是心理健康评估核心指标,临床量表(GAD-7、PHQ-9)赋予重要权重。
  • 压力等级权重×3:自评压力等级包含主观综合感受,信息密度高。
  • 社会支持取负号:社会支持是心理健康的保护因子,高支持降低风险。
  • 睡眠不足惩罚:每日睡眠低于 7 小时对心理健康有累积负面影响。

3.3 风险等级分组

R R R 按三分位数分箱,确保三类样本均衡:

mental_health_risk = { Low R ≤ Q 33 = 32.05 Medium 32.05 < R ≤ Q 67 = 41.35 High R > 41.35 \text{mental\_health\_risk} = \begin{cases} \text{Low} & R \leq Q_{33} = 32.05 \\ \text{Medium} & 32.05 < R \leq Q_{67} = 41.35 \\ \text{High} & R > 41.35 \end{cases} mental_health_risk= LowMediumHighRQ33=32.0532.05<RQ67=41.35R>41.35

风险等级 样本数 占比 焦虑均值 抑郁均值 社会支持均值
Low 49,671 33.1% 3.66 3.66 6.39
Medium 50,982 34.0% 5.50 5.50 5.52
High 49,347 32.9% 7.33 7.35 4.62

三组间焦虑、抑郁差异显著(从低到高递增),社会支持递减,证明该标签具有强临床意义。


4. 数据预处理流程

4.1 处理步骤总览

原始数据(150,000 × 19)
     ↓
删除 student_id(无意义标识列)
     ↓
类别变量 Label Encoding(6列)
     ↓
构建复合目标变量 mental_health_risk
     ↓
目标变量 Label Encoding(High=0 / Low=1 / Medium=2)
     ↓
特征 StandardScaler 标准化(18列)
     ↓
分层随机划分:训练集 70% / 测试集 30%
     ↓
保存预处理器(scaler.pkl, encoders.pkl)

4.2 类别编码

对 6 个类别特征使用 sklearn.preprocessing.LabelEncoder,按字母序映射为整数:

特征 编码映射
gender Female=0, Male=1
stress_level High=0, Low=1, Medium=2
sleep_quality Average=0, Good=1, Poor=2
internet_quality Average=0, Good=1, Poor=2
year 1st=0, 2nd=1, 3rd=2, 4th=3
course 按字母序递增编码

4.3 特征标准化

使用 Z-Score 标准化消除量纲差异,公式为:

z = x − μ σ z = \frac{x - \mu}{\sigma} z=σxμ

其中 μ \mu μ 为训练集均值, σ \sigma σ 为训练集标准差。标准化后所有特征均值为 0,标准差为 1,有利于梯度类模型(LR、SVM)的收敛。

4.4 数据集划分

集合 样本量 比例
训练集 105,000 70%
测试集 45,000 30%

采用 stratify=y 确保三类样本在训练集和测试集中比例一致(约 33% 各类)。


5. 特征选择算法详解

5.1 粒子群优化 PSO

5.1.1 算法原理

粒子群优化(Particle Swarm Optimization, PSO)是受鸟群觅食行为启发的群体智能优化算法。对于二进制特征选择问题,使用 BinaryPSO 变体,每个粒子的位置 x i ∈ { 0 , 1 } n \mathbf{x}_i \in \{0,1\}^n xi{0,1}n 表示一种特征子集(1=选中,0=未选)。

速度更新公式:

v i j ( t + 1 ) = w ⋅ v i j ( t ) + c 1 r 1 [ p b e s t i j − x i j ( t ) ] + c 2 r 2 [ g b e s t j − x i j ( t ) ] v_{ij}(t+1) = w \cdot v_{ij}(t) + c_1 r_1 [pbest_{ij} - x_{ij}(t)] + c_2 r_2 [gbest_j - x_{ij}(t)] vij(t+1)=wvij(t)+c1r1[pbestijxij(t)]+c2r2[gbestjxij(t)]

位置更新(Sigmoid 映射):

S ( v i j ) = 1 1 + e − v i j S(v_{ij}) = \frac{1}{1 + e^{-v_{ij}}} S(vij)=1+evij1

x i j ( t + 1 ) = { 1 if  r a n d ( ) < S ( v i j ( t + 1 ) ) 0 otherwise x_{ij}(t+1) = \begin{cases} 1 & \text{if } rand() < S(v_{ij}(t+1)) \\ 0 & \text{otherwise} \end{cases} xij(t+1)={10if rand()<S(vij(t+1))otherwise

各参数含义:

参数 含义 本项目设置
w w w 惯性权重,控制粒子保持原方向的趋势 0.9
c 1 c_1 c1 认知学习因子,向个体最优趋近 0.5
c 2 c_2 c2 社会学习因子,向全局最优趋近 0.5
k k k 邻域粒子数(局部 PSO) 3
粒子数 搜索空间中的粒子总数 20
迭代次数 最大迭代轮数 30

5.1.2 目标函数设计

cost ( x ) = 1 − F 1 ( x ) \text{cost}(\mathbf{x}) = 1 - F_1(\mathbf{x}) cost(x)=1F1(x)

对每个粒子位置 x \mathbf{x} x,选出对应特征子集,在 5,000 样本的验证子集上训练轻量 RandomForest(20 棵树,深度 5),计算加权 F1-Score,取其补值作为代价(越小越好)。

5.1.3 收敛过程

在这里插入图片描述

图表解读:

  • 横轴为迭代次数(0–30),纵轴为全局最优代价值(1-F1)。
  • 蓝色折线展示每轮迭代的最优代价,蓝色填充区域增强可视化效果。
  • 曲线整体呈下降趋势,表明种群持续向更优特征子集收敛。
  • 最终收敛代价约为 0.231,对应 PSO 验证子集 F1 ≈ 0.769。
  • 在完整测试集上,PSO 特征子集使 XGBoost 达到 F1 = 0.8632。

5.1.4 PSO 选出特征

PSO 从 18 个特征中选出 9 个最重要特征:

选出特征 特征含义 权重类型
anxiety_score 焦虑评分 核心心理指标
depression_score 抑郁评分 核心心理指标
academic_pressure_score 学业压力 压力源
financial_stress_score 经济压力 压力源
social_support_score 社会支持 保护因子
stress_level 综合压力等级 主观感受
daily_study_hours 每日学习时长 生活行为
screen_time_hours 屏幕使用时间 生活行为
internet_quality 网络质量 环境因素

5.2 随机森林特征重要性

5.2.1 算法原理

随机森林中每棵决策树通过 基尼不纯度(Gini Impurity) 来衡量特征的重要性:

G = 1 − ∑ k = 1 K p k 2 G = 1 - \sum_{k=1}^{K} p_k^2 G=1k=1Kpk2

特征 j j j 的重要性定义为该特征在所有树中所有分裂节点处降低不纯度的平均贡献:

Importance ( j ) = 1 ∣ T ∣ ∑ T ∈ T ∑ t ∈ T : v ( t ) = j Δ G ( t ) \text{Importance}(j) = \frac{1}{|\mathcal{T}|} \sum_{T \in \mathcal{T}} \sum_{t \in T: v(t)=j} \Delta G(t) Importance(j)=T1TTtT:v(t)=jΔG(t)

以均值作为阈值,重要性高于均值的特征被选中。

5.2.2 特征重要性可视化

在这里插入图片描述

图表解读:

  • 横轴为特征的基尼重要性得分,纵轴为特征名称。
  • 红色柱代表被选中的特征(重要性 ≥ 均值阈值,虚线位置)。
  • 灰色柱代表未被选中的特征。
  • RF 选出了 5 个特征anxiety_scoredepression_scoreacademic_pressure_scorefinancial_stress_scoresocial_support_score
  • 5 个心理评分类特征重要性远高于其他特征,说明这 5 项是复合风险标签的核心决定因子(符合预期,因为它们直接参与了风险评分公式)。

5.3 SelectKBest(互信息法)

5.3.1 算法原理

互信息(Mutual Information, MI)衡量两个随机变量之间的依赖程度:

I ( X ; Y ) = ∑ x , y p ( x , y ) log ⁡ p ( x , y ) p ( x ) p ( y ) I(X; Y) = \sum_{x,y} p(x,y) \log \frac{p(x,y)}{p(x)p(y)} I(X;Y)=x,yp(x,y)logp(x)p(y)p(x,y)

与皮尔逊相关系数不同,互信息能捕捉非线性关系SelectKBest 使用 mutual_info_classif 计算每个特征与目标变量的互信息,选取得分最高的 k = 10 k=10 k=10 个特征。

5.3.2 互信息得分可视化

在这里插入图片描述

图表解读:

  • 横轴为互信息得分,纵轴为特征名称。
  • 粉色柱为 Top-10 被选中特征,蓝灰色柱为未被选中特征。
  • 虚线为 Top-10 的最低阈值。
  • 互信息得分较高的特征依次为:stress_levelanxiety_scoresleep_qualitysocial_support_scoredepression_score 等。
  • agephysical_activity_hourscgpa 等特征得分偏低,被排除。

5.4 递归特征消除(RFE)

5.4.1 算法原理

RFE(Recursive Feature Elimination)从全特征集出发,每轮用基模型(RandomForest)拟合数据,然后删除重要性最低的若干特征,循环迭代直到剩余 n = 10 n=10 n=10 个特征。

F t + 1 = F t ∖ { argmin j ∈ F t Importance ( j ) } \mathcal{F}_{t+1} = \mathcal{F}_t \setminus \{\text{argmin}_{j \in \mathcal{F}_t} \text{Importance}(j)\} Ft+1=Ft{argminjFtImportance(j)}

本项目设置 step=2,每轮删除 2 个最不重要的特征,在 20,000 样本子集上运行以控制计算时间。

5.4.2 RFE 排名可视化

在这里插入图片描述

图表解读:

  • 横轴为 RFE 排名(Ranking=1 为选中特征),纵轴为特征名称。
  • 橙色柱(Ranking=1)表示被选中的 10 个特征。
  • 浅灰柱数值越大,表示该特征越早被剔除(重要性越低)。
  • RFE 选出:anxiety_scoredepression_scoreacademic_pressure_scorefinancial_stress_scoresocial_support_scoredaily_study_hoursdaily_sleep_hoursscreen_time_hoursattendance_percentagecgpa

5.5 四种特征选择方法对比分析

在这里插入图片描述

图表解读(左侧热力图):

  • 行为特征名称,列为四种选择方法(PSO / RF Importance / SelectKBest / RFE)。
  • 单元格值 1 = 被选中0 = 未被选中,颜色越深代表票数越多。
  • 右侧柱图展示每个特征被几种方法选中(“投票数”)。

共识特征(被 ≥ 2 种方法选中):

特征 投票数 入选方法
anxiety_score 4 PSO、RF、SelectKBest、RFE
depression_score 4 PSO、RF、SelectKBest、RFE
academic_pressure_score 4 PSO、RF、SelectKBest、RFE
financial_stress_score 4 PSO、RF、SelectKBest、RFE
social_support_score 4 PSO、RF、SelectKBest、RFE
stress_level 2 PSO、SelectKBest
daily_study_hours 2 PSO、RFE
screen_time_hours 2 PSO、RFE
daily_sleep_hours 2 SelectKBest、RFE

结论:5 个心理评分特征(焦虑、抑郁、学压、经压、社会支持)被所有方法一致选中,是最稳定的判别特征;PSO 额外捕捉了行为特征(学习时长、屏幕时间)的判别价值。


6. 分类模型详解

6.1 随机森林(Random Forest)

随机森林是 Bagging 集成学习与特征随机化的结合,通过构建多棵决策树并集成投票进行分类。

核心步骤:

  1. Bootstrap 抽样:从训练集中有放回抽取 n n n 个样本。
  2. 随机特征选择:每次分裂时随机选取 d \sqrt{d} d 个特征( d d d 为总特征数)。
  3. 构建决策树:使用信息增益或基尼不纯度作为分裂准则。
  4. 集成预测: k k k 棵树投票,多数类为最终预测。

参数设置:

参数 含义
n_estimators 100 树的数量
max_features sqrt 每次分裂随机特征数
random_state 42 随机种子
n_jobs -1 并行使用全部 CPU

6.2 XGBoost(极端梯度提升)

XGBoost 是 Boosting 框架的高效实现,通过逐步拟合残差、加入正则化防止过拟合。

目标函数:

L ( ϕ ) = ∑ i l ( y i , y ^ i ) + ∑ k Ω ( f k ) \mathcal{L}(\phi) = \sum_{i} l(y_i, \hat{y}_i) + \sum_{k} \Omega(f_k) L(ϕ)=il(yi,y^i)+kΩ(fk)

其中正则项为:

Ω ( f ) = γ T + 1 2 λ ∥ w ∥ 2 \Omega(f) = \gamma T + \frac{1}{2} \lambda \|\mathbf{w}\|^2 Ω(f)=γT+21λw2

T T T 为叶子节点数, w \mathbf{w} w 为叶子权重, γ \gamma γ λ \lambda λ 为超参数。

t t t 轮的叶子最优权重:

w j ∗ = − ∑ i ∈ I j g i ∑ i ∈ I j h i + λ w_j^* = -\frac{\sum_{i \in I_j} g_i}{\sum_{i \in I_j} h_i + \lambda} wj=iIjhi+λiIjgi

其中 g i g_i gi h i h_i hi 分别是损失函数对预测值的一阶和二阶导数。

参数设置:

参数 含义
n_estimators 100 Boosting 轮数
eval_metric mlogloss 多分类交叉熵
n_jobs -1 并行计算
verbosity 0 关闭日志输出

6.3 逻辑回归(Logistic Regression)

多分类逻辑回归使用 Softmax 函数,输出每个类别的概率:

P ( y = k ∣ x ) = e w k T x ∑ j = 1 K e w j T x P(y=k|\mathbf{x}) = \frac{e^{\mathbf{w}_k^T \mathbf{x}}}{\sum_{j=1}^{K} e^{\mathbf{w}_j^T \mathbf{x}}} P(y=kx)=j=1KewjTxewkTx

损失函数为多类交叉熵:

L = − ∑ i ∑ k y i k log ⁡ P ( y i = k ∣ x i ) + λ 2 ∥ W ∥ 2 \mathcal{L} = -\sum_{i} \sum_{k} y_{ik} \log P(y_i = k | \mathbf{x}_i) + \frac{\lambda}{2} \|\mathbf{W}\|^2 L=ikyiklogP(yi=kxi)+2λW2

参数设置:

参数
max_iter 500
solver lbfgs
multi_class auto

6.4 支持向量机(SVM)

SVM 在特征空间中寻找最优分类超平面,最大化类间间隔:

min ⁡ w , b , ξ 1 2 ∥ w ∥ 2 + C ∑ i ξ i \min_{\mathbf{w},b,\boldsymbol{\xi}} \frac{1}{2}\|\mathbf{w}\|^2 + C\sum_i \xi_i w,b,ξmin21w2+Ciξi

使用 RBF 核函数处理非线性问题:

K ( x i , x j ) = exp ⁡ ( − γ ∥ x i − x j ∥ 2 ) K(\mathbf{x}_i, \mathbf{x}_j) = \exp\left(-\gamma \|\mathbf{x}_i - \mathbf{x}_j\|^2\right) K(xi,xj)=exp(γxixj2)

:SVM 计算复杂度约 O ( n 2 ) O(n^2) O(n2) O ( n 3 ) O(n^3) O(n3),在 105,000 样本上训练耗时过长,本项目使用 10,000 样本子集进行训练以控制时间,因此测试指标略低于理论上限。

参数设置: kernel='rbf'C=1.0probability=True(启用概率估计)

6.5 K 近邻(KNN)

KNN 对测试样本 x \mathbf{x} x,找到训练集中距离最近的 k = 7 k=7 k=7 个邻居,以多数投票决定类别:

y ^ = argmax c ∑ i ∈ N k ( x ) 1 [ y i = c ] \hat{y} = \text{argmax}_c \sum_{i \in N_k(\mathbf{x})} \mathbf{1}[y_i = c] y^=argmaxciNk(x)1[yi=c]

距离使用欧几里得距离: d ( x , x ′ ) = ∑ j ( x j − x j ′ ) 2 d(\mathbf{x}, \mathbf{x}') = \sqrt{\sum_j (x_j - x_j')^2} d(x,x)=j(xjxj)2

:KNN 训练时间为 O ( 1 ) O(1) O(1),但预测时间为 O ( n d ) O(nd) O(nd),大数据集预测较慢。本项目使用 15,000 样本子集进行训练。


7. 模型训练与评估

7.1 评估指标

对于多分类问题,使用以下加权平均指标(average='weighted',按类别样本量加权):

指标 公式 含义
准确率 Accuracy T P + T N T P + T N + F P + F N \frac{TP+TN}{TP+TN+FP+FN} TP+TN+FP+FNTP+TN 正确预测占总预测比例
精确率 Precision T P T P + F P \frac{TP}{TP+FP} TP+FPTP 预测为正类中实际为正的比例
召回率 Recall T P T P + F N \frac{TP}{TP+FN} TP+FNTP 实际为正类中被正确预测的比例
F1 分数 2 ⋅ P ⋅ R P + R \frac{2 \cdot P \cdot R}{P + R} P+R2PR 精确率与召回率的调和平均
AUC-ROC ∫ 0 1 T P R   d ( F P R ) \int_0^1 TPR\ d(FPR) 01TPR d(FPR) ROC 曲线下面积,衡量区分能力

7.2 模型对比结果(PSO 特征子集)

在这里插入图片描述

图表解读:

  • 共 3 个子图,分别对比不同特征集下各模型的 Accuracy、F1-Score、AUC。
  • 5 种颜色分别代表 5 种特征集(全特征、PSO、RF重要性、SelectKBest、RFE)。
  • XGBoost 在大多数特征集下性能领先,SelectKBest 特征集整体表现优异。
  • KNN 模型受样本量限制,性能相对较低。

下表列出所有模型在 PSO 特征子集下的完整指标:

模型 Accuracy Precision Recall F1-Score AUC
XGBoost 0.8625 0.8644 0.8625 0.8632 0.9675
SVM 0.8562 0.8566 0.8562 0.8564 0.9650
RandomForest 0.8485 0.8501 0.8485 0.8492 0.9598
LogisticRegression 0.8213 0.8228 0.8213 0.8219 0.9469
KNN 0.7773 0.7777 0.7773 0.7775 0.9196

下表列出所有模型在全特征集下的指标:

模型 Accuracy F1-Score AUC
XGBoost 0.9646 0.9648 0.9976
SVM 0.9167 0.9170 0.9881
RandomForest 0.8964 0.8970 0.9788
LogisticRegression 0.8432 0.8436 0.9628
KNN 0.7015 0.6978 0.8610

7.3 指标热力图

在这里插入图片描述

图表解读:

  • 左图:PSO 特征集下各模型五项指标(绿色越深越高)。
  • 右图:全特征集下各模型五项指标。
  • XGBoost 在两种特征集下均呈深绿色,整体性能最优。
  • 全特征集下所有模型指标普遍高于 PSO 特征集,说明特征选择以牺牲少量精度换取模型简洁性和解释性。

7.4 最优模型混淆矩阵

在这里插入图片描述

图表解读:

  • 左图(计数):三对角线代表正确分类数量,非对角线为误分类数量。
  • 右图(归一化):每行归一化,展示各真实类别的识别准确率。
  • XGBoost(PSO 特征)在三个类别上的识别准确率均超过 84%,中风险(Medium)类略低,这是因为中风险处于边界区域,与高低风险的特征分界不如两端明显。

7.5 ROC 曲线

在这里插入图片描述

图表解读:

  • 展示 5 种模型在 PSO 特征集下的宏平均 ROC 曲线(One-vs-Rest)。
  • 纵轴为真正率(TPR),横轴为假正率(FPR),对角虚线为随机分类器基线。
  • XGBoost(蓝色实线)AUC = 0.9675,曲线最靠近左上角,说明其区分三类风险的能力最强。
  • 所有模型 AUC 均远高于 0.5(随机),最低的 KNN 也达 0.9196。

7.6 雷达图对比

在这里插入图片描述

图表解读:

  • 五边形雷达图,五个顶点分别代表 Accuracy、Precision、Recall、F1-Score、AUC。
  • 各模型的多边形面积越大,综合性能越强。
  • XGBoost(蓝色)多边形面积最大,各维度均衡且突出。
  • KNN(紫色)在 AUC 维度相对较好,但 Accuracy 和 F1 稍弱。

7.7 最优模型特征重要性

在这里插入图片描述

图表解读:

  • 横轴为 XGBoost 在 PSO 选定 9 个特征上的特征重要性。
  • anxiety_scoredepression_score 重要性最高,与目标变量的设计逻辑吻合。
  • stress_levelsocial_support_score 紧随其后,对分类贡献显著。
  • internet_qualityscreen_time_hours 贡献相对较小,但仍被 PSO 保留(在交互效应中有价值)。

7.8 最终模型选择

决策维度 说明
最优模型 XGBoost
使用特征 PSO 选择的 9 个特征
F1-Score 0.8632(测试集)
AUC 0.9675(测试集)
选择理由 在 PSO 特征子集下综合性能最优,梯度提升对类别不平衡和非线性关系具有鲁棒性

8. 系统架构设计

8.1 整体架构

┌─────────────────────────────────────────────────────────────────┐
│                        前端层(Streamlit)                        │
│   ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────┐ │
│   │ 问卷录入 │ │ 状态识别 │ │ 高危预警 │ │ 干预建议 │ │档案管│ │
│   └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──┬───┘ │
└────────┼────────────┼────────────┼────────────┼───────────┼─────┘
         │            │            │            │           │
┌────────▼────────────▼────────────▼────────────▼───────────▼─────┐
│                      业务逻辑层(utils/)                          │
│          model_utils.py          db_utils.py                     │
│     (模型加载/预测/风险评分)    (SQLite CRUD / 统计查询)            │
└────────────────────────────────────────────────────────────────┬─┘
                                                                 │
┌────────────────────────────────────────────────────────────────▼─┐
│                       数据持久层                                   │
│   models/best_model.pkl     data/records.db                      │
│   models/scaler.pkl         (SQLite 心理档案数据库)                │
│   models/label_encoders.pkl                                      │
└──────────────────────────────────────────────────────────────────┘

8.2 数据流向

用户填写问卷
    ↓
表单数据验证(validate)
    ↓
model_utils.predict_risk()
  ├─ 特征向量构建(18维)
  ├─ StandardScaler 标准化
  ├─ 选取 PSO 特征(9维)
  └─ XGBoost 预测 → risk_level + probabilities + risk_score
    ↓
db_utils.save_assessment()
  └─ 写入 SQLite assessments 表
    ↓
跳转「状态识别」页面展示结果

9. 数据库设计

9.1 数据库概览

属性
数据库类型 SQLite 3
文件路径 algorithm/data/records.db
表数量 1 张(assessments)
驱动库 sqlite3(Python 内置)
ORM 查询 pandas.read_sql()

SQLite 具有零配置、嵌入式、无需服务器的特点,适合桌面应用和中小规模数据存储,单文件形式方便迁移与备份。

9.2 assessments 表设计

该表存储每次心理健康评估的完整记录,包括学生基本信息、问卷原始数据和模型预测结果。

表结构

字段名 数据类型 长度 可为空 唯一 默认值 说明
id INTEGER NOT NULL YES AUTO 主键,自增唯一标识
student_id TEXT 50 NOT NULL NO 学号(业务唯一标识)
name TEXT 100 YES NO '' 学生姓名(可选)
assessed_at TEXT 20 YES NO datetime('now','localtime') 评估时间(ISO 格式字符串)
age INTEGER YES NO 年龄(岁)
gender TEXT 20 YES NO 性别(Male/Female/Other)
course TEXT 50 YES NO 专业名称
year TEXT 10 YES NO 年级(1st–5th)
daily_study_hours REAL YES NO 每日学习时长(小时)
daily_sleep_hours REAL YES NO 每日睡眠时长(小时)
screen_time_hours REAL YES NO 每日屏幕时间(小时)
physical_activity_hours REAL YES NO 每周体育锻炼时长(小时)
stress_level TEXT 10 YES NO 压力等级(Low/Medium/High)
anxiety_score INTEGER YES NO 焦虑评分(1–10)
depression_score INTEGER YES NO 抑郁评分(1–10)
academic_pressure_score INTEGER YES NO 学业压力评分(1–10)
financial_stress_score INTEGER YES NO 经济压力评分(1–10)
social_support_score INTEGER YES NO 社会支持评分(1–10)
sleep_quality TEXT 15 YES NO 睡眠质量(Good/Average/Poor)
internet_quality TEXT 15 YES NO 网络质量(Good/Average/Poor)
attendance_percentage REAL YES NO 出勤率(0–100%)
cgpa REAL YES NO 学业绩点(0–10)
risk_level TEXT 10 YES NO 预测风险等级(High/Medium/Low)
risk_score REAL YES NO 综合风险评分(0–1,越高越危险)
prob_high REAL YES NO 高风险概率(0–1)
prob_medium REAL YES NO 中风险概率(0–1)
prob_low REAL YES NO 低风险概率(0–1)
notes TEXT 500 YES NO '' 备注信息(可选)

建表 DDL

CREATE TABLE IF NOT EXISTS assessments (
    id                       INTEGER  PRIMARY KEY AUTOINCREMENT,
    student_id               TEXT     NOT NULL,
    name                     TEXT     DEFAULT '',
    assessed_at              TEXT     DEFAULT (datetime('now','localtime')),
    age                      INTEGER,
    gender                   TEXT,
    course                   TEXT,
    year                     TEXT,
    daily_study_hours        REAL,
    daily_sleep_hours        REAL,
    screen_time_hours        REAL,
    physical_activity_hours  REAL,
    stress_level             TEXT,
    anxiety_score            INTEGER,
    depression_score         INTEGER,
    academic_pressure_score  INTEGER,
    financial_stress_score   INTEGER,
    social_support_score     INTEGER,
    sleep_quality            TEXT,
    internet_quality         TEXT,
    attendance_percentage    REAL,
    cgpa                     REAL,
    risk_level               TEXT,
    risk_score               REAL,
    prob_high                REAL,
    prob_medium              REAL,
    prob_low                 REAL,
    notes                    TEXT     DEFAULT ''
);

9.3 主要数据库操作

操作函数 说明 SQL 类型
init_db() 初始化建表(首次运行) CREATE TABLE IF NOT EXISTS
save_assessment(record) 插入一条评估记录,返回新记录 id INSERT INTO
get_all_assessments() 查询全部记录,按时间倒序 SELECT * ORDER BY assessed_at DESC
search_assessments() 按学号、姓名、风险等级模糊/精确查询 SELECT * WHERE ...
get_student_history() 查询指定学号的历史记录(用于趋势图) SELECT * WHERE student_id = ?
delete_assessment(id) 按主键删除记录 DELETE FROM WHERE id = ?
get_risk_stats() 统计各风险等级人数 GROUP BY risk_level

10. 项目目录结构

program/
└── algorithm/                        算法与系统主目录
    ├── streamlit_app.py              Streamlit 主入口,含全局 CSS 与导航
    ├── algorithm.ipynb               Jupyter Notebook 算法全流程
    ├── student_mental_health_burnout.csv  原始数据集(15万条)
    │
    ├── .streamlit/
    │   └── config.toml               Streamlit 主题与服务器配置
    │
    ├── utils/                        后端工具模块
    │   ├── __init__.py
    │   ├── model_utils.py            模型加载、预测、风险评分
    │   └── db_utils.py               SQLite 数据库增删改查
    │
    ├── pages/                        各功能页面模块(下划线前缀,Streamlit 不自动注册)
    │   ├── _questionnaire.py         页面1:心理问卷录入
    │   ├── _recognition.py           页面2:心理状态识别
    │   ├── _warning.py               页面3:高危学生预警
    │   ├── _intervention.py          页面4:心理干预建议
    │   └── _archive.py               页面5:心理档案管理
    │
    ├── models/                       训练好的模型文件
    │   ├── best_model.pkl            最优模型(XGBoost)
    │   ├── model_xgboost_pso.pkl     XGBoost + PSO 特征
    │   ├── model_randomforest_pso.pkl
    │   ├── model_svm_pso.pkl
    │   ├── model_logisticregression_pso.pkl
    │   ├── model_knn_pso.pkl
    │   ├── scaler.pkl                StandardScaler 预处理器
    │   ├── label_encoders.pkl        类别特征编码器
    │   ├── target_encoder.pkl        目标变量编码器
    │   ├── feature_meta.json         特征元信息
    │   └── feature_selection_results.json  特征选择结果与配置
    │
    ├── charts/                       算法分析图表(由 Notebook 生成)
    │   ├── 01_eda_overview.png
    │   ├── 02_correlation_heatmap.png
    │   ├── 03_pso_convergence.png
    │   ├── 04_rf_feature_importance.png
    │   ├── 05_selectkbest_scores.png
    │   ├── 06_rfe_ranking.png
    │   ├── 07_feature_selection_comparison.png
    │   ├── 08_model_performance_comparison.png
    │   ├── 09_metrics_heatmap.png
    │   ├── 10_best_model_confusion_matrix.png
    │   ├── 11_roc_curves.png
    │   ├── 12_radar_chart.png
    │   ├── 13_best_model_feature_importance.png
    │   └── model_comparison_results.csv
    │
    └── data/                         运行时数据目录
        └── records.db                SQLite 心理档案数据库(运行时自动创建)

explaination/                         项目说明文档目录
├── 详解.md                           本说明文档
└── images/
    ├── algorithm/                    算法流程图与分析图
    └── system/                       系统界面截图

11. 系统界面功能详解

系统采用 Streamlit 框架构建,通过 streamlit_option_menu 实现深蓝色侧边栏多页导航,所有页面共享统一的 CSS 主题样式(主色调 #4A6FA5)。

11.1 心理问卷录入

在这里插入图片描述

界面功能说明:

页面分为两个选项卡:在线填写CSV / Excel 导入

在线填写

表单分为四个分组区域:

分组 包含字段 控件类型
基本信息 学号、姓名、年龄、性别、专业、年级 文本输入、数字输入、下拉选择
心理健康评估 焦虑程度、抑郁倾向、学业压力、经济压力、社会支持 滑块(1–10)
生活习惯 每日睡眠、每日学习、屏幕时间、体育锻炼 数字步进输入
综合评估 压力等级、睡眠质量、网络质量、GPA、出勤率 下拉选择、数字输入

提交流程:

  1. 点击"提交并识别"按钮触发表单验证。
  2. 校验规则:年龄 10–60、各评分 1–10、GPA 0–10、出勤率 0–100%。
  3. 验证通过后调用 predict_risk() 进行预测。
  4. 预测结果连同原始数据持久化到 SQLite 数据库。
  5. 页面显示识别结果(风险等级+颜色徽章),提示跳转状态识别页。

CSV / Excel 导入

支持批量导入功能:

  1. 提供模板下载,包含所有必要列名。
  2. 上传 CSV / XLSX / XLS 文件后自动解析列名(兼容大小写和空格)。
  3. 展示前 8 行数据预览。
  4. 点击"批量导入并识别"逐行验证并预测,显示进度条。
  5. 完成后报告成功/失败统计,并可展开查看错误详情。

11.2 心理状态识别

在这里插入图片描述

界面功能说明:

本页面对已保存的评估记录进行可视化展示与深度分析。

学生选择

下拉列表列出所有已评估记录(格式:学号 — 姓名 [风险等级] 评估时间),默认选中最近一次填写的记录(通过 session_state 传递)。

学生信息卡片

展示学生基本信息(姓名、学号)和 6 项学业指标(年龄、性别、专业、年级、GPA、出勤率),顶部显示彩色风险徽章(红/橙/绿)。

三维可视化

图表 类型 内容
综合风险仪表盘 仪表盘(Gauge) 风险评分百分比,0–30% 绿色区,30–60% 黄色区,60–100% 红色区
各等级预测概率 水平柱状图 三类风险概率(%),颜色对应风险等级
心理维度雷达图 五边形雷达图 焦虑、抑郁、学业压力、经济压力、社会支持五维评分

关键风险因素

系统自动检测以下风险标志并以彩色告警框展示:

  • 焦虑评分 ≥ 7 → 焦虑程度偏高
  • 抑郁评分 ≥ 7 → 抑郁倾向偏高
  • 学业压力 ≥ 8 → 学业压力极高
  • 每日睡眠 < 6 h → 睡眠不足
  • 社会支持 ≤ 3 → 社会支持匮乏
  • 睡眠质量 = Poor → 睡眠质量差
  • 出勤率 < 60% → 出勤偏低

若无上述标志则显示绿色安全提示。


11.3 高危学生预警

在这里插入图片描述

界面功能说明:

本页面为学校心理管理部门提供整体风险态势感知。

统计磁贴(4 格卡片)

顶部展示 4 个彩色磁贴,分别显示:评估总人数(蓝色)、高风险人数(红色)、中风险人数(橙色)、低风险人数(绿色)。顶部边框颜色直观传达风险等级语义。

图表区域

图表 类型 说明
风险等级分布 环形饼图 展示三类风险的比例分布,悬停显示具体人数和百分比
各专业平均风险 水平柱状图 各专业平均风险评分,按分值渐变着色(绿→黄→红)

高风险学生列表

以表格形式列出所有高风险学生,包含:学号、姓名、评估时间、焦虑评分、抑郁评分、压力等级、风险评分。数据支持排序,高风险人数显示在红色告警框中。

个人雷达图

底部提供学生选择下拉框,选中后实时渲染该学生的五维心理雷达图,颜色跟随风险等级(红/橙/绿),右侧显示具体数值摘要,便于快速评估。


11.4 心理干预建议

在这里插入图片描述

界面功能说明:

本页面根据模型预测结果为每名学生生成个性化干预方案。

学生选择与风险告警

默认按风险等级排序(高风险优先),选中学生后立即显示对应颜色的告警框:

  • 高风险 → 红色告警框,提示"立即启动专业干预"
  • 中风险 → 橙色警告框,提示"安排心理辅导"
  • 低风险 → 绿色提示框,说明状态良好

指标概览

9 个指标卡片展示焦虑、抑郁、学业压力、经济压力、社会支持及压力等级、睡眠质量、每日睡眠时长、出勤率。

干预建议卡片

综合干预建议(左侧,按风险等级分 3 档):

风险等级 建议条数 建议内容示例
高风险 6 条 立即预约咨询、启动应急支持、通知家庭、高频随访、减学业压力、建立支持网络
中风险 6 条 预约辅导、正念冥想、改善睡眠、增加锻炼、规划学习、限制屏幕
低风险 5 条 保持健康习惯、坚持锻炼、维护社交、减压技巧、定期自评

专项建议(右侧,根据具体指标动态生成):

触发条件 专项建议标题
焦虑评分 ≥ 7 焦虑管理专项建议(CBT、减少咖啡因)
抑郁评分 ≥ 7 抑郁情绪专项建议(户外活动、避免独处)
睡眠质量 = Poor 睡眠质量改善建议(固定作息、温度控制)
社会支持 ≤ 3 社会支持增强建议(参加小组、主动沟通)
学业压力 ≥ 8 学业压力疏解建议(沟通老师、分解目标)
经济压力 ≥ 8 经济压力缓解建议(申请助学金、家庭沟通)

报告生成与下载

点击"生成并下载评估报告(TXT)"按钮,系统动态生成包含以下内容的文本报告:

  • 学生基本信息
  • 心理风险评估结果(等级+各类概率)
  • 心理健康指标详情
  • 生活状况数据
  • 完整综合与专项干预建议
  • 备注信息

文件以 mental_health_report_{学号}_{日期}.txt 格式命名,可直接下载。“预览报告内容” 折叠面板可在下载前查看报告全文。


11.5 心理档案管理

在这里插入图片描述

界面功能说明:

本页面提供历史评估记录的完整管理功能。

多条件筛选

支持以下筛选条件的自由组合:

  • 学号(模糊匹配,LIKE '%keyword%'
  • 姓名(模糊匹配)
  • 风险等级(精确匹配:全部 / High / Medium / Low)

筛选结果实时统计并以蓝色信息框显示记录总数和高风险记录数。

数据表格

以表格展示以下关键字段:ID、学号、姓名、评估时间、年龄、性别、专业、年级、风险等级、风险评分、焦虑、抑郁、压力等级、睡眠质量、出勤率、GPA。表格高度自适应(最高 360px),支持原生排序和横向滚动。

操作功能

功能 说明
导出 CSV 将当前筛选结果导出为 UTF-8 编码 CSV 文件(含中文 BOM,Excel 可直接打开)
删除记录 展开折叠面板,输入记录 ID,点击确认删除;操作后页面自动刷新(st.rerun()

个人趋势分析

选择学生后,系统查询该学生的全部历史记录:

  • ≥ 2 条记录:渲染趋势折线图,包含三条曲线:
    • 风险评分(红色实线)
    • 焦虑评分归一化(橙色虚线,÷10)
    • 抑郁评分归一化(紫色点线,÷10)
    • 背景三色带:绿色(低风险区 0–0.3)、黄色(中风险区 0.3–0.6)、红色(高风险区 0.6–1.0)
  • = 1 条记录:显示提示说明,展示单次评估的关键指标卡片。

趋势图直观展示学生心理状态的历时变化,便于评估干预效果。


12. 技术栈原理详解

12.1 Streamlit

Streamlit 是一个面向数据科学家的 Python Web 框架,核心特点:

  • 响应式重新运行机制:每次用户交互(按钮点击、滑块拖拽)都触发脚本从头重新执行,无需手动管理状态机。
  • st.session_state:跨页面共享状态(如最新预测结果),避免重复计算。
  • @st.cache_resource:缓存模型对象(joblib.load),首次加载后常驻内存,避免每次请求重新读取 300MB+ 模型文件。
  • streamlit_option_menu:第三方组件,提供 Bootstrap Icons 图标的侧边栏导航,样式高度可定制。

12.2 scikit-learn

scikit-learn 提供统一的 fit() / predict() / predict_proba() API:

  • Pipeline 思想:虽然本项目未使用 sklearn.Pipeline,但遵循了 fit on train → transform both 的标准流程,确保测试集不泄露训练信息(避免 data leakage)。
  • cross_val_score:可用于超参数调优(本项目 PSO 内部使用训练集划分的验证子集)。
  • 特征选择 APISelectKBest(过滤法)、RFE(包装法)均遵循 fit → get_support() 接口。

12.3 XGBoost

XGBoost 相比传统梯度提升(GBDT)的核心改进:

改进点 说明
正则化 目标函数加入 L1/L2 正则,控制模型复杂度,防过拟合
二阶导数 使用 Hessian 矩阵信息(二阶泰勒展开),加快收敛
并行化 特征分裂点预排序并行计算,大数据集速度提升显著
缺失值处理 自动学习缺失值的最优分裂方向
剪枝策略 先生长后剪枝(max_depth + min_child_weight),避免贪婪陷阱

12.4 pyswarms(PSO 库)

pyswarms.discrete.binary.BinaryPSO 实现了二进制粒子群优化:

  • 位置空间: { 0 , 1 } n \{0,1\}^n {0,1}n(每个维度代表是否选择该特征)
  • Sigmoid 转换:将连续速度映射为位翻转概率
  • 目标函数:用户自定义(本项目为 1 - weighted_F1
  • optimizer.cost_history:存储每轮全局最优代价,用于绘制收敛曲线

12.5 Plotly

Plotly 提供交互式图表,本系统使用的核心图表类型:

图表 模块 用途
仪表盘 go.Indicator 风险评分可视化
雷达图 go.Scatterpolar 心理维度多维展示
环形饼图 px.pie(hole=0.45) 风险等级占比
折线图 go.Scatter 趋势追踪
柱状图 go.Bar 模型对比、概率展示
背景带 add_hrect 风险区间着色

所有图表均设置 paper_bgcolor='rgba(0,0,0,0)',与页面白色卡片背景无缝融合。

12.6 SQLite 与 pandas 协作

用户操作 → db_utils → sqlite3.Connection → records.db
                            ↓
               pandas.read_sql(sql, conn)
                            ↓
               DataFrame → Streamlit st.dataframe()
  • 读操作通过 pd.read_sql() 直接将查询结果加载为 DataFrame,减少中间转换。
  • 写操作通过 conn.execute(INSERT ...) 进行原子性写入(with conn: 上下文管理器自动提交/回滚)。
  • 使用 check_same_thread=False 支持 Streamlit 多线程环境下的 SQLite 连接复用。

12.7 joblib 模型持久化

joblib.dump(model, 'models/best_model.pkl')   序列化(训练后)
model = joblib.load('models/best_model.pkl')  反序列化(推理时)

相比 picklejoblib 对包含大型 NumPy 数组的对象(如 RandomForest 包含的大量决策树节点)序列化/反序列化效率更高,支持内存映射(mmap),可显著降低 RAM 占用。

更多推荐