糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 江西省开放数据创新应用大赛vte赛道

江西省开放数据创新应用大赛vte赛道

时间:2022-05-13 06:08:46

相关推荐

江西省开放数据创新应用大赛vte赛道

大家好,我是小k,好久没写博客了,从五月份开始接触机器学习,经过了一段时间沉淀,在11月份第一次参加了意义上的大数据比赛,下面想对这次比赛学习到的东西做个总结QAQ。

比赛地址传送门:

江西开放数据创新应用大赛 ()

1:导入相应包与数据

import seaborn as snsimport lightgbm as lgbimport matplotlib.pyplot as pltimport pandas as pdfrom sklearn.preprocessing import LabelEncoder,OneHotEncoderfrom sklearn.model_selection import KFoldfrom catboost import CatBoostClassifier, Poolfrom sklearn.metrics import mean_squared_error, f1_score, accuracy_scorefrom sklearn.preprocessing import StandardScalerfrom sklearn.model_selection import GridSearchCVfrom sklearn.model_selection import train_test_splittrain = pd.read_excel(r'C:\Users\wzk\Desktop\train.xlsx')test = pd.read_excel(r'C:\Users\wzk\Desktop\predict.xlsx')df_features = train.append(test)

2:观察数据集

#检查数据各列的缺失占比情况df1 = (train.shape[0] - train.count())/train.shape[0]df1[0:20]唯一标识 0.000000flag 0.000000总评分 0.000000住院号 0.000000住院次数 0.000000性别0.000000民族0.000000身高0.000000体重0.004243心率0.000542呼吸0.002167收缩压 0.001083舒张压 0.001806诊断0.0000003P试验 0.981943C反应蛋白 0.939689D-二聚体 0.213344α-淀粉酶 0.972824α-羟丁酸脱氢酶 0.740339α羟丁酸脱氢酶0.803720dtype: float64#检查数据类型 int/float/objectdf_features.select_dtypes(include=['int']).columnsIndex(['住院次数'], dtype='object')df_features.select_dtypes(include=['float']).columnsIndex(['flag', '总评分', '心率', '呼吸', '收缩压', '舒张压', 'D-二聚体', 'α-淀粉酶', 'α-羟丁酸脱氢酶','β2-微球蛋白', '不饱和铁结合力', '凝血酶原时间比率', '凝血酶原时间活动度', '国际标准化比率', '尿酸', '总胆红素','总蛋白', '总铁结合力', '果糖胺', '氯', '球蛋白', '白球比', '白蛋白', '直接胆红素', '磷', '糖化血清蛋白','肌酐', '胰淀粉酶', '葡萄糖', '血清铁', '转铁蛋白', '钾', '铁', '镁', '高密度脂蛋白胆固醇'],dtype='object')obj_columns = []for i, item in enumerate(df_features.dtypes):if item == object:obj_columns.append(df_features.columns[i])print(obj_columns)['唯一标识', '住院号', '性别', '民族', '身高', '体重', '诊断', '3P试验', 'C反应蛋白', 'α羟丁酸脱氢酶', 'γ-谷氨酰基转移酶', 'γ谷氨酰转移酶', '丙型肝炎病毒IgG抗体', '丙氨酸氨基转移酶', '丙肝核心抗原', '乙型肝炎病毒e抗体', '乙型肝炎病毒e抗原', '乙型肝炎病毒核心抗体', '乙型肝炎病毒表面抗体', '乙型肝炎病毒表面抗原', '乙肝病毒大蛋白', '乳酸脱氢酶', '人类免疫缺陷病毒抗体', '低密度脂蛋白胆固醇', '凝血酶原时间', '凝血酶时间', '前白蛋白', '同型半胱氨酸', '天门冬氨酸氨基转移酶', '尿素', '总胆固醇', '抗RA33抗体IgG', '抗环瓜氨酸多肽抗体', '抗环瓜氨酸肽抗体抗体', '抗链球菌溶血素O', '无机磷', '梅毒螺旋体抗体', '活化部分凝血活酶时间', '淀粉酶', '甘油三酯', '碱性磷酸酶', '类风湿因子', '糖类抗原CA242', '纤维蛋白原(Clauss法)', '肌酸激酶', '肌酸激酶MB同功酶', '肌酸激酶同工酶', '脂肪酶', '脂蛋白a', '谷胱甘肽还原酶', '载脂蛋白A1', '载脂蛋白B', '钙', '钠']#热力图观察各特征间的相关度_,ax = plt.subplots(figsize=(50,50))sns.set_style('whitegrid', {'font.sans-serif': ['simhei','FangSong']})sns.heatmap(df_features[features].corr(),annot=True,cmap='RdYlGn',ax=ax);#图太大,无法放到这里

