阿里天池赛后数据分析

本文介绍了一次使用人工智能预测糖尿病遗传风险的比赛经历,包括数据预处理、特征选择与工程、模型训练等多个步骤,最终实现了准确率较高的糖尿病风险预测。

赛后数据分析

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

大赛概况

进入21世纪,生命科学特别是基因科技已经广泛而且深刻影响到每个人的健康生活,于此同时,科学家们借助基因科技史无前例的用一种全新的视角解读生命和探究疾病本质。人工智能(AI)能够处理分析海量医疗健康数据,通过认知分析获取洞察,服务于政府、健康医疗机构、制药企业及患者,实现个性化,可以循证的智慧医疗,推动创新,实现价值。

心血管病、糖尿病等慢性疾病,每年导致的死亡人数占总死亡人数的80%,每年用于慢病医疗费用占中国公共医疗卫生支出的比例超过13%。作为一种常见慢性疾病,糖尿病目前无法根治,但却能通过科学有效的干预、预防和治疗,来降低发病率和提高患者的生活质量。阿里云联合青梧桐健康科技有限公司主办天池精准医疗大赛——人工智能辅助糖尿病遗传风险预测,希望用人工智能的方法和思想处理、分析、解读和应用糖尿病相关大数据,让参赛选手设计高精度,高效,且解释性强的算法来挑战糖尿病精准预测这一科学难题,为学术界和精准医疗提供有力的技术支撑,帮助我们攻克糖尿病。

from pylab import *
mpl.rcParams['font.sans-serif'] = ['Droid Sans Fallback']
mpl.rcParams['axes.unicode_minus'] = False
import pandas as pd

data = pd.read_csv(r'data_flie/d_train_20180102.csv')
data.columns
Index([u'id', u'性别', u'年龄', u'体检日期', u'*天门冬氨酸氨基转换酶', u'*丙氨酸氨基转换酶', u'*碱性磷酸酶',
       u'*r-谷氨酰基转换酶', u'*总蛋白', u'白蛋白', u'*球蛋白', u'白球比例', u'甘油三酯', u'总胆固醇',
       u'高密度脂蛋白胆固醇', u'低密度脂蛋白胆固醇', u'尿素', u'肌酐', u'尿酸', u'乙肝表面抗原', u'乙肝表面抗体',
       u'乙肝e抗原', u'乙肝e抗体', u'乙肝核心抗体', u'白细胞计数', u'红细胞计数', u'血红蛋白', u'红细胞压积',
       u'红细胞平均体积', u'红细胞平均血红蛋白量', u'红细胞平均血红蛋白浓度', u'红细胞体积分布宽度', u'血小板计数',
       u'血小板平均体积', u'血小板体积分布宽度', u'血小板比积', u'中性粒细胞%', u'淋巴细胞%', u'单核细胞%',
       u'嗜酸细胞%', u'嗜碱细胞%', u'血糖'],

dtype='object')

describe_df = data.describe()
describe_df
id年龄*天门冬氨酸氨基转换酶*丙氨酸氨基转换酶*碱性磷酸酶*r-谷氨酰基转换酶*总蛋白白蛋白*球蛋白白球比例...血小板计数血小板平均体积血小板体积分布宽度血小板比积中性粒细胞%淋巴细胞%单核细胞%嗜酸细胞%嗜碱细胞%血糖
count5642.0000005642.0000004421.0000004421.000004421.0000004421.0000004421.0000004421.0000004421.0000004421.000000...5626.0000005619.0000005619.0000005619.0000005626.0000005626.0000005626.0000005626.0000005626.0000005642.000000
mean2866.18415545.58046826.80589227.6520287.48227838.82376276.77110845.82250430.9486041.502538...253.08531810.65344413.3044140.26790756.71846833.7785466.8567722.0437970.6036975.631925
std1655.55564912.96194613.56300322.6115225.63089740.7882824.0160552.6174013.5659970.220621...59.5868280.9854842.1737160.0605037.7999407.2530971.5675831.7109010.2917601.544882
min1.0000003.00000010.0400000.1200022.9800006.36000057.32000029.5400007.0600000.520000...37.0000007.1000008.0000000.04200014.4000007.5000003.1000000.0000000.0000003.070000
25%1433.25000035.00000020.25000015.1300070.37000017.81000074.19000044.13000028.5700001.360000...213.00000010.00000011.7000000.23000051.60000028.8000005.8000000.9000000.4000004.920000
50%2870.50000045.00000023.89000021.4800084.47000026.19000076.63000045.82000030.7800001.490000...249.00000010.60000012.9000000.26000056.70000033.6000006.7000001.6000000.6000005.290000
75%4302.75000054.00000029.27000032.30000100.21000043.85000079.53000047.57000033.1800001.630000...289.00000011.30000014.6000000.30000062.00000038.5000007.7000002.6000000.7000005.767500
max5732.00000093.000000434.950000498.89000374.320000736.990000100.41000054.08000066.1800007.120000...745.00000015.20000025.3000000.71000088.50000076.30000023.20000022.5000003.50000038.430000

