写点什么

XGBoost 在携程搜索排序中的应用

  • 2019-12-27
  • 本文字数:3285 字

    阅读完需:约 11 分钟

XGBoost在携程搜索排序中的应用

一、前言

在互联网高速发展的今天,越来越复杂的特征被应用到搜索中,对于检索模型的排序,基本的业务规则排序或者人工调参的方式已经不能满足需求了,此时由于大数据的加持,机器学习、深度学习成为了一项可以选择的方式。


携程主站搜索作为主要的流量入口之一,是用户浏览信息的重要方式。用户搜索方式多样、对接业务多样给携程主站搜索(下文简称大搜)带来了许多挑战,如:


  • 搜索方式多样化

  • 场景多样化

  • 业务多样化

  • 意图多样化

  • 用户多样化


为了更好满足搜索的多样化,大搜团队对传统机器学习和深度学习方向进行探索。


说起机器学习和深度学习,是个很大的话题,今天我们只来一起聊聊传统机器学习中 XGBoost 在大搜中的排序实践。

二、XGBoost 探索与实践

聊起搜索排序,那肯定离不开 L2R。Learning to Rank,简称(L2R),是一个监督学习的过程,需要提前做特征选取、训练数据的获取然后再做模型训练。


L2R 可以分为:


  • PointWise

  • PairWise

  • ListWise


PointWise 方法只考虑给定查询下单个文档的绝对相关度,不考虑其他文档和给定查询的相关度。


PairWise 方法考虑给定查询下两个文档直接的相对相关度。比如给定查询 query 的一个真实文档序列,我们只需要考虑任意两个相关度不同的文档直接的相对相关度。相比 PointWise,PairWise 方法通过考虑任意两个文档直接的相关度进行排序,有一定的优势。


ListWise 直接考虑给定查询下的文档集合的整体序列,直接优化模型输出的文档序列,使得尽可能接近真实文档序列。


下面先简单介绍 XGBoost 的应用流程:



XGBoost 是一个优化的分布式梯度增强库,增强树模型,灵活便捷。但对高维度的稀疏矩阵支持不是很好,另外调参确实有点麻烦。

三、特征工程实践

在传统机器学习下,特征工程显的尤为重要,不论后续模型工程做的多好,如果前期的特征工程没有做好,那么训练的结果不会有多好。所以对特征处理的总体逻辑如下:


3.1 前期数据准备

首先,我们需要进行需求分析,就是在什么场景下排序。假设我们需要针对搜索召回的 POI 场景进行排序,那么需要确定几件事情:


  • 数据来源:搜索的数据就是各种 POI,然后需要确定我们有哪些数据可以用来排序,比如最近半年的搜索 POI 的曝光点击数据等;

  • 特征梳理:需要梳理影响 POI 排序的因子,例如查询相关特征、POI 相关特征、用户相关特征等;

  • 标注规则制定:每次搜索召回的每个 POI,会有曝光和点击数据,简单点,比如:我们可以将曝光位置作为默认标注分,当有点击,就将标注分在原来的基础上加一;

  • 数据埋点/数据抽取:这是两种方式,可以根据实际需求进行选择;

  • 数据埋点:可以在线上实时生成特征,然后进行日志埋点,离线分析的时候可以直接从日志中拉取即可,这种方式,需要提前进行埋点。

  • 数据抽取:可以通过大数据平台拉取历史数据,然后进行离线计算抽取所需特征,这种方式虽然慢点,但是可以拉取历史数据进行分析。

3.2 特征处理

前期的数据准备工作完成了,接下来可以开始看看数据质量了。


  • 查看缺失值:绝大多数情况下,我们都需要对缺失值进行处理;

  • 特征归一化处理:监督学习对特征的尺度非常敏感,因此,需要对特征归一化用来促进模型更好的收敛;

  • 噪声点处理:异常的数据会影响模型预测的正确性;

  • 特征连续值分析:分析特征的值分布范围是否均匀;

  • 特征之间的相关性分析;



通过连续值特征可以分析每个特征值的大致分布范围,有利于对相关特征进行数据补充或者重新筛选。



通过特征相关性的分析,如上我们看到几个特征之间有很高的相关性,那么可以帮助我们做特征组合或者特征筛选等等方面决策。

