一、问题引入
项目链接:
https://www.kaggle.com/c/crowdflower-search-relevance
解决方案:
https://github.com/ChenglongChen/Kaggle_CrowdFlower
问题描述:
求解两个字段【搜索关键词】和【完整的产品说明和HTML格式标记】之间的相关度,实际上是解决一个搜索算法的问题,决定当一个用户搜索某商品时,以怎样的顺序对搜索结果进行排序。
数据描述:
train.csv - 训练数据集包括:
id:产品ID
查询:使用的搜索词
product_description:完整的产品说明以及HTML格式标记
median_relevance:3个评分者的中位数相关性得分。 该值是1到4之间的整数。
relevant_variance:评分者给出的相关性分数的变化。
test.csv - 测试数据集包括
id:产品ID
查询:使用的搜索词
product_description:完整的产品说明以及HTML格式标记
解决方案:
数据预处理:对原始文本进行清洗,包括去除HTML标记/单词替换/词干提取
特征工程:属性特征/距离特征/基于分组的统计特征等
模型融合:融合了XGBoost/随机森林/Ridge /神经网络等模型,单个效果最好的是XGBoost
输出:得到结果
二、数据预处理
由于python版本不同和系统不同,Windows下运行需要注意的几个地方:
preprocess.py
import cPickle 改为import dill as cPickle
dill模块下载地址:https://github.com/uqfoundation/dill
python安装dill模块教程:https://blog.youkuaiyun.com/taogeanton/article/details/80021831
dfTrain = pd.read_csv(config.original_train_data_path).fillna("") 改为 dfTrain = pd.read_csv(config.original_train_data_path,engine = 'python').fillna("")
从https://www.kaggle.com/c/crowdflower-search-relevance/data下载全部三个数据包,解压后放在.\Data目录下
中间dfTrain["qid"] = map(lambda q: qid_dict[q], dfTrain["query"])
改为
dfTrain["qid"] = list(map(lambda q: qid_dict[q], dfTrain["query"]))
Nlp_utils.py
最后一行return BeautifulSoup(html)改为return BeautifulSoup(html, "lxml")
genFeat_counting_feat.py
函数preprocess_data内,
token_pattern = re.compile(token_pattern, flags = re.UNICODE | re.LOCALE)
改为
token_pattern = re.compile(token_pattern, flags = re.UNICODE)
我不清楚这样是否改变了程序执行结果,但是不改的话似乎无法运行。
所有map外面加上list,这是因为python3中的map是懒惰的。
genFeat_counting_feat.py
generate_dist_stats_feat函数中if indices_dict.has_key(key)改为if key in indices_dict
Feat_utils.py
dump_feat_name里with open(feat_name_file, "wb") as f改为with open(feat_name_file, "w") as f
数据预处理模块执行流程:
特征提取
预提取模块:
下面的每一个特征提取模块都对每一个交叉验证折和整个训练测试集做过一遍,而且同一折/训练测试集,用的一定是同一个fit。
在上面的处理中,所有特征都只是单独地处理了特征然后保存。
三、模型训练
1.模型创建
Hyperopt使用教程:https://www.jianshu.com/p/35eed1567463
XGBoost调参指南:https://cloud.tencent.com/developer/article/1080593
2.模型增强(融合)
模型融合没有如我想象一样用一些高大上的方法,而是只是用了简单的预测结果投票,只是在中间使用调参工具对投票权重进行了优化。
具体融合的原理和trick: https://mlwave.com/kaggle-ensembling-guide/
四、方案总结
原作者在说明文档中给出了几条经验总结:
- 在自然语言处理中,错误拼写和同义词替换这两类预处理的作用举足轻重。
- 预处理得当时,线性模型比非线性模型(SVR,DNN等)效果甚至还要好。
- 善于融合不同的模型。
- Hyperopt是个大大大大大杀器。
我用了差不多两周时间浅尝辄止地阅读完了整个工程之后的一些心得:
- 特征工程是真滴重要。
- 自动调参工具是真滴好用。
- 实践是检验真理的唯一标准,无论是交叉验证方法、损失函数定义或是其他的什么东西,都要在验证后才能给出较好的答案。
- 多开脑洞,多借鉴他人的经验。
- 这样一个大工程对任何人绝非一朝一夕之工,要有决心、信心和耐心。
除第一张解决方案的整体流程图,其他流程图、思维导图均为自己总结绘制;除附上的一些链接,以及方案总结的前半部分系原文说明文档翻译,其余内容原创。感谢方案原作者,博文所有内容不保留版权,如有需要请任意使用。