8 rows × 40 columns

 

data.isnull().sum() / len(data)#缺失值比例
id             0.000000
性别             0.000000
年龄             0.000000
体检日期           0.000000
*天门冬氨酸氨基转换酶    0.216413
*丙氨酸氨基转换酶      0.216413
*碱性磷酸酶         0.216413
*r-谷氨酰基转换酶     0.216413
*总蛋白           0.216413
白蛋白            0.216413
*球蛋白           0.216413
白球比例           0.216413
甘油三酯           0.216058
总胆固醇           0.216058
高密度脂蛋白胆固醇      0.216058
低密度脂蛋白胆固醇      0.216058
尿素             0.244240
肌酐             0.244240
尿酸             0.244240
乙肝表面抗原         0.758419
乙肝表面抗体         0.758419
乙肝e抗原          0.758419
乙肝e抗体          0.758419
乙肝核心抗体         0.758419
白细胞计数          0.002836
红细胞计数          0.002836
血红蛋白           0.002836
红细胞压积          0.002836
红细胞平均体积        0.002836
红细胞平均血红蛋白量     0.002836
红细胞平均血红蛋白浓度    0.002836
红细胞体积分布宽度      0.002836
血小板计数          0.002836
血小板平均体积        0.004077
血小板体积分布宽度      0.004077
血小板比积          0.004077
中性粒细胞%         0.002836
淋巴细胞%          0.002836
单核细胞%          0.002836
嗜酸细胞%          0.002836
嗜碱细胞%          0.002836
血糖             0.000000
dtype: float64
 

可以看出与乙肝相关的特征,缺失值到达了75%以上,于是决定删除乙肝5项,id与血糖无关,也删除,然后将data分为特征和结果标签,并将空缺值用平均值代替,之前打算剔除了体检日期这一特征,想了想等等吧

 
import time
import datetime
from dateutil.parser import parse

data['体检日期'] = (pd.to_datetime(data['体检日期']) - parse('2017-10-09')).dt.days
data['性别'] = data['性别'].map({'男': 1, '女': 0})
train_lable = data['血糖']#提取标签
train_data = data.iloc[:, 0:-1]#提取特征
exclude_other = ['id', '乙肝表面抗原', '乙肝表面抗体', '乙肝e抗原', '乙肝e抗体', '乙肝核心抗体']
for i in exclude_other:
     del train_data[i]
data_mean = train_data.mean()
train_data = train_data.fillna(data_mean)
train_data.shape
(5642, 35)
import matplotlib.pylab as plt
import seaborn as sns


data_corr = data.corr()
fig = plt.figure(figsize=(30, 30))
sns.heatmap(data_corr, vmax=0.9,   square=True, cbar=True, annot=True, fmt='.2f', annot_kws={'size': 10})
plt.show()

 

from scipy import stats

sns.distplot(train_lable)
plt.show()
stats.probplot(train_lable, plot=plt)
plt.show()

sns.boxplot(y = train_lable)
plt.show()

剔除血糖超過20的

del_index = []
for i in range(train_lable.shape[0]):
    if train_lable[i] > 20:
        del_index.append(i)
train_lable.drop(train_lable.index[del_index], inplace=True)
train_data.drop(train_data.index[del_index], inplace=True)
import numpy as np

train_lable_log = np.log1p(train_lable)

sns.distplot(train_lable_log);
plt.show()
stats.probplot(train_lable, plot=plt)
plt.show()

 

data1 = train_data[['性别', '年龄', '体检日期']]
sns.boxplot(data1)
plt.title('其他因素')
plt.show()

data2 = train_data[['*天门冬氨酸氨基转换酶', '*丙氨酸氨基转换酶', '*碱性磷酸酶',
       '*r-谷氨酰基转换酶', '*总蛋白', '白蛋白', '*球蛋白']]
