context-aware recommendation

article/2025/11/1 11:56:35

智能手机的普及让大家随时随地都可接入互联网,而这样的随时随地的应用场景,也让传统推荐技术需要充分考虑,利用这些信息提升推荐的准确性,同时从另外一方面考虑, 这种符合LBS的推荐, 因为有了这些信息后,也能够更加准确。

传统的推荐系统基本上就是根据用户对物品的打分进行推荐, 或者描述为 USER * ITEM -> RATING。 其工作就是去填充一个matrix,matrix的横坐标为item,纵坐标为user,推荐的任务就是根据当前已经获得的该matrix中非空的元素, 去填充该矩阵中没有值得元素,并保证用于填充matrix的模型, 在非空元素上的误差最小。

什么是Context-Aware Recommendation

但在很多场景下, user的rating会受到context的影响, 这里的context在不同的领域会有不同的定义。例如电影推荐,对是否为工作日这样的因素影响会比较大;在LBS应用中,推荐内容是否会被采纳, 会受到地理位置的影响(特别现在移动是个大趋势,后续更多的访问流量都会转向移动),例如手机美团,如果一个人在饭点上美团,则他购买餐馆团购券的概率应该要比夜晚大,而购买离他距离近的餐馆团购券的概率也要比购买距离比较远的团购券大。 这里的地理位置, 时间,就可以看成是context内容。

而在搜索引擎中,例如百度,要增强搜索的个性化(如果我们将搜索也看成推荐问题),那么网民的IP所在地,或者网民之前输入的几个query,都可以看成是context内容。

那context内容如何与传统Recommender技术融合? 这就是推荐技术中的contex-aware recommedation: 结合上下文的推荐。 例如,大家经常会进行团购,而团购中的项目,要数团购饭点的套餐最为划算了,这其中就会直接涉及到上文提到的时间,地点两个上下文因素。举个例子,如果我周末快到吃饭时间进行套餐的团购, 海底捞离我比较远但小肥羊离我比较近,那我还是有可能会考虑离得比较近的小肥羊, 或者离我比较近的海底捞的店。

在我看来,类似于美团, 大众点评这样的生活服务,是最需要Context-Aware Recommendation技术的了(特别是近些年来智能手机的普及,大家很多时间都是用智能手机上网),需要结合用户诸如位置,时间及之前积累的用户信息(user profile)进行推荐。

如何实现context-aware recommendation

一般来说,可以使用以下3类方法,在推荐技术中引入上下文信息:

context-aware-recommendation

  1. Contextual Pre-Filtering
  2. Contextual Post-Filtering
  3. Model-based

Contextual Pre-Filtering

该技术是在数据处理阶段,就使用contextual信息对数据进行处理过滤,之后就可以使用传统的推荐技术进行推荐。假设我们将信息的处理看成是一个漏斗: 在获得候选信息后,逐步根据当前能够获得的信息过滤掉不相关的内容,保留下最相关的内容,则contextual pre-filtering方法就相当于将最严格的信息放在漏斗的最开始,直接过滤掉与用户context不相关的内容。

在实现contextual pre-filtering技术时,需要考虑contextual的表示方式,很多时候可以将这些contextual使用层次信息进行表示,以下是几个例子:

Company: Girlfriend →Friends →NotAlone →AnyCompany;
Place: Theater → AnyPlace;
Time: Saturday →Weekend→ AnyTime.

上边的例子,从左到右越来越泛化。

例如百度关键词搜索推荐系统,推荐地域相关关键词时,如果用户提供了地域信息,例如‘北京’后,在后续的推荐中,就不会考虑‘北京’以外的地域,而北京下属的几个区,都可以作为推荐的候选,这就需要维护一个全国地域term的层次树。 而时间, 关系(上文中的Company)等维度也需要有类似的层次树进行维护。

