本文来自网易云社区

作者:穆学锋

简介:传统的搜索个性化做法是定义个性化的标签,将用户和商品通过个性化标签关联起来,在搜索时进行匹配。传统做法的用户特征基本是离线计算获得,不够实时;个性化标签虽然具有一定的泛化能力,但是其准确性有所不足,不能很好的做精准个性化。本文提出两个创新优化,一是打通实时用户行为的获取流程,并在实时用户流下采用FTRL算法不断的更新用户特征的权重,将用户实时感兴趣的商品加权,达到online training;二是在保证相关性的前提下,采取推荐的思路,避开打个性化标签,结合用户的实时&历史行为,直接预估用户对商品的偏好,并在搜索排序中加权。这两个优化在实际的ABTest结果中表现突出,提升搜索下窄口径UV价值较大,它们都是在用户实时行为的基础上完成的,因此合称为搜索实时个性化模型。

背景

搜索中传统的个性化应用是基于个性化标签来完成的。例如,我们会假设用户在购物时对商品的某些属性有独特的偏好,然后建立属性标签,并基于用户的历史行为构建算法模型将商品上的标签打到用户身上,预估其偏好程度,这就构成了用户在特定类目下对于某属性标签的偏好。模型一旦建立起来,属性标签就构成了一个商品簇,模型的泛化能力会很强。这种方式在用户对某类目的商品行为量巨大时会比较有效,但是一般情况下用户的行为都会比较分散/稀疏,因此模型的准确性一般不高。举个例子,用户A购买了一件有大嘴猴图案的莫代尔T恤,因为是购买行为,是一个表示强偏好的特征,那么模型最后计算出来大概率会显示用户A对于动物图案标签和材质莫代尔标签都有一定的偏好,但实际上呢,可能用户A关心的只是T恤是圆领的。

怎么办呢?一种方法是丰富个性化标签,将领型标签也加入进去,这将是一个很庞大很漫长的profiling构建过程。另一种方法,我们可以转变下思路,用户A对商品B有行为,那么就是A对B有一定的偏爱。因此,我们只要获取用户A所有行为过的商品集合,然后构建模型计算最感兴趣的几个商品,并推给用户。至于,用户是喜欢B的什么特质,什么原因,我们并不用刻画。因为特质太多,我们目前刻画得并不好。

系统框架

要实现我们的思路解决上述的问题,首先得在搜索中获得实时的用户行为流数据。为此,我们设计并实现了如下的系统结构:

从Offline到Nearline再到Online,全方位无死角地获取了用户近期的行为数据,存储到ncr缓存中,行为包括点击、加购、收藏、购买、搜索等等。离线(Offline)任务从hdfs中收集用户在考拉 App端的近期对商品的历史行为数据,计算历史行为特征,每日都dump到缓存中;准实时(Nearline)任务将用户近一小时的行为收集并格式化后也放入NCR缓存;实时(Online)任务直接在Jstorm中解析用户行为日志,梳理需要的行为数据,插入到缓存。这样用户近期的所有行为及其特征都能够在搜索被检索到。

同时,Jstorm在解析用户行为的同时,利用FTRL算法,进行online training,不断的迭代学习用户特征权重;另一方面,离线部分每日会计算一个用户到商品的偏好模型(UserItemPrefer),这两个模型的参数都会存储到NCR中。

用户在考拉APP中对商品的每次行为数据,都会影响FTRL模型和UserItemPrefer模型的参数和特征。当用户来搜索的时候,SR会对NDIR召回的商品集合再重新精排一次,精排时就会从NCR获取个性化标签、UserItemPrefer&ftrl模型的参数,以及用户历史&实时的行为特征,计算一个排序分数。SR按这个分数再加上一些例如无货沉底、重复商品过滤等的业务逻辑,向上层返回排好序的商品列表。用户在当前搜索结果页的行为,都会由这个数据流影响到FTRL模型参数,以及U2I的用户行为特征,从而达到随着用户行为变化,自动学习其个性化偏好的目的。

算法实现

1. FTRL模型的实现

根据用户实时行为,生成相应的特征,使用FTRL模型,实时更新用户的偏好模型。FTRL算法如下:

