applying deep learning to airbnb search

本文原发于公众号:机器学习与推荐系统

这周分享一篇文章:Applying Deep Learning To Airbnb Search,内容如论文标题所示,介绍了爱彼迎如何在自己的搜索工程中应用深度学习。

这篇论文有趣的地方在于,并不是提出一个新颖的算法或模型,而是介绍了爱彼迎在应用深度学习的过程中,发现了哪些有趣且有用的点,进而分享给大家。在此之前,作者表示一直使用 GBDT 进行搜索排序,然而已经陷入了一个瓶颈期,需要深度学习来帮助打破这个瓶颈。

接下来我们一起看看,爱彼迎在应用深度学习的过程中遇到了哪些困难和收获呢?

背景

在爱彼迎的场景中,是作为一个双边市场的交易平台:为房东出租房屋,并且为潜在的租客提供房屋。而大多数情况下,一次订房行为都是从搜索开始的。

搜索排序的第一版往往是手工构建一个打分函数,对爱彼迎而言,在此之后的下一个里程碑就是 GBDT,当 GBDT 的收益难以再进一步时,爱彼迎开始投入了深度学习的怀抱。

除了排序,对整个搜索系统而言,模型需要预测房东愿意接受租客订房的概率,需要预测租客会给 5 星好评的概率等等。

在爱彼迎中,用户往往是搜索->浏览->搜索...->订房,通过多次的搜索与浏览最终实现订房的操作,而这些行为会用来训练数据。训练好的模型再开始进行线上 A/B。

这篇文章的整体结构就是先介绍爱彼迎搜索模型的进化过程,然后是特征工程和系统工程,最后是一些工具和超参的探索。

我个人喜好这篇文章的地方也在于,不同于其它常见的 paper,都是努力讲明自己提出了一个新颖的模型,然后结构是如何,最后实验验证它很优秀。这篇文章重点是告诉大家爱彼迎在搜索上的一些探索与进步,从宏观的角度来为大家展示如何将一个工程逐渐深度化,并且这其中有哪些需要关注的细节。

模型进化

这两幅图分别展示了爱彼迎在搜索中尝试的不同模型,一个是在离线的 NDCG 表现,另外一个则是在线订房的收益。

初步的时候是一个简单的单层 NN 网络,主要是为了跑通整个 pipeline(这和我上篇文章的年度总结中提到的不谋而合)。当完成一个单层网络时,爱彼迎开始逐步优化他们的网络。因为离线指标是 NDCG,所以选择了 lambdarank。

作者在这里给出了一段简要的代码来展示他们的思路:

「Decision Tree/Factorization Machine NN」:除了 lambdaRank,作者表示他们进行了一个模型融合的尝试,将 GBDT,FM 和 NN 结合起来,结构也很直接:

作者表示,虽然将三个模型结合在测试集的指标表现与直接使用神经网络差不多,但是最终列表的头部顺序却大不相同,因此,作者认为模型的融合结合了三类模型的各自优点,但是这里文章中并没有给出进一步的阐述。倒是给了一个参考文献,[我会展示在后面](Ruoxi Wang, Bin Fu, Gang Fu, and Mingliang Wang. 2017. Deep & Cross Network for Ad Click Predictions. In Proceedings of the ADKDD'17 (ADKDD'17). ACM, New York, NY, USA, Article 12, 7 pages.)。

「Deep NN」:接下来就是进入 DNN 时代,作者表示 DNN 就是好使唤。没啥好说的,就是牛逼。作者说他们的初始数据特征都是一些简单的东西,什么价格,设备情况,历史订阅数等,另外还用了两个模型的输出也作为特征喂了进去。

如下图,随着训练数据的增多,训练集和测试集之间的 gap 也逐渐消失:

但是作者表示,不想 DNN 在 CV 领域取得的巨大成功一样(机器和人类的准确度差不多),在当前场景中,人类也无法判断哪些内容是应该正确展示的:毕竟搜索了以后,订不订房子还主要取决于用户的预算和品位风格。

在这里作者表示,要介绍一些其它时候很少有人介绍的东西:一些失败的尝试

失败的模型

成功者千篇一律,失败者却各有千秋。对模型也是有几分相似,作者表示失败的尝试太多了,调两个经典的聊聊:

listing ID

将 item 的交互 ID list 作为特征,直接喂进模型,在搜索,推荐,nlp 等领域都是常见操作,也往往会非常有效,爱彼迎在开始前也是充满了希望。但能写到这里,可见结果肯定是大失所望。

如上图所示,加了 ID 特征和不加 ID 特征,收敛速度以及程度都有很大差异,可见带了 ID 特征的,往往会陷入过拟合。

作者分析了这种现象的可能原因:由于爱彼迎特殊的业务性质导致。