Contextual Pre Filtering方法优点: 在一开始对contextual信息进行处理后,就可以使用传统方法进行推荐,例如将特定contextual相关的数据过滤出来后,就可以使用传统的按内容推荐,协同过滤等方法进行推荐。 如果是实时的搜索引擎,使用类似于Contextual Pre Filtering的方法, 能够有效地减少后续数据的处理量(相当于建立了一个数据过滤漏斗, 在一开始的阶段即将后续不会用到的数据过滤,减少后续策略的计算量);但推荐系统中如果将没中过contextual信息的数据过滤出来单独训练的话,速度并不会有所提升。

Contextual Post-Filtering

该方式对于数据的处理与传统的推荐方式一致, 区别在于当结果已经推荐出来时, 使用contextual信息对结果进行重新过滤或是重排序。

例如, 对于地域这一维contextual信息,百度关键词搜索推荐(Baidu Keyword Recommender,后续简称KR)中就是用Contextual Post-Filtering方法,例如KR首先使用传统的方法进行推荐,之后在结果返回前,会根据地域对关键词进行排序过滤;又例如,美团的app,在进行餐饮团购推荐是,一开始可以使用传统的推荐算法进行推荐(当然此时就应该根据上下文进行粗过滤,例如对于在北京找餐饮服务的网名, 给他推荐一个上海的海底捞可不是一个好的选择), 当传统推荐算法推荐出结果后, 就可以使用上下文来进行过滤排序了。 例如餐饮服务推荐中国,在其他因素固定时,可以优先推荐离用户地理位置近的item。 最终的结果也不是完全按照时间排序, 时间只是众多考虑因素中的一个因子,例如可以使用另一个CTR模型来预估用户的点击概率, 而网名地理位置离餐馆的远近可以作为一维重要特征(其他特征可

以包含推荐物品与网民兴趣的匹配程度, 该item是否与该网民历史购买能力匹配等)

Contextual Post-Filtering的优点: 该方法的优点和Contextual Pre-Filtering一样,可以使用传统的推荐技术。 但该方法与Contextual Pre-Filtering相比,有一个优点: 最终的过滤排序,都是在推荐算法完成后进行的, 当有新的数据,或是算法接入时,最终的排序过滤标准是可以不做调整,只要在最终排序过滤逻辑前引入新算法的推荐结果即可,另一个优点是,最终出的结果的数量,可以视最终可能被保留下来的结果的数量进行调整, 例如按照严格的contextural信息来过滤,可能最终剩下的结果只有两条,此时如果觉得结果太少,则可以适当放松过滤阈值,或者将接近阈值的结果打上特定标签推荐出来(例如,百度关键词搜索推荐中,如果推荐的结果太少,系统会将一些阈值相对偏低的结果也展现出来,只是结果后边会打上‘结果太少?网民也会这样搜索’);但任何事物都有两面性,Contextual Post-Filtering方法的缺点一开始推荐出来的结果,会在后续直接因为Context不match而直接被过滤掉,这样就白白浪费了在排序过滤前的计算。

在实际应用中,需要根据具体应用选择使用Contextual Pre-Filtering或是Contextual Post-Filtering方法,而更为常见的是,两种实现思路经常会同时在同一系统中出现,仍然以KR中地域属性为例,在进行关键词候选结果选择时(一般称为触发过程),就会使用地域信息对结果进行粗选;在得到候选结果后,会使用地域信息(包括层级地域信息)对关键词进行更精细化的排序过滤。

Contextual-Model

可以理解为传统的Model-based推荐方法, 区别在于在进行模型训练时, 就将Contextual作为特征加入模型进行训练, 该方法的优点是直接可以使用一个模型完成推荐, 缺点在于如果上下文信息维度较多, 会导致训练数据较为稀疏, 同时当结果较差时不容易进行优化,因为众多因素进行了融合,很难指出问题出在什么地方。而Contextual Pre-Filtering和Post-Filtering方法,可以理解为对问题进行了拆解。这样的策略架构,问题定位会相对容易一些。

