天池大数据竞赛——天池精准医疗大赛人工智能辅助糖尿病遗传风险预测赛后总结

天池大数据竞赛官方网址(链接)

六、预测算法

1. LightGBM

  LightGBM利用基于histogram的算法,通过将连续特征(属性)值分段为discrete bins来加快训练的速度并减少内存的使用。直方图算法的基本思想:先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。遍历数据时,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。基于histogram算法有很多优点,包括减少分割增益的计算量、通过直方图的相减来进行进一步的加速、减少内存的使用、减少并行学习的通信代价等。

  Gradient Boosting Decision Tree(GBDT)是一种被广泛使用的算法,目前也有很多实现方法,比如说scikit-learn,LightGBM。其实关于梯度提升树不同的实现,本质就是所使用的损失函数和最小化损失函数的方法有所差异。而梯度提升算法的核心思想就是通过拟合负梯度值去学习决策树。

  相关代码如下,仍需要根据实际应用做出相应的更改。

# coding:utf-8
#Author: chenhao
#date: Jan.22.2018
#Description: Tianchi Medical solution train dataset with Lightgbm, use the coxbox to soft the datasetimport time
import datetime
import numpy as np
import pandas as pd
import lightgbm as lgb
from dateutil.parser import parse
from sklearn.cross_validation import KFold
from sklearn.metrics import mean_squared_error
from scipy import statsdata_path = 'data/'train = pd.read_csv(data_path + 'd_train_20180102.csv', encoding='gb2312')
test = pd.read_csv(data_path + 'd_test_A_20180102.csv', encoding='gb2312')def make_feat(train, test):train_id = train.id.values.copy()test_id = test.id.values.copy()#对数据进行合并与重塑data = pd.concat([train, test])data['性别'] = data['性别'].map({'男': 1, '女': 0, '??':0})data['体检日期'] = (pd.to_datetime(data['体检日期']) - parse('2017-9-10')).dt.days#data.fillna(data.median(axis=0), inplace=True)train_feat = data[data.id.isin(train_id)]test_feat = data[data.id.isin(test_id)]#对数据缺失值进行处理train_feat = train_feat.drop(['id','乙肝表面抗原','乙肝表面抗体','乙肝e抗原','乙肝e抗体','乙肝核心抗体'],axis=1)test_feat = test_feat.drop(['id','乙肝表面抗原','乙肝表面抗体','乙肝e抗原','乙肝e抗体','乙肝核心抗体'], axis=1)#对缺少一部分的数据进行填充train_feat.fillna(train_feat.median(axis=0), inplace=True)test_feat.fillna(test_feat.median(axis=0), inplace=True)#删除离群值train_feat = train_feat.drop(train_feat[train_feat['*r-谷氨酰基转换酶'] > 600 ].index)train_feat = train_feat.drop(train_feat[train_feat['白细胞计数'] > 20.06].index)train_feat = train_feat.drop(train_feat[train_feat['*丙氨酸氨基转换酶'] == 498.89].index)train_feat = train_feat.drop(train_feat[train_feat['单核细胞%'] > 20 ].index)train_feat = train_feat.drop(train_feat[train_feat['*碱性磷酸酶'] > 340].index)    #有待调整train_feat = train_feat.drop(train_feat[train_feat['*球蛋白'] > 60].index)train_feat = train_feat.drop(train_feat[train_feat['嗜酸细胞%'] > 20].index)train_feat = train_feat.drop(train_feat[train_feat['*天门冬氨酸氨基转换酶'] > 300].index)train_feat = train_feat.drop(train_feat[train_feat['血小板计数'] > 700].index)train_feat = train_feat.drop(train_feat[train_feat['*总蛋白'] > 100].index)return train_feat, test_feat'''#对训练数据进行平滑处理train_feat['甘油三酯'], a = stats.boxcox(train_feat['甘油三酯'])train_feat['*r-谷氨酰基转换酶'], b = stats.boxcox(train_feat['*r-谷氨酰基转换酶'])train_feat['白球比例'], c = stats.boxcox(train_feat['白球比例'])train_feat['*天门冬氨酸氨基转换酶'], d = stats.boxcox(train_feat['*天门冬氨酸氨基转换酶'])test_feat['甘油三酯'], a1 = stats.boxcox(test_feat['甘油三酯'])test_feat['*r-谷氨酰基转换酶'], a1 = stats.boxcox(test_feat['*r-谷氨酰基转换酶'])test_feat['白球比例'], a1 = stats.boxcox(test_feat['白球比例'])test_feat['*天门冬氨酸氨基转换酶'], a1 = stats.boxcox(test_feat['*天门冬氨酸氨基转换酶'])#train_feat['甘油三酯'] += 2#test_feat['甘油三酯'] += 2
'''train_feat, test_feat = make_feat(train, test)predictors = [f for f in test_feat.columns if f not in ['血糖']]def evalerror(pred, df):label = df.get_label().values.copy()score = mean_squared_error(label, pred) * 0.5return ('0.5mse', score, False)print('开始训练...')#原版调参数据
params = {'learning_rate': 0.01,'boosting_type': 'gbdt','objective': 'regression','metric': 'mse','sub_feature': 0.7,'num_leaves': 60,'colsample_bytree': 0.7,'feature_fraction': 0.7,'min_data': 100,'min_hessian': 1,'verbose': -1,
}print('开始CV 5折训练...')
t0 = time.time()
train_preds = np.zeros(train_feat.shape[0])
#产生相应的id数为行数5列全零数据
test_preds = np.zeros((test_feat.shape[0], 5))
kf = KFold(len(train_feat), n_folds=5, shuffle=True, random_state=520)
for i, (train_index, test_index) in enumerate(kf):print('第{}次训练...'.format(i))train_feat1 = train_feat.iloc[train_index]train_feat2 = train_feat.iloc[test_index]lgb_train1 = lgb.Dataset(train_feat1[predictors], train_feat1['血糖'], categorical_feature=['性别'])lgb_train2 = lgb.Dataset(train_feat2[predictors], train_feat2['血糖'])gbm = lgb.train(params,lgb_train1,num_boost_round=3000,valid_sets=lgb_train2,verbose_eval=100,feval=evalerror,early_stopping_rounds=100)feat_imp = pd.Series(gbm.feature_importance(), index=predictors).sort_values(ascending=False)train_preds[test_index] += gbm.predict(train_feat2[predictors])test_preds[:, i] = gbm.predict(test_feat[predictors])
print('线下得分:    {}'.format(mean_squared_error(train_feat['血糖'], train_preds) * 0.5))
print('CV训练用时{}秒'.format(time.time() - t0))submission = pd.DataFrame({'pred': test_preds.mean(axis=1)})
submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None,index=False, float_format='%.3f')

2. XGBoost

  eXtreme Gradient Boosting(XGBoost)是Gradient Boosting Machine的另外一种实现,其最大的特点在于,它能够自动利用CPU的多线程进行并行,同时在算法上加以改进,提高了精度。XGBoost的主要特点包括,基于树能够自动处理稀疏数据的提升学习算法,采用加权分位数法来搜索近似最优分裂点,并行和分布式计算,基于分块技术的大量数据高效快速处理。

  XGBoost不同于传统的GBDT的方式,其只利用了一阶的导数信息并对损失函数做了二阶的泰勒展开,并在目标函数之外加入了正则项整体求最优解,用以权衡目标函数的下降和模型的复杂程度,避免过拟合。将目标函数做泰勒展开,并引入正则项。相关的理论介绍在CSDN中均可搜索到。编辑器输入公式太不方便了。。

  相关代码如下,仍需要根据实际应用做出相应的更改。

# coding:utf-8
#Author: chenhao
#date: Jan.21.2018
#Description: Tianchi Medical solution train dataset with XGBoost,besides, use the coxbox to soft the datasetimport time
import datetime
import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.preprocessing import MinMaxScaler
from dateutil.parser import parse
from scipy import statsdata_path = 'data/'train = pd.read_csv(data_path + 'd_train_20180102.csv', encoding='gb2312')
test = pd.read_csv(data_path + 'd_test_A_20180102.csv', encoding='gb2312')train['性别'] = train['性别'].map({'男': 1, '女': 0})
test['性别'] = test['性别'].map({'男': 1, '女': 0})train['体检日期'] = (pd.to_datetime(train['体检日期']) - parse('2017-9-10')).dt.days
test['体检日期'] = (pd.to_datetime(test['体检日期']) - parse('2017-9-10')).dt.daystrain.fillna(train.median(axis=0), inplace=True)
test.fillna(test.median(axis=0), inplace=True)# 删除离群值
train = train.drop(train[train['*r-谷氨酰基转换酶'] > 600].index)
train = train.drop(train[train['白细胞计数'] > 20.06].index)
train = train.drop(train[train['*丙氨酸氨基转换酶'] == 498.89].index)
train = train.drop(train[train['单核细胞%'] > 20].index)
train = train.drop(train[train['*碱性磷酸酶'] > 340].index)  # 有待调整
train = train.drop(train[train['*球蛋白'] > 60].index)
train = train.drop(train[train['嗜酸细胞%'] > 20].index)
train = train.drop(train[train['*天门冬氨酸氨基转换酶'] > 300].index)
train = train.drop(train[train['血小板计数'] > 700].index)
train = train.drop(train[train['*总蛋白'] > 100].index)#去除缺失值较多的数据
train_y = train['血糖']
train_x = train.drop(['id','血糖','乙肝表面抗原','乙肝表面抗体','乙肝核心抗体','乙肝e抗原','乙肝e抗体'], axis=1)
test_x = test.drop(['id','乙肝表面抗原','乙肝表面抗体','乙肝核心抗体','乙肝e抗原','乙肝e抗体'], axis=1)train_out = xgb.DMatrix(train_x, label=train_y)
test_out = xgb.DMatrix(test_x)test_preds = np.zeros((test_x.shape[0],1))
#submission = pd.DataFrame({'label': test_preds.mean(axis=1)})
#submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None, index=False, float_format='%.3f')#print (test_preds)params = {'booster': 'gbtree','objective': 'reg:linear','eval_metric': 'mae','gamma': 0.1,'min_child_weight': 1.3,'max_depth': 5,'lambda': 10,'subsample': 0.71,'colsample_bytree': 0.7,'colsample_bylevel': 0.7,'eta': 0.01,'tree_method': 'exact','seed': 0,'nthread': 12}watchlist = [(train_out,'train')]
model = xgb.train(params,train_out,num_boost_round=3000,evals=watchlist)test_preds[:,0] = model.predict(test_out)
print(test_preds)submission = pd.DataFrame({'pred': test_preds.mean(axis=1)})
submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None, index=False, float_format='%.3f')

3. Keras

  Keras是基于Theano的一个深度学习框架,是一个高度模块化的神经网络库,支持GPU和CPU。Keras有多个独立的模块,且可以自由组合,其中包括neural layers, cost functions, optimizers, initialization schemes, activation functions, regularization. Keras的核心是一个模型,用来阻止各个网络层次结构。最简单的是Sequential模型,即序贯模型,是一个个网络层的线性叠加。对于更复杂的结构,应该使用keras提供的function API. function API允许构建任何的网络结构。

  下面是Keras的一些模块的介绍:

  Optimizers,Optimizers包含了一些优化的方法,比如最基本的随机梯度下降SGD,另外还有Adagrad、Adadelta、RMSprop、Adam,一些新的方法以后也会被不断添加进来。

  Objectives,这是目标函数模块,keras提供了mean_squared_error,mean_absolute_error,squared_hinge,hinge,binary_crossentropy,categorical_crossentropy这几种目标函数。

  Activations,这是激活函数模块,keras提供了linear、sigmoid、hard_sigmoid、tanh、softplus、relu、softplus,另外softmax也放在Activations模块里(我觉得放在layers模块里更合理些)。此外,像LeakyReLU和PReLU这种比较新的激活函数,keras在keras.layers.advanced_activations模块里提供。

  Initializations,这是参数初始化模块,在添加layer的时候调用init进行初始化。keras提供了uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal这几种。

  Layers,layers模块包含了core、convolutional、recurrent、advanced_activations、normalization、embeddings这几种layer。其中core里面包含了flatten(CNN的全连接层之前需要把二维特征图flatten成为一维的)、reshape(CNN输入时将一维的向量弄成二维的)、dense(就是隐藏层,dense是稠密的意思),还有其他的就不介绍了。convolutional层基本就是Theano的Convolution2D的封装。

  Preprocessing,这是预处理模块,包括序列数据的处理,文本数据的处理,图像数据的处理。重点看一下图像数据的处理,keras提供了ImageDataGenerator函数,实现data augmentation,数据集扩增,对图像做一些弹性变换,比如水平翻转,垂直翻转,旋转等。

  Models,这是最主要的模块,模型。上面定义了各种基本组件,model是将它们组合起来。

  相关代码如下,仍需要根据实际应用做出相应的更改。

# coding=utf-8
'''
Author: chenhao
date: Jan.25.2018
Description: Use the train_Drop_Delete_Log.csv and PolynomialFeature in XGB model
'''
import pandas as pd
import datetime
import numpy as np
from dateutil.parser import parsemodelfile = 'modelweight.model' #神经网络权重保存data_path = 'data/'train = pd.read_csv(data_path + 'train_Drop_Delete_Log_Poly_keras.csv', encoding='gb2312')
test = pd.read_csv(data_path + 'test_Drop_Delete_Log_Poly_keras.csv', encoding='gb2312')# 对数据简单处理
train_y = train['BS']
train_x = train.drop(['BS'],axis=1)
test_x = testtest_preds = np.zeros((test_x.shape[0],1))train_x = train_x.as_matrix()
train_y = train_y.as_matrix()
test_x = test_x.as_matrix()# 3 建立一个简单BP神经网络模型
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential()  #层次模型
model.add(Dense(100,input_dim=801,init='uniform')) #输入层,Dense表示BP层
model.add(Activation('relu'))  #添加激活函数
model.add(Dense(1,input_dim=100))  #输出层
model.compile(loss='mean_squared_error', optimizer='adam') #编译模型
model.fit(train_x, train_y, nb_epoch = 1000, batch_size = 6) #训练模型1000次
model.save_weights(modelfile) #保存模型权重#4 预测,并还原结果。
#x = ((data[feature] - data_mean[feature])/data_std[feature]).as_matrix()
#data[u'L1_pred'] = model.predict(x) * data_std['L1'] + data_mean['L1']test_preds = model.predict(test_x)
print(test_preds)submission = pd.DataFrame({'pred': test_preds.mean(axis=1)})
submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None, index=False, float_format='%.3f')

七、模型融合

  原始训练数据集中,高血糖值的个体样本数量过少,导致构建出来的模型对于高血糖部分预测不准确,同时由下面的的评价标准可以得知,高血糖样本测试集的预测结果对于结果的评价具有重要意义。实现单模型融合的过程中,需要增大训练集中高血糖个体的权重,因此将测试集中已预测出的数据进行比较,对于较高的测试集样本认为是疑似高血糖测试集样本,并将其筛选出来用高血糖预测模型来预测该部分的数据并存储。这种数据提升的模型能够有效的提升高血糖部分样本预测的准确性。

  数据融合与提升的模型结构示意图如图9所示,首先,从初始的训练集中提取高血糖值的个体样本,采用相应的算法搭建模型预测,获得对应的高血糖预测模型。从初始的测试集中用单模型进行预测,对于预测结果超过平均值一定阈值的样本个体作为疑似高血糖样本个体提取出来,用高血糖预测模型进行预测并保存,通过相应的融合方式完整整个数据集的融合。经试验与测试,这种方法能够有效地提升预测的结果,具体结果参见第八部分。


八、评价指标与结果

1. 评价指标

  将测试集中预测得到的结果与个体实际检测到的血糖结果进行对比,以均方误差为评价指标,得出的结果越小越好,均方误差的计算公式如下:


  其中,m为总人数,y(i)为选手预测的第i个人的血糖值,y(i)为第i个人的实际血糖检测值。

2. 测试结果

  本次选取7次试验的结果作为课题试验的结果,试验测试的结果如图10所示,分别用LightGBM、XGBoost、Keras作为三种单模型结构,同时添加模型融合提到的融合预测模型参与比对。图中X轴表示进行7次试验并且每次试验对每个模型进行调优与修改,Y轴表示评价指标下的结果。由图可知,大部分的情况下单模型预测的结果Keras优于LightGBM优于XGBoost,融合预测模型的预测效果比所有的单模型有显著的提升。


天池大数据竞赛——糖尿病遗传风险预测赛后总结(二)相关推荐

  1. 阿里天池大赛[人工智能辅助糖尿病遗传风险预测]赛后总结

    题目以及数据介绍 人工智能辅助糖尿病遗传风险预测 Github 代码以及数据 Github 初始思想 1.从头开始,先看一下初始数据以及数据的简单分析吧 训练数据,最后一列是血糖: A榜测试数据 第九 ...

  2. 阿里天池大数据竞赛——口碑商家客流量预测 A2

    阿里天池大赛koubeiyuce1 2017年二月份,天池大数据比赛,口碑商家客流量预测,参赛地址及详情: https://tianchi.shuju.aliyun.com/competition/i ...

  3. 《天池精准医疗大赛-人工智能辅助糖尿病遗传风险预测》模型复现和数据挖掘-论文_企业

    大赛概况 进入21世纪,生命科学特别是基因科技已经广泛而且深刻影响到每个人的健康生活,于此同时,科学家们借助基因科技史无前例的用一种全新的视角解读生命和探究疾病本质.人工智能(AI)能够处理分析海量医 ...

  4. 天池精准医疗大赛——人工智能辅助糖尿病遗传风险预测

    在18年1月参加了天池精准医疗大赛-人工智能辅助糖尿病遗传风险预测.我国有1.1亿人患有糖尿病,是世界上糖尿病患者最多的国家,每年用于糖尿病的医疗费用超过3000亿,与我们赛题相关的妊娠糖尿病是其中一 ...

  5. 《天池精准医疗大赛-人工智能辅助糖尿病遗传风险预测》模型复现和数据挖掘-企业科研_论文作业

    大赛概况 进入21世纪,生命科学特别是基因科技已经广泛而且深刻影响到每个人的健康生活,于此同时,科学家们借助基因科技史无前例的用一种全新的视角解读生命和探究疾病本质.人工智能(AI)能够处理分析海量医 ...

  6. 基于XGBOOST的糖尿病遗传风险预测(1)

    博客基于Xgboost方法对糖尿病遗传预测风险进行预测,实际上是对人体血糖值的预测.论文以天池精准医疗大赛--人工智能辅助糖尿病遗传风险预测为背景,对其提供的数据进行人体血糖值进行预测. 本质而言是使 ...

  7. 阿里巴巴天池大数据竞赛黄金联赛全面开战,全球同步报名,只为寻找最聪明的你!...

    阿里巴巴天池大数据竞赛黄金联赛全面开战,全球同步报名,只为寻找最聪明的你!          天池大数据竞赛是由阿里巴巴集团主办,面向全球新生代力量的高端算法竞赛.通过开放海量数据和"天池& ...

  8. 【参赛记录】糖尿病遗传风险预测

    [参赛记录]糖尿病遗传风险预测 一.选题背景 二.题目任务 2.1 数据集字段说明 2.2 训练集说明 2.3 测试集说明 三.评估指标 四.数据分析和处理 4.1 缺失值和异常值分析 缺失值 异常值 ...

  9. AI比赛-NER:“万创杯”中医药天池大数据竞赛——中药说明书实体识别挑战

    大赛概况 疫情催化下,人工智能正在持续助力中医药传承创新加速发展,其中中医用药知识体系沉淀挖掘是一个基础工作.通过挖掘中药说明书构建中药合理用药的知识图谱,将为中医规范诊疗奠定较好基础.挑战旨在通过抽 ...

  10. 讯飞:糖尿病遗传风险预测Coggle挑战赛公开

    导入数据------------------------- train_df = pd.read_csv('./糖尿病遗传风险预测挑战赛公开数据/比赛训练集.csv', encoding='gbk') ...

最新文章

  1. 关于《重启人工智能》11条建议的思考
  2. print格式化输出,以及使用format控制
  3. 十二 手游开发神器 cocos2d-x editor 之游戏暂停悬浮层
  4. php7.1 改动,PHP7错误处理机制修改
  5. SAP调用WSDL报错,求解!
  6. vivado环境下实现比较器
  7. It's all about buffers: zero-copy, mmap and Java NIO
  8. 三维重建9:点云图像的滤波方法小结
  9. C++ __gnu_pbds(hash,可并堆,平衡树)
  10. java 强制向上转型,Java 转型(向上或向下转型)详解及简单实例
  11. Using WIN32 calling convention 阅读笔记
  12. [CTSC1999][网络流24题]家园
  13. matlab中心化样本矩阵,第二讲实验.doc
  14. super()的作用
  15. Silverlight中的ControlTemplate
  16. C++中一个类禁止继承好麻烦
  17. 运行c语言程序显示已停止运行程序,c – “此应用程序已请求运行时以不寻常的方式终止它.”...
  18. 美国要贩卖网民隐私:最大成人网站出手反击
  19. Hspice中的测量语句(II)
  20. 【论文阅读】基于深度神经网络的人体运动姿态估计与识别

热门文章

  1. 使用css让div半透明
  2. 计算机课堂有趣的游戏,有趣的课堂游戏作文范文5篇
  3. SolidWorks零件改名后与工程图关联教程
  4. win10任务栏透明_手把手教你把win10桌面变得逼格满满(任务栏可以透明哦)
  5. Win10用注册表开启任务栏透明
  6. dex2jar .\classes.dex - .\classes-dex2jar.jar com.googlecode.d2j.DexException: not support version
  7. python使用numpy按一定格式读取bin文件
  8. 谷歌怎么保存网页为图片?
  9. 那些年啊,那些事——一个程序员的奋斗史 ——16
  10. java通用排序工具类