Python+SPSS数学建模实战:慢性病影响因素分析与可视化全流程
数学建模竞赛中,数据处理与分析能力往往决定了作品的深度与竞争力。面对慢性病影响因素分析这类典型的社会医学问题,如何高效完成从原始问卷到可视化报告的全流程?本文将手把手带你用Python和SPSS构建完整分析链路,涵盖数据清洗、特征工程、统计建模到结果解读的每个技术细节。
1. 数据预处理:从原始问卷到分析数据集
拿到原始问卷数据(如Excel格式的A2附件)时,首先需要建立标准化的预处理流程。我们使用pandas进行高效清洗:
import pandas as pd import numpy as np # 读取原始数据 raw_data = pd.read_excel('chronic_disease_survey.xlsx', header=1) # 基础清洗步骤 def basic_cleaning(df): # 删除空行 df = df.dropna(how='all') # 填充缺失ID df['ID'] = df['ID'].fillna(pd.Series(range(1, len(df)+1))) # 统一缺失值标记 df.replace([-99, 'NA', ''], np.nan, inplace=True) # 类型转换 for col in df.select_dtypes(include=['object']): try: df[col] = pd.to_numeric(df[col]) except: pass return df cleaned_data = basic_cleaning(raw_data)针对问卷数据的特殊处理技巧:
- 多选题拆分:使用
str.get_dummies()处理"选择所有适用项"类问题 - 量表题标准化:对Likert量表题进行Z-score标准化
- 异常值检测:通过IQR方法识别极端值
# 多选题处理示例 diet_habits = cleaned_data['Q15'].str.get_dummies(sep=',') cleaned_data = pd.concat([cleaned_data, diet_habits.add_prefix('Q15_')], axis=1) # 量表题标准化 from sklearn.preprocessing import StandardScaler scale_cols = ['Q23', 'Q24', 'Q25'] scaler = StandardScaler() cleaned_data[scale_cols] = scaler.fit_transform(cleaned_data[scale_cols])2. 膳食合理性评估:基于指南的量化分析
参考《中国居民膳食指南》(A3附件),我们需要构建可量化的评估体系。以下是核心评估维度:
| 评估维度 | 对应问卷条目 | 评分规则 |
|---|---|---|
| 食物多样性 | Q5-Q14 | 每周摄入≥12种食物得1分 |
| 谷类摄入 | Q15_1-Q15_3 | 每日全谷物占比≥1/3得0.5分 |
| 蔬果摄入 | Q16-Q18 | 每日≥500g得1分 |
| 奶制品摄入 | Q19 | 每日300-500ml得0.5分 |
| 盐油控制 | Q20-Q22 | 食盐≤5g/日得0.5分 |
Python实现自动评分:
def calculate_diet_score(row): score = 0 # 食物多样性 food_variety = row[['Q5','Q6','Q7','Q8','Q9','Q10','Q11','Q12','Q13','Q14']].notna().sum() score += 1 if food_variety >= 12 else 0 # 全谷物占比 if row['Q15_1'] == 1 and row['Q15_2'] >= 3: score += 0.5 # 蔬果摄入 veg_fruit = row['Q16'] + row['Q17'] score += 1 if veg_fruit >= 500 else 0 return score cleaned_data['diet_score'] = cleaned_data.apply(calculate_diet_score, axis=1)使用SPSS进行可视化验证:
- 将Python处理后的数据导出为CSV
- 在SPSS中执行:
GRAPHS → BOXPLOT → 选择diet_score作为变量 - 添加分组变量(如年龄段)进行对比分析
注意:实际评分应根据具体问卷结构调整,这里展示的是核心逻辑框架
3. 影响因素相关性分析:多方法组合策略
面对年龄、职业等不同变量类型,需要采用混合分析方法:
3.1 连续变量 vs 连续变量
- Pearson相关系数:线性关系检验
- Spearman秩相关:单调关系检验
# Python实现 corr_matrix = cleaned_data[['age', 'BMI', 'diet_score']].corr(method='pearson') # 热力图可视化 import seaborn as sns sns.heatmap(corr_matrix, annot=True, cmap='coolwarm')3.2 分类变量 vs 分类变量
- 卡方检验:检验变量独立性
- Cramer's V:衡量关联强度
SPSS操作路径:
Analyze → Descriptive Statistics → Crosstabs → 选择行变量和列变量 → Statistics中勾选Chi-square和Phi/Cramer's V3.3 连续变量 vs 分类变量
- ANOVA(正态分布)
- Kruskal-Wallis检验(非正态分布)
Python代码示例:
from scipy import stats # 按职业分组分析饮食得分 groups = [group['diet_score'] for name, group in cleaned_data.groupby('occupation')] f_val, p_val = stats.f_oneway(*groups) print(f"ANOVA结果: F={f_val:.2f}, p={p_val:.4f}")4. 慢性病预测模型:机器学习实战
针对问题3的慢性病预测,我们构建特征工程与模型训练流程:
4.1 特征构建
从原始问卷中提取关键特征:
features = { 'smoking': cleaned_data['Q30'].map({'从不':0, '偶尔':1, '经常':2}), 'alcohol': cleaned_data['Q31'].apply(lambda x: 1 if x>2 else 0), 'exercise_freq': cleaned_data['Q26'], 'work_stress': cleaned_data['Q27'], 'sleep_quality': cleaned_data['Q28'], 'diet_score': cleaned_data['diet_score'] } X = pd.DataFrame(features) y = cleaned_data['hypertension'] # 目标变量4.2 神经网络建模
使用scikit-learn实现简易BP神经网络:
from sklearn.neural_network import MLPClassifier from sklearn.model_selection import train_test_split # 数据拆分 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) # 模型训练 model = MLPClassifier(hidden_layer_sizes=(10,5), activation='relu', max_iter=1000) model.fit(X_train, y_train) # 特征重要性分析 perm = PermutationImportance(model, random_state=1).fit(X_test, y_test) eli5.show_weights(perm, feature_names=X.columns.tolist())4.3 模型解释技巧
- SHAP值分析:解释特征贡献度
- 部分依赖图:展示特征边际效应
import shap # SHAP分析 explainer = shap.DeepExplainer(model, X_train[:100]) shap_values = explainer.shap_values(X_test[:10]) shap.summary_plot(shap_values, X_test)5. 人群分类与健康建议:聚类分析应用
基于因子分析和K-means聚类实现人群细分:
5.1 SPSS因子分析步骤
- 选择菜单:
Analyze → Dimension Reduction → Factor - 将饮食、运动、生活习惯等变量放入分析框
- 设置提取方法为主成分分析,保留特征值>1的因子
- 使用Varimax旋转提高解释性
5.2 Python聚类实现
from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler # 使用因子得分作为输入 factor_scores = pd.read_csv('spss_factor_scores.csv') scaler = StandardScaler() scaled_data = scaler.fit_transform(factor_scores) # 肘部法则确定K值 inertia = [] for k in range(1, 10): kmeans = KMeans(n_clusters=k, random_state=42) kmeans.fit(scaled_data) inertia.append(kmeans.inertia_) # 可视化确定最佳聚类数 plt.plot(range(1,10), inertia, marker='o') plt.xlabel('Number of clusters') plt.ylabel('Inertia')5.3 人群特征画像与建议
通过聚类中心解读人群特征:
| 人群类型 | 饮食特征 | 运动特征 | 健康建议 |
|---|---|---|---|
| 类型1 | 高盐高油 | 久坐少动 | 控制外卖频率,设置站立办公时间 |
| 类型2 | 蔬果不足 | 偶尔运动 | 增加彩虹蔬果摄入,培养晨练习惯 |
| 类型3 | 结构合理 | 规律运动 | 保持现有习惯,注意睡眠质量 |
在SPSS中可通过以下路径生成人群分布图:
Graphs → Chart Builder → 选择散点图 → 设置因子得分为坐标轴 → 以聚类结果为分组变量6. 分析报告整合技巧
将Python与SPSS优势结合,打造专业级报告:
数据���架构:
Python数据清洗 → SPSS高级统计 → Python机器学习 → SPSS可视化自动化衔接:
- 使用
pyreadstat库直接读写SPSS格式文件 - 通过Python调用SPSS语法文件执行批量分析
- 使用
import pyreadstat # 将Python数据保存为SPSS格式 pyreadstat.write_sav(cleaned_data, 'cleaned_data.sav') # 调用SPSS执行语法文件 import subprocess subprocess.run(['pspp', 'analysis_script.sps'])- 可视化组合方案:
- 使用Python的Matplotlib/Seaborn制作复杂图表
- 利用SPSS的交互式图表功能快速探索数据
- 最终用Tableau或Power BI整合所有可视化成果
在数学建模竞赛中,这种技术组合既能保证分析深度,又能提升工作效率。记得保存每个步骤的代码和输出结果,形成完整的分析溯源链条。