时序数据与Embedding

在最近查看腾讯赛赛题介绍的时候突然发现赛题有点熟悉,进而在看渔佬对今年腾讯赛分享,以及大白对DCIC海洋赛的比赛总结时,思路逐渐清晰:所有的时序序列都可以用Embedding的操作。本文将以几个历史比赛案例(按照参赛的时间排序),讲解时序数据与Embedding的应用场景。文章末尾将介绍与腾讯赛相似的几个历史赛题。

01 蛋白质序列

第一次在非典型NLP领域看到Embedding是在“基于人工智能的药物分子筛选”比赛中,这个比赛任务是根据蛋白质序列来预测蛋白质和小分子之间的亲和力数值。
Kaggle知识点:时序数据与Embedding - 图1
这个开源还是小伍哥的开源,使用蛋白质序列训练一个词向量,然后使用LightGBM进行训练。小伍哥在2年前都这么帅了,赞!

  1. texts = [[word for word in re.findall(r'.{3}',document)]
  2. for document in list(protein_concat['Sequence'])]
  3. model = Word2Vec(texts,size=n,window=4,min_count=1,negative=3,
  4. sg=1,sample=0.001,hs=1,workers=4)

这是一个两年前的比赛,当然Top获奖方案还是需要使用一些领域知识。所以在没有领域知识的情况下或许无脑Embedding是一个不错的选择。

小伍哥的分享:

源碼

  1. ########################################
  2. ##加载包,估计就这些够了,成绩1.34
  3. import gc
  4. import re
  5. import sys
  6. import time
  7. import jieba
  8. import os.path
  9. import os
  10. import datetime
  11. import numpy as np
  12. import pandas as pd
  13. import lightgbm as lgb
  14. import gensim
  15. from gensim.models import Word2Vec
  16. ######################################## data read #####################################
  17. #工作空间设置
  18. data_path = 'C:/Users/wuzhengxiang/Desktop/晶泰科技比赛数据/'
  19. os.chdir(data_path)#设置当前工作空间
  20. print (os.getcwd())#获得当前工作目录
  21. #数据读取
  22. df_protein_train = pd.read_csv('df_protein_train.csv')#1653
  23. df_protein_test = pd.read_csv('df_protein_test.csv')#414
  24. protein_concat = pd.concat([df_protein_train,df_protein_test])
  25. df_molecule = pd.read_csv('df_molecule.csv')#111216
  26. df_affinity_train = pd.read_csv('df_affinity_train.csv')#165084
  27. df_affinity_test = pd.read_csv('df_affinity_test_toBePredicted.csv')#41383
  28. df_affinity_test['Ki'] = -11
  29. data = pd.concat([df_affinity_train,df_affinity_test])
  30. ##############################################################################################
  31. ########### feature ############
  32. ###############################################################################################
  33. #1、Fingerprint分子指纹处理展开
  34. feat = []
  35. for i in range(0,len(df_molecule)):
  36. feat.append(df_molecule['Fingerprint'][i].split(','))
  37. feat = pd.DataFrame(feat)
  38. feat = feat.astype('int')
  39. feat.columns=["Fingerprint_{0}".format(i) for i in range(0,167)]
  40. feat["Molecule_ID"] = df_molecule['Molecule_ID']
  41. data = data.merge(feat, on='Molecule_ID', how='left')
  42. #2、df_molecule其他特征处理
  43. feat = df_molecule.drop('Fingerprint',axis=1)
  44. data = data.merge(feat, on='Molecule_ID', how='left')
  45. #3、protein 蛋白质 词向量训练 看不懂的加公众号:Python_R_wu,稍后会讲解下,来不及写
  46. n = 128
  47. texts = [[word for word in re.findall(r'.{3}',document)]
  48. for document in list(protein_concat['Sequence'])]
  49. model = Word2Vec(texts,size=n,window=4,min_count=1,negative=3,
  50. sg=1,sample=0.001,hs=1,workers=4)
  51. vectors = pd.DataFrame([model[word] for word in (model.wv.vocab)])
  52. vectors['Word'] = list(model.wv.vocab)
  53. vectors.columns= ["vec_{0}".format(i) for i in range(0,n)]+["Word"]
  54. wide_vec = pd.DataFrame()
  55. result1=[]
  56. aa = list(protein_concat['Protein_ID'])
  57. for i in range(len(texts)):
  58. result2=[]
  59. for w in range(len(texts[i])):
  60. result2.append(aa[i])
  61. result1.extend(result2)
  62. wide_vec['Id'] = result1
  63. result1=[]
  64. for i in range(len(texts)):
  65. result2=[]
  66. for w in range(len(texts[i])):
  67. result2.append(texts[i][w])
  68. result1.extend(result2)
  69. wide_vec['Word'] = result1
  70. del result1,result2
  71. wide_vec = wide_vec.merge(vectors,on='Word', how='left')
  72. wide_vec = wide_vec.drop('Word',axis=1)
  73. wide_vec.columns = ['Protein_ID']+["vec_{0}".format(i) for i in range(0,n)]
  74. del vectors
  75. name = ["vec_{0}".format(i) for i in range(0,n)]
  76. feat = pd.DataFrame(wide_vec.groupby(['Protein_ID'])[name].agg('mean')).reset_index()
  77. feat.columns=["Protein_ID"]+["mean_ci_{0}".format(i) for i in range(0,n)]
  78. data = data.merge(feat, on='Protein_ID', how='left')
  79. #################################### lgb ############################
  80. train_feat = data[data['Ki']> -11].fillna(0)
  81. testt_feat = data[data['Ki']<=-11].fillna(0)
  82. label_x = train_feat['Ki']
  83. label_y = testt_feat['Ki']
  84. submission = testt_feat[['Protein_ID','Molecule_ID']]
  85. len(testt_feat)
  86. train_feat = train_feat.drop('Ki',axis=1)
  87. testt_feat = testt_feat.drop('Ki',axis=1)
  88. train_feat = train_feat.drop('Protein_ID',axis=1)
  89. testt_feat = testt_feat.drop('Protein_ID',axis=1)
  90. train_feat = train_feat.drop('Molecule_ID',axis=1)
  91. testt_feat = testt_feat.drop('Molecule_ID',axis=1)
  92. #lgb算法
  93. train = lgb.Dataset(train_feat, label=label_x)
  94. test = lgb.Dataset(testt_feat, label=label_y,reference=train)
  95. params = {
  96. 'boosting_type': 'gbdt',
  97. 'objective': 'regression_l2',
  98. 'metric': 'l2',
  99. #'objective': 'multiclass',
  100. #'metric': 'multi_error',
  101. #'num_class':5,
  102. 'min_child_weight': 3,
  103. 'num_leaves': 2 ** 5,
  104. 'lambda_l2': 10,
  105. 'subsample': 0.7,
  106. 'colsample_bytree': 0.7,
  107. 'colsample_bylevel': 0.7,
  108. 'learning_rate': 0.05,
  109. 'tree_method': 'exact',
  110. 'seed': 2017,
  111. 'nthread': 12,
  112. 'silent': True
  113. }
  114. num_round = 3000
  115. gbm = lgb.train(params,
  116. train,
  117. num_round,
  118. verbose_eval=50,
  119. valid_sets=[train,test]
  120. )
  121. preds_sub = gbm.predict(testt_feat)
  122. #结果保存
  123. nowTime=datetime.datetime.now().strftime('%m%d%H%M')#现在
  124. name='lgb_'+nowTime+'.csv'
  125. submission['Ki'] = preds_sub
  126. submission.to_csv(name, index=False)

