并不想花太多精力去拼比赛拿名次,毕竟又工作又带娃,时间并不多。但比较喜欢看比赛里的技术论坛。工作中的内容相对要单一很多,很容易陷入狭窄的思维中,而比赛中,大家的思维还是很有营养的。偶尔遇到合胃口的数据,下一份,玩一玩还是不错。

之前的糖尿病大赛,看到的时候离初赛结束只有几天了,周末紧急下载数据,搞了一天弄出结果,然而没有办法提交,后来仔细看了下赛制才发现,初赛最后两天会换数据,之前没提交过的,最后两天没办法提交。遗憾呀,搞了一天,结果都没能验证一下测试集的loss。

4月末看到双高预测比赛,看着还有几天,忍不住又下了数据,结果五一果断玩去了,得到5月5号换数据前一天,又开始加急处理,名次什么,无所谓的,目标是提交一次。最终经历曲折的7个小时,终于提交了两次(实际方法一样,迭代次数稍微不同),结果loss为0.0367,好意外的结果。

这7个小时中,干了些什么呢?请看笨妞的流水账。

1. 合并数据

合并数据和滤去太少的列,这个完全照搬技术圈里面的程序,帖子的地址,只用了其中一部分,后面提特征的觉得不太能用,自己玩了。

import pandas as pd
import numpy as np
pd.set_option('max_colwidth',512)data_part1 = pd.read_csv("dataset/meinian_round1_data_part1_20180408.txt", sep="$")
data_part2 =pd.read_csv("dataset/meinian_round1_data_part2_20180408.txt", sep='$')
data = pd.concat([data_part1, data_part2])
print(data.shape)
# (8104368, 3)# 把table_id相同的体检项,全部保留;堆叠为同一行保存,以 “;” 分隔
data_keep_all = data.groupby(['vid','table_id'],as_index=False).apply(lambda x:";".join(map(str, x['field_results'])))
data_keep_all = pd.DataFrame(data_keep_all,columns=['field_results'])
print(data_keep_all.shape)
# (7820997,)#  转化为 行列格式
data_fmt_all = data_keep_all.unstack(fill_value=None)
data_fmt_all.columns = data_fmt_all.columns.droplevel(level=0)
print(data_fmt_all.shape)
# (57298, 2795) 共有2795个特征值# 缺失值统计
null_count = data_fmt_all.isnull().sum()
print(len(null_count[null_count<50000]))
# 256 缺失值少于50000的特征只有256个..# 删除缺失值过多的数据
data_keep_50000 = data_fmt_all .drop(labels=null_count [null_count >=50000].index,axis=1)
data_keep_50000 .to_csv("tmp/data_keep_50000.csv")

经过这段程序处理后,两个数据文件中每个受检查者的所有检查项目合并到一行中,原本的2795项检查结果,通过丢掉缺失值大于50000个的特征处理后,剩下256个。

2. 特征进一步过滤

这一步实际上花了比较长时间,因为都是手动看数据、分析每一项可能是哪一类检查。剩下的256项检查结果,里面包含外科基本检查、内科基本检查、医生问诊、口腔检查、CT、超声、心电图、眼科检查、妇科检查、各类生化检查等。其中很多检查结果都是自然语言,这些特征我直接放弃了。原因很简单,除了脑部CT、动脉超声对高血压和高血脂有诊断帮助,其他超声、CT,心电图对双高基本没用;眼科、口腔、妇科、尿检等跟双高也基本不搭边;外科基本检查、内科基本检查大家体检都会做的,按按肚子,看看腿,更不沾边了。还有一个致命的原因,我根本没有时间做复杂的NLP啊。所以,该扔就扔。这一扔就只剩下28维特征了。酷!

这28维特征里面除了数值类型的,还有字符类型的,大概的扫了一遍,把字符类型的按照规则转化为数值,特征基本定型。