后记:  前几天看到一个新闻,称美团2013年已经实现盈利。当时看到这个信息的时候还挺震惊的。2011年的时候百团大战时,团购网站都在各种烧钱推广。百度为了让团购网站能够更高效地在凤巢上进行推广(也可以理解为更高效地挣团购网站的钱),设计了无关键词拍卖系统: 团购网站只要提供团购页面(或是团购页面的结构化属性描述),即可在百度上进行推广。但悲剧的是该系统才刚要开发完毕,团购网站的前就已经烧得差不多了, 之后就出现一大批团购网站的倒闭。。。。现在美团居然活得好好的。

同时结合自己做推荐系统的几年,觉得美团和大众点评这样的网站,是最适合加大推荐系统研发投入的: 每个美团/大众点评用户都有自己的ID,也都有自己够买的商品(explicit rating)和自己浏览的网页(implicit rating),同时手机客户端的的位置,时间信息可以作为推荐的context信息增强推荐的准确性。所以如果后续仍想在推荐系统方面做一些工作的话, 美团和大众点评都会是不错的选择。

附上一个index.baidu.com上几个关键词的搜索量变化, 美团的曲线是相当的漂亮!

美团网效果数据

百度关键词工具介绍参见:http://support.baidu.com/product/fc/4.html?castk=24b18bi7062c720d0d596

也可关注我的微博: weibo.com/dustinsea

或是直接访问: http://semocean.com


http://chatgpt.dhexx.cn/article/VVEI4YE1.shtml

相关文章

accept函数_使用函数式接口

像上几章提到的,函数式接口定义且只定义了一个抽象方法。函数式接口很有用,因为抽象方法的签名可以描述Lambda表达式的签名。函数式接口的抽象方法的签名成为函数描述符。所以为了应用不同的Lambda表达式,你需要一套能够描述常见函数描述符的…

accept函数(TCP)

accept函数&#xff08;TCP&#xff09; #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能&#xff1a;阻塞等待客户端的连接请求 sockfd&#xff1a;文件描述符&#…

Context context = getApplicationContext()

使用getApplicationContext 取得的是当前app所使用的application&#xff0c;这在AndroidManifest中唯一指定。意味着&#xff0c;在当前app的任意位置使用这个函数得到的是同一个Context 1、Context概念 其实一直想写一篇关于Context的文章&#xff0c;但是又怕技术不如而误人…

AutoCompleteTextView

自动完成的提供建议的文本 使用方法 //arrays.xml <?xml version"1.0" encoding"utf-8"?> <resources><array name"city_name"><item>Chengdu</item><item>Beijing</item><item>Tianjin<…

http状态码、accept、Content-Type

一、http状态码 &#xff08;1&#xff09;http状态码 1XX&#xff1a;信息&#xff0c;服务器收到请求&#xff0c;需要请求者继续执行操作 2XX&#xff1a;成功&#xff0c;操作被成功接收并处理 3XX&#xff1a;重定向&#xff0c;需要进一步的操作以完成请求 4XX&#xf…

Gated-Attention Readers for Text Comprehension

Gated-Attention Readers for Text Comprehension 文本理解中的门控attention阅读器 code Abstract 本文研究的是完形填空问题式MRC&#xff0c;作者提出的门控注意力阅读器集中了多跳结构和一种新的注意力计算机制&#xff08;基于query嵌入和RNN文档阅读器中间状态之间的…

Html中Input的accept属性

Accept属性规定通过在文件上传提交的服务接受的文件类型 但是accept属性只能适用在Html input类型为文件类型&#xff0c;也就是说其他类型的input accept属性就不适用 我写的这个过滤文件属性是针对于后缀名为.xls的文件&#xff0c;所有的文件只要不是.xls后缀就不显示出来…

ApplicationContext

如果说BeanFactory是Spring的心脏&#xff0c;那么Application就是完整的身躯。ApplicationContext就是由BeanFactory派生出来的。 1、ApplicationContext ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径…

ActionContext

1、ActionContext翻译成中文就是Action的上下文&#xff08;为什么说是上下文&#xff0c;是应为他的生命周期长&#xff0c;和我们的项目的生命周期是相同的&#xff0c;我们很多公共的东西都放在里面&#xff0c;方便存取 &#xff09;&#xff0c;ActionContext是struts2的上…

