diff options
Diffstat (limited to '')
| -rw-r--r-- | .agents/skills/kaggle-learner/references/knowledge/tabular/amp-parkinsons-2021.md | 593 |
1 files changed, 593 insertions, 0 deletions
diff --git a/.agents/skills/kaggle-learner/references/knowledge/tabular/amp-parkinsons-2021.md b/.agents/skills/kaggle-learner/references/knowledge/tabular/amp-parkinsons-2021.md new file mode 100644 index 0000000..82b4f3b --- /dev/null +++ b/.agents/skills/kaggle-learner/references/knowledge/tabular/amp-parkinsons-2021.md @@ -0,0 +1,593 @@ +# AMP®-Parkinson's Disease Progression Prediction (2023) + +## Competition Brief + +**竞赛基本信息** +- **主办方**: AMP (Accelerating Medicines Partnership) +- **时间**: 2023年 +- **类型**: 表格数据/医疗预测 +- **数据规模**: 小样本数据集 +- **评价目标**: SMAPE (Symmetric Mean Absolute Percentage Error) + +**任务描述** +预测帕金森病患者的疾病进展情况。使用蛋白质和肽段数据(通过质谱测量脑脊液样本)来预测患者未来的 MDS-UPDRS 评分。 + +**数据特点** +- **蛋白质数据**: 227个蛋白质特征 +- **肽段数据**: 来自多个质谱实验 +- **时间序列**: 每个患者有多次访问记录 +- **样本量**: 相对较小(小样本竞赛) +- **目标变量**: MDS-UPDRS 评分的进展 + +**评价指标** +SMAPE (Symmetric Mean Absolute Percentage Error) +- 对称性平均绝对百分比误差 +- 范围 [0, 200],越小越好 +- 对异常值相对鲁棒 + +--- + +## Top Solutions Analysis + +### 1st Place - Connecting Dotts (Dmitry Gordeev et al.) + +**核心策略** +- **模型组合**: LightGBM + Neural Network 的简单平均 +- **特征工程**: 精心设计的蛋白质和肽段聚合特征 +- **数据处理**: 针对神经网络的标准化和二值化 + +**关键技术细节** + +1. **特征工程** + - 蛋白质和肽段的聚合统计量(均值、中位数、标准差) + - 时间序列特征的构造 + - 蛋白质-肽段关系特征的提取 + +2. **模型架构** + - **LightGBM**: 梯度提升树模型 + - **Neural Network**: 深度学习模型 + - **集成策略**: 简单平均 + +3. **数据预处理** + - NN专用预处理: 特征缩放 + - 特征二值化处理 + - 缺失值处理策略 + +**代码要点** +```python +# 模型集成示例 +final_prediction = (lgb_pred + nn_pred) / 2 +``` + +### 2nd Place - No Luck, All Skill + +**核心策略** +- 发布时间: 2023年6月19日 +- 强调特征工程的重要性 +- 多模型集成策略 + +**关键特征** +- 详细的特征工程流程 +- 模型融合技术 +- 验证策略设计 + +### 3rd Place - Hajime Tamura + +**核心策略** +- 发布时间: 2023年5月19日 +- **分组策略**: 将数据分成两组分别优化 +- 简洁的解决方案(三个主要函数) + +**关键创新** +- 数据分组优化 +- 针对性模型训练 +- 简化流程提升效率 + +### 4th/5th Place - Ambrosm (#5: Find the Control Group) + +**核心策略** +- 发布时间: 2023年5月18日 +- **控制组识别**: 关键创新点 +- 利用对照组信息改进预测 + +**关键洞察** +- 识别并分离控制组样本 +- 针对不同组别使用不同策略 +- 提升模型区分度 + +### 9th Place - Makotu + +**核心策略** +- 发布时间: 2023年5月18日 +- 详细的特征工程和模型调优 + +### 13th Place - FNOA + +**技术要点** +- 中等排名的稳定方案 +- 实用的特征工程方法 + +### 43rd Place - Wojciech Victor Fulmyk (Top 3% Silver) + +**重要发现** +- **XGBoost 和 LightGBM 表现不佳** +- 强调传统树模型在这个数据集上的局限性 +- 探索其他模型方向 + +**技术要点** +```python +# 他们的发现表明传统 GBDT 可能不是最佳选择 +# 需要考虑其他模型或更复杂的特征工程 +``` + +### 89th Place - Giba (Non-Leaky Solution) + +**核心策略** +- 强调无数据泄露的干净方案 +- 可复现的验证策略 + +--- + +## Common Techniques Across Solutions + +### 1. Feature Engineering Patterns + +**蛋白质/肽段聚合特征** +```python +# 时间聚合 +protein_stats = train.groupby('patient_id')['protein'].agg([ + 'mean', 'median', 'std', 'min', 'max' +]) + +# 肽段聚合 +peptide_stats = train.groupby('patient_id')['peptide'].agg([ + 'mean', 'count', 'nunique' +]) +``` + +**时间序列特征** +- 访问间隔时间 +- 进展速度估计 +- 基线和随访差异 + +**蛋白质-肽段关系** +- 蛋白质包含的肽数量 +- 肽段来源的蛋白质信息 + +### 2. Model Selection Insights + +**成功模型** +- LightGBM (部分方案) +- Neural Networks / MLP +- 集成方法 + +**需要谨慎的模型** +- XGBoost (43rd方案指出效果不佳) +- 纯线性模型 +- 单一模型(推荐集成) + +### 3. Validation Strategies + +**关键原则** +- 避免患者级别的数据泄露 +- 时间基础的分割 +- 分组交叉验证 + +```python +from sklearn.model_selection import GroupKFold + +gkf = GroupKFold(n_splits=5) +for train_idx, val_idx in gkf.split(X, y, groups=patient_ids): + # 训练和验证 +``` + +### 4. Data Leakage Prevention + +**常见陷阱** +- 同一患者的多次访问分散在训练/验证集 +- 未来信息泄露到训练集 +- 蛋白质/肽段测试集信息泄露 + +**预防措施** +- 严格的患者级别分割 +- 时间有序分割 +- 仔细的特征构造审计 + +--- + +## Code Templates + +### Basic Feature Engineering + +```python +import pandas as pd +import numpy as np + +def create_protein_features(train_proteins, test_proteins): + """创建蛋白质聚合特征""" + def process(df): + stats = df.groupby('patient_id')['NPX'].agg([ + ('protein_mean', 'mean'), + ('protein_std', 'std'), + ('protein_min', 'min'), + ('protein_max', 'max') + ]).reset_index() + return stats + + train_stats = process(train_proteins) + test_stats = process(test_proteins) + + return train_stats, test_stats + +def create_peptide_features(train_peptides, test_peptides): + """创建肽段聚合特征""" + def process(df): + stats = df.groupby('patient_id')['PeptideAbundance'].agg([ + ('peptide_mean', 'mean'), + ('peptide_std', 'std'), + ('peptide_count', 'count') + ]).reset_index() + return stats + + train_stats = process(train_peptides) + test_stats = process(test_peptides) + + return train_stats, test_stats + +def create_time_features(train_clinical, test_clinical): + """创建时间序列特征""" + def process(df): + df = df.copy() + df['visit_month'] = df['visit_month'].astype(int) + df['pred_month'] = df['visit_month'] + df['updrs_test_month'] + + # 计算自基线以来的时间 + df['months_since_baseline'] = df.groupby('patient_id')['visit_month'].transform(lambda x: x - x.min()) + + return df + + return process(train_clinical), process(test_clinical) +``` + +### Model Training Template + +```python +import lightgbm as lgb +from sklearn.model_selection import GroupKFold +from sklearn.metrics import mean_absolute_error + +def smape(y_true, y_pred): + """SMAPE 评估指标""" + return 100 * np.mean(2 * np.abs(y_pred - y_true) / (np.abs(y_true) + np.abs(y_pred) + 1e-8)) + +def train_lightgbm(X_train, y_train, groups, params=None): + """训练 LightGBM 模型""" + if params is None: + params = { + 'objective': 'regression', + 'metric': 'mae', + 'learning_rate': 0.01, + 'num_leaves': 31, + 'max_depth': -1, + 'feature_fraction': 0.8, + 'bagging_fraction': 0.8, + 'bagging_freq': 5, + 'verbose': -1 + } + + gkf = GroupKFold(n_splits=5) + models = [] + scores = [] + + for train_idx, val_idx in gkf.split(X_train, y_train, groups=groups): + X_tr, X_val = X_train.iloc[train_idx], X_train.iloc[val_idx] + y_tr, y_val = y_train.iloc[train_idx], y_train.iloc[val_idx] + + train_data = lgb.Dataset(X_tr, label=y_tr) + val_data = lgb.Dataset(X_val, label=y_val, reference=train_data) + + model = lgb.train( + params, + train_data, + num_boost_round=10000, + valid_sets=[train_data, val_data], + callbacks=[lgb.early_stopping(100), lgb.log_evaluation(0)] + ) + + pred = model.predict(X_val) + score = smape(y_val, pred) + + models.append(model) + scores.append(score) + + print(f'Average SMAPE: {np.mean(scores):.2f}') + + return models, scores + +# 使用示例 +# models, scores = train_lightgbm(X_train, y_train, patient_ids) +``` + +### Neural Network Template + +```python +import tensorflow as tf +from sklearn.preprocessing import StandardScaler + +def create_nn_model(input_dim, hidden_units=[256, 128, 64]): + """创建神经网络模型""" + model = tf.keras.Sequential([ + tf.keras.layers.Input(shape=(input_dim,)), + ]) + + for units in hidden_units: + model.add(tf.keras.layers.Dense( + units, + activation='relu', + kernel_regularizer=tf.keras.regularizers.l2(0.01) + )) + model.add(tf.keras.layers.Dropout(0.3)) + model.add(tf.keras.layers.BatchNormalization()) + + model.add(tf.keras.layers.Dense(1, activation='linear')) + + model.compile( + optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), + loss='mae', + metrics=['mae'] + ) + + return model + +def train_nn(X_train, y_train, groups, epochs=100, batch_size=32): + """训练神经网络""" + # 标准化 + scaler = StandardScaler() + X_train_scaled = scaler.fit_transform(X_train) + + gkf = GroupKFold(n_splits=5) + models = [] + scores = [] + + for train_idx, val_idx in gkf.split(X_train_scaled, y_train, groups=groups): + X_tr, X_val = X_train_scaled[train_idx], X_train_scaled[val_idx] + y_tr, y_val = y_train.iloc[train_idx], y_train.iloc[val_idx] + + model = create_nn_model(X_train.shape[1]) + + early_stop = tf.keras.callbacks.EarlyStopping( + monitor='val_loss', + patience=10, + restore_best_weights=True + ) + + history = model.fit( + X_tr, y_tr, + validation_data=(X_val, y_val), + epochs=epochs, + batch_size=batch_size, + callbacks=[early_stop], + verbose=0 + ) + + pred = model.predict(X_val).flatten() + score = smape(y_val, pred) + + models.append((model, scaler)) + scores.append(score) + + print(f'Average SMAPE: {np.mean(scores):.2f}') + + return models, scores +``` + +### Ensemble Template + +```python +def ensemble_predictions(lgb_models, nn_models, X_test): + """集成多个模型的预测""" + # LightGBM 预测 + lgb_preds = np.mean([model.predict(X_test) for model in lgb_models], axis=0) + + # NN 预测(需要标准化) + _, scaler = nn_models[0] + X_test_scaled = scaler.transform(X_test) + nn_preds = np.mean([ + model.predict(X_test_scaled).flatten() + for model, _ in nn_models + ], axis=0) + + # 简单平均 + final_pred = (lgb_preds + nn_preds) / 2 + + return final_pred +``` + +--- + +## Best Practices + +### 1. Data Understanding + +**蛋白质数据特性** +- 227个蛋白质可能来自不同通路 +- 部分蛋白质可能高度相关 +- 需要探索蛋白质-疾病关系 + +**肽段数据特性** +- 肽数量远大于蛋白质数 +- 多个肽段可能来自同一蛋白质 +- 肽段丰度需要归一化 + +**临床数据特性** +- MDS-UPDRS 评分范围 0-260 +- 不同子评分(第一部分到第四部分) +- 访问时间间隔不均匀 + +### 2. Feature Engineering Guidelines + +**DOs** +- ✅ 创建患者级别的聚合特征 +- ✅ 利用时间序列信息 +- ✅ 探索蛋白质-肽段关系 +- ✅ 考虑蛋白质生物学意义 +- ✅ 使用领域知识构造特征 + +**DON'Ts** +- ❌ 在测试集上计算统计量 +- ❌ 混合不同患者的未来信息 +- ❌ 忽略数据的时间顺序 +- ❌ 过度使用目标编码(容易泄露) + +### 3. Model Selection Strategy + +**推荐流程** +1. 从简单模型开始(线性模型、决策树) +2. 尝试 LightGBM(部分方案有效) +3. 探索神经网络(1st方案使用) +4. 集成多个模型 +5. 针对性调整超参数 + +**模型选择考虑** +- 数据量小 → 简单模型或强正则化 +- 特征多 → 特征选择或降维 +- 时序特性 → 考虑时间序列模型 +- 集成收益 → 尝试模型融合 + +### 4. Validation Strategy + +**推荐方法** +```python +# 患者级别的 Group K-Fold +from sklearn.model_selection import GroupKFold + +gkf = GroupKFold(n_splits=5) +for fold, (train_idx, val_idx) in enumerate(gkf.split(X, y, groups=patient_ids)): + print(f'Fold {fold + 1}') + # 训练和验证 +``` + +**时间序列分割** +```python +from sklearn.model_selection import TimeSeriesSplit + +tscv = TimeSeriesSplit(n_splits=5) +for fold, (train_idx, val_idx) in enumerate(tscv.split(X)): + # 确保验证集在时间上晚于训练集 +``` + +### 5. Common Pitfalls + +**数据泄露** +- ❌ 将同一患者的多次访问分散到训练和验证集 +- ❌ 在分割前计算全局统计量 +- ❌ 使用未来信息预测过去 + +**过拟合** +- ❌ 特征过多而样本过少 +- ❌ 过度调参导致验证集泄露 +- ❌ 复杂模型在小数据集上 + +**评估偏差** +- ❌ 使用错误的评估指标 +- ❌ 忽略 SMAPE 的对称性 +- ❌ 不关注预测的分布特性 + +### 6. Domain Knowledge Integration + +**帕金森病相关** +- MDS-UPDRS 评分的临床意义 +- 蛋白质标志物的生物学作用 +- 疾病进展的非线性特性 + +**蛋白质组学** +- 质谱数据的技术变异 +- 蛋白质-肽段的定量关系 +- 缺失值的含义 + +### 7. Hyperparameter Tuning + +**LightGBM 关键参数** +```python +params = { + 'learning_rate': 0.01, # 降低学习率 + 'num_leaves': 31, # 控制复杂度 + 'max_depth': -1, # 不限制深度 + 'min_data_in_leaf': 20, # 小数据集增大此值 + 'feature_fraction': 0.8, # 特征采样 + 'bagging_fraction': 0.8, # 数据采样 + 'bagging_freq': 5, + 'lambda_l1': 0.1, # L1 正则化 + 'lambda_l2': 0.1, # L2 正则化 +} +``` + +**神经网络关键参数** +```python +# 小数据集推荐 +hidden_units = [128, 64, 32] # 减少层数和单元数 +dropout_rate = 0.3 # 增加 dropout +l2_reg = 0.01 # L2 正则化 +learning_rate = 0.001 # 适中学习率 +batch_size = 32 # 小批量 +``` + +--- + +## Key Takeaways + +1. **小样本竞赛特点** + - 特征工程比模型复杂度更重要 + - 避免过拟合是关键 + - 简单模型集成可能优于复杂单模型 + +2. **医疗数据特殊性** + - 需要理解领域知识 + - 数据泄露风险更高 + - 评估指标的临床意义 + +3. **成功的共同点** + - 仔细的特征工程 + - 严格的验证策略 + - 模型集成 + - 避免数据泄露 + +4. **需要注意的陷阱** + - XGBoost/LightGBM 不是万能的(43rd方案发现) + - 数据泄露容易但难以发现 + - 小样本的过拟合风险 + +5. **推荐的学习路径** + - 从 1st, 2nd, 3rd 方案学习顶级思路 + - 从 5th, 9th 方案学习实用技巧 + - 从 43rd 方案学习失败经验 + - 综合多个方案形成自己的方法 + +--- + +## Resources + +### Official Writeups +- [1st Place Solution - Connecting Dotts](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/connecting-dotts-1st-place-solution) +- [2nd Place Solution - No Luck, All Skill](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/no-luck-all-skill-2nd-place-solution) +- [3rd Place Solution - Hajime Tamura](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/hajime-tamura-3rd-place-solution) +- [5th Place Solution - Ambrosm](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/ambrosm-5-find-the-control-group) +- [9th Place Solution - Makotu](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/makotu-9th-place-solution) +- [13th Place Solution - FNOA](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/fnoa-13th-place-solution) +- [43rd Place Solution - Wojciech Victor Fulmyk](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/wojciech-victor-fulmyk-43rd-top-3-silver-medal-sol) +- [89th Place Solution - Giba (Non-Leaky)](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/writeups/giba-top-89-non-leaky-solution) + +### External Resources +- [H2O.ai Blog: Navigating the Parkinson's Disease Prediction Challenge with AI](https://h2o.ai/blog/2023/winners-insight-navigating-the-parkinsons-disease-prediction-challenge-with-ai/) +- [中文复现: 小样本比赛也能有稳定区分度](https://zhuanlan.zhihu.com/p/669527953) + +### Competition Pages +- [Main Competition Page](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction) +- [Data Description](https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/data) +- [Discussion Forum](https://www.kaggle.com/c/amp-parkinsons-disease-progression-prediction/discussion) + +### Code Notebooks +- [LightGBM Starter with Added Features](https://www.kaggle.com/code/sijovm/lightgbm-starter-with-added-features) +- [XGB Baseline with Added Features](https://www.kaggle.com/code/sijovm/xgb-baseline-with-added-features) +- [AMP® - PDPP EDA + TF Model](https://www.kaggle.com/code/callmewenhao/amp-pdpp-eda-tf-model) +- [AMP® - PDPP EDA](https://www.kaggle.com/code/gunesevitan/amp-pdpp-eda) |