通过上面初步分析,我们可以发现,很多特征的缺失值特别多,我刚开始选择把缺失值70%以上的特征全部删了,但我发现删了之后训练得到的分数奇低,所以我先将他们全填-1,0处理。

对于各个特征的数据类型,刚开始我有点诧异,为什么object类型会这么多,正常来说医学上很多测量值应该都为float类型,仔细的观察数据后,我惊奇的发现有些列中某些行会出现>,=号,进而导致整列的数据类型被定义为object类型。所以在训练前我尝试将它们改成float型进行训练。

3:数据清洗

接上述问题,可以发现官方所给的训练集存在很大的问题,对于这些问题,我主要做了以下事情作为尝试。

#删除缺失值大于90%的列,其它列的缺失值先默认填值处理df_features.drop(labels='住院次数',axis=1,inplace = True)模板如此,多余行我就不展示了。#将部分object类型特征转化为float类型from numpy import *a = []for item in df_features['身高']:try:if float(item) >= 140 and float(item) <= 200:a.append(float(item))else:a.append(mean(a))except:a.append(mean(a))df_features.drop(axis=1, columns=['身高'], inplace=True)df_features['身高'] = a同样模板如此。

当然,我这些只是最基本的一些尝试,对于数据集中的一些特征,官方给出了相应正常值的范围,在填值这个方面,我们可以认为将空缺值填正常值范围内的值,并进行相应的标注。

4:特征工程

因为业务能力编程能力的限制,在特征工程方面,我第一反应想做的就是通过matplotlib与seaborn包做出相应特征相关度的图,再进行一些简单的特征衍生。

#生活中最常见的BMI概念,查表观察体重和身高相关度也有0.4+from numpy import *a = []for item in train['体重']:try:if float(item)>=30 and float(item)<=100:a.append(float(item))else:a.append(mean(a))except:a.append(mean(a))from numpy import *b = []for item in train['身高']:try:if float(item) >= 140 and float(item) <= 200:b.append(float(item))else:b.append(mean(b))except:b.append(mean(b))c = []for i in range(len(b)):b[i] = b[i]/100c.append(a[i]/(b[i]*b[i]))train['BMI'] = c

当然,主要的上分途径还是多亏了一个大佬开源的单特征方法,对于诊断这个特征,使用word2vec对文字生成词向量,再将词向量送入到模型中进行处理,实现过程如下。

import jiebaimport jieba.analyseimport codecs # python封装的文件的工具包import pandas as pdtrain = pd.read_excel(r'C:\Users\wzk\Desktop\train.xlsx')test = pd.read_excel(r'C:\Users\wzk\Desktop\predict.xlsx')df = pd.DataFrame()a = []for item in train['诊断'].values:a.append(item)import gensimfrom gensim.models import Word2Vecimport loggingfrom gensim.models import FastTextlogging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)model = FastText(a, window=3, min_count=1, min_n = 3 , max_n = 6)model.save('Word2Vec.model')model = FastText.load('Word2Vec.model')a = []for item in test['诊断'].values:a.append(model.wv[item])import numpy as npa = np.array(a)for i in range(100):df['word2vec_诊断_' + str(i+1)] = a[:,i]df.to_csv(r'诊断1.csv')

单特征+单模就能直接干上0.5+。

5:模型选择