对算法的两点修正:

  • FTRL在每个特征维度上做梯度下降,随着用户行为的累积,频繁更新的特征权重更新步长越来越小,趋于一个稳定的值,而实际上用户的关注点会随时间变化,累积的特征并不一定产生正向的效果,因此增加了时间维度,记录每个维度特征更新的时间,根据时间进行衰减。

  • FTRL具有比较好的稀疏性,但是用户的实时行为会产生大量的特征,还是会有很多低频特征的权重不为0,保存在用户模型里,一方面使得用户模型太大,另一方面对效果影响也不大,因此,对FTRL输出的特征再进行一轮筛选:1)最近1小时的特征按时间保留TOP100;2)最近12小时的特征按权重保留TOP100;3)所有特征按权重保留TOP100。

2. UserItemPrefer   模型的实现

• 描述:选择点击、加购、收藏、购买等行为构成特征,预估用户对商品偏好程度

•       样本:

–      历史user-goods pair

–      Target:当日搜索是否有点击

•       特征:

–      User-goods pair维度的特征

–      Goods维度的特征

•       机器学习方法:SPARK-LR

•       训练结果:经调试,AUC 0.73

效果展示

1. FTRL模型

  • demo示例:

这是线上某用户的行为序列:   用户首先搜了“拖鞋”,点击了商品1464699 ,翻几页之后又搜索了"melissa "这个品牌,最终购买了商品1511276。

2017-06-04 20:41:48 search 拖鞋 iOS

2017-06-04 20:41:55 click 1464699 iOS

......

2017-06-04 21:05:32 cart_page iOS

2017-06-04 21:05:44 pay 1511276* -

在搜索结果中商品位置的变化,(红框中的是商品1511276):

没有用户实时模型的商品排序:

增加了用户实时模型的商品排序:

  • 测试效果:总共进行两轮迭代,测试时间段分别为:2017-02月初~2017-02月中和2017-05月底~2017-06月初总体增加窄口径UV价值3%

2.  UserItemPrefer   模型

  • 测试方法:搜索内ABTest

  • 测试时间: 2017.05月底~2017.06月初

  • 测试结果:经过11天的线上测试,窄口径UV价值提升2.55%。

3. 补充说明

  • A/B测试:简单来说,就是为同一个目标制定两个方案(比如两个页面、两个算法),让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下用户的使用情况,看哪个方案更符合设计。其实这是一种“先验”的实验体系,属于预测型结论,与“后验”的归纳性结论差别巨大。A/B测试的目的在于通过科学的实验设计、采样样本代表性、流量分割与小流量测试等方式来获得具有代表性的实验结论,并确信该结论在推广到全部流量可信。

  • 关于A/B Test指标增长的说明:各位看官可能觉得增长2%有点微不足道,但对于算法模型来说,已经比较可观了。首先,A/B测试比对的两者是剔除了自然增长、大促等其他因素的,是纯算法带来的增长,比较真实可靠。另外,举个业界的实例:一般淘宝会由几十人组件一个大项目团队,经过一年的算法迭代,在双11大促时拿到5~10%的指标增长。由此可见一斑。

  • UV价值:名词解释,公式上 UV价值=引导的成交额/访问UV,约等于uv转化率*客单价,一般在搜索中所说的引导的成交额指严口径成交额(即点此买此),访问UV是指访问搜索的UV数。因此,以成交额作为考核指标的考拉,采用uv价值更吻合平台kpi。涵义上,UV价值的是指访问搜索的用户的平均价值,是搜索内功的体现。

未来计划

目前来说实时个性化完成了第一版,后续我们会从如下方面进行深入探索。

  1. 将用户偏好商品的相似商品也纳入进来,在搜索时,也择机展示给用户,提升购物效率

  2. 挖掘用户行为序列中的频繁模式,尝试序列模式推荐

参考文献

原文:搜索实时个性化模型——基于FTRL和个性化推荐的搜索排序优化

网易云大礼包:https://www.163yun.com/gift

本文来自网易云社区,经作者穆学锋授权发布

相关文章:
【推荐】 网易云安全DDoS高防全新上线 ,游戏防护实力领先