B榜第三名的分享:

02 病毒序列

第二次在非典型NLP比赛中看到Embedding是在“第三届阿里云安全赛”中,这个比赛任务是需要根据程序的API序列进行分类。
image.png
这场比赛我参加过,也因此在线下赛认识了大白。安全赛中也是不同的病毒API是一个单词,执行序列组成一个样本。
但是在这个比赛中,由于API个数比较少,所以Embedding反而没有TF-IDF有效。当然在stacking阶段,Embedding也是有提升的。

03 船舶序列

最近一次是在最近结束的DCIC海洋赛中看到了Embedding,这也是一个非典型的NLP比赛,赛题任务需要根据渔船的运动轨迹进行行为分类。
Kaggle知识点:时序数据与Embedding - 图3
这场比赛大白也参加了,每个渔船id的速度、经纬度看做是一个序列信息,利用速度、经纬度的分位数统计量,将浮点特征分桶转成一个类型特征。
使用深度学习的word2vec的CBOW算法无监督训练,获取经纬度(x-y)和速度(speed)的类型向量,每个渔船id的经纬度和速度向量取平均作为特征,这个思路和Fasttext比较类似。
大白的分享:

04 APP序列

最近一次是在易观用户性别年龄预测比赛中遇到,这也是一个非典型的NLP比赛,赛题任务需要根据用户手机APP使用序列来对用户的年龄和性别进行分类。
Kaggle知识点:时序数据与Embedding - 图4
在易观这场比赛中,chizhu获得了冠军,我是亚军。这场比赛的核心也是APP序列建模,使用Embedding构建特征。

chizhu在易观的分享:

看到这里,有没有发现本次腾讯赛的赛题也是这个路子。大赛的题目尝试从另一个方向来验证这个假设,即以用户在广告系统中的交互行为作为输入来预测用户的人口统计学属性。
如果你参加了本次腾讯赛,chizhu 的分享可以参考。Coggle数据科学也会持续关注,大家一起学起来~
image.png