import codecs
import pandas as pddef isnumber(aString):try:float(aString)return Trueexcept:return Falsef = codecs.open('tmp/data_keep_50000_part1.csv', 'r', 'gbk')
df_col = ['id']
for i in range(28):df_col.append('f' + str(i))
print(df_col)
f_df = pd.DataFrame(columns =df_col)
line = f.readline()
line = f.readline()
j = 0
normal_exp = ['阴性', '正常', 'normal', '-', '阴性(+)', '阴性(+)', '-        0mmol/L', '0(-)', '-        0umol/L','-           0g/L', '-       0CELL/uL', '-    10CELL/uL', '--', '-     10CELL/uL']
positive_exp = ['阳性', '+', '阳性(+)']
pattern = '[0-9]+\.[0-9]+'
prog = re.compile(pattern)
while line:words = line.strip().split(',')idx = words[0]f_list = []null_num = 0for i in range(28):feature = words[i + 1]if ';' in feature:feature = feature.split(';')[1]  if feature == '':f_list.append(None)null_num += 1elif isnumber(feature) or feature.isdigit():f_list.append(float(feature))elif feature in normal_exp:f_list.append(float(0))elif  feature in positive_exp:f_list.append(float(1))elif '+' in feature:n = 0.0for c in feature:if c == '+':n += 1.0f_list.append(float(n)) elif feature == '>=1.030':f_list.append(1.030) else:a = re.search( pattern, feature)try:f_list.append(float(a.group()))except:print(feature)f_list.append(None)tmp_dict = {'id': idx}for i in range(28):tmp_dict[df_col[i + 1]] = f_list[i]f_df.loc[j] = tmp_dict#print(tmp_dict)line = f.readline()j += 1if j%1000 == 0 :print(j)
f_df.to_csv('tmp/feature.csv')
f.close()
print(len(f_df))

特征规模变为57298x28.

3. 筛除个数小于20000的特征项,并补全缺失值,做归一化(这段代码因为fillna函数不知为什么,老容易罢工,结果用了无比笨重的方式)

print(len(null_count[null_count<20000]))
f_df_chosen = f_df.drop(labels='f26',axis=1)
f_df_chosen.to_csv('tmp/feature_chosen.csv')#“阴”“阳”性数据补全
f_df_filled = f_df_chosen.fillna({'f0':0})
#数值数据补全
f_df_filled = f_df_filled.fillna({'f1':f_df_filled['f1'].mean(),'f2':f_df_filled['f2'].mean(), 'f3':f_df_filled['f3'].mean(),'f4':f_df_filled['f4'].mean(),'f5':f_df_filled['f5'].mean(),'f6':f_df_filled['f6'].mean(),'f7':f_df_filled['f7'].mean(),'f8':f_df_filled['f8'].mean(),'f9':f_df_filled['f9'].mean(),'f10':f_df_filled['f10'].mean(),'f11':f_df_filled['f11'].mean(),'f12':f_df_filled['f12'].mean(),'f13':f_df_filled['f13'].mean(),'f14':f_df_filled['f14'].mean(),'f15':f_df_filled['f15'].mean(),'f17':f_df_filled['f17'].mean(),'f18':f_df_filled['f18'].mean(),'f16':f_df_filled['f16'].mean(),'f19':f_df_filled['f19'].mean(),'f20':f_df_filled['f20'].mean(),'f21':f_df_filled['f21'].mean(),'f22':f_df_filled['f22'].mean(),'f23':f_df_filled['f23'].mean(),'f24':f_df_filled['f24'].mean(),'f25':f_df_filled['f25'].mean(),'f27':f_df_filled['f27'].mean()})
#数值型数据归一化
f_df_filled.set_index(['id'], inplace = True)
f_df_norm = (f_df_filled - f_df_filled.min()) / (f_df_filled.max() - f_df_filled.min())
f_df_filled.info()
f_df_filled.to_csv('tmp/feature_filled.csv')

4. 获取训练数据

这个赛题中,训练和测试的基本数据都在前面处理的两部分数据中,训练文件只包含受检人的vid和5项指标的值,测试文件只包含要测试的vid。在整合训练数据和测试数据时,需要将基本文件和训练文件按照vid联合获取训练数据,整合测试数据需要基本数据和测试vid联合获取测试特征数据。(因为没有事先好好观察数据,这里还走了弯路。原本在第2步筛除数据时,将特征少于10维的vid丢掉,那时以为处理的数据就是训练数据,这样避免某些vid数据缺失太多,预测不准。结果这样一来,一共9538个测试vid,在基本数据中只有7000多个匹配到特征了)

label_df = pd.read_csv('dataset/meinian_round1_train_20180408.csv', index_col='vid')
label_df = label_df.astype(float)
train_df = pd.concat([f_df_norm, label_df], axis=1, join='inner')
train_df = train_df.astype(float)
train_df.info()

5. 获取测试数据

test_vid_df = pd.read_csv('dataset/meinian_round1_test_a_20180409.csv', index_col='vid')
test_df = pd.concat([f_df_norm, test_vid_df], axis=1, join='inner')
test_df.info()

6. 训练标签数据清洗

特征数据清洗整理完之后,还有标签数据也得清洗,这个比赛里面有些舒张压比收缩压还大,有些数据为负,这些都需要清理掉。负值数据直接通过手动删除了,收缩压和舒张压清理如下:

train_df = train_df.drop(labels=train_df[train_df['收缩压']<=train_df['舒张压']].index, axis=0)

7. 训练