readonly option is set (add ! to override)错误的解决

在mac电脑或linux系统中经常操作修改某个文件后保存退出出现readonly option is set (add ! to override)。如图&#xff1a; 正常情况下按 A进入编辑模式修改文件后按ESC退出编辑模式&#xff0c;:wq命令保存退出&#xff0c;但经常会遇到以上显示&#xff0c;文件权限只读或者…

ByteBuffer的allocate和allocateDirect

在Java中当我们要对数据进行更底层的操作时&#xff0c;通常是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时常常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; Java代码 public static ByteBuffer allocate(int capacity…

直接内存 直接内存的释放和回收

直接内存 特点 不属于Java虚拟机管理&#xff0c;属于系统内存&#xff1b;属于操作系统&#xff0c;常见于NIO操作时&#xff0c;比如ByteBuffer【】用于数据缓冲区分配回收成本较高&#xff0c;但读写性能高&#xff1b;不受JVM内存回收管理 文件读写过程 java不具备磁盘…

解决The‘Access-Control-Allow-Origin‘ header contains multiple values‘*, ....‘, but only one is allowed

报错内容&#xff1a; Access to XMLHttpRequest at ‘http://www.z…n.com/api/login’ from origin ‘http://z…n.com’ has been blocked by CORS policy: The ‘Access-Control-Allow-Origin’ header contains multiple values ‘*, http://z…n.com’, but only one is …

C++中std::allocator的使用

标准库中包含一个名为allocator的类&#xff0c;允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。 new有一些灵活性上的局限&#xff0c;其中一方面表现在它将内存分配和对象构造组合在了一起。类似的&#xff0c;delete将对象析构和内…

alloc的流程

1⃣️ 2⃣️ 3⃣️ 现在我们看的objc源码都是2.0的版本&#xff0c;之前还有一个1.0的版本 4⃣️ 5⃣️核心方法 最主要的就是最下面三个方法 他的最重要作用就是开辟内存 cls->instanceSize 先计算出需要的内存空间大小这个大小只和对象的成员变量有关 在没有成员变量…

ByteBuffer.allocate()与allocateDirect()的区别

allocate()产生的是HeapByteBuffer的实例, 本质上是一个no direct buffer, allocateDirect()产生的是DirectByteBuffer的实例, 本质是一个direct buffer 主要区别 buffer的创建方式不同, no direct buffer还可以通过封装已存在的byte array来产生执行IO操作时不同, no direct …

ByteBuffer常用方法与分析

目录 目标 常用API 工具方法 演示案例 allocate(int capacity)和allocateDirect(int capacity) put()和get() flip()和hasRemaining() clear() compact() wrap() 总结 目标 掌握ByteBuffer常用方法&#xff0c;分析ByteBuffer对象在切换读写模式的情况下基本属性的变…

allocate与allocateDirect的性能测试

allocate与allocateDirect的性能测试 测试工具JMH测试代码JMH结果结论 测试工具JMH java基准测试框架 测试代码 直接分配系统内存(allocateDirect) -测试申请内存性能JVM堆分配内存(allocate)-测试申请内存性能直接内存-操作-连续二十次添加(allocateDirect)-测试内存操作性能…

ByteBuffer.allocate()与ByteBuffer.allocateDirect()方法的区别

在Java中当我们要对数据进行更底层的操作时&#xff0c;一般是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时经常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; public static ByteBuffer allocate(int capacity) public s…

8、ByteBuffer(方法演示2(allocate堆内存和allocateDirect直接内存))

ByteBuffer&#xff08;方法演示2&#xff08;allocate堆内存和allocateDirect直接内存&#xff09;&#xff09; Allocate&#xff1a;java堆内存:读写效率低&#xff0c;收到gc的影响&#xff08;因为我们的java对象也是存在堆内存的&#xff09; &#xff01;&#xff01;…