因为在其它领域,比如抖音这种,一个短视频被观看的次数是不受限制;比如在淘宝,一个商品被购买的次数也是不受限制的。而将 ID 的交互记录作为一条特征,本身就需要这样大量的行为记录。但是在爱彼迎,即使最热门的房间,一年也最多被订 365 次。

所以这一条也表明,我们在选择特征时需要充分考虑自己的业务场景,而这是建立在对自己当前业务 sense 的基础上。

多任务学习

考虑到订房这一行为的限制,爱彼迎就开始考虑浏览行为是不受限制的,能不能从浏览行为入手呢?

上图展示了浏览和订阅之间的比例分布,看得出订阅相比于浏览记录要稀疏很多。另一方面,越多的浏览量一般越容易带来订房行为。因此爱彼迎进行了一个多任务学习模型,将订房和浏览时长都作为优化目标。

设计好模型以后,哎,现在可以用 listing ID 了吧。

最后一看,结果不妙,好家伙,这模型净给人展示那些特别贵,或者特个性的房间了,用户的确爱看,浏览时长也的确增加,但是对订房本身的指标没太大帮助呀。

特征工程

这里爱彼迎提出了一些思路,对特征进行处理使其满足某些属性,帮助神经网络可以有效的进行数学运算。

特征正则化

在一开始,作者直接使用了他们以前在 GBDT 中的特征,但是效果不好。追述原因后发现,GBDT 对特征的具体数值不是很关心,主要是关心特征数值之间的相对顺序。但是神经网络对数值是很敏感的。

如果不是同一类的特征,数值范围差异很大,会导致梯度传播误差过大。比如某些太大的值直接使得 ReLU 函数失效,产生梯度消失。

所以对输入的特征,最理想的就是让他们的范围集中在 -1 到 1 之间,且均值为 0。

为此,作者提出了两个正则化的方法:

  • 对服从正态分布的特征,通过 (feature_val − μ)/σ 来转换其分布;

  • 对服从幂律分布的特征,通过 log((1+feature_val) / (1+median)) 来转换其分布。

特征分布

通过上一步可以将特征的分布平滑,可是为什么要做平滑这件事呢?

排查 bug

首先就是样本中的异常特征值,通常是很难直接观察出来的。但是如果样本的特征是平滑的,这个时候做一个分布图出来,就可以很容易看到那些异常的样本特征值。

比如某个地区的房价作为一个特征,如果某条样本误将过去一个月的订房价当做了一天的订房间,那么在特征的分布图中,这个值就会很明显的突起。

有利于模型的泛化能力

神经网络相比于其它机器学习方法,优势之一就是出色的泛化能力,从这个角度,作者进行了分析,提出了特征分布平滑的作用。

上面这幅图分别展示了神经网络的每一层输出的分布情况,可以观察到,最终的输出层分布最为平滑。而且是从输入层开始逐渐越来越平滑。这是不是神经网络具有优秀泛化能力的原因呢?

作者表示,在实际应用中,模型都是通过训练数据来学习一个高维特征空间中的分布。但是在训练的时候,不可能所有的特征组合都被观察到,所以模型训练的过程就是从不平滑的分布中去逐渐插值学习。

这样也可以理解,下层分布越平滑,上层就越可能对看不到的特征进行插值。而最底层自然就是输入层。

另一方面为了验证泛化能力,作者尝试了将所有的价格都 x2,x3,x4等等,结果最终的 NDCG 都是出奇的稳定。

一般来讲,特征平滑是很容易做到的。稍微进行处理就可以轻松的将特征分布迁移到合适且平滑的形式,但是有时候针对某些特征,爱彼迎还是做了一些专门的特征工程去让它们的分布平滑起来。

其中一个例子就是针对用户搜索后展示房子的地理位置,下面这幅图记录了整个过程:一开始是经纬度的分布,明显很不平滑;后面改为距离用户搜索地图中心的距离,再后来又加上了对数函数;最终就得到了一个满足要求的特征分布。

检查特征的完整性

特征的分布如果不平滑,有可能会帮助我们检查特征的完整性(其实某种程度上,我觉得也可以和前面的排查 bug 有些类似)。

作者在这里举了一个例子是用房子的入住天数作为特征,结果发现分布不平滑,如下左图。究其原因是部分房源要求入住的最短时长不同,有的甚至要求最少几个月。

所以作者利用平均入住天数做了一个平滑,就形成了右图的幂律分布。

![image-20210228090023053](/Users/songshiwei/Library/Application Support/typora-user-images/image-20210228090023053.png)

高基特征

前面尝试过 listing ID,但是效果不好。那么爱彼迎还在哪些方面尝试过高基分类特征呢?

