机器学习在马蜂窝酒店聚合中的应用初探
出门旅行,订酒店是必不可少的一个环节。住得干净、舒心对于每个出门在外的人来说都非常重要。
在线预订酒店让这件事更加方便。当用户在马蜂窝打开一家选中的酒店时,不同供应商提供的预订信息会形成一个聚合列表准确地展示给用户。这样做首先避免同样的信息多次展示给用户影响体验,更重要的是帮助用户进行全网酒店实时比价,快速找到性价比最高的供应商,完成消费决策。
酒店聚合能力的强弱,决定着用户预订酒店时可选价格的「厚度」,进而影响用户个性化、多元化的预订体验。为了使酒店聚合更加实时、准确、高效,现在马蜂窝酒店业务中近 80% 的聚合任务都是由机器自动完成。本文将详细阐述酒店聚合是什么,以及时下热门的机器学习技术在酒店聚合中是如何应用的。
Part.1 应用场景和挑战
1.酒店聚合的应用场景
马蜂窝酒旅平台接入了大量的供应商,不同供应商会提供很多相同的酒店,但对同一酒店的描述可能会存在差异,比如:
酒店聚合要做的,就是将这些来自不同供应商的酒店信息聚合在一起集中展示给用户,为用户提供一站式实时比价预订服务:
下图为马蜂窝对不同供应商的酒店进行聚合后的展示,不同供应商的报价一目了然,用户进行消费决策更加高效、便捷。
2.挑战
(1) 准确性
上文说过,不同供应商对于同一酒店的描述可能存在偏差。如果聚合出现错误,就会导致用户在 App 中看到的酒店不是实际想要预订的:
在上图中,用户在 App 中希望打开的是「精途酒店」,但系统可能为用户订到了供应商 E 提供的「精品酒店」,对于这类聚合错误的酒店我们称之为 「AB 店」。可以想象,当到店后却发现没有订单,这无疑会给用户体验造成灾难性的影响。
(2) 实时性
解决上述问题,最直接的方式就是全部采取人工聚合。人工聚合可以保证高准确率,在供应商和酒店数据量还不是那么大的时候是可行的。
但马蜂窝对接的是全网供应商的酒店资源。采用人工的方式聚合处理得会非常慢,一来会造成一些酒店资源没有聚合,无法为用户展示丰富的预订信息;二是如果价格出现波动,无法为用户及时提供当前报价。而且还会耗费大量的人力资源。
酒店聚合的重要性显而易见。但随着业务的发展,接入的酒店数据快速增长,越来越多的技术难点和挑战接踵而来。
Part.2 初期方案:余弦相似度算法
初期我们基于余弦相似度算法进行酒店聚合处理,以期降低人工成本,提高聚合效率。
通常情况下,有了名称、地址、坐标这些信息,我们就能对一家酒店进行唯一确定。当然,最容易想到的技术方案就是通过比对两家酒店的名称、地址、距离来判断是否相同。
基于以上分析,我们初版技术方案的聚合流程为:
-
输入待聚合酒店 A;
-
ES 搜索与 A 酒店相距 5km 范围内相似度最高的 N 家线上酒店;
-
N 家酒店与 A 酒店分别开始进行两两比对;
-
酒店两两计算整体名称余弦相似度、整体地址余弦相似度、距离;
-
通过人工制定相似度、距离的阈值来得出酒店是否相同的结论。
整体流程示意图如下:
「酒店聚合流程 V1」上线后,我们验证了这个方案是可行的。它最大的优点就是简单,技术实现、维护成本很低,同时机器也能自动处理部分酒店聚合任务,相比完全人工处理更加高效及时。
但也正是因为这个方案太简单了,问题也同样明显,我们来看下面的例子 (图中数据虚构,仅为方便举例):
相信我们每个人都可以很快判断出这是两家不同的酒店。但是当机器进行整体的相似度计算时,得到的数值并不低:
为了降低误差率,我们需要将相似度比对的阈值提升至一个较高的指标范围内,因此大量的相似酒店都不会自动聚合,仍需要人工处理。
最后,此版方案机器能自动处理的部分只占到约 30%,剩余 70% 仍需要人工处理;且机器自动聚合准确率约为 95%,也就是有 5% 的概率会产生 AB 店,用户到店无单,入住体验非常不好。
于是,伴随着机器学习的兴起,我们开始了将机器学习技术应用于酒店聚合中的探索之旅,来解决实时性和准确性这对矛盾。
Part.3 机器学习在酒店聚合中的应用
下面我将结合酒店聚合业务场景,分别从机器学习中的分词处理、特征构建、算法选择、模型训练迭代、模型效果来一一介绍。
3.1 分词处理
之前的方案通过比对「整体名称、地址」获取相似度,粒度太粗。
分词是指对酒店名称、地址等进行文本切割,将整体的字符串分为结构化的数据,目的是解决名称、地址整体比对粒度太粗的问题,同时也为后面构建特征向量做准备。
3.1.1 分词词典
在聊具体的名称、地址分词之前,我们先来聊一下分词词典的构建。现有分词技术一般都基于词典进行分词,词典是否丰富、准确,往往决定了分词结果的好坏。
在对酒店的名称分词时,我们需要使用到酒店品牌、酒店类型词典,如果纯靠人工维护的话,需要耗费大量的人力,且效率较低,很难维护出一套丰富的词典。
在这里我们使用统计的思想,采用机器+人工的方式来快速维护分词词典:
-
随机选取 100000+酒店,获取其名称数据;
-
对名称从后往前、从前往后依次逐级切割;
-
每一次切割获取切割词且切割词的出现频率+1;
-
出现频率较高的词,往往就是酒店品牌词或类型词。
上表中示意的是出现频率较高的词,得到这些词后再经过人工简单筛查,很快就能构建出酒店品牌、酒店类型的分词词典。
3.1.2 名称分词
想象一下人是如何比对两家酒店名称的?比如:
-
A:7 天酒店 (酒仙桥店)
-
B:如家酒店 (望京店)
首先,因为经验知识的存在,人会不自觉地进行「先分词后对比」的判断过程,即:
-
7 天--->如家
-
酒店--->酒店
-
酒仙桥店--->望京店
所以要想对比准确,我们得按照人的思维进行分词。经过对大量酒店名称进行人工模拟分词,我们对酒店名称分为如下结构化字段:
着重说下「类型前 2 字」这个字段。假如我们需要对如下 2 家酒店名称进行分词:
-
酒店 1:龙门南昆山碧桂园紫来龙庭温泉度假别墅
-
酒店 2:龙门南昆山碧桂园瀚名居温泉度假别墅
分词效果如下:
我们看到分词后各个字段相似度都很高。但类型前 2 字分别为:
-
酒店 1 类型前 2 字:龙庭
-
酒店 2 类型前 2 字:名居
这种情况下此字段 (类型前 2 字) 具有极高的区分度,因此可以作为一个很高效的对比特征。
3.1.3 地址分词
同样,模拟人的思维进行地址分词,使之地址的比对粒度更细更具体。具体分词方式见下图:
下面是具体的分词效果展示如下:
小结
分词解决了对比粒度太粗的缺点,现在我们大约有了 20 个对比维度。但对比规则、阈值怎么确定呢?
人工制定规则、阈值存在很多缺点,比如:
-
规则多变。20 个对比维度进行组合会出现 N 个规则,人工不可能全部覆盖这些规则;
-
人工制定阈值容易受「经验主义」先导,容易出现误判。
所以,对比维度虽然丰富了,但规则制定的难度相对来说提升了 N 个数量级。机器学习的出现,正好可以弥补这个缺点。机器学习通过大量训练数据,从而学习到多变的规则,有效解决人基本无法完成的任务。
下面我们来详细看下特征构建以及机器学习的过程。
3.2 特征构建
我们花了很大的力气来模拟人的思维进行分词,其实也是为构建特征向量做准备。
特征构建的过程其实也是模拟人思维的一个过程,目的是针对分词的结构化数据进行两两比对,将比对结果数字化以构造特征向量,为机器学习做准备。
对于不同供应商,我们确定能拿到的数据主要包括酒店名称、地址、坐标经纬度,可能获得的数据还包括电话和邮箱。
经过一系列数据调研,最终确定可用的数据为名称、地址、电话,主要是:因为
-
部分供应商经纬度坐标系有问题,精准度不高,因此我们暂不使用,但待聚合酒店距离限制在 5km 范围内;
-
邮箱覆盖率较低,暂不使用。
要注意的是,名称、地址拓展对比维度主要基于其分词结果,但电话数据加入对比的话首先要进行电话数据格式的清洗。
最终确定的特征向量大致如下,因为相似度算法比较简单,这里不再赘述:
3.3 算法选择:决策树
判断酒店是否相同,很明显这是有监督的二分类问题,判断标准为:
-
有人工标注的训练集、验证集、测试集;
-
输入两家酒店,模型返回的结果只分为「相同」或「不同」两类情况。
经过对多个现有成熟算法的对比,我们最终选择了决策树,核心思想是根据在不同 Feature 上的划分,最终得到决策树。每一次划分都向减小信息熵的方向进行,从而做到每一次划分都减少一次不确定性。这里摘录一张图片,方便大家理解:
(图源:《机器学习西瓜书》)
3.3.1 Ada Boosting OR Gradient Boosting
具体的算法我们选择的是 Boosting。「三个臭皮匠,顶过诸葛亮」这句话是对 Boosting 很好的描述。Boosting 类似于专家会诊,一个人决策可能会有不确定性,可能会失误,但一群人最终决策产生的误差通常就会非常小。
Boosting 一般以树模型作为基础,其分类目前主要为 Ada Boosting、Gradient Boosting。Ada Boosting初次得出来一个模型,存在无法拟合的点,然后对无法拟合的点提高权重,依次得到多个模型。得出来的多个模型,在预测的时候进行投票选择。如下图所示:
Gradient Boosting 则是通过对前一个模型产生的错误由后一个模型去拟合,对于后一个模型产生的错误再由后面一个模型去拟合…然后依次叠加这些模型:
一般来说,Gradient Boosting 在工业界使用的更广泛,我们也以 Gradient Boosting 作为基础。
3.3.2 XGBoost OR LightGBM
XGBoost、LightGBM 都是 Gradient Boosting 的一种高效系统实现。
我们分别从内存占用、准确率、训练耗时方面进行了对比,LightGBM 内存占用降低了很多,准确率方面两者基本一致,但训练耗时却也降低了很多。
内存占用对比:
准确率对比:
训练耗时对比:
(图源:微软亚洲研究院)
基于以上对比数据参考,为了模型快速迭代训练,我们最终选择了 LightGBM。
3.4 模型训练迭代
由于使用 LightGBM,训练耗时大大缩小,所以我们可以进行快速的迭代。
模型训练主要关注两方面内容:
-
训练结果分析
-
模型超参调节
3.4.1 训练结果分析
训练结果可能一开始差强人意,没有达到理想的效果,这时需要我们仔细分析什么原因导致的这个结果,是特征向量的问题?还是相似度计算的问题?还是算法的问题?具体原因具体分析,但总归会慢慢达到理想的结果。
3.4.2 模型超参调节
这里主要介绍一些超参数调节的经验。首先大致说一下比较重要的参数:
(1) maxdepth 与 numleaves
maxdepth 与 numleaves 是提高精度以及防止过拟合的重要参数:
-
maxdepth : 顾名思义为「树的深度」,过大可能导致过拟合
-
numleaves 一棵树的叶子数。LightGBM 使用的是 leaf-wise 算法,此参数是控制树模型复杂度的主要参数
(2) feature_fraction 与 bagging_fraction
feature_fraction 与 bagging_fraction 可以防止过拟合以及提高训练速度:
-
feature_fraction :随机选择部分特征 (0<feature_fraction <1)
-
bagging_fraction 随机选择部分数据 (0<bagging_fraction<1)
(3) lambda_l1 与 lambda_l2
lambda_l1 与 lambda_l2 都是正则化项,可以有效防止过拟合。
-
lambda_l1 :L1 正则化项
-
lambda_l2 :L2 正则化项
3.5 模型效果
经过多轮迭代、优化、验证,目前我们的酒店聚合模型已趋于稳定。
对方案效果的评估通常是凭借「准确率」与「召回率」两个指标。但酒店聚合业务场景下,需要首先保证绝对高的准确率(聚合错误产生 AB 店影响用户入住),然后才是较高的召回率。
经过多轮验证,目前模型的准确率可以达到 99.92% 以上,召回率也达到了 85.62% 以上:
可以看到准确率已经达到一个比较高的水准。但为保险起见,聚合完成后我们还会根据酒店名称、地址、坐标、设施、类型等不同维度建立一套二次校验的规则;同时对于部分当天预订当天入住的订单,我们还会介入人工进行实时的校验,来进一步控制 AB 店出现的风险。
3.6 方案总结
整体方案介绍完后,我们将基于机器学习的酒店聚合流程大致示意为下图:
经过上面的探索,我们大致理解了:
-
解决方案都是一个慢慢演进的过程,当发现满足不了需求的时候就会进行迭代;
-
分词解决了对比粒度太粗的缺点,模拟人的思维进行断句分词;
-
机器学习可以得到复杂的规则,通过大量训练数据解决人无法完成的任务。
Part 4 写在最后
新技术的探索充满挑战也很有意义。未来我们会进一步迭代优化,高效完成酒店的聚合,保证信息的准确性和及时性,提升用户的预订体验,比如:
-
进行不同供应商国内酒店资源的坐标系统一。坐标对于酒店聚合是很重要的 Feature,相信坐标系统一后,酒店聚合的准确率、召回率会进一步提高。
-
打通风控与聚合的闭环。风控与聚合建立实时双向数据通道,从而进一步提高两个服务的基础能力。
上述主要讲的是国内酒店聚合的演进方案,对于「国外酒店」数据的机器聚合,方法其实又很不同,比如国外酒店名称、地址如何分词,词形还原与词干提取怎么做等,我们在这方面有相应的探索和实战,总体效果甚至优于国内酒店的聚合,后续我们也会通过文章和大家分享,希望感兴趣的同学持续关注。
本文作者:刘书超,交易中心-酒店搜索研发工程师;贺夏龙、康文云,智能中台-内容挖掘工程师。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Microsoft 警告 Windows 用户注意来自 IE 浏览器中的 0day 攻击
微软已经确认,Internet Explorer 中的 0day 漏洞正在被一些人恶意利用。 该漏洞影响所有 Windows 10 版本,Windows 8.1 和最近停产的 Windows7。 微软在 Windows Server 设备上将其评为“中等”,而在 Windows 客户端版本上,其则被评为“关键”。 Internet Explorer 9,Internet Explorer 10和Internet Explorer 11均受该漏洞影响。远程执行代码可以使网络罪犯获得与登录用户相同的权限,从而可以完全控制受感染的设备。 微软解释说,攻击者可以通过精心制作的网站进行攻击。其在一个advisory 中表示:“脚本引擎处理Internet Explorer中内存中的对象的方式中存在一个远程执行代码漏洞。该漏洞可能以一种攻击者可以在当前用户的上下文中执行任意代码的方式来破坏内存。成功利用此漏洞的攻击者可以获得与当前用户相同的用户权限”。 据微软透露,它已经在进行修复,但与此同时,建议用户应用手动解决方法,以防止设备受到攻击。通报中指出,鉴于“Microsoft知道有限的攻击”,因此...
- 下一篇
Spring-cloud微服务实战【三】:eureka注册中心(中)
回忆一下,在上一篇文章中,我们创建了两个springboot项目,并且在consumer项目中通过restTemplate进行HTTP通信,成功访问到了producer提供的接口,思考一下这样的实现方式有什么问题? 1.consumer必须知道producer的IP,才能调用对方的HTTP接口,并且在consumer代码中使用硬编码的方式来访问producer的HTTP接口,代码耦合度高,实现方式不优雅.也许有童鞋会说,我们可以在application.properties配置文件进行配置,那么请看第二个问题. 2.一般来说,生产环境的producer是一个集群,有多个IP,那我consumer该怎么写请求地址?并且假如producer集群的IP变了,consumer应用需要修改配置,重新打包上线.这对于一个高并发访问的生产项目来说是不可接受的.因此,consumer应用需要一种机制,可以在访问producer的时候不需要关心producer的IP,并且该机制还应该提供类似于观察者模式的通知机制,在producer的IP进行变更的时候,及时通consumer,并且还能提供类...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- 设置Eclipse缩进为4个空格,增强代码规范
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6