
一、赛题背景与核心理解2026 年江西省研究生数学建模竞赛赛题 3 的题目是“电子健康记录数据补全及其优化算法”。这是一道非常典型的医学数据建模题核心不是简单地把缺失值填上而是要围绕电子健康记录数据的缺失机制、数据稀疏性、矩阵补全方法、主成分分析和多算法对比建立一套完整、可靠、可解释的 EHR 缺失补全与临床指标挖掘方案。电子健康记录即 EHR通常包含患者在住院或随访过程中的生命体征、实验室检查、人口学信息、病情标签等。相比问卷调查数据EHR 更贴近真实临床过程但它也有一个非常突出的特点缺失非常严重。很多指标不是每个小时都测有些实验室指标只有病情变化时才测有些患者住院时间短有些患者记录周期长这会导致同一个数据集中不同患者、不同变量、不同时间点的缺失程度差异巨大。优惠链接关注最上方名片和qun链接自动回复获取2026最新江西省研究生数学建模成品资料赛题123题全套参考方案全套代码思路助攻论文结果数据https://download.csdn.net/download/qq_40379132/92961957https://download.csdn.net/download/qq_40379132/92961960https://download.csdn.net/download/qq_40379132/92961962本题提供的数据来自类似 CINC2019 的临床时间序列数据。每位患者对应一个.psv文件文件中的每一行代表一次时间观测每一列代表一个生命体征或临床变量。题目要求选取标准化子集开展建模重点完成缺失率统计、变量筛选与归一化简单矩阵缺失值补全基于 NMF 的低秩矩阵补全基于补全数据的 PCA 主成分分析根据 PCA 结果筛选关键生命体征指标在不同缺失比例下比较 SVD-PCA、NMF 及其他算法的补全精度综合误差、稳定性和复杂度筛选最优 EHR 数据补全模型。这道题的本质是在高缺失、强异质、不同量纲的临床 EHR 数据中构建可靠的数据补全模型并验证补全结果是否能提升后续 PCA 分析和关键生理指标挖掘的有效性。高分论文不能只写“用均值填补、NMF 填补、PCA 分析”。真正好的方案必须回答以下问题为什么 EHR 数据会缺失缺失是随机缺失还是非随机缺失哪些变量缺失率过高应当剔除归一化应在什么时候做NMF 为什么适合非负生命体征数据分解秩 r 如何选择如何避免 NMF 过拟合补全后 PCA 的主成分是否更稳定补全精度如何在不同缺失率下验证最终哪个算法更适合 EHR 数据二、整体建模主线本题建议采用“五层递进式建模框架”第一层数据读取与缺失模式分析。从.psv文件读取患者 EHR 矩阵统计每个变量、每个患者、每个时间点的缺失率识别高缺失变量和可用变量。第二层数据标准化与低维补全。对筛选出的有效变量进行 Min-Max 归一化或 Z-score 标准化标记 NaN 缺失位置并对题目给出的小矩阵采用均值填补、KNN 填补、SVD 填补或 NMF 填补进行示范。第三层NMF 低秩矩阵补全。将清洗后的 EHR 数据构造成观测矩阵 (A)使用带缺失掩码的 NMF 模型 (A \approx WH)通过迭代更新非负矩阵 (W) 与 (H)完成缺失点填补。第四层PCA 主成分分析与临床规律挖掘。对 NMF 补全后的完整数据进行 Z-score 标准化计算协方差矩阵提取第一、第二主成分计算方差贡献率和指标载荷筛选关键生命体征指标。第五层多算法、多缺失率补全精度对比。以补全后的完整数据作为基准在 10%、20%、30%、40%、50% 五档缺失率下随机掩码分别用 SVD-PCA、NMF、KNN、MICE、SoftImpute 等方法补全计算 RSE并从精度、稳定性和复杂度三方面选择最优模型。最终论文主线可以概括为缺失识别 → 变量筛选 → 矩阵补全 → PCA 降维 → 关键指标筛选 → 多算法鲁棒比较 → 最优补全模型推荐。三、任务一数据预处理、缺失率计算、归一化与低维矩阵补全3.1 数据读取与字段理解每位患者的 EHR 数据是一个.psv文件字段通常包括HR心率O2Sat血氧饱和度Temp体温SBP收缩压MAP平均动脉压DBP舒张压Resp呼吸频率EtCO2呼气末二氧化碳BaseExcess碱剩余HCO3碳酸氢根FiO2吸入氧浓度pH酸碱度PaCO2动脉二氧化碳分压SaO2动脉血氧饱和度AST、BUN、Creatinine、Glucose、Lactate 等实验室指标Age、Gender、Unit1、Unit2、HospAdmTime、ICULOS 等基础特征SepsisLabel脓毒症标签题目要求对 p000001.psv 的前 40 个生命特征以及缺失信息进行统计并选择前 36 个特征变量找出其中缺失率小于 90% 的前 11 个特征标量。这里的“前 36 个特征变量”一般可以理解为剔除相对稳定的基础变量或标签后的动态生命体征变量重点关注随时间变化的临床指标。3.2 缺失率计算对某一特征 (j)缺失率定义为[MR_j\frac{\sum_{i1}^{n}I(x_{ij}\text{ is NaN})}{n}]其中 (n) 是该患者的观测时间点数量(I) 是指示函数。若 (MR_j 0.9)说明该变量至少有 10% 的有效观测可以保留进入后续建模。对每个患者也可以计算整体缺失率[MR_i\frac{\sum_{j1}^{p}I(x_{ij}\text{ is NaN})}{p}]该指标可用于筛选观测质量较高的患者样本。3.3 为什么要剔除高缺失变量EHR 中某些实验室指标缺失率极高例如 TroponinI、Fibrinogen、Bilirubin_direct 等指标可能并不是所有患者都检测。若直接保留会产生两个问题第一补全结果主要由模型猜测得到可信度很低第二这些变量会对 PCA 和距离计算产生不稳定影响。因此缺失率过高的变量不应盲目补全。合理做法是缺失率低于 30%优先保留缺失率 30%–70%视临床意义和模型需要选择保留缺失率 70%–90%谨慎使用缺失率超过 90%一般剔除。题目明确要求筛选缺失率小于 90% 的变量这是为了确保后续补全具有基本数据支撑。3.4 归一化方法生命体征变量量纲不同。比如心率单位是次/分钟体温单位是摄氏度血压单位是 mmHgpH 范围约 7 左右。若不归一化数值范围大的变量会在 NMF、SVD、PCA 中占据不合理权重。常用归一化方法有两种。Min-Max 归一化[x\frac{x-x_{\min}}{x_{\max}-x_{\min}}]优点是将数据压缩到 ([0,1])适合 NMF因为 NMF 要求非负输入。Z-score 标准化[z\frac{x-\mu}{\sigma}]优点是适合 PCA因为 PCA 基于方差结构Z-score 可以消除量纲影响。建议流程是NMF 补全前使用 Min-Max 归一化保证非负性PCA 分析前使用 Z-score 标准化保证协方差分析公平。3.5 任务一代码读取 psv 文件、统计缺失率、筛选变量import os import zipfile import numpy as np import pandas as pd from io import TextIOWrapper ZIP_PATH 附件2_data_cinc2019.zip def read_psv_from_zip(zip_path, inner_path): with zipfile.ZipFile(zip_path) as z: with z.open(inner_path) as f: return pd.read_csv(TextIOWrapper(f), sep|) def list_training_setA_files(zip_path): with zipfile.ZipFile(zip_path) as z: names [ n for n in z.namelist() if n.startswith(cinc2019/training/training_setA/) and n.endswith(.psv) and __MACOSX not in n ] return sorted(names) files_A list_training_setA_files(ZIP_PATH) print(training_setA 文件数量:, len(files_A)) print(前5个文件:, files_A[:5]) df1 read_psv_from_zip(ZIP_PATH, cinc2019/training/training_setA/p000001.psv) print(df1.head()) print(df1.shape) # 前 40 个生命特征不含 SepsisLabel feature_cols_40 df1.columns[:40] missing_rate df1[feature_cols_40].isna().mean().sort_values() missing_table pd.DataFrame({ feature: missing_rate.index, missing_rate: missing_rate.values }) print(missing_table) # 前 36 个特征中缺失率小于 90% 的前 11 个 feature_cols_36 df1.columns[:36] mr36 df1[feature_cols_36].isna().mean() selected_11 mr36[mr36 0.90].sort_values().head(11).index.tolist() print(缺失率小于90%的前11个变量:) print(selected_11)3.6 选取 50 份 36×41 规格患者数据矩阵题目要求从 training_setA 中筛选 50 份 36×41 规格患者临床数据矩阵。这里的 36 行表示选择前 36 个时间点41 列表示完整字段包括 40 个特征和 SepsisLabel。若某患者记录长度不足 36则不选若长度超过 36则取前 36 行或按任务要求取标准化片段。为了保证比较公平可以统一取每位患者的前 36 条记录。def load_standardized_patients(zip_path, n_patients50, n_rows36, n_cols41): files list_training_setA_files(zip_path) matrices [] names [] for path in files: df read_psv_from_zip(zip_path, path) if df.shape[0] n_rows and df.shape[1] n_cols: mat df.iloc[:n_rows, :n_cols].copy() matrices.append(mat) names.append(os.path.basename(path)) if len(matrices) n_patients: break return names, matrices names50, mats50 load_standardized_patients(ZIP_PATH, n_patients50) print(选取患者数:, len(mats50)) print(第一个矩阵形状:, mats50[0].shape)3.7 标记 NaN 缺失位置缺失掩码矩阵 (M) 定义为[M_{ij}\begin{cases}1, A_{ij}\text{ 已观测}\0, A_{ij}\text{ 缺失}\end{cases}]后续 NMF 和误差计算都要依赖这个掩码。def nan_mask(matrix_df): A matrix_df.values.astype(float) observed_mask ~np.isnan(A) missing_mask np.isnan(A) return A, observed_mask, missing_mask A0, obs0, miss0 nan_mask(mats50[0]) print(缺失数量:, miss0.sum()) print(观测数量:, obs0.sum())3.8 小矩阵缺失补全示例题目给出一个含 NaN 的小矩阵要求选取两种以上方法完成补全。这里可展示三种均值填补、KNN 填补、低秩 SVD 填补。方法一列均值填补特点简单、快速、稳定但忽略变量间相关性。方法二KNN 填补特点利用相似样本信息适合局部结构明显的数据但对距离度量敏感。方法三低秩 SVD 填补特点利用矩阵低秩结构适合变量之间存在潜在相关结构的数据。from sklearn.impute import SimpleImputer, KNNImputer from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer A_small np.array([ [5, 3, 8, 1], [9, 7, 4, np.nan], [6, 5, 2, 9], [1, 8, 3, 7], [4, 6, 2, 5], [8, 1, 6, np.nan], [np.nan, np.nan, np.nan, np.nan], [np.nan, np.nan, np.nan, np.nan], [np.nan, np.nan, np.nan, np.nan] ], dtypefloat) # 1. 均值填补 mean_imputer SimpleImputer(strategymean) A_mean mean_imputer.fit_transform(A_small) # 2. KNN 填补 knn_imputer KNNImputer(n_neighbors2) A_knn knn_imputer.fit_transform(A_small) # 3. MICE/迭代回归填补 iter_imputer IterativeImputer(random_state2026, max_iter20) A_iter iter_imputer.fit_transform(A_small) print(均值填补:) print(np.round(A_mean, 3)) print(KNN填补:) print(np.round(A_knn, 3)) print(迭代回归填补:) print(np.round(A_iter, 3))论文中要说明低维小矩阵示例只是展示不同补全思想真正高维 EHR 数据应采用能利用低秩结构和变量相关性的模型例如 NMF、SVD-PCA 或 MICE。四、任务二NMF 缺失填充与 PCA 主成分分析建模4.1 为什么选择 NMFNMF即非负矩阵分解假设非负数据矩阵 (A) 可以近似分解为[A \approx WH]其中[W \ge 0,\quad H \ge 0](W) 表示样本在潜在生理模式上的权重(H) 表示每个潜在模式在不同生命体征上的贡献。NMF 适合本题有三个原因第一生命体征经 Min-Max 归一化后为非负数据符合 NMF 非负约束。第二EHR 变量之间存在潜在低秩结构例如血压、心率、呼吸、血氧等可能共同反映循环和呼吸状态。第三NMF 分解具有一定可解释性每个潜在因子可以看作某类生理状态模式。4.2 带缺失掩码的 NMF 目标函数由于原始矩阵存在缺失不能直接对 NaN 计算误差。应只在观测位置上拟合[\min_{W,H\ge0}\frac{1}{2}|M\odot(A-WH)|_F^2\lambda(|W|_F^2|H|_F^2)]其中 (M) 是观测掩码矩阵(\odot) 表示逐元素乘积。这个模型的含义是只要求 (WH) 在原本有观测值的位置尽量接近真实值而缺失位置由低秩结构自动估计。4.3 分解秩 r 的选择分解秩 (r) 决定潜在生理模式数量。若 (r) 太小模型欠拟合若 (r) 太大模型可能过拟合噪声。可以用以下方法选择 (r)交叉验证随机遮盖一部分已知值比较不同 (r) 的 RSE重构误差拐点法观察误差随 (r) 增加的下降曲线临床可解释性通常选择 3–10 个潜在生理模式更易解释稳定性分析多次初始化后结果波动小的 (r) 更可靠。建议论文中选用交叉验证法确定 (r)并给出误差曲线。4.4 NMF 缺失补全代码import numpy as np def masked_nmf(A, mask, rank5, max_iter500, lr0.005, reg1e-4, random_state2026): 带缺失掩码的 NMF。 A: 已归一化矩阵缺失位置可先填0 mask: 观测位置为1缺失位置为0 rng np.random.default_rng(random_state) n, p A.shape W rng.random((n, rank)) H rng.random((rank, p)) losses [] A_filled np.nan_to_num(A, nan0.0) M mask.astype(float) for it in range(max_iter): WH W H E M * (WH - A_filled) grad_W E H.T reg * W grad_H W.T E reg * H W - lr * grad_W H - lr * grad_H W np.maximum(W, 1e-8) H np.maximum(H, 1e-8) if it % 20 0: loss 0.5 * np.sum(E ** 2) 0.5 * reg * (np.sum(W ** 2) np.sum(H ** 2)) losses.append(loss) A_hat W H A_completed A_filled.copy() A_completed[~mask] A_hat[~mask] return A_completed, W, H, losses4.5 构造 50 份患者合并矩阵题目可以有两种理解方式第一种把每个患者 36×41 矩阵展平为一个样本向量形成 50×1476 的矩阵第二种把 50 个患者的所有时间点拼接形成 1800×41 的矩阵。更推荐第二种因为 PCA 和 NMF 面向生命体征变量保留列含义更清楚。def concat_patient_matrices(mats, use_colsNone): frames [] for df in mats: if use_cols is not None: frames.append(df[use_cols]) else: frames.append(df) return pd.concat(frames, axis0, ignore_indexTrue) # 只使用前40个生命体征不含标签 feature_cols mats50[0].columns[:40].tolist() X_raw concat_patient_matrices(mats50, use_colsfeature_cols) print(X_raw.shape)4.6 Min-Max 归一化并保留缺失位置def minmax_scale_with_nan(df): X df.values.astype(float) X_scaled X.copy() mins np.nanmin(X_scaled, axis0) maxs np.nanmax(X_scaled, axis0) ranges maxs - mins ranges[ranges 0] 1.0 X_scaled (X_scaled - mins) / ranges return X_scaled, mins, ranges X_scaled, mins, ranges minmax_scale_with_nan(X_raw) mask ~np.isnan(X_scaled) X_nmf, W, H, losses masked_nmf( X_scaled, mask, rank6, max_iter600, lr0.003, reg1e-4 ) print(补全后是否仍有 NaN:, np.isnan(X_nmf).sum())4.7 PCA 主成分分析PCA 分析要使用 Z-score 标准化[Z_{ij}\frac{x_{ij}-\mu_j}{\sigma_j}]协方差矩阵[C\frac{1}{n-1}Z^TZ]特征分解[Cv_k\lambda_k v_k]第 (k) 个主成分方差贡献率[CR_k\frac{\lambda_k}{\sum_j\lambda_j}]样本在第 (k) 个主成分上的得分[Score_kZv_k]4.8 PCA 代码from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA def run_pca(X_completed, feature_names, n_components2): scaler StandardScaler() Z scaler.fit_transform(X_completed) pca PCA(n_componentsn_components) scores pca.fit_transform(Z) loadings pd.DataFrame( pca.components_.T, indexfeature_names, columns[fPC{i1} for i in range(n_components)] ) explained pca.explained_variance_ratio_ score_df pd.DataFrame( scores, columns[fPC{i1}_score for i in range(n_components)] ) return pca, score_df, loadings, explained pca, score_df, loadings, explained run_pca(X_nmf, feature_cols, n_components2) print(第一主成分贡献率:, explained[0]) print(第二主成分贡献率:, explained[1]) print(累计贡献率:, explained[:2].sum()) print(载荷最高的指标:) print(loadings.abs().sort_values(PC1, ascendingFalse).head(10))五、任务三基于 PCA 结果的临床数据规律挖掘5.1 主成分载荷的解释PCA 的关键不是只算出方差贡献率而是解释主成分代表什么临床含义。主成分载荷越大说明该生命体征对该主成分贡献越大。例如若 PC1 在 HR、Resp、Temp、WBC、Lactate 上载荷较高可能代表炎症/感染应激状态若 PC2 在 SBP、MAP、DBP 上载荷较高可能代表循环血流动力学状态若某主成分在 O2Sat、SaO2、PaCO2、FiO2 上载荷较高可能代表呼吸氧合状态若 BUN、Creatinine 载荷较高可能代表肾功能状态。本题虽然背景提到肿瘤筛查但数据标签中包含脓毒症标签因此论文写作时可以更稳妥地表述为“患者高危生理状态预警指标”不要强行说某指标一定是肿瘤特异指标。5.2 关键预警指标筛选方法可以用以下规则筛选关键指标在 PC1 或 PC2 中绝对载荷排名前 10在两类主成分中均具有较高载荷方差贡献率较高主成分中的高载荷变量优先缺失率不能过高具有明确临床意义。综合评分可定义为[S_jCR_1|l_{j1}|CR_2|l_{j2}|-\alpha MR_j]其中 (CR_1,CR_2) 是第一、第二主成分贡献率(l_{j1},l_{j2}) 是载荷系数(MR_j) 是缺失率。该指标兼顾主成分贡献和数据可用性。5.3 关键指标筛选代码def select_key_indicators(loadings, explained, missing_rate, top_k10, alpha0.2): mr missing_rate.reindex(loadings.index).fillna(0) score ( explained[0] * loadings[PC1].abs() explained[1] * loadings[PC2].abs() - alpha * mr ) result pd.DataFrame({ PC1_loading: loadings[PC1], PC2_loading: loadings[PC2], missing_rate: mr, importance_score: score }).sort_values(importance_score, ascendingFalse) return result.head(top_k), result missing_rate_all X_raw.isna().mean() top_indicators, indicator_table select_key_indicators( loadings, explained, missing_rate_all, top_k12 ) print(top_indicators)5.4 补全前后 PCA 对比题目要求分别对 NMF 补全前残缺原始数据、补全后完整数据开展同等条件 PCA对比主成分组成和方差贡献率变化。由于 PCA 不能直接处理 NaN因此补全前可以用简单均值填补作为“原始残缺数据的基础处理”基准然后与 NMF 补全结果比较。对比指标包括第一、第二主成分贡献率变化累计贡献率变化载荷排序稳定性关键指标是否更符合临床解释主成分得分散点是否更连续、更少异常点。from sklearn.impute import SimpleImputer from scipy.stats import spearmanr # 补全前简单均值填补作为基准 mean_imputer SimpleImputer(strategymean) X_mean mean_imputer.fit_transform(X_scaled) pca_mean, score_mean, load_mean, exp_mean run_pca(X_mean, feature_cols, n_components2) pca_nmf, score_nmf, load_nmf, exp_nmf run_pca(X_nmf, feature_cols, n_components2) print(均值基准 PCA 贡献率:, exp_mean) print(NMF补全 PCA 贡献率:, exp_nmf) # 载荷排序相关性 rank_corr_pc1 spearmanr(load_mean[PC1].abs(), load_nmf[PC1].abs()).correlation rank_corr_pc2 spearmanr(load_mean[PC2].abs(), load_nmf[PC2].abs()).correlation print(PC1载荷排序相关:, rank_corr_pc1) print(PC2载荷排序相关:, rank_corr_pc2)论文中可以这样解释如果 NMF 补全后第一、第二主成分贡献率更高说明补全增强了数据中的主要结构如果载荷排序更稳定说明关键指标识别更可靠如果主成分散点图中异常离散点减少说明补全改善了数据质量。六、任务四多算法、多缺失率补全精度对比与最优模型筛选6.1 缺失率模拟实验设计题目要求设置 10%、20%、30%、40%、50% 五档缺失比例在基准完整数据集上随机掩码生成缺失样本。实验流程如下将 NMF 初步补全或较完整的数据作为基准完整数据在观测数据中随机选择一定比例位置设为 NaN用不同算法进行补全只在被人工遮盖的位置计算误差重复多次随机掩码统计平均 RSE 和标准差。6.2 RSE 指标相对平方误差[RSE\frac{\sum_{(i,j)\in\Omega}(x_{ij}-\hat{x}{ij})^2}{\sum{(i,j)\in\Omega}x_{ij}^2}]也可以使用开方形式[RSE\sqrt{\frac{\sum_{(i,j)\in\Omega}(x_{ij}-\hat{x}{ij})^2}{\sum{(i,j)\in\Omega}x_{ij}^2}}]论文中应明确使用哪一种。推荐使用带根号形式便于和 RMSE 类似解释。6.3 多算法补全方法建议比较以下方法。方法一均值填补优点计算最快基准方法。缺点低估方差破坏变量相关性。方法二KNN 填补优点利用相似样本局部结构。缺点缺失率高时邻居不稳定计算成本较高。方法三SVD-PCA 低秩补全优点利用全局低秩结构适合强相关变量。缺点可能产生负值对非负生命体征需后处理。方法四NMF 补全优点非负约束强结果更符合生命体征非负特性具有潜在生理模式解释。缺点对秩 r 和初始化敏感迭代成本较高。方法五MICE 迭代回归填补优点变量间关系表达灵活。缺点高维高缺失时容易不稳定计算较慢。6.4 SVD-PCA 补全代码def svd_impute(X_missing, rank5, max_iter100, tol1e-5): X X_missing.copy() mask ~np.isnan(X_missing) # 初始用列均值填补 col_mean np.nanmean(X, axis0) inds np.where(np.isnan(X)) X[inds] np.take(col_mean, inds[1]) last_X X.copy() for it in range(max_iter): U, S, Vt np.linalg.svd(X, full_matricesFalse) S_rank np.diag(S[:rank]) X_hat U[:, :rank] S_rank Vt[:rank, :] # 只更新缺失位置 X[~mask] X_hat[~mask] diff np.linalg.norm(X - last_X) / (np.linalg.norm(last_X) 1e-8) if diff tol: break last_X X.copy() # 非负裁剪 X np.clip(X, 0, 1) return X6.5 多算法统一评估代码from sklearn.impute import SimpleImputer, KNNImputer from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer def create_random_mask(X_full, missing_rate0.2, random_state2026): rng np.random.default_rng(random_state) X_missing X_full.copy() n, p X_full.shape total n * p num_missing int(total * missing_rate) all_indices np.arange(total) selected rng.choice(all_indices, sizenum_missing, replaceFalse) rows selected // p cols selected % p eval_mask np.zeros_like(X_full, dtypebool) eval_mask[rows, cols] True X_missing[eval_mask] np.nan return X_missing, eval_mask def rse_score(X_true, X_pred, eval_mask): numerator np.sum((X_true[eval_mask] - X_pred[eval_mask]) ** 2) denominator np.sum(X_true[eval_mask] ** 2) 1e-8 return np.sqrt(numerator / denominator) def impute_by_method(X_missing, method, rank6): if method mean: return SimpleImputer(strategymean).fit_transform(X_missing) if method knn: return KNNImputer(n_neighbors5).fit_transform(X_missing) if method mice: return IterativeImputer(max_iter20, random_state2026).fit_transform(X_missing) if method svd: return svd_impute(X_missing, rankrank) if method nmf: mask ~np.isnan(X_missing) X_imp, _, _, _ masked_nmf( X_missing, mask, rankrank, max_iter400, lr0.003, reg1e-4 ) return X_imp raise ValueError(未知方法) def evaluate_imputation_methods(X_full, missing_rates(0.1,0.2,0.3,0.4,0.5), methods(mean,knn,mice,svd,nmf), repeats5): records [] for rate in missing_rates: for rep in range(repeats): X_missing, eval_mask create_random_mask( X_full, missing_raterate, random_state2026 rep ) for method in methods: try: X_pred impute_by_method(X_missing, method, rank6) X_pred np.clip(X_pred, 0, 1) rse rse_score(X_full, X_pred, eval_mask) records.append({ missing_rate: rate, repeat: rep, method: method, RSE: rse }) except Exception as e: records.append({ missing_rate: rate, repeat: rep, method: method, RSE: np.nan }) return pd.DataFrame(records) # 以 X_nmf 作为近似完整基准数据进行模拟遮盖 result_df evaluate_imputation_methods(X_nmf, repeats3) summary result_df.groupby([missing_rate, method])[RSE].agg([mean, std]).reset_index() print(summary)6.6 稳定性与复杂度评价仅看 RSE 不够。最优模型要综合考虑平均 RSERSE 标准差缺失率升高时误差增长速度计算时间临床解释性是否满足非负约束。可定义综合得分[Score_m\alpha \overline{RSE}_m\beta SD(RSE_m)\gamma T_m\delta C_m]分数越低越好。其中 (T_m) 是归一化计算时间(C_m) 是模型复杂度惩罚。import time def timed_impute(X_missing, method): start time.time() X_pred impute_by_method(X_missing, method) elapsed time.time() - start return X_pred, elapsed def model_selection_score(summary, time_tableNone): # 示例仅用RSE均值和标准差 df summary.copy() df[score] df[mean] 0.5 * df[std].fillna(0) return df.sort_values([missing_rate, score])论文中可以给出结论低缺失率下KNN 或 SVD-PCA 可能表现较好中高缺失率下NMF 由于非负低秩约束更稳定极高缺失率下所有算法误差都会明显增大但 NMF 和 SVD-PCA 的退化更可控若考虑临床解释性NMF 更适合作为 EHR 数据补全主模型。七、论文写作结构建议摘要摘要应突出EHR 高缺失问题、缺失率筛选、NMF 补全、PCA 关键指标挖掘、多算法 RSE 对比和最优模型推荐。可写成本文针对电子健康记录数据高缺失、高维度和多量纲特征共存的问题建立了基于缺失模式分析、非负矩阵分解补全和主成分分析的 EHR 数据修复与指标挖掘框架。首先对 training_setA 中患者.psv文件进行读取与缺失率统计筛选缺失率小于 90% 的有效生命体征变量并构建 50 份 36×41 标准化临床矩阵。随后采用 Min-Max 归一化与缺失掩码记录方法构建带非负约束的 NMF 低秩补全模型实现 EHR 缺失值填充。在补全数据基础上利用 Z-score 标准化和 PCA 主成分分析提取主要生理状态模式并基于主成分载荷和方差贡献率筛选关键预警指标。最后在 10% 至 50% 五档人工缺失率下比较均值填补、KNN、SVD-PCA、NMF 和 MICE 等方法的 RSE、稳定性与计算复杂度。实验表明NMF 在中高缺失率下具有较优稳定性和临床解释性适合作为本类 EHR 稀疏数据的核心补全模型。第一章问题重述与数据特点说明 EHR 数据来源、变量类型、患者时序矩阵结构、缺失严重性和任务目标。重点强调EHR 缺失不是普通随机缺失临床数据量纲差异大补全结果会影响后续 PCA 和风险指标筛选必须同时考虑补全精度和临床可解释性。第二章数据预处理与缺失分析包括读取 p000001.psv统计前 40 个生命体征缺失率在前 36 个特征中筛选缺失率小于 90% 的前 11 个变量选取 50 份 36×41 标准矩阵归一化构造缺失掩码。第三章低维矩阵补全示例对题目给出的小矩阵采用均值填补、KNN 填补和迭代回归填补。说明不同方法特点为后续高维补全做铺垫。第四章NMF 缺失补全模型写清楚为什么 NMF 适合 EHRNMF 模型公式缺失掩码目标函数分解秩选择迭代优化方法补全结果生成完整数据集。第五章PCA 主成分分析包括Z-score 标准化协方差矩阵特征值分解第一、第二主成分得分方差贡献率主成分载荷解释。第六章基于 PCA 的关键指标挖掘根据载荷系数和贡献率筛选关键生命体征指标。建议结合医学含义讨论 HR、O2Sat、Temp、SBP、MAP、Resp、Lactate、WBC、Creatinine 等变量可能对应的循环、呼吸、炎症、代谢、肾功能等状态。第七章补全前后 PCA 对比对比均值填补基准和 NMF 补全后 PCA主成分贡献率是否提高载荷结构是否更稳定关键指标是否更集中补全是否提升数据质量。第八章多算法、多缺失率精度对比设置 10%、20%、30%、40%、50% 缺失率比较均值填补KNNMICESVD-PCANMF。评价指标RSERSE 标准差计算时间模型可解释性非负性约束。第九章结论与建议总结高缺失变量不宜盲目补全NMF 能利用非负低秩结构适合中高缺失 EHRPCA 可帮助筛选患者生理状态关键指标多缺失率模拟验证比单次补全更可信最优补全模型应综合精度、稳定性和临床解释性。八、最终博客总结赛题 3 的高分关键不是简单把 NaN 填上而是建立一套完整的 EHR 缺失数据分析体系。首先要从缺失机制出发识别哪些变量值得补全、哪些变量应当剔除其次要根据 NMF 的非负低秩结构构建适合生命体征数据的补全模型再次要通过 PCA 判断补全后的数据是否增强了主要生理结构最后要通过多算法、多缺失率的 RSE 实验验证模型的鲁棒性。一句话概括本题赢在“缺失模式识别清楚、NMF 补全逻辑严谨、PCA 临床解释充分、多算法对比完整”。如果要发布博客可以在文末说明完整资源包含论文全文、数据读取代码、缺失率统计结果、NMF 补全代码、PCA 主成分分析图表、多缺失率 RSE 对比表、算法稳定性分析和可复现实验说明。本文仅展示核心思路与部分代码。