选择xgboost算法来学习这个题目。本人实际上还并不懂xgboost的基本原理,参加这个比赛很重要的目的就是玩玩xgboost,但是为了先提交,暂时没有时间详细学习xgboost的基本原理了。安装之后,看了官方使用文档,然后直接上。

原则上应该要先cv调参的,但是,依然由于中间犯了个低级错误,浪费了1个小时,没有时间调参了。

def trainandTest(X_train, y_train, X_test, vid_list, n):# XGBoost训练过程print('开始训练...')model = xgb.XGBRegressor(learning_rate=0.05, n_estimators=800, max_depth=5, min_child_weight=5, seed=0,subsample=0.7, colsample_bytree=0.7, gamma=0.1, reg_alpha=1, reg_lambda=1)model.fit(X_train, y_train)# 对测试集进行预测print('开始测试...')print(len(X_test))ans = model.predict(X_test)print(ans[0:10])ans_len = len(ans)pd_data = pd.DataFrame(columns=['vid', 'y'])for i in range(0, ans_len):tmp_dict = {'vid': vid_list[i], 'y': ans[i]}pd_data.loc[i] = tmp_dictpd_data.to_csv('submit_800_' + str(n) + '.csv', index=None)print('完成')return pd_data
print('读训练数据...')
#X_train, y_train = featureSet(train_df, '收缩压')
train_x_df = train_df.drop(labels=['收缩压', '舒张压', '血清甘油三酯', '血清高密度脂蛋白', '血清低密度脂蛋白'],axis=1)
print(train_x_df.info())
train_arr = np.array(train_x_df)
X_train = train_arr.tolist()
vid_list = test_df.index
train_y_1 = train_df['收缩压'].tolist()
print(train_y_1[0:10])
train_y_2 = train_df['舒张压'].tolist()
train_y_3 = train_df['血清甘油三酯'].tolist()
train_y_4 = train_df['血清高密度脂蛋白'].tolist()
train_y_5 = train_df['血清低密度脂蛋白'].tolist()
print('读测试数据...')
test_x_df = test_df.drop(labels=[ '收缩压', '舒张压', '血清甘油三酯', '血清高密度脂蛋白', '血清低密度脂蛋白'],axis=1)
test_arr = np.array(test_x_df)
X_test = test_arr.tolist()
# 预测最终的结果pd_1 = trainandTest(X_train, train_y_1, X_test, vid_list, 1)
pd_1.set_index(['vid'], inplace = True)
pd_1 = pd_1.astype(int)
pd_2 = trainandTest(X_train, train_y_2, X_test, vid_list, 2)
pd_2.set_index(['vid'], inplace = True)
pd_2 = pd_2.astype(int)
#一直跑出来结果为NAN的原因是,label里面有一个缺失值
pd_3 = trainandTest(X_train, train_y_3, X_test, vid_list, 3)
pd_3.set_index(['vid'], inplace = True)
pd_4 = trainandTest(X_train, train_y_4, X_test, vid_list, 4)
pd_4.set_index(['vid'], inplace = True)
pd_5 = trainandTest(X_train, train_y_5, X_test, vid_list, 5)
pd_5.set_index(['vid'], inplace = True)

分5次训练和预测,略显尴尬。

8. 合并数据并提交

#合并数据
pd_1.rename(columns={'y':'收缩压'}, inplace = True)
pd_2.rename(columns={'y':'舒张压'}, inplace = True)
pd_3.rename(columns={'y':'血清甘油三酯'}, inplace = True)
pd_4.rename(columns={'y':'血清高密度脂蛋白'}, inplace = True)
pd_5.rename(columns={'y':'血清低密度脂蛋白'}, inplace = True)
pd_result = pd.concat([pd_1, pd_2], axis=1, join='inner')
pd_result = pd.concat([pd_result, pd_3], axis=1, join='inner')
pd_result = pd.concat([pd_result, pd_4], axis=1, join='inner')
pd_result = pd.concat([pd_result, pd_5], axis=1, join='inner')
pd_result = pd_result.reset_index(drop=False)
pd_result.to_csv('result_800.csv', index=None)

9. 犯过的低级错误

训练文件中,5项label中“血清甘油三脂”有一个缺失值,但是我在前面查看info的时候没有发现,后面再训练这一项的时候,怎么调节参数,预测值都是nan,后来无语了,把算法换成lr,想着是不是因为这一项的最大值和最小值差异较大xgboost不适合。结果lr自觉的报“输入值包含nan”才回去查找缺失值。各种调参、换模型,浪费了接近1个小时。

查找缺失值

#确定nan的位置
np.where(np.isnan(train_df))