工业类的比赛,catboost,xgboost,lightgbm三大巨头,对于二分类的比赛,在网上查阅资料,很多大佬都是用树模型,所以在选择模型这方面,我选用了五折lgb。

在群里听那些大佬们分享,也有很多人也用nn来做,不过似乎不太稳定。

6:模型训练

在训练中,会发现一个问题,就是打印出结果发现全是0,对于这个问题,经过查阅相应资料后,发现是训练集数据不平衡造成的,意思就是训练集中0和1数量差距悬殊而非常容易过拟合。对于这类问题,使用SMOTE算法后得到了解决。

from imblearn.over_sampling import SMOTEparams = {"objective": "binary","num_leaves": 58,"max_depth": -1,"learning_rate": 0.10584835945584467,"bagging_fraction": 0.9, # subsample"feature_fraction": 0.9, # colsample_bytree"bagging_freq": 5, # subsample_freq"bagging_seed": ,"verbosity": -1,'num_threads': 8, # 进程数 根据机器资源调整from sklearn.model_selection import StratifiedKFoldfolds = StratifiedKFold(n_splits=5, shuffle=True, random_state=)oof = np.zeros([len(X), ])predictions = np.zeros([len(X_test), ])X,y = SMOTE(random_state=42).fit_resample(X,y) for fold_, (trn_idx, val_idx) in enumerate(folds.split(X, y)):print("fold n°{}".format(fold_ + 1))X_train, X_valid = X[features].iloc[trn_idx], X[features].iloc[val_idx]y_train, y_valid = y[trn_idx], y[val_idx]X_train, y_train = SMOTE(random_state=42).fit_resample(X_train, y_train)trn_data = lgb.Dataset(X_train, y_train)val_data = lgb.Dataset(X_valid, y_valid)oof = np.zeros([len(X_valid )+1])num_round = 100clf = lgb.train(params,trn_data,num_round,valid_sets=[trn_data, val_data],verbose_eval=1000,early_stopping_rounds=500)print(y_valid)oof = clf.predict(X_valid, num_iteration=clf.best_iteration)print(oof)for i in range(len(oof)):if oof[i]>=0.5:oof[i] = 1else:oof[i] = 0F2(y_valid,oof) predictions += clf.predict(X_test, num_iteration=clf.best_iteration)print(predictions)predictions/=fold_

7:模型评估

参考官网的评估指标

我们可以自己定义一个损失函数,以便于能够在线下自我对训练结果的好坏进行评估。

def F2(true_labels, pre_labels):a = [i for i in range(true_labels.shape[0]) if (true_labels.values[i] == 1 and pre_labels[i] == 1)]b = [i for i in range(true_labels.shape[0]) if (true_labels.values[i] == 0 and pre_labels[i] == 1)]c = [i for i in range(true_labels.shape[0]) if (true_labels.values[i] == 1 and pre_labels[i] == 0)]TP = len(a)TN = len(b)FP = len(c)precision = TP / (TP + TN + FP)recall = TP / (TP + FP)F2 = (5 * precision * recall) / (4 * precision + recall)print("precision= %f, recall= %f, F2= %f"%(precision, recall, F2))

当然,线下线上还是有点差别的,有时候在验证集上表现得好不一定在测试集就能表现得好,所以更多时候还是要通过提交来进行评估。

8:取巧上分

通过一次一次的训练,我们发现在4000个样本,预测的1越多分数越高,我想这应该是跟评估函数有关系更多的关注你预测的成功的情况。然后我们还发现score这个特征和flag相关性特别高,甚至可以说是决定了flag,在训练集中只要score>5,flag就会是1。所以我们进行了既对score进行了训练也对flag进行了训练,最后再将两者预测的1并起来,发现在b榜能干上0.6。

9:总结

大数据类的比赛,考验的是对数据的敏感度和业务能力,也渐渐明白为什么一些好的公司会对面试者的业务能力有要求。

在比赛中学习是提升业务能力比较好的一个方法,第一次正式参加比较正式的比赛,虽然没能够进决赛,但确实从中学到了挺多。

如果觉得《江西省开放数据创新应用大赛vte赛道》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。