这里举了一个例子,就是地理位置,直接利用了谷歌的 s2 地图库。通过将地名和 s2 地图库结合起来,做一个哈希函数,然后得到的哈希值作为一个特征向量,喂进神经网络进行学习。

例如 {”San Francisco”, 539058204} → 71829521

最终的一个应用例子如下:

可以看到这个热力图,当搜索 San Francisco 时,并不是单纯的以这里为热力图中心,直接线性距离发散热度。明显 San Francisco 下方的陆地比旁边的水域邻居更具有热度。

系统工程

这里整体流程可能和大家是比较相似的,线上服务是一个 Java 服务。处理数据用 spark,训练模型用 TensorFlow,数据分析用 Scala 和 Java 等。

这里作者提到几个 trick,可能会对我们有帮助:

protobufs 和数据集

在之前他们用的是 GBDT,数据是 CSV 文件,开始神经网络以后,他们沿用了这套数据格式,将 CSV 转化成 feed_dict 喂进网络。但是发现 GPU 利用率只有 25%。

后来他们使用 protobufs 和数据集,避免了训练时对数据的格式转换,这一步大约带来 17X 的训练加速,并且 GPU 利用率达到 90%。

静态特征

对爱彼迎这种业务而言,一套房子的硬性特征是不会改变的(至少轻易不会改变),比如房子的地理位置,房子的结构,公共设施等。每条训练数据的这些特征不断的加载,是很大的 IO 消耗。

所以爱彼迎直接使用房子的 ID 作为特征,来取代掉这些静态特征,只有当这些信息发生变化时,才会加载进训练。

Java 神经网络库

这里就是简单介绍了一下,他们自己开发了一个 Java 神经网络库。

超参

这一部分也没啥内容 ==!

爱彼迎的结果就是 dropout 效果不明显,作者觉得原因是 dropout 适合那些数据噪音比较大的情况。

再就是初始化权重,他们觉得在 -1 到 1 之间随机,比全部设 0 好。

学习率和 batch size 没调出来啥东西~~~

特征的重要性

这里作者也做了一些分析,我们简单的概括出来就是:

得分拆解

如何知道哪些特征比较重要,哪些特征可以省略呢?作者想到了从最后的得分进行拆解,但是后来得出一个结论,凡是经过了非线性激活函数的特征,根本无法分离出其对最终得分的真正影响,所以这样的拆解都是没有意义的~~

AB 测试

这个显然易见,每次少一个特征,然后去观察性能变化。但是作者说,每次去掉一个特征的影响,甚至都无法和训练中的数据噪音区分出来。

重新排列一部分特征

另外一个思路就是将某类特征的值全部随机化,再来判断性能。这样子这些特征依然生效,但是打乱值后看看它是否会对模型构成影响。这样子的确可以观察到一些特征的重要性。

但是作者提出了几点需要注意的地方:第一,观察的特征需要与其它特征独立,这往往是很难实现的;第二,由于打乱了特征值,所以可能会对模型最终的结果构成影响(比如构建出一些现实生活中不存在的特征组合),进而误导我们的方向。

####结果的特征分析

这里的思路是利用测试集上的结果,将结果排序,分析头部和尾部的特征分布,就可以知道模型在不同的取值范围如何应用这些特征。

考虑了价钱所以头部和尾部的结果对价钱的分布就有所不同,但是浏览时长的特征没有被考虑,分布就很接近。这也是一个去分析特征重要性的方法。

总结

正如文章最后说的一样,他们感觉自己对深度学习在搜索的应用才刚刚开始。

将某项业务从非深度学习模式切换到神经网络上来,并不是直接喂到模型里就完事儿的,需要前期逐步的稳扎稳打,当整个 pipeline 打通,数据,特征工程,系统工程等等都完备了,才是你开始探索模型的时候。

而这个探索的过程,本质上其实考验的还是你对业务的熟悉和理解。

我自己最近也在迁移一项搜索工程,准备将其整个 NN 的链路打通,这篇文章带给我的启发还是多的。不过最主要的核心,其实还是对业务的理解,可以看到上面很多内容,都是可以从爱彼迎本身的业务角度阐释的。