首次试水天池数据大赛——7个小时玩了把美年健康AI大赛相关推荐

  1. CSDN首次试水,投石问路

    此篇为庆祝我以后准备在这个平台记录我的学习情况,噢,加油!!!

  2. ​阿里云天池工业AI大赛暨中国“印象盐城,数创未来”大数据竞赛正式启动

    记者 | 张俊潇 官网 | www.datayuan.cn 微信公众号ID | datayuancn 10月11日,"2017杭州·云栖大会"在万众期待中盛大召开,会上马云宣布组建 ...

  3. 电商试水“先白拿后付费” 大数据筛选信用买家

    尺码拿不准,当季新品购买量少.无评价,东西小贵不知道是不是自己的style--有电商近日试水的"先试后买"一扫你的纠结. 近日,有电商对"达人会员"发出邀请,推 ...

  4. 专访阿里云AI科学家闵万里:AI试水电力调度是道让人兴奋的题目

    "用电之痛"是全国千万用电及售电企业的大难题.业内人士预测,2017年我国电力生产行业资产规模将达到86852亿元.据悉,仅2016年全社会用电量达59198亿千瓦,其中3.5%是 ...

  5. 互联网日报 | 瑞幸咖啡同意支付1.8亿美元达成和解;国产游戏海外收入首破千亿;滴滴试水信用支付...

    今日看点 ✦ 瑞幸咖啡同意支付1.8亿美元罚款,与美SEC达成会计欺诈指控和解 ✦ 百度智能云推出"云智生态计划",并设立30亿基金 ✦ 滴滴试水信用支付:推出"滴滴月付 ...

  6. 天池工业AI大赛-智能制造质量预测 比赛历程和技术方案总结复赛48名

    一.参赛 研二导师的项目摸鱼结束后,思考了一下出路,项目和机器学习相关,重在特征提取的传统算法研究和目标识别的多样算法融合,简单说就是理论,MATLAB,推导三要素组成.来年就要面对就业,没有点成果或 ...

  7. 美团试水机器人送外卖;苹果向第三方提供 iPhone 维修零件;GoLand 2019.2.1 发布 | 极客头条...

    快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...

  8. 【号外】联手腾讯故宫试水“互联网+”

    朱元璋戴墨镜说Rap.妃子在宫内用VR眼镜玩游戏,这并非某个穿越剧内容,而是故宫和腾讯宣布合作的创意H5,该页面发布后迅速"席卷"朋友圈. 转发这条H5的微信用户中,还包括腾讯董事 ...

  9. 电商派争夺零售派:传统百货扎堆试水O2O

    21世纪经济报道 曾几何时,风头正健的电子商务巨头与传统零售百货之间,隔着楚河汉界.双方摆出的架势非此即彼,一轮轮争夺消费者购买力的大战充满火药味. 但在商界,没有永远的敌人,只有不变的利益.从201 ...

最新文章

  1. 桌面虚拟化之远程协助
  2. Java使用Jdbc操作MySql数据库(一)
  3. 什么是node网站服务器,node.js
  4. 抢票神器成GitHub热榜第一,支持候补抢票,Python跑起来 | 标星8400
  5. 内联函数的声明和定义
  6. sqlserver拼接sql插入table_10个SQL技巧
  7. 企业发卡修复版源码(短链二维码)
  8. android 访问本地image url_微信图片无法通过 WXSS 获取,可使用网络图片或 base64或image...
  9. 二叉链表java_二叉树的二叉链表存储及其Java实现
  10. 十七款PDF在线处理转换器,目前最全合集
  11. win10安装影子系统导致的蓝屏,终止代码:BAD_SYSTEM_CONFIG
  12. 彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index
  13. mysql awr v1.0.2发布
  14. 3D打印机赋予了海岸生态系统极大的恢复能力
  15. Fortran NINT函数意思
  16. 线上知识付费潮流中的青年人:寻找消费与求知的平衡点
  17. vue会不会?看了你就会了!干了#兄弟们
  18. 对数计算的实现方式(在windows计算器、OneNote、Python和Java中)
  19. glog logging library for C++
  20. python基础学习笔记——完结

热门文章

  1. 二柱子卖的西瓜上315啦!一个故事读懂315危机公关
  2. 架构漫谈(八):从架构的角度看如何写好代码 + 我的思考
  3. Centos下安装SSH、FTP服务
  4. 客户旅程分析 Customer Journey Mapping
  5. 可以几分钟快速对接支付宝APP支付和手机网站支付?
  6. 最新瑞芯微四核芯片RK3288开源开发板
  7. css美观文本框_如何为美观和用户友好的文本使用类型
  8. 户外直播、移动直播遇到弱网信号差,如何保证流畅又高清画面传输
  9. php校园学校宿舍管理系统 php毕业设计题目课题选题 php毕业设计项目作品源码(3)班主任和宿舍管理员功能
  10. Java使用opencv调用微信扫描二维码引擎,附带windows和linux需要的动态库文件