2022年数维杯国际大学生数学建模挑战赛
C题 如何利用大脑结构特征和认知行为特征诊断阿尔茨海默病
原题再现:
阿尔茨海默病(AD)是一种起病隐匿的进行性神经退行性疾病。临床特征为全谱痴呆,包括记忆障碍、失语、流利不畅、失认、视觉空间技能障碍、执行功能障碍以及人格和行为改变,其原因尚不清楚。它的特点是进行日常生活活动的能力逐渐下降,伴有各种神经精神症状和行为障碍。该疾病通常在老年人中呈进行性,在疾病发作后 10 至 20 年逐渐丧失独立生活技能并死于并发症。
阿尔茨海默病的临床前阶段,也称为轻度认知障碍(MCI),是正常和重度之间的过渡状态。由于患者及其家属对疾病的认知有限,67%的患者被诊断为中度至重度,错过了最佳干预阶段。因此,早期准确诊断阿尔茨海默病和轻度认知障碍具有重要意义。
所附数据包含在不同时间点(一个时间点为数量)收集的4850例认知正常老年人(CN)、1416例主观记忆主诉(SMC)、2968例早期轻度认知障碍(EMCI)、5236例晚期轻度认知障碍(LMCI)患者和1738例阿尔茨海默病(AD)患者的具体信息特征。请利用附录中提供的不同类别人群的大脑结构特征和认知行为特征,构建阿尔茨海默病识别模型,设计智能诊断方法,准确诊断阿尔茨海默病。
1.对所附数据的特征指标进行预处理,研究数据特征与阿尔茨海默病诊断的相关性。
2.利用附加的大脑结构特征和认知行为特征,设计阿尔茨海默病的智能诊断。
3.首先,将CN,MCI和AD分为三大类。然后,对于 MCI 中包含的三个子类(SMC、EMC 和 LMCI),聚类继续细化为三个子类。
4.附件中的同一样本包含在不同时间点收集的特征,请结合时间点进行分析,以揭示不同类别疾病随时间演变的模式。
5.请查阅相关文献,描述CN、SMC、EMCI、LMCI 和 AD 五类的早期干预和诊断标准。
题拿到手之后中文翻译过程(不论是亚太杯还是美赛皆是如此)
不要使用有道翻译,因为里面存在格式有道翻译之后缺失格式,条理不清晰;我这里推荐使用转成html文件,然后打开html的时候使用笔记本自带的Microsoft Edge浏览器打开即可,如下图所示:
问题分析:
问题1分析
问题1要求我们对数据的特征变量进行预处理,并研究数据特征与阿尔茨海默病诊断之间的相关性。首先要通过查看相关信息来理解数据中的特征变量,然后必须对原始数据集进行观察和分析,从而揭示出数据中大量缺失值和信息重叠的变量。因此,需要python等数据处理软件来清理原始数据。具体来说,需要去除相关性较小、信息重叠、缺失值较多的特征变量,剩余的少量缺失值需要采用均值填充法进行填充,最后将定性变量转换为定量变量。针对数据特征与阿尔茨海默病诊断的相关性,主要采用随机森林模型生成变量重要性图,得到特征变量与阿尔茨海默病诊断的相关性强度,然后通过特征变量箱线图验证随机森林中得到的结果与阿尔茨海默病的类型相关疾病诊断。
问题2分析
问题2要求我们使用额外的大脑结构特征和认知行为特征来设计阿尔茨海默病诊断。我们通过比较目前用于监督学习的几种主流分类算法(随机森林、XGBoost、SVM)将DX_bl诊断分为两类,一类是正常的,另一类是有病的,ADNIMERGE_New数据集分类。使用结构脑特征和认知行为特征变量构建模型,以便对于预测变量的已知值,获得目标变量的相应值。反复训练此模型,直到它可以在训练数据集上达到预定的准确性。然后比较不同模型的拟合度,并选择最佳模型来诊断阿尔茨海默病。
问题3分析
问题 3 要求我们首先将 CN、CMI 和 AD 分为三大类,然后针对 MCI 中包含的三个子类(SMC、EMCI 和 LMCI),将聚类继续细化为三个子类。为了完成数据的分类,选择了随机森林和决策树方法进行分类。首先将数据处理成三大类进行分类模型构建,然后提取三个子类(SMC、EMCI和LMCI)进行分类模型构建,达到聚类分类的目的并分析其效果。
问题4分析
问题4要求我们根据包含不同时间点集合的特征,结合时间点分析附件中的同一样本,以发现不同类别疾病随时间演变的模式。为此,首先选择具有来自多个不同时间点数据的受试者,然后过滤具有相同集合数量的受试者,并排除包含大量缺失值的受试者。利用得到的实验数据来选择重要的特征变量进行研究。由于单个受试者的数据存在差异,我们对同一指数的多个受试者进行平均,以消除他们的个体差异,从而研究他们随时间推移的演变模式。
问题5分析
问题5要求我们参考相关文献来描述CN、SMC、EMCI、LMCI和AD五类的早期干预和诊断标准。为此,本文阅读了多篇权威文献和期刊,整合AD诊断标准的历史,从而获得AD诊断标准的发展情况,并将其与本文联系起来,希望为AD诊断标准提供一些新思路。
数据处理:
ADNIMERGE_New,我们在数据集中发现了大量的缺失值和复杂变量。针对这种情况,我们首先对数据进行了初步筛选,流程如下。
基于对每个变量的理解和研究目的,我们删除了研究者第一次收到数据收集时记录的历史数据,即包含“b1”后缀的变量,仅截获了研究数据项的当前值。其余 64 个变量。然后删除了DK分类变量相关性或重叠信息较少的特征变量,如:COLPROT, ORIGPROT, PTID, SITE, VISCODE, EXAMDATE, FLDSTRENG, FSVERSION, Month, EcogPtMem,EcogPtLang、EcogPtVisspat、EcogPtPlan、EcogPtOrganEcogPtDivatt、EcogPtTotal、EcogSPMem、EcogSPLang、EcogSPVisspat、EcogSPPlan、EcogSPOrgan、EcogSPDivatt、EcogSPTotal和30个特征变量被删除。最后,删除了缺失特征变量程度较大的特征变量,因为缺失特征变量的程度过大不利于数据分析和研究,即使采用各种处理缺失值的方法弥补缺失值,也会极大地破坏数据的真实性, 并且获得的分析结果不再令人信服。经过最终的数据筛选,我们总共获得了24个特征变量用于研究,变量如下:AGE,PTGENDER,PTEDUCAT,PTRACCAT,PTETHCAT,PTMARRY,ADAS11、ADAS13、ADASQ4、MMSE、RAVLT_immediate、RAVLT_learning、RAVLT_forgetting、RAVLT_perc_forgetting、LDELTOTAL、TRABSCOR、FAQ、mPACCdigit、mPACCtrailsB、IMAGEUID、心室、WholeBrain、ICV 和 DX。
对于某些过滤的特征变量,仍然缺少数据,因此需要对这 24 个变量进行进一步的填充过程。本问题采用均值法按类别(CN、AD、LMCI、EMCI、SMC)求有缺失值的特征变量的均值,然后将均值插入到相应的缺失值中。
由于特征变量中也有定性变量,因此还需要将定性变量转换为类似于(0,1)的变量形式。
论文及程序需要的请见下方“ 只会建模 QQ名片” 点击QQ名片即可
论文缩略图:
部分程序代码
from sklearn.ensemble import RandomForestClassifier as RandomForest
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy as sp
import seaborn.apionly as sns
import sklearn.metrics as metrics
import warnings
adnimerge = pd.read_csv('E:/program-py/sss.csv')
adnimerge.head()
adnimerge_bl = adnimerge.loc[adnimerge['VISCODE']=='bl']
adnimerge_bl = adnimerge_bl.drop('M', axis=1)
adnimerge_bl = adnimerge_bl.drop(['EXAMDATE_bl', 'CDRSB_bl',
'ADAS11_bl', 'ADAS13_bl', 'MMSE_bl',
'RAVLT_immediate_bl', 'RAVLT_learning_bl',
'RAVLT_forgetting_bl',
'RAVLT_perc_forgetting_bl', 'FAQ_bl', 'Ventricles_bl',
'Hippocampus_bl', 'WholeBrain_bl', 'Entorhinal_bl',
'Fusiform_bl',
'MidTemp_bl', 'ICV_bl', 'MOCA_bl', 'EcogPtMem_bl',
'EcogPtLang_bl',
'EcogPtVisspat_bl', 'EcogPtPlan_bl', 'EcogPtOrgan_bl',
'EcogPtDivatt_bl', 'EcogPtTotal_bl', 'EcogSPMem_bl',
'EcogSPLang_bl', 'EcogSPVisspat_bl', 'EcogSPPlan_bl',
'EcogSPOrgan_bl', 'EcogSPDivatt_bl', 'EcogSPTotal_bl',
'FDG_bl',
'AV45_bl', 'Years_bl', 'Month_bl'], axis=1)
adnimerge_bl.head()
adnimerge_bl['DX_bl'].value_counts()
df1=adnimerge_bl['PTRACCAT'].value_counts()
df1
adnimerge_bl.shape
for col in adnimerge_bl.columns:
print(col, adnimerge_bl[col].isnull().sum())
data1=adnimerge_bl[[
'MMSE','RAVLT_immediate','RAVLT_learning','RAVLT_forgetting',
'RAVLT_perc_forgetting','LDELTOTAL','FAQ','Ventricles','DX_bl''WholeB
rain','ICV','']]
data1
for col in data1.columns:
print(col, data1[col].isnull().sum())
cols_with_na=[]
for column in data1:
if data1[column].isnull().any()==True:
cols_with_na.append(column)
meand1f = data1.copy()
for col in cols_with_na:
if data1[col].dtype=='float64':
meandf[col] = data1[col].fillna(data1[col].mean())
else:
meandf[col] = data1[col].fillna(data1[col].mode()[0])
np.any(pd.isnull(meandf))
meandf.head()
meandf.isnull().sum()
mapping = {
'CN': 0,
'AD': 1,
'LMCI': 1,
'EMCI':1,
'SMC':1
}
meandf['DX_bl'] =meandf['DX_bl'].map(mapping)
meandf.head()
meandf.isnull().sum()
X=meandf.drop('DX_bl',axis=1)
y=meandf['DX_bl']
X
plt.bar(y.value_counts().index, y.value_counts())
plt.show()
X_train, X_test, y_train, y_test = train_test_split(X,
y,test_size=0.2,random_state=0)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators=50)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)
from sklearn.metrics import classification_report
result1 = classification_report(y_test, y_pred)
print("Classification Report:",)
print (result1
result2 = accuracy_score(y_test,y_pred)
print("Accuracy:",result2)
importances = classifier.feature_importances_
feat_labels = meandf.columns[:-1]
indices = np.argsort(importances)[::-1]
for f in range(X_train.shape[1]):
print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]],
importances[indices[f]]))
importances = classifier.feature_importances_
print(importances)
x_columns =meandf.columns[1:]
indices = np.argsort(importances)[::-1]
x_columns_indices = []
for f in range(X_train.shape[1]):
print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]],
importances[indices[f]]))
x_columns_indices.append(feat_labels[indices[f]])
print(x_columns_indices)
print(x_columns.shape[0])
print(x_columns)
print(np.arange(x_columns.shape[0]))
# ## XGBOOST
import xgboost as xgb
from sklearn.model_selection import RandomizedSearchCV
# xgboost
from xgboost import XGBClassifier
model = XGBClassifier()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
y_pred
res = classification_report(y_test, y_pred)
print("Classification Report:",)
print (res)
res2 = accuracy_score(y_test,y_pred)
print("Accuracy:",res2)
from sklearn.model_selection import KFold
param_dist = {
'n_estimators':range(80,200,4),
'max_depth':range(2,15,1),
'learning_rate':np.linspace(0.01,2,20),
'subsample':np.linspace(0.7,0.9,20),
'colsample_bytree':np.linspace(0.5,0.98,10),
'min_child_weight':range(1,9,1)
}
cvv = KFold(3)
grid = RandomizedSearchCV(model,param_dist,cv =
cvv,n_iter=100,refit="roc_auc",n_jobs = -1)
grid.fit(X_train,y_train)
best_estimator = grid.best_estimator_
print(best_estimator)
print(grid.best_score_)
# SVM
from sklearn.svm import SVC
model = SVC()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print(classification_report(y_test, predictions))
from sklearn.model_selection import GridSearchCV
param_grid = {'C': [0.1, 1, 10, 100],
'gamma': [1, 0.1, 0.01, 0.001, 0.0001],
'gamma':['scale', 'auto'],
'kernel': ['linear']}
grid = GridSearchCV(SVC(), param_grid, refit = True, verbose =
3,n_jobs=-1)
grid.fit(X_train, y_train)
print(grid.best_params_)
grid_predictions = grid.predict(X_test)
#ARIMA
import numpy
import pandas
from spsspro.algorithm import statistical_model_analysis
data = pandas.DataFrame({
"A": numpy.random.random(size=20)
})
result = statistical_model_analysis.arima_analysis(data=data, p=0, d=0,
q=0, forecast_num=10)
print(result)