sns.boxplot(data2)
plt.title('酶蛋白')
plt.show()

train_data.drop(train_data[(train_data['*天门冬氨酸氨基转换酶'] > 200) | (train_data['*丙氨酸氨基转换酶'] > 250) |
                           (train_data['*r-谷氨酰基转换酶'] > 600)].index, inplace=True)
data3 = train_data[['甘油三酯', '总胆固醇','高密度脂蛋白胆固醇', '低密度脂蛋白胆固醇']]
sns.boxplot(data3)
plt.title('醇')
plt.show()

 

train_data.drop(train_data[(train_data['甘油三酯'] > 30) | (train_data['总胆固醇'] > 20)].index, inplace=True)
data4 = train_data[['尿素', '肌酐', '尿酸']]
sns.boxplot(data4)                                          
plt.title('肾相关')
plt.show()

 

 data5 = train_data[['白细胞计数', '红细胞计数', '血红蛋白', '红细胞压积', '红细胞平均体积', '红细胞平均血红蛋白量', '红细胞平均血红蛋白浓度',
       '红细胞体积分布宽度', '血小板计数']]
sns.boxplot(data5)       
plt.title('細胞數')
plt.show()

 

train_data.drop(train_data[(train_data['血小板计数'] > 600)].index, inplace=True)
data6 = train_data[['血小板平均体积', '血小板体积分布宽度', '血小板比积']]
sns.boxplot(data6)
plt.title('血小板')
plt.show()

 

data7 = train_data[['中性粒细胞%','淋巴细胞%', '单核细胞%', '嗜酸细胞%', '嗜碱细胞%']]
sns.boxplot(data7)
plt.title('其他細胞')
plt.show()

 

train_data.drop(train_data[(train_data['中性粒细胞%'] < 23) | (train_data['淋巴细胞%'] > 65) |  (train_data['单核细胞%'] >20)].index, inplace=True)
drop_col = ['嗜碱细胞%','单核细胞%','白球比例','白蛋白','*总蛋白', '低密度脂蛋白胆固醇', '血小板比积','淋巴细胞%']
train_data.drop((drop_col), axis=1, inplace=True)
fig = plt.figure(figsize=(20, 20))
data_corr = train_data.corr()
sns.heatmap(data_corr, vmax=0.9,   square=True)
plt.show()



填补空缺值

 

train_data = train_data.fillna(-999)
def data_yunsun(train, test):
    train['霉'] = train['*天门冬氨酸氨基转换酶'] + train['*丙氨酸氨基转换酶'] + train['*碱性磷酸酶'] + train['*r-谷氨酰基转换酶']
    test['霉'] = test['*天门冬氨酸氨基转换酶'] + test['*丙氨酸氨基转换酶'] + test['*碱性磷酸酶'] + test['*r-谷氨酰基转换酶']

    train['尿酸/肌酐'] = train['尿酸'] / train['肌酐']
    test['尿酸/肌酐'] = test['尿酸'] / test['肌酐']

    train['肾'] = train['尿酸'] + train['尿素'] + train['肌酐']
    test['肾'] = test['尿酸'] + test['尿素'] + test['肌酐']

    train['红细胞计数*红细胞平均血红蛋白量'] = train['红细胞计数'] * train['红细胞平均血红蛋白量']
    test['红细胞计数*红细胞平均血红蛋白量'] = test['红细胞计数'] * test['红细胞平均血红蛋白量']

    train['红细胞计数*红细胞平均血红蛋白浓度'] = train['红细胞计数'] * train['红细胞平均血红蛋白浓度']
    test['红细胞计数*红细胞平均血红蛋白浓度'] = test['红细胞计数'] * test['红细胞平均血红蛋白浓度']

    train['红细胞计数*红细胞平均体积'] = train['红细胞计数'] * train['红细胞平均体积']
    test['红细胞计数*红细胞平均体积'] = test['红细胞计数'] * test['红细胞平均体积']

    train['嗜酸细胞'] = train['白细胞计数'] * train['嗜酸细胞%']
    test['嗜酸细胞'] = test['白细胞计数'] * test['嗜酸细胞%']

    train['血红蛋白/红细胞计数*红细胞平均血红蛋白浓度'] = train['血红蛋白'] / train['红细胞计数*红细胞平均血红蛋白浓度']
    test['血红蛋白/红细胞计数*红细胞平均血红蛋白浓度'] = test['血红蛋白'] / test['红细胞计数*红细胞平均血红蛋白浓度']
    return train, test

 