四、模型工程实践

4.1 评估指标制定

在搜索业务中,考虑的有以下两种情况:


  • 看重用户搜索的成功率,即有没有点击;

  • 看重页面第一屏的曝光点击率;


在文章开头提到的 L2R 的三种分类中,我们在 XGBoost 参数 objective 配置“rank:pairwise”,同时使用搜索系统常用的评估指标 NDCG (Normalized Discounted Cumulative Gain) 。


def _to_list(x):    if isinstance(x, list):        return x    return [x]
def ndcg(y_true, y_pred, k=20, rel_threshold=0): if k <= 0: return 0 y_true = _to_list(np.squeeze(y_true).tolist()) y_pred = _to_list(np.squeeze(y_pred).tolist()) c = list(zip(y_true, y_pred)) random.shuffle(c) c_g = sorted(c, key=lambda x: x[0], reverse=True) c_p = sorted(c, key=lambda x: x[1], reverse=True) idcg = 0 ndcg = 0 for i, (g, p) in enumerate(c_g): if i >= k: break if g > rel_threshold: idcg += (math.pow(2, g) - 1) / math.log(2 + i) for i, (g, p) in enumerate(c_p): if i >= k: break if g > rel_threshold: ndcg += (math.pow(2, g) - 1) / math.log(2 + i) if idcg == 0: return 0 else: return ndcg / idcg
复制代码

4.2 初始模型训练

前期通过基础的模型训练,可以初步得出一些初始参数和相关特征的重要度等相关信息。


train_dmatrix = DMatrix(x_train, y_train)valid_dmatrix = DMatrix(x_valid, y_valid)test_dmatrix = DMatrix(x_test)
train_dmatrix.set_group(group_train)valid_dmatrix.set_group(group_valid)test_dmatrix.set_group(group_test)
params = {'objective': 'rank:pairwise', 'eta': 0.5, 'gamma': 1.0, 'min_child_weight': 0.5, 'max_depth': 8,'eval_metric':'ndcg@10-','nthread':16}xgb_model = xgb.train(params, train_dmatrix, num_boost_round=1000, evals=[(valid_dmatrix, 'validation')])
复制代码



import pandas as pd print('特征名称', '特征权重值')feature_score = xgb_model.get_fscore()pd.Series(feature_score).sort_values(ascending=False)
复制代码


4.3 模型调优五部曲

通过上述基础的模型训练,我们可以得出相关的初始参数,进入到五部曲环节,XGBoost 参数调节基本为五个环节:


  • Step 1:选择一组初始参数;

  • Step 2:改变 max_depth 和 min_child_weight;

  • Step 3:调节 gamma 降低模型过拟合风险;

  • Step 4:调节 subsample 和 colsample_bytree 改变数据采样策略;

  • Step 5:调节学习率 eta;


例如我们在通过 step1,可以观察弱分类数目的大致范围,看看模型是过拟合还是欠拟合。



通过 step2 调整树的深度和节点权重,这些参数对 XGBoost 性能影响最大,我们简要概述他们:


  • max_depth:树的最大深度。增加这个值会使模型更加复杂,也容易出现过拟合,深度 3-10 是合理的;

  • min_child_weight:正则化参数。如果树分区中的实例权重小于定义的总和,则停止树构建过程。


可以通过网格搜索发现最佳结果,当然也可以通过其他方式。



我们看到,从网格搜索的结果,分数的提高主要是基于 max_depth 增加。min_child_weight 稍有影响的成绩,但是 min_child_weight = 6 会更好一些。

4.4 模型离线评估

通过调优五部曲,训练,生成最终的模型之后,就要进入离线评估阶段。离线拉取线上生产用户的请求,模拟生产,对模型预测的结果进行检验,根据在之前评估指标制定环节所提到的用户点击率和第一屏曝光点击率,比对线上用户点击产品的位置和模型预测的位置,同时对比两者之间的第一屏曝光点击率。

4.5 模型预测

通过 AB 实验,对模型进行线上预测,实时监测效果评估,方便之后的迭代和优化。

