赛题背景
帕金森病 (PD) 是一种致残的脑部疾病,会影响运动、认知、睡眠和其他正常功能。不幸的是,目前没有治愈的方法 - 并且疾病会随着时间的推移而恶化。据估计,到2037年,美国将有1万人患有帕金森病,经济成本接近6亿美元。研究表明,蛋白质或肽异常在这种疾病的发作和恶化中起着关键作用。在数据科学的帮助下,更好地了解这一点可以为开发新的药物治疗以减缓进展或治愈帕金森病提供重要线索。
竞赛主办方加速药物伙伴关系®帕金森病(AMP®PD)是政府,行业和非营利组织之间的公私合作伙伴关系,通过美国国立卫生研究院基金会(FNIH)进行管理。该伙伴关系创建了AMP PD知识平台,其中包括帕金森病患者的深层分子表征和纵向临床分析,目的是识别和验证帕金森病的诊断,预后和/或疾病进展生物标志物。
您的工作可以帮助寻找治疗帕金森病的方法,这将减轻这种疾病患者的大量痛苦和医疗费用。
赛题任务
本次竞赛的目标是预测MDS-UPDR评分,该评分衡量帕金森病患者的进展。运动障碍协会赞助的统一帕金森病评定量表(MDS-UPDRS)修订版是对与帕金森病相关的运动和非运动症状的全面评估。
参赛者将开发一个模型,该模型根据帕金森病受试者与正常年龄匹配的对照受试者随时间推移的蛋白质和肽水平数据进行训练。
数据描述
这是一个时间序列代码竞赛:参赛者将接收测试集数据并使用Kaggle的时间序列API进行预测。
- train_peptides.csv
-
visit_id
-
visit_month
-
patient_id
-
UniProt
-
Peptide
-
PeptideAbundance
-
- train_proteins.csv
-
visit_id
-
visit_month
-
patient_id
-
UniProt
-
NPX
-
- train_clinical_data.csv
-
visit_id
-
visit_month
-
patient_id
-
updrs_[1-4]
-
upd23b_clinical_state_on_medication
-
-
supplemental_clinical_data.csv
-
example_test_files/
-
amp_pd_peptide/
-
public_timeseries_testing_util.py
评估标准
提交的评估标准是预测值和实际值之间的SMAPE。当实际值和预测值都为0时,我们定义SMAPE = 0。对于每个采集蛋白质/肽样本的患者访问,参赛者需要估计他们在该次访问中的UPDRS得分,并预测其6、12和24个月后任何可能出现的访问得分。最终未进行任何访问的预测将被忽略。
参赛者必须使用提供的python 时间序列 API 提交此竞赛,以确保模型不会及时向前查看时间。若要使用 API,请按照 Kaggle 笔记本中的以下模板进行操作:
import amp_pd_peptide
env = amp_pd_peptide.make_env() # initialize the environment
iter_test = env.iter_test() # an iterator which loops over the test files
for (test, test_peptides, test_proteins, sample_submission) in iter_test:
sample_prediction_df['rating'] = np.arange(len(sample_prediction)) # make your predictions here
env.predict(sample_prediction_df) # register your predictions
优胜方案
第一名
https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/discussion/411505
我们的最终解决方案是两个模型的简单平均值:LGB 和 NN。两个模型都基于相同的特征进行了训练(+NN的缩放/二值化):
-
访问月
-
预测范围
-
目标预测月
-
指示就诊期间是否采血
-
补充数据集指标
-
指标患者是否在第 6、18 和 48 个月就诊
-
以前的“非年度”访问次数(第 6 次或第 18 次)
-
目标索引(我们将数据集透视为具有单个目标列)
核心代码:
import numpy as np
import pandas as pd
from sklearn.model_selection import KFold
def load_data(base_path = "data"):
proteins = pd.read_csv(f"{base_path}/train_proteins.csv")
peptides = pd.read_csv(f"{base_path}/train_peptides.csv")
clinical = pd.read_csv(f"{base_path}/train_clinical_data.csv")
supplement = pd.read_csv(f"{base_path}/supplemental_clinical_data.csv")
return proteins, peptides, clinical, supplement
proteins, peptides, clinical, supplement = load_data("../input/amp-parkinsons-disease-progression-prediction")
supplement.loc[supplement["visit_month"] == 5, "visit_month"] = 6
def smape1p_ind(A, F):
val = 200 * np.abs(F - A) / (np.abs(A+1) + np.abs(F+1))
return val
def smape1p(A, F):
return smape1p_ind(A, F).mean()
def max_dif(val, lst):
lst0 = [x for x in lst if x < val]
if len(lst0) == 0:
return -1
return val - max(lst0)
def count_prev_visits(val, lst):
lst0 = [x for x in lst if x < val]
return len(lst0)
class DataPrep:
def __init__(self, target_horizons=[0, 6, 12, 24], test_vmonths = [0, 6, 12, 18, 24, 36, 48, 60, 72, 84]):
self.target_horizons = target_horizons
self.test_vmonths = test_vmonths
def fit(self, proteins_df, peptides_df, clinical_df):
pass
def fe(self, sample, proteins_df, peptides_df, clinical_df):
for v_month in [0, 6, 12, 18, 24, 36, 48, 60, 72, 84]:
p = list(clinical_df[clinical_df["visit_month"] == v_month]["patient_id"].unique())
sample[f"visit_{v_month}m"] = sample.apply(lambda x: (x["patient_id"] in p) and (x["visit_month"] >= v_month), axis=1).astype(int)
p = list(proteins_df[proteins_df["visit_month"] == v_month]["patient_id"].unique())
sample[f"btest_{v_month}m"] = sample.apply(lambda x: (x["patient_id"] in p) and (x["visit_month"] >= v_month), axis=1).astype(int)
sample[f"t_month_eq_{v_month}"] = (sample["target_month"] == v_month).astype(int)
sample[f"v_month_eq_{v_month}"] = (sample["visit_month"] == v_month).astype(int)
for hor in self.target_horizons:
sample[f"hor_eq_{hor}"] = (sample["horizon"] == hor).astype(int)
sample["horizon_scaled"] = sample["horizon"] / 24.0
blood_samples = proteins_df["visit_id"].unique()
sample["blood_taken"] = sample.apply(lambda x: x["visit_id"] in blood_samples, axis=1).astype(int)
all_visits = clinical_df.groupby("patient_id")["visit_month"].apply(lambda x: list(set(x))).to_dict()
all_non12_visits = sample.apply(lambda x: [xx for xx in all_visits.get(x["patient_id"], []) if xx <= x["visit_month"] and xx%12 != 0], axis=1)
sample["count_non12_visits"] = all_non12_visits.apply(lambda x: len(x))
return sample
def transform_train(self, proteins_df, peptides_df, clinical_df):
sample = clinical_df.rename({"visit_month":"target_month", "visit_id":"visit_id_target"}, axis=1).\
merge(clinical_df[["patient_id", "visit_month", "visit_id"]], how="left", on="patient_id")
sample["horizon"] = sample["target_month"] - sample["visit_month"]
sample = sample[sample["horizon"].isin(self.target_horizons)]
sample = sample[sample["visit_month"].isin(self.test_vmonths)]
# Features
sample = self.fe(sample,
proteins_df[proteins_df["visit_month"].isin(self.test_vmonths)],
peptides_df[peptides_df["visit_month"].isin(self.test_vmonths)],
clinical_df[clinical_df["visit_month"].isin(self.test_vmonths)])
# Targets reshape
res = []
for tgt_i in np.arange(1, 5):
delta_df = sample.copy()
if f"updrs_{tgt_i}" in delta_df.columns:
delta_df["target"] = delta_df[f"updrs_{tgt_i}"]
delta_df["target_norm"] = delta_df["target"] / 100
delta_df["target_i"] = tgt_i
res.append(delta_df)
sample = pd.concat(res, axis=0).reset_index(drop=True)
if f"updrs_1" in sample.columns:
sample = sample.drop(["updrs_1", "updrs_2", "updrs_3", "updrs_4"], axis=1)
for tgt_i in np.arange(1, 5):
sample[f"target_n_{tgt_i}"] = (sample["target_i"] == tgt_i).astype(int)
return sample
def transform_test(self, proteins_df, peptides_df, test_df, sub_df):
sub = sub_df.copy()
sub["patient_id"] = sub["prediction_id"].apply(lambda x: int(x.split("_")[0]))
sub["visit_month"] = sub["prediction_id"].apply(lambda x: int(x.split("_")[1]))
sub["visit_id"] = sub.apply(lambda x: str(x["patient_id"]) + "_" + str(x["visit_month"]), axis=1)
sample = sub[["patient_id", "visit_month", "visit_id", "prediction_id"]]
sample["horizon"] = sample["prediction_id"].apply(lambda x: int(x.split("_")[5]))
sample["target_i"] = sample["prediction_id"].apply(lambda x: int(x.split("_")[3]))
sample["visit_month"] = sample["visit_month"]
sample["target_month"] = sample["visit_month"] + sample["horizon"]
del sample["prediction_id"]
# Features
sample = self.fe(sample, proteins_df, peptides_df, test_df)
for tgt_i in np.arange(1, 5):
sample[f"target_n_{tgt_i}"] = (sample["target_i"] == tgt_i).astype(int)
return sample
dp3 = DataPrep()
dp3.fit(proteins, peptides, clinical)
sample3 = dp3.transform_train(proteins, peptides, clinical)
sample3 = sample3[~sample3["target"].isnull()]
sample3["is_suppl"] = 0
sup_sample3 = dp3.transform_train(proteins, peptides, supplement)
sup_sample3 = sup_sample3[~sup_sample3["target"].isnull()]
sup_sample3["is_suppl"] = 1
print(sample3.shape)
print(sup_sample3.shape)
第四名: https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/discussion/411398
第五名: https://www.kaggle.com/competitions/amp-parkinsons-disease-progression-prediction/discussion/411388
关注下方【学姐带你玩AI】🚀🚀🚀
回复“比赛”领取190+场比赛top方案合集
码字不易,欢迎大家点赞评论收藏!