'''catboost'''
def test_ans(X_train, Y_train, X_test):
    cat_feature_inds = []
    cat_feature_inds.append(0)
    num_ensembles = 5
    y_pred = 0.0
    for i in tqdm(range(num_ensembles)):
        model = CatBoostRegressor(
            iterations=1000, learning_rate=0.03,
            depth=6, l2_leaf_reg=3,
            loss_function='RMSE',
            eval_metric='RMSE',
            random_seed=i)

        model.fit(X_train, Y_train,cat_features=[0])

        y_pred += model.predict(X_test)

    y_pred /= num_ensembles

    submission = pd.DataFrame({'pred': y_pred})

    submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None,

                      index=False, float_format='%.4f')
'''xgboost'''
def test_ans2(X_train, y_train):
    import xgboost as xgb
    from sklearn.metrics import mean_squared_error
    kf = KFold(n_splits=5, shuffle=False)
    params = {
        'max_depth': 6,
        'eta': 0.1,
        'silent': 1,
        'gamma':0.0468,
        'alpha':0.4640,
        'lambda': 0.8571,
        'objective': 'count:poisson'
    }

    print "*********"
    y_pred = 0.0
    for train_index, test_index in kf.split(X_train):
        dtrain = xgb.DMatrix(X_train[train_index], y_train[train_index])
        dtest = xgb.DMatrix(X_train[test_index], y_train[test_index])
        dtest2 = xgb.DMatrix(X_test)
        watch_list = [(dtest, 'eval'), (dtrain, 'train')]
        num_rounds = 1000
        model = xgb.train(params, dtrain, num_rounds, watch_list)
        ans = model.predict(dtest)
        # score += ((ans-y_train[test_index])**2).sum()/(2*y_train[test_index].shape[0])
        y_pred += model.predict(dtest2, ntree_limit=model.best_ntree_limit)
    print "+++++++++++"

    y_pred /= 5
    submission = pd.DataFrame({'pred': y_pred})

    submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None,

                      index=False, float_format='%.4f')
'''ligthGBM'''
def test_ans3(X_train, y_train, X_test):
    import lightgbm as lgb
    kf = KFold(n_splits=5, shuffle=False)
    params = {
        'learning_rate': 0.01,

    'boosting_type': 'gbdt',

    'objective': 'poisson',

    'bagging_fraction': 0.8,

    'bagging_freq':1,

    'num_leaves': 12,

    'colsample_bytree': 0.6,

    'max_depth': 6,

    'min_data': 5,

    'min_hessian': 1,

    'verbose': -1
    }
    score = 0.0
    ans = 0.0
    for train_index, test_index in kf.split(X_train):
        lgb_train = lgb.Dataset(X_train[train_index], y_train[train_index])
        lgb_eval = lgb.Dataset(X_train[test_index], y_train[test_index], reference=lgb_train)
        # lgb_test = lgb.Dataset(X_test)
        gbm = lgb.train(params,
                        lgb_train,
                        num_boost_round=20000,

                        valid_sets=lgb_eval,

                        verbose_eval=500,

                        early_stopping_rounds=200)
        y_pred = gbm.predict(X_train[test_index], num_iteration=gbm.best_iteration)
        ans +=  gbm.predict(X_test, num_iteration=gbm.best_iteration)
        score += ((y_pred-y_train[test_index])**2).sum()/(2*y_train[test_index].shape[0])
    print score/5
    ans /= 5
    submission = pd.DataFrame({'pred': ans})

    submission.to_csv(r'sub{}.csv'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')), header=None,

                      index=False, float_format='%.4f')