五、总结与展望

  • 对于传统的机器学习,最重要的一步是要做好需求分析,评估这种算法是否能有效解决该问题,否则得不偿失;

  • 前期的特征工程非常关键。通过多次的摸索发现,特征没有选取好,或者数据覆盖不全,标注没做好,导致后续模型不论怎么调优,都无法达到预定的效果;

  • 选定目标后,可以先尝试一些优秀的开源工具、优秀的数据分析工具。直观的图表能帮助你做更好的决策,优秀的算法库,能避免重复造轮子;

  • 单一的算法无法满足搜索排序应用场景,多模型融合以及深度学习方向需要做更深入的探索与实践;


作者介绍


曹城,携程搜索部门高级研发工程师,主要负责携程搜索的个性化推荐和搜索排序等工作。


本文转载自公众号携程技术(ID:ctriptech)。


原文链接


https://mp.weixin.qq.com/s/X4K6UFZPxL05v2uolId7Lw


2019-12-27 14:002948

评论

发布
暂无评论
发现更多内容

中国垂直行业SaaS,这样走可能是新出路

ToB行业头条

智慧园区数字转型下的移动App建设策略

Onegun

移动应用 智慧城市 智慧园区

提交代码「前置处理」,向前一小步,效率提升「亿点点」

极狐GitLab

DevOps 极狐GitLab git hook lefthook 代码前置

让 AI 更简单 人工智能平台 SEAL 携手龙蜥落地达摩院算法能力 | 龙蜥案例

OpenAnolis小助手

开源 操作系统 SEAL 达摩院 龙蜥案例

智能感知编码优化与落地实践

百度开发者中心

人工智能 视频 百度智能云

iOS MachineLearning 系列(4)—— 静态图像分析之物体识别与分类

珲少

北大GPT解题有数学老师内味了,用人话讲难题,从高中数学到高数都能搞定

Openlab_cosmoplat

人工智能 开源社区

深度分享 | API 测试经济学与 API First 践行

Apifox

程序员 前端 接口 后端 API

把“ai模型+低代码”应用在项目管理中,效率翻了好几倍

优秀

AI 低代码

在企业内容城池边,它建立起一支保卫军

ToB行业头条

构建云边端一体的分布式云架构,软硬结合驱动边缘计算创新场景

百度开发者中心

云计算 存储 边缘云

如何开发一个小程序自定义组件

Onegun

小程序 前端 小程序组件

手势识别:让你的手成为计算机的新界面

来自四九城儿

HarmonyOS Codelabs最新参考

坚果

OpenHarmony 三周年连更

行业分析| 视频监控——AI自动巡检

anyRTC开发者

人工智能 音视频 视频监控 自动巡检

面试还不懂JVM性能调优,看这篇文章就够了!

程序员小毕

程序员 面试 后端 JVM jvm调优

世界读书日特辑 | 华为阅读深耕精品书,让读书变得赏心“悦目”

最新动态

走进社区客户端测试 | 得物技术

得物技术

测试

视频大文件传输的演变:从“卷轴男孩”到自动化

镭速

知名直播App被苹果商店下架,或涉及侵权问题

HIFIVE音加加

ios iphone 软件开发

乌合之众再次上演,打工人将被AI一键淘汰?

引迈信息

人工智能 AI 低代码 AIGC ChatGPT

您有一份直播回放待查收!

BinTools图尔兹

直播回放 版本发布

九科信息流程挖掘产品bit-Miner即将开放面向对象流程挖掘能力

九科Ninetech

流程挖掘

MobTech MobLink|引流统计一站式服务

MobTech袤博科技

“精准测试” 在商家地址专项的探索 | 得物技术

得物技术

给广场舞大妈讲讲什么是大语言模型!

FN0

AIGC

vue 入门知识点有哪些?

海拥(haiyong.site)

三周年连更

烟雾弹?突然转变?如何看待微软发声:中国是主要的对手

加入高科技仿生人

人工智能 AI 数智化 ChatGPT

MegEngine 使用小技巧:量化

MegEngineBot

量化 MegEngine

selenium源码通读·10 |webdriver/common/proxy.py-Proxy类分析

Python 测试 自动化测试 源码剖析 selenium

向量嵌入:AutoGPT的幻觉解法?

OneFlow

XGBoost在携程搜索排序中的应用_大数据_曹城_InfoQ精选文章