搜索实时个性化模型——基于FTRL和个性化推荐的搜索排序优化的更多相关文章

  1. 基于Neo4j的个性化Pagerank算法文章推荐系统实践

    新版的Neo4j图形算法库(algo)中增加了个性化Pagerank的支持,我一直想找个有意思的应用来验证一下此算法效果.最近我看Peter Lofgren的一篇论文<高效个性化Pagerank ...

  2. 基于octree的空间划分及搜索操作

    (1)  octree是一种用于管理稀疏3D数据的树形数据结构,每个内部节点都正好有八个子节点,介绍如何用octree在点云数据中进行空间划分及近邻搜索,实现“体素内近邻搜索(Neighbors wi ...

  3. 基于Solr和Zookeeper的分布式搜索方案的配置

    1.1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候 ...

  4. 概率图模型 基于R语言 这本书中的第一个R语言程序

    概率图模型 基于R语言 这本书中的第一个R语言程序 prior <- c(working =0.99,broken =0.01) likelihood <- rbind(working = ...

  5. 机器学习之路:python 网格搜索 并行搜索 GridSearchCV 模型检验方法

    git:https://github.com/linyi0604/MachineLearning 如何确定一个模型应该使用哪种参数? k折交叉验证: 将样本分成k份 每次取其中一份做测试数据 其他做训 ...

  6. (四)Qt实现自定义模型基于QAbstractTableModel (一般)

    Qt实现自定义模型基于QAbstractTableModel 两个例子 例子1代码 Main.cpp #include <QtGui> #include "currencymod ...

  7. 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式

    Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...

  8. ADO.NET实体框架Entity Framework模型-基于元数据解析

           上一篇简单介绍了EF的XML模型结构,在基于xml解析一文中,主要使用xml查询技术Xpath,XQuery来得到实体模型中相应信息的,由于这种方式在数据库庞大,表关系复杂的情况下,有诸 ...

  9. 调参侠的末日? Auto-Keras 自动搜索深度学习模型的网络架构和超参数

    Auto-Keras 是一个开源的自动机器学习库.Auto-Keras 的终极目标是允许所有领域的只需要很少的数据科学或者机器学习背景的专家都可以很容易的使用深度学习.Auto-Keras 提供了一系 ...

随机推荐

  1. ffmpeg最简单的解码保存YUV数据 <转>

    video的raw data一般都是YUV420p的格式,简单的记录下这个格式的细节,如有不对希望大家能指出.   YUV图像通常有两种格式,一种是packet 还有一种是planar    从字面上 ...

  2. 退出telnet 命令

    很多时候 telnet 完就无法退出了,ctrl+c 有时也无法退出 后来找到了正确的命令 ctrl+]  然后在telnet 命令行输入 quit  就可以退出了

  3. PHP - 引用计数

    引用计数以及是否是引用变量,一个神奇的函数,查看当前引用计数: <?php xdebug_debug_zval('a'); 以上例程会输出: a: (refcount=1, is_ref=0)= ...

  4. Spring事务管理API

  5. 正则表达式在java程序中的使用

    package com.boco; import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;im ...

  6. Scala基础:面向对象之对象和继承

    对象 object 相当于 class 的单个实例,通常在里面放一些静态的 field 或者 method:在 Scala 中没有静态方法和静态字段,但是可以使用 object 这个语法结构来达到同样 ...

  7. git远程代码库回滚(webstorm下)

    git远程代码库回滚(webstorm下) 1. 场景 添加了一个文件[file-for-test.js]到git的控制下 进行了三次修改,并分别进行了三次commit,最后进行了一次push git ...

  8. 79. Word Search在字母矩阵中查找单词

    [抄题]: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed ...

  9. 启动redis注意事项

    1.需要修改配置文件 redis.conf 三处 a.将bind 127.0.0.0    修改为  bind 0.0.0.0 b.daemonize no      修改为   daemonize ...

  10. Openssl ec命令

    一.简介 椭圆曲线密钥处理工具 二.语法 openssl ec [-inform PEM|DER] [-outform PEM|DER] [-in filename] [-out filename] ...