1. 项目背景 基于项目提供的汽车相关数据,通过聚类分析的方法实现汽车产品聚类,以构建汽车产品画像、分析产品定位、完成汽车竞品分析等要求。 2. 项目数据 项目提供的汽车数据包括26个字段共205条数据,数据文件为“car_price.csv” 26个字段可以划分为类别型变量和数值型变量两种,包括汽车的长/宽/高、汽车净重、燃油系统、燃油类型、驱动类型、峰值转速、里程数、汽车价格等。 3. 项目要求 通过聚类的方法构建汽车产品画像、分析不同类别汽车的产品定位,寻找Volkswagen大众汽车的竞品品牌。 4. 项目思路 第一步:数据字段理解 根据项目所提供的数据,对数据中26个字段进行理解。结合汽车行业的相关知识,26个字段可以大致归为两类:第一类是车辆自身属性(如燃油系统、燃油类型、汽缸数、峰值转速、汽车长宽高等);第二类是车辆的市场属性(如车辆名称、车辆价格、风险评估等级)。 26个字段主要分为数值型变量和类别型变量两类。 第二步:原始数据描述性统计及变量分布可视化 对原始数据进行描述性统计并对数据中的字段分布进行可视化(详情见主文档)。通过对原始数据的观察,数据不存在缺失值、不存在重复值,“CarName”字段存在部分车辆品牌名称错误的情况。 第三步:确定聚类方法,明确聚类要求 通过对原始数据的变量观察,该数据变量主要为数值型变量和类别型变量两类,且类别型变量数量较多,常用的K-means聚类只能分析数值型变量,无法考虑类别型变量所包含的信息。二阶段聚类法适用于包含数值型和类别型变量的混合数据,因此考虑使用二阶段聚类法分析数据。 二阶段聚类法的要求是:类别型变量符合多项式分布(即变量的值分属几个类别);数值型变量间要相互独立,且数值型变量近似服从正态分布。项目所给出的数据中,类别型变量符合多项式分布,因此仅需进一步观察并处理数值型变量。 第四步:特征工程 数据清洗与新变量生成。原始数据指给出了车辆的名称,没有给出车辆所属品牌,结合最终聚类分析的需要,根据“CarName”字段提取出车辆所属品牌信息,命名为“brand”。同时对品牌名称中的错误拼写进行清洗。 变量相关性分析与可视化。由于二阶段聚类要求数值型变量间相互独立,所以需要对数值型变量间的相关性进行查看与处理。相关性分析结果表示14个数值型变量之间存在高相关性情况,需要结合汽车知识背景与变量特征进行进一步处理。 高相关变量的处理——“highwaympg”和“citympg”呈高度正相关。其实不管是高速mpg还是城市mpg,其本质都是mpg指标,而且通过观察数据,二者之间的差异较小(极值、均值),因此考虑将二者合并为一个指标'mpg',计算方式为取二者均值:mpg=(highwaympg+citympg)/2; 高相关性变量的处理——“price”变量与其余变量产生高相关性的频数最多,可能是因为车辆自身属性和配置的变动会直接影响着车辆的市场价格。此外,与其他变量相比,price属性属于车辆的市场销售属性(而非车辆自身属性),在聚类中更适合作为类别型变量,对车辆的价位进行划分,因此,考虑将price变量转换为类别型变量,按照其价格分布划分为Low price(20000)三类; 高相关性变量的处理——对于其余数值型变量,变量数目较多且多个变量之间存在相关性,因此考虑使用因子分析对数值型变量进行降维,以减少数值型变量的数目并使变量间相互独立。 第五步:数值型变量因子分析结果(基于SPSS实现) 利用SPSS对数值型变量进行因子分析,KMO值>0.8,巴特利球形检验p值=0,说明参与因子分析的变量间存在相关性,可以进行因子分析。最终得到两个因子。 第一个因子包括:车长、车宽、车净重、引擎尺寸、车轴距、mpg、马力、车内径比。简单将该因子归纳为车辆截面与马力因子; 第二个因子包括:车高、峰值转速、车压缩比。简单将该因子归纳为车辆垂面与转速因子; 第六步:两阶段聚类及结果(基于SPSS实现) 对处理后的数据进行两阶段聚类,最终将205辆车聚为两类。 根据SPSS聚类结果,第一类中包含120条车辆数据,占总数据的58.5%;第二类中包含85条车辆数据,占总数据的41.5%。两类簇数据规模近似,没有过大或过小的类簇。 根据SPSS聚类结果,聚类质量属于“良好”范围,仍有进一步改进和优化的空间。 根据SPSS聚类结果,显著区分两类类簇的变量(重要性>0.6)按重要性大小排序依次是驱动类型、燃油系统、车辆截面与马力因子、价格范围。 汽车产品画像与产品定位 根据区分类簇的四个重要标签来对数据中的汽车产品进行产品画像与产品定位。 第一类画像:驱动类型多为fwd(前轮驱动),燃油系统多
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值