出门旅行,订酒店是必不可少的一个环节。住得干净、舒心对于每个出门在外的人来说都非常重要。在线预订酒店让这件事更加方便。当用户在马蜂窝打开一家选中的酒店时,不同供应商提供的预订信息会形成一个聚合列表准确地展示给用户。这样做首先避免同样的信息多次展示给用户影响体验,更重要的是帮助用户进行全网酒店实时比价,快速找到性价比最高的供应商,完成消费决策。酒店聚合能力的强弱,决定着用户预订酒店时可选价格的「厚度」,进而影响用户个性化、多元化的预订体验。为了使酒店聚合更加实时、准确、高效,现在马蜂窝酒店业务中近80%的聚合任务都是由机器自动完成。本文将详细阐述酒店聚合是什么,以及时下热门的机器学习技术在酒店聚合中是如何应用的。Part.1应用场景和挑战1.酒店聚合的应用场景马蜂窝酒旅平台接入了大量的供应商,不同供应商会提供很多相同的酒店,但对同一酒店的描述可能会存在差异,比如:酒店聚合要做的,就是将这些来自不同供应商的酒店信息聚合在一起集中展示给用户,为用户提供一站式实时比价预订服务:下图为马蜂窝对不同供应商的酒店进行聚合后的展示,不同供应商的报价一目了然,用户进行消费决策更加高效、便捷。2.挑战(1)准确性上文说过,不同供应商对于同一酒店的描述可能存在偏差。如果聚合出现错误,就会导致用户在App中看到的酒店不是实际想要预订的:在上图中,用户在App中希望打开的是「精途酒店」,但系统可能为用户订到了供应商E提供的「精品酒店」,对于这类聚合错误的酒店我们称之为「AB店」。可以想象,当到店后却发现没有订单,这无疑会给用户体验造成灾难性的影响。(2)实时性解决上述问题,最直接的方式就是全部采取人工聚合。人工聚合可以保证高准确率,在供应商和酒店数据量还不是那么大的时候是可行的。但马蜂窝对接的是全网供应商的酒店资源。采用人工的方式聚合处理得会非常慢,一来会造成一些酒店资源没有聚合,无法为用户展示丰富的预订信息;二是如果价格出现波动,无法为用户及时提供当前报价。而且还会耗费大量的人力资源。酒店聚合的重要性显而易见。但随着业务的发展,接入的酒店数据快速增长,越来越多的技术难点和挑战接踵而来。Part.2初期方案:余弦相似度算法初期我们基于余弦相似度算法进行酒店聚合处理,以期降低人工成本,提高聚合效率。通常情况下,有了名称、地址、坐标这些信息,我们就能对一家酒店进行唯一确定。当然,最容易想到的技术方案就是通过比对两家酒店的名称、地址、距离来判断是否相同。基于以上分析,我们初版技术方案的聚合流程为:1.输入待聚合酒店A;2.ES搜索与A酒店相距5km范围内相似度最高的N家线上酒店;3.N家酒店与A酒店分别开始进行两两比对;4.酒店两两计算整体名称余弦相似度、整体地址余弦相似度、距离;5.通过人工制定相似度、距离的阈值来得出酒店是否相同的结论。整体流程示意图如下:「酒店聚合流程V1」上线后,我们验证了这个方案是可行的。它最大的优点就是简单,技术实现、维护成本很低,同时机器也能自动处理部分酒店聚合任务,相比完全人工处理更加高效及时。但也正是因为这个方案太简单了,问题也同样明显,我们来看下面的例子(图中数据虚构,仅为方便举例):相信我们每个人都可以很快判断出这是两家不同的酒店。但是当机器进行整体的相似度计算时,得到的数值并不低:为了降低误差率,我们需要将相似度比对的阈值提升至一个较高的指标范围内,因此大量的相似酒店都不会自动聚合,仍需要人工处理。最后,此版方案机器能自动处理的部分只占到约30%,剩余70%仍需要人工处理;且机器自动聚合准确率约为95%,也就是有5%的概率会产生AB店,用户到店无单,入住体验非常不好。于是,伴随着机器学习的兴起,我们开始了将机器学习技术应用于酒店聚合中的探索之旅,来解决实时性和准确性这对矛盾。Part.3机器学习在酒店聚合中的应用下面我将结合酒店聚合业务场景,分别从机器学习中的分词处理、特征构建、算法选择、模型训练迭代、模型效果来一一介绍。3.1分词处理之前的方案通过比对「整体名称、地址」获取相似度,粒度太粗。分词是指对酒店名称、地址等进行文本切割,将整体的字符串分为结构化的数据,目的是解决名称、地址整体比对粒度太粗的问题,同时也为后面构建特征向量做准备。3.1.1分词词典在聊具体的名称、地址分词之前,我们先来聊一下分词词典的构建。现有分词技术一般都基于词典进行分词,词典是否丰富、准确,往往决定了分词结果的好坏。在对酒店的名称分词时,我们需要使用到酒店品牌、酒店类型词典,如果纯靠人工维护的话,需要耗费大量的人力,且效率较低,很难维护出一套丰富的词典。在这里我们使用统计的思想,采用机器+人工的方式来快速维护分词词典:1.随机选取+酒店,获取其名称数据;2.对名称从后往前、从前往后依次逐级切割;3.每一次切割获取切割词且切割词的出现频率+1;4.出现频率较高的词,往往就是酒店品牌词或类型词。上表中示意的是出现频率较高的词,得到这些词后再经过人工简单筛查,很快就能构建出酒店品牌、酒店类型的分词词典。3.1.2名称分词想象一下人是如何比对两家酒店名称的?比如:A:7天酒店(酒仙桥店)B:如家酒店(望京店)首先,因为经验知识的存在,人会不自觉地进行「先分词后对比」的判断过程,即:7天---如家酒店---酒店酒仙桥店---望京店所以要想对比准确,我们得按照人的思维进行分词。经过对大量酒店名称进行人工模拟分词,我们对酒店名称分为如下结构化字段:着重说下「类型前2字」这个字段。假如我们需要对如下2家酒店名称进行分词:酒店1:龙门南昆山碧桂园紫来龙庭温泉度假别墅酒店2:龙门南昆山碧桂园瀚名居温泉度假别墅分词效果如下:我们看到分词后各个字段相似度都很高。但类型前2字分别为:酒店1类型前2字:龙庭酒店2类型前2字:名居这种情况下此字段(类型前2字)具有极高的区分度,因此可以作为一个很高效的对比特征。3.1.3地址分词同样,模拟人的思维进行地址分词,使之地址的比对粒度更细更具体。具体分词方式见下图:下面是具体的分词效果展示如下:小结分词解决了对比粒度太粗的缺点,现在我们大约有了20个对比维度。但对比规则、阈值怎么确定呢?人工制定规则、阈值存在很多缺点,比如:1.规则多变。20个对比维度进行组合会出现N个规则,人工不可能全部覆盖这些规则;2.人工制定阈值容易受「经验主义」先导,容易出现误判。3.所以,对比维度虽然丰富了,但规则制定的难度相对来说提升了N个数量级。机器学习的出现,正好可以弥补这个缺点。机器学习通过大量训练数据,从而学习到多变的规则,有效解决人基本无法完成的任务。下面我们来详细看下特征构建以及机器学习的过程。3.2特征构建我们花了很大的力气来模拟人的思维进行分词,其实也是为构建特征向量做准备。特征构建的过程其实也是模拟人思维的一个过程,目的是针对分词的结构化数据进行两两比对,将比对结果数字化以构造特征向量,为机器学习做准备。对于不同供应商,我们确定能拿到的数据主要包括酒店名称、地址、坐标经纬度,可能获得的数据还包括电话和邮箱。1.经过一系列数据调研,最终确定可用的数据为名称、地址、电话,主要是:因为2.部分供应商经纬度坐标系有问题,精准度不高,因此我们暂不使用,但待聚合酒店距离限制在5km范围内;3.邮箱覆盖率较低,暂不使用。4.要注意的是,名称、地址拓展对比维度主要基于其分词结果,但电话数据加入对比的话首先要进行电话数据格式的清洗。最终确定的特征向量大致如下,因为相似度算法比较简单,这里不再赘述:3.3算法选择:决策树判断酒店是否相同,很明显这是有监督的二分类问题,判断标准为:有人工标注的训练集、验证集、测试集;输入两家酒店,模型返回的结果只分为「相同」或「不同」两类情况。·经过对多个现有成熟算法的对比,我们最终选择了决策树,核心思想是根据在不同Feature上的划分,最终得到决策树。每一次划分都向减小信息熵的方向进行,从而做到每一次划分都减少一次不确定性。这里摘录一张图片,方便大家理解:(图源:《机器学习西瓜书》)3.3.1AdaBoostingORGradientBoosting具体的算法我们选择的是Boosting。「三个臭皮匠,顶过诸葛亮」这句话是对Boosting很好的描述。Boosting类似于专家会诊,一个人决策可能会有不确定性,可能会失误,但一群人最终决策产生的误差通常就会非常小。Boosting一般以树模型作为基础,其分类目前主要为AdaBoosting、GradientBoosting。AdaBoosting初次得出来一个模型,存在无法拟合的点,然后对无法拟合的点提高权重,依次得到多个模型。得出来的多个模型,在预测的时候进行投票选择。如下图所示:GradientBoosting则是通过对前一个模型产生的错误由后一个模型去拟合,对于后一个模型产生的错误再由后面一个模型去拟合…然后依次叠加这些模型:一般来说,GradientBoosting在工业界使用的更广泛,我们也以GradientBoosting作为基础。3.3.2XGBoostORLightGBMXGBoost、LightGBM都是GradientBoosting的一种高效系统实现。我们分别从内存占用、准确率、训练耗时方面进行了对比,LightGBM内存占用降低了很多,准确率方面两者基本一致,但训练耗时却也降低了很多。内存占用对比:准确率对比:训练耗时对比:(图源:微软亚洲研究院)基于以上对比数据参考,为了模型快速迭代训练,我们最终选择了LightGBM。3.4模型训练迭代由于使用LightGBM,训练耗时大大缩小,所以我们可以进行快速的迭代。模型训练主要
转载请注明:
http://www.aideyishus.com/lktp/8430.html