后面还会继续分享一些其它搜索和推荐的文章,欢迎找我探讨学习。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MDA(Model Driven Architecture)是一种用于企业的应用开发方法论。MDA的核心理念是将系统的建模、设计、实现和部署过程从技术细节中解耦,以实现系统的可扩展性和可维护性。 在应用MDA到企业中,首先需要进行系统的建模。通过对企业业务流程、数据模型和需求进行建模,可以将企业系统抽象成一系列模型。这些模型描述了系统的组成部分、功能和行为。建立基于模型的设计,可以使开发人员更加关注系统的业务逻辑,而不是技术实现细节。 然后,通过使用MDA工具和技术,可以自动生成系统的代码和配置文件。这样,开发人员可以避免手动编写繁琐的代码,提高开发效率。MDA中使用的元模型和模板语言可以根据不同的目标平台生成适当的代码。 在企业中应用MDA还可以提高系统的可维护性。通过将系统抽象成模型,可以轻松地对系统进行修改和扩展,而不会影响底层的实现。这使得企业可以更加灵活地应对不断变化的市场需求和业务需求。 此外,应用MDA还可以促进企业的组件化和重用。通过将系统分解成可重用的组件,可以提高软件开发的生产力和质量。组件化还可以使企业能够更好地组织、维护和管理复杂的软件系统。 总之,应用MDA到企业中可以提高系统的可维护性、可扩展性和可重用性。通过将系统建模、自动生成代码和配置文件,可以减少开发时间和成本,并使开发人员能够更专注于业务逻辑。因此,MDA是现代企业应用开发的一种重要方法论。 ### 回答2: MDA(Model Driven Architecture)是一种软件开发方法论,适用于企业级应用程序的开发。MDA的核心理念是将业务逻辑与应用程序的实现相分离,通过使用模型来驱动应用程序的开发过程。 MDA的第一步是创建一个概念模型,该模型描述了企业的业务需求和过程。概念模型包括实体、关系、属性和规则等元素。这些元素帮助开发团队理解企业的运作方式,确定业务需求,并为应用程序开发提供基础。 接下来,使用模型转换工具将概念模型转换为平台无关模型(PIM)。PIM是一个抽象的模型,不依赖于任何具体的技术或平台。它描述了应用程序的结构、行为和交互方式,但不指定编程语言或硬件平台。 在PIM的基础上,使用模型转换工具将其转换为平台相关模型(PSM)。PSM是根据特定的技术和平台生成的模型,如Java、.NET或Android平台。PSM将PIM中的抽象概念转化为具体的编程代码和配置。 最后,通过模型转换工具将PSM转换为最终的运行时代码。这些生成的代码可以在特定的技术和平台上编译和运行,从而实现了基于模型的应用程序开发。 应用MDA到企业级应用程序的开发中,可以提供以下好处: 1. 提高开发效率:通过使用模型驱动的方法,开发人员能够更加专注于业务逻辑的描述和规划,而不必关注具体的技术细节。这能够节省开发时间,提高开发效率。 2. 简化维护和更新:企业级应用程序通常具有复杂的业务逻辑和功能需求。使用模型驱动的方法能够提供更清晰、可维护的代码结构,使得应用程序的维护和更新更加容易。 3. 提高系统的质量和一致性:通过使用MDA,整个应用程序的设计和实现可以基于一个统一的模型。这确保了系统的一致性和质量,并减少了代码错误和漏洞的可能性。 综上所述,将MDA应用到企业级应用程序的开发中,可以提供更高的开发效率、更简化的维护和更新以及更高的系统质量和一致性。这对于企业来说是非常有价值的,可以帮助企业更好地满足业务需求并提升竞争力。 ### 回答3: 将 MDA 应用于企业可以带来许多好处。MDA (Model Driven Architecture,模型驱动架构) 是一种面向模型的软件开发方法论,它将业务需求和系统设计分解为多个层次的模型,并通过模型转换来自动生成代码。 首先,应用 MDA 可以提高软件开发的效率。通过将系统设计分解为模型层次,开发人员可以更清楚地理解业务需求,并根据需求对模型进行调整。随后,可以利用模型转换工具将模型自动转换为可执行的代码,减少了手动编码的工作量,从而快速生成高质量的代码。 其次,应用 MDA 可以增强系统的可维护性和扩展性。由于模型是对系统设计的抽象表示,通过对模型进行修改可以很容易地更新系统的功能和逻辑。而且,由于模型和代码之间的映射关系明确,当需求改变时,只需对模型进行调整,而不需要对现有代码进行大规模的修改。 此外,应用 MDA 还可以促进系统的标准化和重用。通过定义通用的模型和模型规范,可以使开发人员在开发不同系统时具有一致的设计方法和开发框架。同时,可以将常见的模型和模型转换规则作为模型库和模型转换插件进行共享和重用,提高开发效率和代码质量。 最后,应用 MDA 还可以提升系统的可测试性和可靠性。通过使用模型来生成代码,可以快速生成可执行的系统,从而方便地进行测试和验证。此外,通过模型转换过程中的自动化检查和验证,可以发现和修复潜在的设计和实现问题,提高系统的质量和可靠性。 总之,将 MDA 应用于企业可以提高软件开发的效率、增强系统的可维护性和扩展性、促进系统的标准化和重用,并提升系统的可测试性和可靠性。这些优势可以帮助企业更有效地开发和维护软件系统,提高业务的竞争力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值