关于推荐系统:解密游戏推荐系统的建设之路

作者:vivo 互联网服务器团队- Ke Jiachen、Wei Ling本文从零开始介绍了游戏举荐我的项目的倒退历程,论述了大型项目建设中遇到的业务与架构问题以及开发工程师们的解决方案,描述了游戏举荐我的项目的特点以及业务倒退方向,有着较好的参考与借鉴意义。 一、游戏举荐的背景与意义从信息获取的角度来看,搜寻和举荐是用户获取信息的两种次要伎俩,也是无效帮忙产品变现的两种形式,搜寻是一个十分被动的行为,并且用户的需要十分明确,在搜索引擎提供的后果里,用户也能通过浏览和点击来明确的判断是否满足了用户需要。 然而,举荐零碎承受信息是被动的,需要也都是含糊而不明确的。 举荐零碎的作用就是建设更加有效率的连贯,更有效率地连贯用户与内容和服务,节约大量的工夫和老本。以此背景,游戏举荐零碎由此诞生。 游戏举荐零碎从设计之初就作为游戏散发的平台,向公司内所有次要流量入口(游戏核心、利用商店、浏览器、jovi等)散发游戏,零碎通过各种举荐算法及举荐策略,为用户举荐下载付费志愿较高且兼顾商业价值的游戏,从而为公司带来支出。倒退至明天,该零碎还具备类游戏内容与素材的举荐性能。 二、游戏举荐的初期模型游戏举荐的目标是推出用户想要且兼顾商业价值的游戏,以此来进步业务的支出指标。此处的商业价值是由经营侧通过策略规定去把控的,而用户动向游戏则是通过算法排序失去的,算法排序所须要的特色数据,以及举荐成果的反馈数据则由埋点信息上报以供计算剖析。 因而咱们的模型能够分成四大块: 经营举荐规定配置算法模型训练举荐策略失效 数据埋点上报 模块间的交互如下:在策略失效前,经营会先在配置核心生成对应的配置规定,这些规定会以缓存的模式存储以供举荐高并接口调用。当用户拜访app利用某些特定页面时,其后盾会带着对应的场景信息来申请游戏举荐后盾,举荐后盾依据场景信息映射相干配置(召回,标签,过期,算法等..........)调用算法服务并进行资源排序,最终将举荐的后果反馈给app利用。 app利用在展现举荐页面的同时,也将用户相应的行为数据以及举荐数据的相干埋点进行上报。 三、业务增长与架构演进随着接入零碎带来的正向收益的晋升,越来越多的业务抉择接入游戏举荐零碎,这使得咱们反对的性能日益丰盛。 目前游戏举荐笼罩的场景有分类、专题、榜单、首页、搜寻等;蕴含的策略类型有干涉、打散、资源配比、保量;反对的举荐类型更是丰盛:联运游戏、小游戏、内容素材、举荐理由。 这些丰盛的应用场景使得业务的复杂度老本增长,令咱们在性能,扩展性,可用性上面临着新的挑战,也推动着咱们架构改革。 3.1 熵增环境下的通用组合策略在0 到 1 的过程中,游戏举荐聚焦于进步散发量,这时候思考得更多的是怎么把游戏推出去,在代码实现上应用分层架构来划分执行的业务。 然而在1 到 2 的过程中, 咱们游戏举荐不仅仅举荐游戏,也举荐内容和素材;同时在策略调用上也更加灵便,不同场景其调用的策略是不同的,执行程序也是不同的;更重要的是退出了很多用户个性化业务与动静规定,这些都使得现有业务代码急剧收缩,扩大起来顾此失彼,无从下手。因而咱们急需一个高复用,易扩大,低代码的策略框架去解决这些问题。 如图所示,通用组合策略负责流转的角色有两个acceptor和executor,通信媒介是举荐上下文context。负责执行逻辑的角色有三个matcher,listener和process,它们都有多个不同逻辑的实现类。当申请游戏举荐零碎时,acceptor会先从配置中动静查问策略模板进行匹配,接着listener组件会执行相应的预处理逻辑。解决后acceptor通过上下文context将工作流转给executor处理器。executor再依据配置,将process依据前置条件进行筛选并排列组合,最初埋点返回。 通过这套通用的策略,咱们在实现个别业务的时候,只有扩大具体matcher和process,并在配置核心将场景和解决优先级绑定起来,就能实现大部分的场景开发,这样研发者能够更聚焦于某个逻辑流程的开发,而不必疲于梳理代码,并进行扩大设计。 3.2 多级缓存与近实时策略游戏举荐零碎服务于手机游戏用户,处于整个零碎链路的上游,峰值流量在3W TPS左右 ,是个读远多于写的零碎。“读”流量来自于用户在各种举荐场景,列表、搜寻、下载钱下载后、榜单等,写数据次要来源于经营相干策略的变更,所以咱们面临的一个重大挑战就是如何在保障可用性的前提下应答高频的读申请。 为了保证系统的读性能,咱们采纳了redis + 本地缓存的设计。配置更新后先写mysql,写胜利后再写redis。本地缓存定时生效,应用懒加载的形式从redis中读取相干数据。这种设计能保障最终一致性,软状态时服务集群数据存在短暂不统一的状况,晚期对业务影响不大,能够认为是一个逐渐放量的过程。 晚期原先部署节点较少,整个零碎达到最终一致性的工夫较短,但随着节点减少到数百台,这个工夫就变得不是那么谐和了。 同时随着业务复杂度的减少,经常是多个配置策略决定这一个举荐后果,此时本地缓存的状态极大影响了测试和点检的便当,如果配置更改不能做到立马更新本地缓存,那就要期待漫长的一段时间能力开始验证逻辑。因而,咱们对缓存构造做出了如下的调整: 与先前不同的是,咱们退出音讯队列并通过配置版本号的比对来实现策略的实时更新同步,获得了很好的成果。 3.3 高并服务的垃圾回收解决任何一个java服务都逃离不了FGC的魔咒,高并服务更是如此。很多服务每天两位数的FGC更是粗茶淡饭,显然这对业务的稳定性和服务性能影响是微小的。游戏举荐这边通过一直实际总结了一套较为通用的办法很好地解决了这个问题: 能够看到起初jvm配置较为惯例:1G的年老代,2G的老年代以及一些其余常见的多线程回收的配置,其后果就是每天10次的FGC,YGC单次耗时在100ms,FGC耗时在350 - 400ms。咱们晓得线上接口容忍的范畴个别是200ms以内,不超过300ms,这样显然是不达标的。 通过剖析,咱们发现高并服务的高频FGC来源于这几个方面: 大量的本地缓存(堆内)占据了老年代的空间,大大增加了老年代叠满的频率。高并申请导致了对象的急速生成,年老代空间不足以包容这剧增的对象,导致其未达到存活阈值(15次)就降职至老年代。引入的监控组件为了性能,经常提早 1 - 2 min再将数据上报服务端,导致这部分数据也无奈在年老代被回收。当然这还不是问题的全副,FGC还有个致命问题就是stop the world,这会导致业务长时间无奈响应,造成经济损失。反过来,就算FGC频繁,stop the world 只有1ms,也是不会对业务造成影响的,因而不能单单以FGC的频率来判断jvm服务的gc性能的好坏。通过下面的探讨,咱们在实践中失去了如下的解决方案: 不常变动的缓存(小时级别)移到堆外,以此缩小老年代叠满的根底阈值。变动不那么频繁的缓存(分钟级别)更新的时候进行值比照,如果值一样则不更新,以此缩小老年代的沉积。应用G1回收器:-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=25 -XX:MaxNewSize=3072M -Xms4608M -Xmx4608M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M  ...

February 27, 2023 · 1 min · jiezi

关于推荐系统:推荐系统协同过滤在Spark中的实现

作者:vivo 互联网服务器团队-Tang Shutao 现如今举荐无处不在,例如抖音、淘宝、京东App均能见到举荐零碎的身影,其背地波及许多的技术。 本文以经典的协同过滤为切入点,重点介绍了被工业界宽泛应用的矩阵合成算法,从实践与实际两个维度介绍了该算法的原理,通俗易懂,心愿可能给大家带来一些启发。 笔者认为要彻底搞懂一篇论文,最好的形式就是入手复现它,复现的过程你会遇到各种各样的纳闷、实践细节。 一、 背景1.1 引言在信息爆炸的二十一世纪,人们很容易吞没在常识的陆地中,在该场景下搜索引擎能够帮忙咱们迅速找到咱们想要查找的内容。 在电商场景,现在的社会物质极大丰富,商品目不暇接,品种繁多。消费者很容易挑花眼,即用户将会面临信息过载的问题。 为了解决该问题,举荐引擎应运而生。例如咱们关上淘宝App,JD app,B站视频app,每一个场景下都有举荐的模块。 那么此时有一个幼儿园小朋友忽然问你,为什么JD给你举荐这本《程序员颈椎痊愈指南》?你可能会答复,因为我的职业是程序员。 接着小朋友又问,为什么《Spark大数据分析》这本书排在第6个举荐位,而《Scala编程》排在第2位?这时你可能无法回答这个问题。 为了答复该问题,咱们构想上面的场景: 在JD的电商零碎中,存在着用户和商品两种角色,并且咱们假如用户都会对本人购买的商品打一个0-5之间的分数,分数越高代表越喜爱该商品。基于此假如,咱们将下面的问题转化为用户对《程序员颈椎痊愈指南》,《Spark大数据分析》,《Scala编程》这三本书打分的话,用户会打多少分(用户之前未购买过这3本书)。因而物品在页面的先后顺序就等价于预测用户对这些物品的评分,并且依据这些评分进行排序的问题。 为了便于预测用户对物品的评分问题,咱们将所有三元组(User, Item, Rating),即用户User给本人购买的商品Item的评分为Rating,组织为如下的矩阵模式: 其中,表格蕴含\( m\)个用户和\(n\)个物品,将表格定义为评分矩阵\({\bf{R}}_{m \times n}\),其中的元素\(r_{u,i}\)示意第\(u\)个用户对第\(i\)个物品的评分。 例如,在下面的表格中,用户user-1购买了物品 item-1, item-3, item-4,并且别离给出了4,2,5的评分。最终,咱们将原问题转化为预测红色空格处的数值。 1.2 协同过滤协同过滤,简略来说是利用与用户趣味相投、领有独特教训之群体的爱好来举荐给用户感兴趣的物品。趣味相投应用数学语言来表白就是类似度 (人与人,物与物)。因而,依据类似度的对象,协同过滤能够分为基于用户的协同过滤和基于物品的协同过滤。 以评分矩阵为例,以行方向观测评分矩阵,每一行代表每个用户的向量示意,例如用户user-1的向量为 [4, 0, 2, 5, 0, 0]。以列方向观测评分矩阵,每一列示意每个物品的向量示意,例如物品item-1的向量为[4, 3, 0, 0, 5]。 基于向量示意,类似度的计算有多种公式,例如余弦类似度,欧氏间隔,皮尔森。这里咱们以余弦类似度为例,它是咱们中学学过的向量夹角 (中学只波及2维和3维) 的高维推广,余弦类似度公式很容易了解和应用。给定两个向量\(\mathbf{A}=\{a\_1, \cdots, a\_n\}\)和\(\mathbf{B}=\{b\_1, \cdots, b\_n\}\),其夹角定义如下: \(\cos(\theta)=\frac{\bf{A}\cdot \bf{B}}{{|\bf{A}}|{|\bf{B}}|}=\frac{a\_1 b\_1 + \cdots + a\_n b\_n}{\sqrt{a\_1^2+\cdots a\_n^2}\sqrt{b\_1^2 + \cdots b\_n^2}}\) 例如,咱们计算user-3和user-4的余弦类似度,二者对应的向量别离为 [0, 2, 0, 3, 0, 4],[0, 3, 3, 5, 4, 0] ...

July 25, 2022 · 8 min · jiezi

关于推荐系统:云音乐预估系统建设与实践

作者:小人物1. 什么是预估零碎?    预估零碎的外围工作是实现模型计算,能够认为模型就是一个函数(举例:f(x1, x2)= ax1 + bx2 +c)。其中参数a、b、c是通过模型训练得出的权重值,自变量x1与x2就是特色,模型计算就是应用自变量x1与x2求解的过程。    因而预估框架须要做的是:构造函数输出(特色),计算函数失去后果(模型计算)。即:特色抽取、模型计算。 特色抽取特色是对某个行为相干信息的形象表白。举荐过程中某个行为信息必须转换成某种数学模式能力被机器学习模型所学习。为了实现这种转换,就必须将行为过程中的信息以特色的模式抽取进去。模型计算集成机器学习库,加载机器学习平台训练出的模型,依照模型构造执行既定的矩阵、向量等计算。2. 预估零碎的设计思考2.1 通用计划的局限    业内常见的计划是特色解决服务 + tfserving模型计算服务,这种计划是将特色解决和模型计算分服务部署。在特色数量不大时能够提供较好的反对,但特色数量一旦变多,就会呈现显著的性能问题,次要是因为特色要跨网络(跨过程)传递给底层机器学习库,这样就会带来屡次编解码与内存拷贝,会造成微小的性能开销。 2.2、新零碎的思考依据业务需要,并汲取通用计划存在的优缺点,咱们构建了新的高性能预估零碎,该零碎领导思路是: 高性能:谋求特色抽取与模型计算高性能,提供大规模特色抽取和大规模模型计算的能力。形象与复用:零碎分层设计,分层复用;线上线下特色抽取逻辑复用;特色抽取提出算子概念,建设算子库,实现特色复用。实时化:实现样本采集实时化、模型训练实时化和模型更新实时化。可扩展性:特色抽取提供自定义算子接口,不便自定义算子的实现;模型计算提供集成多种机器学习库的能力。下图展现了云音乐预估零碎架构: 3. 预估零碎的建设过程一个优良的预估零碎须要解决如下三个问题: 如何解决特色和模型的高效迭代?如何解决预估计算的性能问题?有没有机会通过工程伎俩晋升算法成果?3.1 特色与模型的高效迭代3.1.1 零碎分层设计零碎分层设计,仅裸露下层接口层,不同业务间齐全复用中间层和底层实现,较大水平缩小代码开发。 底层框架层:该层提供异步机制、工作队列、session治理、多线程并发调度、通络通信相干的逻辑、内部文件加载与卸载等两头逻辑层:封装查问治理、缓存治理、模型更新治理、模型计算治理等性能下层接口层:依照执行流程提供HighLevel接口,算法在此层实现逻辑下图展现了框架分层设计: 3.1.2 配置化实现模型计算全流程依照执行流程,把处理过程分成三个阶段,别离是:数据查问、特色抽取、模型计算。在框架中对每个阶段进行抽取和封装,并提供配置化描述语言来实现各个阶段的逻辑表白。 (1) 数据查问通过XML配置表名、查问key、缓存工夫、查问依赖等就能实现特色数据的内部查问、解析、缓存全流程。如下所示: <feature_tables> <table name="music-rec-fm_set_action" alias="trash_song" tag="user" key="user_id"/> <table name="music_fm_dsin_user_static_ftr_dpb" alias="u_static" tag="user" key="user_id"/> <table name="alg_song_ua_rt" alias="u_rt_red" tag="user" key="user_id" subkey="1"/> <table name="fm_dsin_song_promoted_info_feature_dpb_mdb" alias="item_promoted" tag="item" key="item_id" cache_time="7200" cache_size="800000" query_type="sync"/> <table name="fm_dsin_song_static_feature_dpb_mdb" alias="item_static" tag="item" key="item_id" cache_time="7200" cache_size="800000" query_type="asyc"/></feature_tables>特色数据查问配置化带来了开发效率的大幅晋升,用几行配置就实现了以往须要大量编码能力实现的特色查问性能。 (2) 特色抽取开发特色抽取库,封装特色抽取算子,开发特色计算DSL语言,通过配置化实现整个特色抽取过程。如下所示: <feature_extract_config cache="true" log_level="3" log_echo="false" version="2"> <fea name="isfollowedaid" dataType="int64" default="0L" extractor="StringHit($item_id, $uLikeA.followed_anchors)"/> <fea name="rt_all_all_pv" dataType="int64" default="LongArray(0, 5)" extractor="RtFeature($all_all_pv.f, 2)"/> <fea name="anchor_all_impress_pv" dataType="int64" default="0" extractor="ReadIntVec($rt_all_all_pv, 0)"/> <fea name="anchor_all_click_pv" dataType="int64" default="0" extractor="ReadIntVec($rt_all_all_pv, 1)"/> <fea name="anchor_all_impress_pv_id" dataType="int64" default="0" extractor="Bucket($anchor_all_impress_pv, $bucket.all_impress_pv)"/> <fea name="anchor_all_ctr_pv" dataType="float" default="0.0" extractor="Smooth($anchor_all_click_pv, $anchor_all_impress_pv, 1.0, 1000.0, 100.0)"/> <fea name="user_hour" dataType="int64" extractor="Hour()" default="0L"/> <fea name="anchor_start_tags" dataType="int64" extractor="Long2ID($live_anchor_index.start_tags,0L,$vocab.start_tags)" default="0L"/></feature_extract_config>特色抽取库的会在上面具体介绍。 (3) 模型计算对模型加载、参数输出、模型计算等进行封装,通过配置化实现模型加载与计算全流程。具体特点如下: 预估框架集成tensorflow core,反对多种模型状态。反对多模型加载,反对多模型交融打分。反对多buf模型更新,主动实现模型预热加载。反对多种格局的参数输出(Example和Tensor),内置Example结构器和Tensor结构器,对外屏蔽简单的参数结构细节,简略易用。扩大多种机器库,例如paddle、gbm等。<model_list> <!-- pb模型,tensor输出,指定out_names --> <id model_name="model1" model_type="pb" input_type="tensor" out_names="name1;name2" separator=";" /> <!-- savedmodel模型,tensor输出,指定out_names --> <id model_name="model2" model_type="mdl" input_type="tensor" out_names="name1;name2" separator=";" /> <!-- savedmodel模型,example输出,指定out_aliases --> <id model_name="model3" model_type="mdl" input_type="example" out_aliases="aliase1;aliase2" separator=";" signature="serving_default" /></model_list>通过上述配置,能够实现模型加载,模型输出结构,模型计算全流程。用几行配置实现了之前须要大量编码能力实现的模型计算性能。 ...

June 15, 2022 · 1 min · jiezi

关于推荐系统:推荐系统知识清单

提纲入门书籍入门教程公开数据集我的项目代码技术博文学术会议应用领域 入门书籍1.《举荐零碎实际》 作者:项亮入门首选。这本书是国内第一本讲举荐零碎的书,能让你疾速晓得如何把学到的理论知识利用到实际,如何将编程能力利用到举荐零碎中去。尽管书中列举的代码存在一些争议,但瑕不掩瑜。强烈推荐!2.《个体智慧编程》(Programming Collective Intelligence)这本书非常适合数学知识相对来说较少但又想深刻该畛域的读者,或有理论我的项目需要但没有足够工夫去深刻理解的实践者。该书的作者十分直观地展现了人工智能和机器学习中的大量经典的算法,更重要的是,作者在展现算法时应用的例子都是互联网中十分有代表性的场景,很多状况下还会联合一些理论经营的Web站点的数据作进一步阐释,深入浅出。与机器学习相干课程联合学习,将会事倍功半。 《举荐零碎 : 技术、评估及高效算法》(Recommender Systems Handbook)作者:Francesco Ricci, Lior Rokach, Bracha Shapira, Paul B. Kantor这本书被很多人称为“枕边书”。全书共有六百多页,目前已订正至第二版,中文译本也曾经发行。对于想把举荐作为钻研方向始终做上来的人来说, 这本书必看!这本书以专题的模式,波及到了举荐零碎相干的方方面面。每个专题都会列出专题中波及到的论文及未来的发展趋势, 具备很好的指导作用,既可作为入门实践导读,又可作为特定问题的材料索引。《举荐零碎》(Recommender Systems: An Introduction)作者:Dietmar Jannach, Markus Zanker, Alexander Felfernig, Gerhard Friedrich这本书内容笼罩较全面,实践绝对简略,不会有太多难懂的公式。这本书最大的长处是对举荐零碎做了一个很好的整顿和概括,简直概括了举荐零碎所波及的每一个模块,为读者上了一堂很好的举荐引擎架构课。看过这本书后,基本上能对举荐零碎有一个清晰地了解和绝对残缺的把控。 Music Recommendation and Discovery作者: Òscar Celma这本书以音乐举荐为内容,对音乐举荐的需要和问题、罕用做法和成果评估做了一个大体的介绍,对于成果评测局部的内容值得细读。 Word Sense Disambiguation: Algorithms and Applications这本书全面探索了词义消歧这一问题,并对重要的算法、形式、指标、后果、哲学问题和利用也有涉猎,并有这个畛域的权威学者对本畛域的历史及倒退所做的较为全面的综述。如果波及到关键词举荐或文本举荐, 能够查阅这本书。入门教程明尼苏达大学举荐零碎课程该课程由明尼苏达大学公布,共蕴含五个课程,别离为:举荐零碎导入、最近邻协同过滤、举荐零碎评估、矩阵合成、举荐零碎的成就,对入门的同学来说或者会有帮忙。 公开数据集参考原文 我的项目代码参考原文 技术博文参考原文 学术会议参考原文 应用领域图书影音:Netflix、Youtube、MovieLens、豆瓣、网易云音乐新闻资讯:Google News、今日头条、知乎、Hulu人际社交:Facebook、Twitter、微博、人人网游览出行:Wanderfly、TripAdvisor、蚂蜂窝、去哪儿电商批发:亚马逊、淘宝、天猫、京东

April 27, 2022 · 1 min · jiezi

关于推荐系统:全局视角系统学习推荐系统实战中提升竞争力吾爱学习无mi

download:全局视角零碎学习《举荐零碎》,实战中晋升竞争力一道题目看到一个很乏味的题目:实现一个办法,反对链式调用。 lazyman.lazy('Lisa').sleep(3).sleepFirst(4).eat('lunch');// 4s后输入:Sleep Afater 4// 输入:I'm Lisa// 3s后输入:Sleep After 3// 输入:I'm eat lunch解法话不多说,间接上代码:class LazyMan { callbacks = []; constructor() { this.next(); } next() { setTimeout(() => { const firstFn = this.callbacks.shift(); firstFn && firstFn(); }, 0); } lazy(name) { this.callbacks.push(() => { console.log(`Hi, I'm ${name}`); this.next(); }); return this; } sleep(time) { this.callbacks.push(() => { setTimeout(() => { console.log(`Sleep after ${time}`); this.next(); }, time * 1000); }); return this; } sleepFirst(time) { this.callbacks.unshift(() => { setTimeout(() => { console.log(`Sleep after ${time}`); this.next(); }, time * 1000); }); return this; } eat(item) { this.callbacks.push(() => { console.log(`I am eat ${item}`); this.next(); }); return this; }}const lazyman = new LazyMan();lazyman.lazy('Lisa').sleep(3).sleepFirst(4).eat('lunch');题解剖析这个题目,首先要知道如何实现链式调用,就是设置一个类,类中申明的办法的结尾最初都会从新返回该类实例的援用,这样就可能链式调用了。 ...

March 16, 2022 · 1 min · jiezi

关于推荐系统:推荐系统评测指标

一. 评测指标用户满意度、预测准确度、覆盖率、多样性、 新颖性、惊喜度、信任度、实时性、健壮性、商业指标 1. 用户满意度满意度是评测举荐零碎的最重要指标,只能通过用户考察或者在线试验取得,次要是通过考察问卷的模式,须要从不同的侧面询问用户对后果的不同感触 2. 预测准确度标是最重要的举荐零碎离线评测指标,通过离线试验计算 def Recall(train, test, N): hit = 0 all = 0 for user in train.keys(): tu = test[user] rank = GetRecommendation(user, N) for item, pui in rank: if item in tu: hit += 1 all += len(tu) return hit / (all * 1.0)def Precision(train, test, N): hit = 0 all = 0 for user in train.keys(): tu = test[user] rank = GetRecommendation(user, N) for item, pui in rank: if item in tu: hit += 1 all += N return hit / (all * 1.0) 1. 评分预测准确度个别通过均方根误差(RMSE)和均匀绝对误差(MAE)计算,那么RMSE的定义为: ...

March 5, 2022 · 2 min · jiezi

关于推荐系统:推荐系统入门笔记二-推荐算法

一. 协同过滤举荐算法(基于邻域的算法)1. 算法分类基于用户的协同算法: 跟你爱好类似的人喜爱的货色你也很有可能喜爱基于物品的协同算法: 跟你喜爱的货色类似的货色你也很有可能喜爱1.1 实现协同过滤举荐有以下几个步骤:找出最类似的人或物品:Top-N 类似的人或物品通过计算两两的类似度来进行排序,即可找出TOP-N类似的人或物品依据类似的人或物品产生举荐后果利用TOP-N后果生成初始举荐后果,而后过滤掉用户曾经有过记录的物品或明确示意不感兴趣的物品1.2 基于用户的协同算法基于用户的协同过滤算法是举荐零碎中最古老的算法 1.2.1 根底算法当一个用户A须要个性化举荐时,能够先找到和他有类似趣味的其余用户,而后把那些用户喜爱的、而用户A没有据说过的物品举荐给A。这种办法称为基于用户的协同过滤算法。用户的协同过滤算法次要包含两个步骤: 找到和指标用户趣味类似的用户汇合找到这个汇合中的用户喜爱的,且指标用户没有据说过的物品举荐给指标用户步骤(1)的要害就是计算两个用户的趣味类似度,协同过滤算法次要利用行为的类似度计算趣味的类似度 ,给定用户u和用户v,令N(u)示意用户u已经有过正反馈的物品汇合,令N(v) 为用户v已经有过正反馈的物品汇合。那么,咱们能够通过如下的Jaccard公式简略地计算u和v的趣味类似度:$$W_{uv}=\frac{|N(_u)\cup N(_v)|}{|N(_u)\cap N(_v)|}$$或者通过余弦类似度计算:$$ W_{uv}=\frac{|N(u)\cap N(_v)|}{\sqrt{|N(_u)||N(_v)}}$$计算案例: Jaccard 公式计算:$$\frac{|\{a,b,d\}\cap\{a,c\}}{|\{a,b,d\}\cup\{a,c\}|}$$后果:$$\frac{\{a\}}{\{a,b,c,d\}}=\frac{1}{4}$$余弦类似度计算:$$\frac{|\{a,b,d\}\cap\{a,c\}|}{\sqrt{|\{a,b,d\}||\{a,c\}|}}=\frac{1}{\sqrt{6}}$$同理:$$W_{AC}=\frac{|\{a,b,d\}\cap\{b,e\}|}{\sqrt{|\{a,b,d\}||\{b,e\}|}}=\frac{1}{\sqrt6}$$$$W_{AD}=\frac{|\{a,b,d\}\cap\{c,d,e\}|}{\sqrt{|\{a,b,d\}||\{c,d,e\}|}}=\frac{1}{3}$$1.2.1 算法实现jaccard 算法: def jaccard(train): W=dict() # 计算两两用户之间的类似度 for u in train: for v in train: # 如果是同一个用户跳过 if u==v: continue # 两个用户点击物品的交加 cap=train[u]&train[v] # 两个用户点击物品的并集 cup=train[u]|train[v] # 两个用户的类似度 W[u,v]=len(cap)/len(cup) return W

November 9, 2021 · 1 min · jiezi

关于推荐系统:推荐系统入门笔记一-推荐系统简介和架构

一.举荐零碎简介们逐步从信息匮乏的时代走入了信息过载,举荐零碎就是解决信息消费者,如何从大量信息中找到本人感兴趣的信息是一件十分艰难的事件,作为信息生产者, 如何让本人生产的信息怀才不遇这一矛盾的重要工具,举荐零碎的工作就是分割用户和信息,一方面帮忙用户发现对本人有价值的信息 1.解决信息过载的计划分类目录笼罩大量热门⽹站。Hao123 Yahoo索引擎须要用户被动提供精确的关键词,通过搜索词明确需要。Google Baidu举荐零碎不须要用户提供明确的需要,而是通过剖析用户的历史行为给用户的趣味建模,给⽤户举荐能够满⾜他们趣味和需要的信息。举荐零碎和搜索引擎比照 搜寻举荐行为形式被动被动用意明确含糊个性化弱强流量散布马太效应长尾效应指标疾速满足继续服务评估指标扼要简单马太效应:即所谓强人更强,弱者更弱的效应长尾效应:从需要的角度来看,大多数的需要会集中在头部,而这部分咱们能够称之为风行,而散布在尾部的需要是个性化的,零散的小量的需要。而这部分差异化的、大量的需要会在需要曲线下面造成一条长长的“尾巴”,而所谓长尾效应就在于它的数量上,将所有非风行的市场累加起来就会造成一个比风行市场还大的市场。 2. 什么是举荐零碎没有明确需要的用户拜访了咱们的服务, 且服务的物品对用户形成了信息过载, 零碎通过剖析用户历史行为对物品进行排序,并将排在后面的物品展现给用户,这样的零碎就是举荐零碎 3. 举荐零碎的作用高效连贯用户和物品, 发现长尾商品留住用户和内容生产者, 实现商业指标4. 个性化举荐的两个条件存在信息过载用户大部分时候没有特地明确的需要5. 举荐系统分类社会化举荐(即让好友给本人举荐物品)基于内容的举荐(通过剖析用户已经看过的电影找到用户喜爱的演员和导演)基于协同过滤(找到和本人历史趣味类似的一群用户,看看他们最近在看什么电影)基于风行度的举荐 查看票房排行榜6.举荐零碎和Web我的项目的区别web我的项目: 解决简单逻辑 解决高并发 实现高可用 为用户提供稳固服务, 构建一个稳固的信息流通的服务,对后果有确定预期举荐零碎: 谋求指标增长, 留存率/浏览工夫/GMV (Gross Merchandise Volume电商网站成交金额)/视频网站VV (Video View),后果是概率问题7.举荐零碎的应用领域1. 电子商务电子商务网站是个性化举荐零碎的一大应用领域,。驰名的电子商务网站亚马逊是个性化举荐零碎的踊跃利用者和推广者 2. 电影和视频网站该畛域胜利应用举荐零碎的一家公司就是Netflix 3. 个性化音乐电台Pandora(做音乐基因工程的我的项目,次要基于内容)次要基于内容,对歌曲的不同个性(比方旋律、节 12 第 1 章 好的举荐零碎 奏、编曲和歌词等)进行标注,这些标注被称为音乐的基因,Pandora会依据专家标注的基因计算歌曲的类似度,并给用户举荐和他之前喜爱的音乐在基因上类似的其余音乐Last.fm记录了所有用户的听歌记录以及用户对歌曲的反馈,在这一根底上计算出不同用户在歌曲上的爱好类似度,从而给用户举荐和他有类似听歌喜好的其余 用户喜爱的歌曲。Last.fm没有应用专家标注,而是次要利用用户行为计算歌曲的类似度豆瓣电台4. 社交网络互联网最激动人心的产品莫过于以Facebook和Twitter为代表的社交网络应用 5.个性化浏览Google Reader,鲜果网,Zite和 Flipboard(挪动设施) 6. 基于地位的服务在中关村晃荡时,肚子饿了,关上手机,发现下面给你举荐了几家中关村不错的饭馆,价格、 环境、服务、口味都如你所愿,基于地位给用户举荐离他近的且他感兴趣的服务,用户就更有可能去生产 7. 个性化邮件通过剖析用户浏览邮件的历史行为和习惯对新邮件进行从新排序,从而进步用户的工作效率 8 个性化广告即如何将广告投放给它的潜在客户群,个性化广告投放和广义个性化举荐的区别是,个性化举荐着重于帮忙用户找到可能令他们感兴趣的物品,而广告举荐着重于帮忙广告找到可能对它们感兴趣的用户 二. 举荐零碎的架构1. 举荐零碎的因素UI 和 UE(前端界面)数据 (Lambda架构)业务知识举荐算法2. 举荐零碎架构2.1 举荐零碎整体架构 2.2 大数据Lambda架构由Twitter工程师Nathan Marz(storm我的项目发起人)提出,Lambda零碎架构提供了一个联合实时数据和Hadoop事后计算的数据环境和混合平台, 提供一个实时的数据视图 2.2.1 分层架构 批处理层数据不可变, 可进行任何计算, 可程度扩大,高提早(几分钟~几小时),包含组件:日志收集 Flume,分布式存储 Hadoop hdfs,分布式计算 Hadoop MapReduce & spark,视图存储数据库实时处理层流式解决, 继续计算,存储和剖析某个窗口期内的数据,包含组件:实时数据收集 flume & kafka,实时数据分析 spark streaming/storm/flink服务层次要工作是将曾经计算好的数据传递给前端申请2.3 举荐算法架构 ...

November 9, 2021 · 1 min · jiezi

关于推荐系统:推荐系统实践UserBase-CF-预测评分

一.筹备1. 评分预测公式预测分数= (用户类似度* 对电影的评分)之和/类似度之和 2. 数据集movielens数据集 中 ml-latest-small.zip 地址:https://grouplens.org/dataset... 二.算法实现1. 加载数据集def load_data(data_path): '''加载数据,data_path 为数据集门路 file_path = r'E:\RecommendData\ml-latest-small\ratings.csv' ''' cache_path = os.path.join(cache_dir, 'ratings_matrix.cache') print('开始加载数据集...') if os.path.exists(cache_path): print('加载缓存中') ratings_matrix = pd.read_pickle(cache_path) print("从缓存加载数据结束") else: # 从数据集中加载数据 print("加载新数据中...") dtype = {'userId': np.int32, 'movieId': np.int32, 'rating': np.float32} # 读取csv文件内容 ratings = pd.read_csv(data_path, dtype=dtype, usecols=range(3)) # 对读取到的数据进行透视,组成用户为 index movieId 为列的数据结构 ratings_matrix = ratings.pivot_table(index=['userId'], columns=['movieId'], values="rating") # 将数据存入缓存文件 ratings_matrix.to_pickle(cache_path) print("加载数据结束") return ratings_matrix2. 应用皮尔逊算法计算用户类似度def compute_pearson_similarity(ratings_matrix, based='user'): ''' 计算皮尔逊相关系数 ''' user_similarity_cache_path = os.path.join(cache_dir, 'user_similarity.cache') item_similarity_cache_path = os.path.join(cache_dir, 'item_similarity.cache') if based == 'user': # 计算用户类似度 if os.path.exists(user_similarity_cache_path): similarity = pd.read_pickle(user_similarity_cache_path) else: # 计算用户类似度 similarity = ratings_matrix.T.corr() # 将用户类似度写入缓存中 similarity.to_pickle(user_similarity_cache_path) elif based == 'item': # 计算物品类似度 if os.path.exists(item_similarity_cache_path): # item similar 已存在,读取缓存 similarity = pd.read_pickle(item_similarity_cache_path) else: # item similarity 不存在,从新计算类似度,保留进缓存 similarity = ratings_matrix.corr() # 将item类似度写入缓存中 similarity.to_pickle(item_similarity_cache_path) else: print("传入based 值谬误") return similarity3.预测算法def predict(uid, iid, ratings_matrix, user_similar): # 获取与uid 类似的用户 similar_users = user_similar[uid].drop([uid]).dropna() # 筛选正相干的用户 similar_users = similar_users.where(similar_users > 0).dropna() # 提醒没有类似用户 if similar_users.empty is True: raise Exception("用户<%d>没有类似的用户" % uid) # uid 近邻类似用户中筛选 对iid物品有评分记录的用户 ids = set(ratings_matrix[iid].dropna().index) & set(similar_users.index) # 依据用户ids 获取对应的类似的用户及类似度 finally_similar_users = similar_users.loc[list(ids)] sum_up = 0 sum_down = 0 # 对每个类似的用户进行循环 for sim_uid, similarity in finally_similar_users.iteritems(): # 类似用户评过分的说有电影 sim_user_rated_movies = ratings_matrix.loc[sim_uid].dropna() # 类似用户对指定电影的评分 sim_user_rating_for_item = sim_user_rated_movies[iid] # 类似用户 类似度* 对电影的评分 sum_up += similarity * sim_user_rating_for_item # 各个类似用户类似度之后 sum_down += similarity # 预测分数为 (类似用户类似度* 对电影的评分)之和/类似度之和 predict_rating = sum_up / sum_down print("预测出用户<%d>对电影<%d>的评分:%0.2f" % (uid, iid, predict_rating)) return round(predict_rating, 2)4. 对用户所有电影进行评分预测def _predict_all(uid, item_ids, ratings_matrix, user_similar): # 预测全副评分 # 对指定用户做所有电影举荐 for iid in item_ids: try: # 对指定用户指定电影做评分预测 rating = predict(uid, iid, ratings_matrix, user_similar) except Exception as e: print(e) else: yield uid, iid, ratingdef predict_all(uid, rating_matrix, user_similar, filter_rule=None): # 预测全副评分,并依据条件进行前置过滤 if not filter_rule: # 不进行过滤 item_ids = rating_matrix.columns elif isinstance(filter_rule, str) and filter_rule == 'unhot': '''过滤非热门电影''' # 统计每部电影的评分次数 count = rating_matrix.count() # 过滤评分次数高于10词的电影,作为热门电影 item_ids = count.where(count > 10).dropna().index elif isinstance(filter_rule, str) and filter_rule == 'rated': '''过滤用户评分过的电影''' # 获取用户对所有电影的评分记录 user_ratings = rating_matrix.loc[uid] # 评分范畴是1-5,小于6的都是评分过的,除此以外的都是没有评分的 _ = user_ratings < 6 item_ids = _.where(_ == False).dropna().index elif isinstance(filter_rule, list) and set(filter_rule) == set(["unhot", "rated"]): count = rating_matrix.count() ids1 = count.where(count > 10).dropna().index user_ratings = rating_matrix.loc[uid] _ = user_ratings < 6 ids2 = _.where(_ == False).dropna().index item_ids = set(ids1) & set(ids2) else: raise Exception("有效的过滤参数") yield from _predict_all(uid, item_ids, rating_matrix, user_similar)5. 返回K个举荐后果def top_k_rs_result(K): file_path = r'E:\RecommendData\ml-latest-small\ratings.csv' ratings_matrix = load_data(file_path) user_similarity = compute_pearson_similarity(ratings_matrix, based='user') results = predict_all(1, ratings_matrix, user_similarity, filter_rule=["unhot", "rated"]) return sorted(results, key=lambda x: x[2], reverse=True)[:K]三.预测后果[(1, 1041, 4.76), (1, 714, 4.72), (1, 80906, 4.7), (1, 1235, 4.63), (1, 3030, 4.63), (1, 65261, 4.63), (1, 1178, 4.57), (1, 1217, 4.56), (1, 318, 4.55), (1, 1104, 4.55), (1, 3451, 4.55), (1, 280, 4.54), (1, 168252, 4.52), (1, 3246, 4.5), (1, 58, 4.49), (1, 290, 4.49), (1, 115569, 4.49), (1, 1243, 4.48), (1, 142488, 4.47), (1, 800, 4.45)]

September 28, 2021 · 3 min · jiezi

关于推荐系统:推荐系统学习笔记三

doc2vecDoc2vec办法是一种无监督算法,能从变长的文本(例如:句子、段落或文档)中学习失去固定长度的特色示意。Doc2vec也能够叫做 Paragraph Vector、Sentence Embeddings,它能够取得句子、段落和文档的向量表白,是Word2Vec的拓展,其具备一些长处,比方不必固定句子长度,承受不同长度的句子做训练样本。 简略来说就是先用大量文本进行训练失去模型,之后用模型就能够将任意一段文本转为向量。有了向量,能力进行类似度的计算。 gensim里有现成的doc2vec,间接拿来应用就行 gensim的应用import osimport gensimimport smart_openimport loggingimport sqlite3logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)def read_db3(fname): conn = sqlite3.connect(fname) cur = conn.cursor() cur.execute('select lngid,description from modify_title_info_zt where description !=""') outtext = cur.fetchone() while outtext: tokens = gensim.utils.simple_preprocess(outtext[1]) yield gensim.models.doc2vec.TaggedDocument(tokens, outtext[0]) outtext = cur.fetchone()train_corpus = list(read_db3('zt_aipjournal_20210615_1.db3'))下面的代码非常简单,将db3中的description字段进行小写化、去掉符号、分词失去用来训练的语料 model = gensim.models.doc2vec.Doc2Vec(vector_size=100, min_count=2, epochs=10,workers=4)model.build_vocab(train_corpus)model.train(train_corpus, total_examples=model.corpus_count, epochs=model.epochs)model.save('aip.model')vector_size 向量的维数,默认100 min_count 去掉词频小于设定值的词 epochs 迭代次数 默认10次 workers 训练的过程数 训练实现后保留模型,供之后应用。 下面的语料有18万个文档,100维的模型训练工夫用了500秒,训练300维的模型用了750秒 def read_corpus(fname, tokens_only=False): with smart_open.open(fname, encoding="utf8") as f: for i, line in enumerate(f): tokens = gensim.utils.simple_preprocess(line) if tokens_only: yield tokens else: # For training data, add tags yield gensim.models.doc2vec.TaggedDocument(tokens, [i])test_corpus = list(read_corpus('test.txt', tokens_only=True))new_model = gensim.models.doc2vec.Doc2Vec.load('aip.model')vectorlist = []for i in range (len(test_corpus)): vectorlist.append(new_model.infer_vector(test_corpus[i]))import numpy as npfrom gensim import matutilsline = 'Three hundred thirty-one Chinese school children on Taiwan were given an aqueous oil trachoma vaccine and 322 an aqueous oil placebo'vector = new_model.infer_vector(gensim.utils.simple_preprocess(line))for i in range(0,7): similarity = np.dot(matutils.unitvec(vector), matutils.unitvec(vectorlist[i])) print(similarity)训练实现保留的模型,之后能够间接载入进行应用 类似度计算采纳余弦类似度 ...

July 9, 2021 · 1 min · jiezi

关于推荐系统:推荐系统学习笔记二

用户画像用户画像到底是什么?它是对用户信息的向量化示意,就是 User Profile,俗称“用户画像”。用户画像不是举荐零碎的目标,而是在构建举荐零碎的过程中产生的一个关键环节的副产品。构建用户画像须要上面两个步骤。 1 结构化文本咱们拿到的文本,经常是自然语言形容的,用行话说,就是“非结构化”的,然而计算机在解决时,只能应用结构化的数据索引,检索,而后向量化后再计算;所以剖析文本,就是为了将非结构化的数据结构化,好比是将模拟信号数字化一样,只有这样能力送入计算机,持续计算。从物品端的文本信息,咱们能够利用成熟的 NLP 算法剖析失去的信息有上面几种。 关键词提取:最根底的标签起源,也为其余文本剖析提供根底数据,罕用 TF-IDF 和 TextRank。内容分类:将文本依照分类体系分类,用分类来表白较粗粒度的结构化信息。常用工具FastText主题模型:从大量已有文本中学习主题向量,而后再预测新的文本在各个主题上的概率分布状况,也很实用,其实这也是一种聚类思维,主题向量也不是标签模式,也是用户画像的罕用形成。罕用的开源的 LDA 训练工具有 Gensim,PLDA 等嵌入:“嵌入”也叫作 Embedding,从词到篇章,无不能够学习这种嵌入表白。嵌入表白是为了挖掘出字面意思之下的语义信息,并且用无限的维度表达出来。2 标签抉择对物品端的文本进行结构化,失去了诸如标签(关键词、分类等)、主题、词嵌入向量。接下来就是第二步:把物品的结构化信息给用户。一种简略粗犷的方法是间接把用户产生过行为的物品标签累积在一起。 内容举荐算法对于基于内容的举荐零碎,最简略的举荐算法当然是计算类似度即可,用户的画像内容就示意为稠密的向量,同时内容端也有对应的稠密向量,两者之间计算余弦类似度,依据类似度对举荐物品排序。 余弦类似度 基于用户的协同过滤背地的思维 你有没有过这种感觉,你遇到一个人,你发现他喜爱的书、喜爱的电影也基本上都是你喜爱的,从此以后,你就想老是想问他:还有什么好举荐的,最近又看了什么书,最近又看了什么电影?这个感觉十分地天然间接,它就是基于用户的协同过滤背地思维。具体来说就是:先依据历史消费行为帮你找到一群和你口味很类似的用户;而后依据这些和你很类似的用户再生产了什么新的、你没有见过的物品,都能够举荐给你。 解决步骤 1 筹备用户向量实践上能够给每一个用户失去一个向量。为什么要说是“实践上”呢?因为失去向量的前提是:用户须要在咱们的产品里有行为数据,否则就得不到这个向量。这个向量有这么三个特点: 向量的维度就是物品的个数向量是稠密的,也就是说并不是每个维度上都有数值,起因当然很简略,这个用户并不是生产过所有物品向量维度上的取值能够是简略的 0 或者 1,也就是布尔值,1 示意浏览过,0 示意没有。2 用每一个用户的向量,两两计算用户之间的类似度,设定一个类似度阈值或者设定一个最大数量,为每个用户保留与其最类似的用户。这里咱们同样采纳余弦类似度进行计算 3 为每一个用户产生举荐后果。把和他类似的用户们浏览过的物品汇总起来,去掉用户本人曾经看过的物品,剩下的排序输入就是举荐后果。具体的汇总形式咱们用一个公式来示意。等号右边就是计算一个物品 i 和一个用户 u 的匹配分数,等号左边是这个分数的计算过程,分母是把和用户 u 类似的 n 个用户的类似度加起来,分子是把这 n 个用户各自对物品 i 的态度,依照类似度加权求和。这里的态度最简略就是 0 或者 1,1 示意喜爱过,0 示意没有,如果是评分,则能够是 0 到 5 的取值。整个公式就是类似用户们的态度加权平均值。 本文依据 刑无刀的举荐零碎三十六式 整顿而来

June 24, 2021 · 1 min · jiezi

关于推荐系统:推荐系统学习笔记一

举荐零碎的由来,信息过载互联网的呈现和遍及给用户带来了大量的信息,满足了用户在信息时代对信息的需要,但随着网络的迅速倒退而带来的网上信息量的大幅增长,使得用户在面对大量信息时无奈从中取得对本人真正有用的那局部信息,对信息的应用效率反而升高了,这就是所谓的信息超载(information overload)问题。 在这样的状况下,无论是信息消费者还是信息生产者都遇到了很大的挑战:作为信息消费者,如何从大量信息中找到本人感兴趣的信息是一件十分艰难的事件;作为信息生产者,如何让本人生产的信息怀才不遇,受到宽广用户的关注,也是一件十分艰难的事件。 为了解决信息过载的问题,曾经有有数科学家和工程师提出了很多蠢才的解决方案,按工夫先后,办法为以下三类 分类目录搜索引擎举荐零碎 分类目录定义分类目录是将网站信息系统地分类整理,提供一个按类别编排的网站目录,在每类中,排列着属于这一类别的网站站名、网址链接、内容提要,以及子分类目录,能够在分类目录中逐级浏览寻找相干的网站。 作用对网页进行分类,不便查找和检索 应用条件须要当时明确查找信息所属分类,如分类不清则无奈找到相应后果 相干公司雅虎 hao123智图期刊导航 搜索引擎定义搜索引擎是指依据肯定的策略、使用特定的计算机程序从互联网上采集信息,在对信息进行组织和解决后,为用户提供检索服务,将检索的相干信息展现给用户的零碎。 作用进步人们获取收集信息的速度,为人们提供更好的网络应用环境。 应用条件明确要查找的信息,晓得关键词,查找什么就搜寻什么,当用户无奈找到精确形容本人需要的关键词时,搜索引擎就无能为力了 相干公司谷歌百度智图搜寻 举荐零碎常见的举荐零碎淘宝京东今日头条 抖音 定义举荐零碎是一种信息过滤零碎,用于预测用户对物品的“评分”或“偏好”,把那些最终会在用户(User)和物品(Item)之间产生的连贯提前找进去。 作用在用户没有明确需要时,本源以往的记录,从大量信息中筛选用户最感兴趣的信息进行出现。 应用条件举荐零碎须要曾经存在的连贯,从已有的连贯去预测将来的连贯。 深刻理解举荐零碎什么是连贯这里说一下“连贯”这个词,这个词含意十分宽泛,但凡可能产生关系的都是连贯,比方用户对物品做出了一个行为,或者用户的某些属性和物品的属性一样等等,有关系就是连贯。 为什么这么说呢?这是基于这么一个事实:万事万物有相互连接的大趋势,比方人和人偏向于有更多社会连贯,于是有了各种社交产品;比方人和商品有越来越多的生产连贯,于是有了各种电商产品;人和资讯有越来越多的浏览连贯,于是有了信息流产品。 这还只是纯数字世界,随着各种物理实体智能化趋势越来越显著,万物互联还会进一步强化。世界是一个数字化的大网,但外面只有两类节点:人和其余。人是互联的终极意义,“其余”统称为物品,物品可能是人、资讯、消费品、服务等。举荐零碎就是要在这张微小的网中,一直去发现那些很可能会和人产生连贯的另一类物品节点,让它们和用户真的建设连贯。 举荐零碎常见分类以看电影为例,一般来说,咱们在想看电影又不晓得看什么时,可能会用以下形式决定最终看什么电影。 向敌人征询。咱们兴许会关上聊天工具,找几个常常看电影的好敌人,问问他们有没有什么电影能够举荐。甚至,咱们能够关上微博,发表一句“我要看电影”,而后期待热心人举荐电影。这种形式在举荐零碎中称为社会化举荐(social recommendation),即让好友给本人举荐物品。咱们个别都有喜爱的演员和导演,有些人可能会关上搜索引擎,输出本人喜爱的演员名,而后看看返回后果中还有什么电影是本人没有看过的。比方我十分喜爱周星驰的电影,于是就去豆瓣搜寻周星驰,发现他早年的一部电影我还没看过,于是就会看一看。这种形式是寻找和本人之前看过的电影在内容上类似的电影。举荐零碎能够将上述过程自动化,通过剖析用户已经看过的电影找到用户喜爱的演员和导演,而后给用户举荐这些演员或者导演的其余电影。这种举荐形式在举荐零碎中称为基于内容的举荐(content-based filtering)。咱们还可能查看排行榜,比方驰名的IMDB电影排行榜,看看他人都在看什么电影,他人都喜爱什么电影,而后找一部广受好评的电影观看。这种形式能够进一步扩大:如果能找到和本人历史趣味类似的一群用户,看看他们最近在看什么电影,那么后果可能比宽泛的热门排行榜更能合乎本人的趣味。这种形式称为基于协同过滤(collaborative filtering)的举荐 什么是好的举荐零碎一个残缺的举荐零碎个别存在3个参与方(如下图所示):用户、物品提供者和提供举荐零碎的网站。 以图书举荐为例,首先,举荐零碎须要满足用户的需要,给用户举荐那些令他们感兴趣的图书。 其次,举荐零碎要让各出版社的书都可能被举荐给对其感兴趣的用户,而不是只举荐几个大型出版社的书。 最初,好的举荐零碎设计,可能让举荐零碎自身收集到高质量的用户反馈,不断完善举荐的品质,减少用户和网站的交互,进步网站的支出。因而在评测一个举荐算法时,须要同时思考三方的利益,一个好的举荐零碎是可能令三方共赢的零碎。 然而传统的举荐零碎大都是起一个“精益求精”的作用,个别很少会将其作为外围性能来承载产品。因为举荐零碎通常的指标不是帮用户找到相干内容,而是心愿用户生产内容,生产越多越好,于是业界逐步演变出一个比拟畸形的意识,“好的举荐零碎应该变成一个工夫杀手,让用户走进去就不想进去”才是最好的。 搭建举荐零碎须要怎么的团队一个举荐零碎复杂度没有下限,然而有最低标准,所以上面在估算举荐零碎团队规模时,依照上限来预计,照这个形式建设的团队就叫做“有上限的团队”。 这里先定义团队的角色,既然是组建“有上限团队”,当然依照能省则省的准则。 算法工程师,承当的是数据科学家和机器学习工程师的双重职责,主要职责是荡涤数据,训练离线举荐模型,开发算法接口,评估指标。后端开发工程师,承当算法之外的开发工作,负责调用举荐 RPC 服务,开发必要的过滤逻辑,API 接口的开发,填充具体字段等。运维工程师,负责数据库的搭建保护,日志的收集,在线零碎的高可用回收用户反馈数据,对立存储日志数据。 本文依据 刑无刀的举荐零碎三十六式与项亮的举荐零碎实战 整顿而来

June 10, 2021 · 1 min · jiezi

关于推荐系统:网易云课堂个性化推荐实践与思考

作者/ 韩虹莹 编辑/ Ein从人和信息的博弈谈举荐零碎缘起首先谈谈我了解的举荐零碎。 如果说举荐零碎的定义是什么,每本书每篇文章说的都不太一样,协同过滤1992年就曾经有了,三十年里有数大佬剖析了个性化举荐的缘起和意义,世界曾经不须要多一个人的见解。然而,当所有人都说一件事件是正确的时候,咱们也要想分明它为什么是正确的。 如果你问我举荐零碎是什么,我会通知你,是信息到人的精准散发。那么为什么在这个时代举荐零碎才应运而生?今人不会须要信息精准散发,车马信息都很慢,今人学富五车不过当初一个书包的信息量;唯有当初人才须要信息精准散发,信息太多工夫太少,乱花渐欲迷人眼,所以咱们须要一个智能的零碎,帮忙你过去过滤信息,所以举荐零碎是人和信息的桥梁。 当然,正如罗马不是一天建成的一样,在互联网上搭个桥也是要演进的,最开始是个小木桥——门户网站,用分类导航散发了信息;起初演变到了石板桥——搜索引擎,人能够更精准的找信息;逐渐的信息太多了,要变成信息找人,在这个过程中,无论是信息的消费者,还是信息的生产者,都遇到了未曾预感的艰难,信息消费者找不到信息了,信息生产者无奈让本人的信息展示在消费者眼前,有痛点就有需要,有需要就有产品,于是举荐零碎作为一个产品,恰到好处又必然的到来。凯文凯利在《必然》里,把这个趋势称为“过滤”: 进行过滤是必然的,因为咱们在不停地制作新货色。而在咱们将要制作的新货色中,首要的一点就是发明新的形式来过滤信息和个性化定制,以突显咱们之间的差别。人如何和信息相处,举荐零碎既不是终点,恐怕也不会是终局,但它曾经是以后人们对于解决信息所能做的最好的实际了。 举荐零碎要如何满足需要举荐零碎应该独自作为一个产品来看,他是一个什么产品呢?作为一个加工信息的产品,它肯定要满足信息供需两端的需要,才有价值。 所以作为一个举荐零碎,要把本人定义在一个中间方的地位,能够说 C 端用户和产品经理都是你的用户,两端的需要都须要被满足,所以既须要你想技术计划,还须要你去想,你怎么更好的满足两端的需要,用户只须要你精准的帮他找到信息。而对于产品方,须要开掘想通过举荐零碎取得什么。 对于用户端(信息需要端),最迫切的需要是如何帮我精准的找到我须要的信息。 对于公司端(信息供给端),是为了满足一些商业化的需要,比方吸引用户,加强用户黏性,进步用户转化率,比方资讯平台,短视频平台,信息流平台心愿晋升用户活跃度,缩短用户停留时间,电商平台心愿进步用户购买转化率。 举荐零碎惯例架构 从上图来看,一个残缺的举荐零碎包含数据局部和模型局部,数据局部次要依赖大数据离线或在线解决平台,次要实现的工作包含数据的收集和 ETL 解决,生成举荐模型所须要的特色数据。 举荐零碎模型局部是主体,这部分要在提供举荐模型服务之前,实现模型的训练,而后对输出数据进行解决,通过不同的召回或排序策略,生成最初的输入后果。一个惯例的工业级举荐零碎,在模型局部次要包含召回层,过滤层,排序层,也可依据业务须要判断是否须要补充策略与算法层。 1. "召回层"个别利用高效的召回规定、算法或简略的模型,疾速从海量的候选集中召回用户可能感兴趣的物品。 2. "过滤层"个别依据特定场景业务需要,对召回的数据进行过滤。 3. "排序层"利用排序模型对初筛的候选集进行精排序。 4. "补充策略与算法层"也被称为"再排序层",能够在将举荐列表返回用户之前,为兼顾后果的"多样性" "风行度" "新鲜度"等指标,联合一些补充的策 略和算法对举荐列表进行肯定的调整,最终造成用户可见的举荐列表。 举荐零碎常见模型概述与比拟先来一个举荐算法倒退的工夫线 能够从图中看出,2016年是举荐零碎从传统机器学习模型到深度学习模型的转折点,这一年微软的 Deep Crossing ,谷歌的 Wide&Deep ,以及 FNN 、 PNN 等一大批 优良的深度学习举荐模型相继推出,继而逐步成为举荐零碎的支流。但传统举荐模型依然要被器重,第一它们是深度学习的根底,很多货色都是一脉相承的,矩阵合成的隐向量思维在Embedding中持续倒退,FM中的核心思想——特色穿插也在深度学习中持续应用,逻辑回归能够看做神经元的另一种表现形式。第二这些算法的硬件要求低,后果可解释性强,训练容易,仍是大量场景所实用的。 机器学习举荐模型演化过程 能够从图中看出,2016年是举荐零碎从传统机器学习模型到深度学习模型的转折点,这一年微软的 Deep Crossing ,谷歌的 Wide&Deep ,以及 FNN 、 PNN 等一大批 优良的深度学习举荐模型相继推出,继而逐步成为举荐零碎的支流。但传统举荐模型依然要被器重,第一它们是深度学习的根底,很多货色都是一脉相承的,矩阵合成的隐向量思维在Embedding中持续倒退,FM中的核心思想——特色穿插也在深度学习中持续应用,逻辑回归能够看做神经元的另一种表现形式。第二这些算法的硬件要求低,后果可解释性强,训练容易,仍是大量场景所实用的。 协同过滤协同过滤是举荐零碎畛域利用最宽泛的模型了,而且大家一说到举荐零碎,就会间接关联到协同过滤,而且是基于用户的协同过滤 or 基于物品的协同过滤,其实从某种程度上了解,矩阵合成也是协同过滤的一种,基于用户,商品的协同过滤属于基于近邻的协同过滤,从更大一点的范畴来说,大多数机器学习和分类算法能够了解为协同过滤的一个分支,协同过滤能够看做是分类问题的泛化,正是因为这个起因,实用于分类的许多模型也能够通过泛化利用于协同过滤。 本节次要针对的,还是宽泛意义上了解的,基于近邻的协同过滤,这类协同过滤,其实就是基于用户-用户,物品-物品的类似度计算。 基于用户协同过滤当用户须要个性化举荐时,能够先找到与他类似其余用户(通过趣味、喜好或行为习惯等,而后把那些用户喜爱的并且本人不晓得的物品举荐给用户。 步骤: 筹备用户向量,在该矩阵中,实践上每个用户失去一个向量向量维度是物品个数,向量是稠密的,向量取值能够是简略的0或1用每个用户向量,两两计算用户之间类似度,设定一个类似度阈值,为每个用户保留与其最类似的用户为每个用户产生举荐后果基于物品协同过滤基于物品的协同过滤算法简称,其简略利用情景是:当一个用户须要个性化举荐时,例如因为他之前购买过金庸的《射雕英雄传》这本书,所以会给他举荐《神雕侠侶》,因为其余用户很多都同时购买了这两本书。 步骤: 构建用户物品的关系矩阵,能够是购买行为,或购买后的评估,购买次数等两两计算物品类似度,失去物品类似度矩阵产生举荐后果,典型的两种模式:①为某个物品举荐相干物品;②集体首页的“猜你喜爱”计算类似度的形式有如下几种: ①余弦类似度,余弦类似度( Cosine Similarity )掂量了用户向量t和用户向量j之间的向量夹角大小。 显然,夹角越小,证实余弦类似 度越大,两个用户越类似。 ...

April 28, 2021 · 1 min · jiezi

关于推荐系统:BI思考题阿里定向广告模型

=============== 定向广告和搜寻广告的区别搜寻广告的实现场景次要是在用户被动去搜寻商品的状况下,依据用户搜寻的内容举荐给他可能喜爱的商品,如果以来示意用户可能喜爱的商品的概率,则广告的可能表达形式是: 其中ad示意候选广告集,user示意用户特色,context示意上下文场景,设施,事件等等。而整个就示意为上述情况下用户点击广告的条件概率。而搜寻广告中,因为用户曾经搜寻了相干的商品,则候选广告集ad的范畴就是和搜寻关键词相干。 然而如果用户在未收回搜寻申请时,如何在淘宝主页上出现用户可能感兴趣的商品内容,进而吸引用户点击,就是定向广告发挥作用的时候了。在这种状况下,候选广告集的范畴就是依据用户之前的购买,搜寻,点击状况来筛选出的可能感兴趣的商品列表。 定向广告的常见应用模型 依据广告的表达形式来看,其实能够形象为一个二分类问题(点击或不点击,或者说CTR预估)。所以定向广告模型演变过程如下: Logistic Regression:万能的LR;MLR:在LR的根底上又倒退进去了Mixed Logistic Regression,其和LR的区别在于MLR能够依据理论状况别离应用不同的LR模型,具备了肯定的非线性能力。DNN:因为深度神经网络能够很好的表白非线性关系,并且在CV和NLP场景中的广泛应用,所以在举荐场景中DNN也被拿来解决在大数据场景中的非线性关系。DIN:深度趣味网络采纳了Attention的原理,将用户的趣味散布依据状况激活并退出到模型训练中。DIEN:DIEN在DIN的根底上优化了趣味演变层,在Attention中嵌入了序列机制,绝对趣味作用失去了强化。DSIN:这个模型也是在DIN的根底上,将用户行为分为一段一段的session,并用multi-head Attention来获取session内的趣味。DIN中Attention的原理机制DIN根本的模型构架还是一个embedding layer和一个MLP组成的,其中embedding layer作用是把稠密矩阵转移到一个向量空间中,MLP的次要作用是对embedding进行拟合分类输入。在这两个阶段两头,DIN退出了一个activation unit组件,其次要应用的就是attention的机理来计算user feature group的权重。 Activation Unit的构造如下,则其应用的attention原理能够了解为用户的历史行为对候选ad的权重都是不同的,而用用户历史行为的embedding和候选ad的embedding通过外积的模式来表白相关性。这样在输出之后的MLP时,相关性使得模型能够更好地对候选ad去关注那些有用的历史行为。 DIEN绝对于DIN有哪些翻新DIN是中的Attention对于候选ad只是关注了有用的历史行为,然而疏忽了一个问题是,用户的历史行为其实是一个工夫序列,其会有趣味的变动,迁徙。所以DIEN在DIN的根底上,退出了Interest extractor layer(核心部件是GRU)进行趣味提取,而后对提取的趣味加上了一个Interest evolving layer,用改进型AUGRU,并把Attention权重退出到外面让GRU更加关注趣味的演变,削弱趣味漂移,之后才输出到MLP中。 DSIN对于Session的洞察是怎么的,如何对Session趣味进行表白DSIN提出的问题是,尽管用户具备动静趣味演变,然而用户应用淘宝的体现为阶段性的,也就是间断搜寻一段时间,而后进行,并且每次产生搜寻拜访时,搜寻的物品是很相近,然而两次隔开产生的间断搜寻大概率差异很大。DSIN对这种状况,对用户序列建设session,每个session是一个给定工夫范畴内产生的交互列表,同一个session内的行为高度同构,而跨session之间是异构的。如下图,session在间断浏览裤子,session2就曾经在搜寻美甲,session3又有变动。然而每个session外部是一个类别的,这就是DSIN发现的问题。 所以DSIN对用户的间断行为划分成session,而后用带偏执编码的self attention对每个session进行建模,而后用BI-LSTM捕获用户不同历史会话趣味的交互和演变,设计一个部分的流动单元,将他们与指标项聚合起来,造成行为序列的最终表达形式。 首先Session Division Layer 对序列进行宰割session。然而session中还是会呈现用户的随便行为使的session偏移,所以Session Interest Extractor Layer在每个session中应用multi-head attention来关注session的重点,加重不相干性行为的影响。Session Interest Extractor Layer对带有session趣味重点的session应用BI-LSTM来捕获用户session趣味的动静演变。之后SIE层和SII层别离示意的session趣味重点,以及趣味的演变输出到Session Interest Activating Layer与指标商品之间去计算相关性,给session趣味设立权重,最终和原始特色合并输出给MLP。 依据以上形容能够看出,session的趣味表白次要是通过SIE层的关注趣味重点,SII层的趣味演变,并最终通过SIA层调配权重来达到表白趣味的目标。 如果你来设计淘宝定向广告,会有哪些future work(即下一个阶段的idea) 鉴于目前淘宝定向广告曾经十分高效了,接下来我感觉可能的下一步走向应该有: 依据用户历史行为和趣味推断用户可能购买的但从没波及过的畛域。须要建设常识图谱,模型能够认知商品之间的相干关系,并依据工夫因素推断可能购买的商品。有些商品具备强烈的季节性或者时效性(羽绒服,西瓜,凉鞋),定向广告也须要带有时效性(即对趣味附加一个周期权重),这样定向广告的投放也会有显著的季节性。

February 26, 2021 · 1 min · jiezi

关于推荐系统:推荐系统入门新闻推荐模型排序模型融合

排序模型通过召回的操作, 咱们曾经进行了问题规模的缩减, 对于每个用户, 抉择出了N篇文章作为了候选集,并基于召回的候选集构建了与用户历史相干的特色,以及用户自身的属性特色,文章本省的属性特色,以及用户与文章之间的特色,上面就是应用机器学习模型来对结构好的特色进行学习,而后对测试集进行预测,失去测试集中的每个候选集用户点击的概率,返回点击概率最大的topk个文章,作为最终的后果。 排序阶段抉择了三个比拟有代表性的排序模型,它们别离是: LGB的排序模型LGB的分类模型深度学习的分类模型DIN失去了最终的排序模型输入的后果之后,还抉择了两种比拟经典的模型集成的办法: 输入后果加权交融Staking(将模型的输入后果再应用一个简略模型进行预测)导入库import numpy as npimport pandas as pdimport picklefrom tqdm import tqdmimport gc, osimport timefrom datetime import datetimeimport lightgbm as lgbfrom sklearn.preprocessing import MinMaxScalerimport warningswarnings.filterwarnings('ignore')读取排序特色data_path = './data_raw'save_path = './temp_results'offline = False# 从新读取数据的时候,发现click_article_id是一个浮点数,所以将其转换成int类型trn_user_item_feats_df = pd.read_csv(save_path + 'trn_user_item_feats_df.csv')trn_user_item_feats_df['click_article_id'] = trn_user_item_feats_df['click_article_id'].astype(int)if offline: val_user_item_feats_df = pd.read_csv(save_path + 'val_user_item_feats_df.csv') val_user_item_feats_df['click_article_id'] = val_user_item_feats_df['click_article_id'].astype(int)else: val_user_item_feats_df = None tst_user_item_feats_df = pd.read_csv(save_path + 'tst_user_item_feats_df.csv')tst_user_item_feats_df['click_article_id'] = tst_user_item_feats_df['click_article_id'].astype(int)# 做特色的时候为了不便,给测试集也打上了一个有效的标签,这里间接删掉就行del tst_user_item_feats_df['label']返回排序后的后果def submit(recall_df, topk=5, model_name=None): recall_df = recall_df.sort_values(by=['user_id', 'pred_score']) recall_df['rank'] = recall_df.groupby(['user_id'])['pred_score'].rank(ascending=False, method='first') # 判断是不是每个用户都有5篇文章及以上 tmp = recall_df.groupby('user_id').apply(lambda x: x['rank'].max()) assert tmp.min() >= topk del recall_df['pred_score'] submit = recall_df[recall_df['rank'] <= topk].set_index(['user_id', 'rank']).unstack(-1).reset_index() submit.columns = [int(col) if isinstance(col, int) else col for col in submit.columns.droplevel(0)] # 依照提交格局定义列名 submit = submit.rename(columns={'': 'user_id', 1: 'article_1', 2: 'article_2', 3: 'article_3', 4: 'article_4', 5: 'article_5'}) save_name = save_path + model_name + '_' + datetime.today().strftime('%m-%d') + '.csv' submit.to_csv(save_name, index=False, header=True)# 排序后果归一化def norm_sim(sim_df, weight=0.0): # print(sim_df.head()) min_sim = sim_df.min() max_sim = sim_df.max() if max_sim == min_sim: sim_df = sim_df.apply(lambda sim: 1.0) else: sim_df = sim_df.apply(lambda sim: 1.0 * (sim - min_sim) / (max_sim - min_sim)) sim_df = sim_df.apply(lambda sim: sim + weight) # plus one return sim_dfLGB排序模型# copy 一份trn_user_item_feats_df_rank_model = trn_user_item_feats_df.copy()if offline: val_user_item_feats_df_rank_model = val_user_item_feats_df.copy() tst_user_item_feats_df_rank_model = tst_user_item_feats_df.copy()# 定义特色列lgb_cols = ['sim0', 'time_diff0', 'word_diff0','sim_max', 'sim_min', 'sim_sum', 'sim_mean', 'score','click_size', 'time_diff_mean', 'active_level', 'click_environment','click_deviceGroup', 'click_os', 'click_country', 'click_region','click_referrer_type', 'user_time_hob1', 'user_time_hob2', 'words_hbo', 'category_id', 'created_at_ts','words_count'] # 排序模型分组trn_user_item_feats_df_rank_model.sort_values(by=['user_id'], inplace=True)g_train = trn_user_item_feats_df_rank_model.groupby(['user_id'], as_index=False).count()["label"].valuesif offline: val_user_item_feats_df_rank_model.sort_values(by=['user_id'], inplace=True) g_val = val_user_item_feats_df_rank_model.groupby(['user_id'], as_index=False).count()["label"].values# 排序模型定义lgb_ranker = lgb.LGBMRanker(boosting_type='gbdt', num_leaves=31, reg_alpha=0.0, reg_lambda=1, max_depth=-1, n_estimators=100, subsample=0.7, colsample_bytree=0.7, subsample_freq=1, learning_rate=0.01, min_child_weight=50, random_state=2018, n_jobs= 16) # 排序模型训练if offline: lgb_ranker.fit(trn_user_item_feats_df_rank_model[lgb_cols], trn_user_item_feats_df_rank_model['label'], group=g_train, eval_set=[(val_user_item_feats_df_rank_model[lgb_cols], val_user_item_feats_df_rank_model['label'])], eval_group= [g_val], eval_at=[1, 2, 3, 4, 5], eval_metric=['ndcg', ], early_stopping_rounds=50, )else: lgb_ranker.fit(trn_user_item_feats_df[lgb_cols], trn_user_item_feats_df['label'], group=g_train) # 模型预测tst_user_item_feats_df['pred_score'] = lgb_ranker.predict(tst_user_item_feats_df[lgb_cols], num_iteration=lgb_ranker.best_iteration_)# 将这里的排序后果保留一份,用户前面的模型交融tst_user_item_feats_df[['user_id', 'click_article_id', 'pred_score']].to_csv(save_path + 'lgb_ranker_score.csv', index=False)# 预测后果从新排序, 及生成提交后果rank_results = tst_user_item_feats_df[['user_id', 'click_article_id', 'pred_score']]rank_results['click_article_id'] = rank_results['click_article_id'].astype(int)submit(rank_results, topk=5, model_name='lgb_ranker') # 五折穿插验证,这里的五折穿插是以用户为指标进行五折划分# 这一部分与后面的独自训练和验证是离开的def get_kfold_users(trn_df, n=5): user_ids = trn_df['user_id'].unique() user_set = [user_ids[i::n] for i in range(n)] return user_setk_fold = 5trn_df = trn_user_item_feats_df_rank_modeluser_set = get_kfold_users(trn_df, n=k_fold)score_list = []score_df = trn_df[['user_id', 'click_article_id','label']]sub_preds = np.zeros(tst_user_item_feats_df_rank_model.shape[0])# 五折穿插验证,并将两头后果保留用于stakingfor n_fold, valid_user in enumerate(user_set): train_idx = trn_df[~trn_df['user_id'].isin(valid_user)] # add slide user valid_idx = trn_df[trn_df['user_id'].isin(valid_user)] # 训练集与验证集的用户分组 train_idx.sort_values(by=['user_id'], inplace=True) g_train = train_idx.groupby(['user_id'], as_index=False).count()["label"].values valid_idx.sort_values(by=['user_id'], inplace=True) g_val = valid_idx.groupby(['user_id'], as_index=False).count()["label"].values # 定义模型 lgb_ranker = lgb.LGBMRanker(boosting_type='gbdt', num_leaves=31, reg_alpha=0.0, reg_lambda=1, max_depth=-1, n_estimators=100, subsample=0.7, colsample_bytree=0.7, subsample_freq=1, learning_rate=0.01, min_child_weight=50, random_state=2018, n_jobs= 16) # 训练模型 lgb_ranker.fit(train_idx[lgb_cols], train_idx['label'], group=g_train, eval_set=[(valid_idx[lgb_cols], valid_idx['label'])], eval_group= [g_val], eval_at=[1, 2, 3, 4, 5], eval_metric=['ndcg', ], early_stopping_rounds=50, ) # 预测验证集后果 valid_idx['pred_score'] = lgb_ranker.predict(valid_idx[lgb_cols], num_iteration=lgb_ranker.best_iteration_) # 对输入后果进行归一化 valid_idx['pred_score'] = valid_idx[['pred_score']].transform(lambda x: norm_sim(x)) valid_idx.sort_values(by=['user_id', 'pred_score']) valid_idx['pred_rank'] = valid_idx.groupby(['user_id'])['pred_score'].rank(ascending=False, method='first') # 将验证集的预测后果放到一个列表中,前面进行拼接 score_list.append(valid_idx[['user_id', 'click_article_id', 'pred_score', 'pred_rank']]) # 如果是线上测试,须要计算每次穿插验证的后果相加,最初求均匀 if not offline: sub_preds += lgb_ranker.predict(tst_user_item_feats_df_rank_model[lgb_cols], lgb_ranker.best_iteration_) score_df_ = pd.concat(score_list, axis=0)score_df = score_df.merge(score_df_, how='left', on=['user_id', 'click_article_id'])# 保留训练集穿插验证产生的新特色score_df[['user_id', 'click_article_id', 'pred_score', 'pred_rank', 'label']].to_csv(save_path + 'trn_lgb_ranker_feats.csv', index=False) # 测试集的预测后果,屡次穿插验证求均匀,将预测的score和对应的rank特色保留,能够用于前面的staking,这里还能够结构其余更多的特色tst_user_item_feats_df_rank_model['pred_score'] = sub_preds / k_foldtst_user_item_feats_df_rank_model['pred_score'] = tst_user_item_feats_df_rank_model['pred_score'].transform(lambda x: norm_sim(x))tst_user_item_feats_df_rank_model.sort_values(by=['user_id', 'pred_score'])tst_user_item_feats_df_rank_model['pred_rank'] = tst_user_item_feats_df_rank_model.groupby(['user_id'])['pred_score'].rank(ascending=False, method='first')# 保留测试集穿插验证的新特色tst_user_item_feats_df_rank_model[['user_id', 'click_article_id', 'pred_score', 'pred_rank']].to_csv(save_path + 'tst_lgb_ranker_feats.csv', index=False)# 预测后果从新排序, 及生成提交后果# 单模型生成提交后果rank_results = tst_user_item_feats_df_rank_model[['user_id', 'click_article_id', 'pred_score']]rank_results['click_article_id'] = rank_results['click_article_id'].astype(int)submit(rank_results, topk=5, model_name='lgb_ranker')LGB分类模型# 模型及参数的定义lgb_Classfication = lgb.LGBMClassifier(boosting_type='gbdt', num_leaves=31, reg_alpha=0.0, reg_lambda=1, max_depth=-1, n_estimators=500, subsample=0.7, colsample_bytree=0.7, subsample_freq=1, learning_rate=0.01, min_child_weight=50, random_state=2018, n_jobs= 16, verbose=10) # 模型及参数的定义lgb_Classfication = lgb.LGBMClassifier(boosting_type='gbdt', num_leaves=31, reg_alpha=0.0, reg_lambda=1, max_depth=-1, n_estimators=500, subsample=0.7, colsample_bytree=0.7, subsample_freq=1, learning_rate=0.01, min_child_weight=50, random_state=2018, n_jobs= 16, verbose=10) # 模型训练if offline: lgb_Classfication.fit(trn_user_item_feats_df_rank_model[lgb_cols], trn_user_item_feats_df_rank_model['label'], eval_set=[(val_user_item_feats_df_rank_model[lgb_cols], val_user_item_feats_df_rank_model['label'])], eval_metric=['auc', ],early_stopping_rounds=50, )else: lgb_Classfication.fit(trn_user_item_feats_df_rank_model[lgb_cols], trn_user_item_feats_df_rank_model['label']) # 模型预测tst_user_item_feats_df['pred_score'] = lgb_Classfication.predict_proba(tst_user_item_feats_df[lgb_cols])[:,1]# 将这里的排序后果保留一份,用户前面的模型交融tst_user_item_feats_df[['user_id', 'click_article_id', 'pred_score']].to_csv(save_path + 'lgb_cls_score.csv', index=False)# 预测后果从新排序, 及生成提交后果rank_results = tst_user_item_feats_df[['user_id', 'click_article_id', 'pred_score']]rank_results['click_article_id'] = rank_results['click_article_id'].astype(int)submit(rank_results, topk=5, model_name='lgb_cls')# 五折穿插验证,这里的五折穿插是以用户为指标进行五折划分# 这一部分与后面的独自训练和验证是离开的def get_kfold_users(trn_df, n=5): user_ids = trn_df['user_id'].unique() user_set = [user_ids[i::n] for i in range(n)] return user_setk_fold = 5trn_df = trn_user_item_feats_df_rank_modeluser_set = get_kfold_users(trn_df, n=k_fold)score_list = []score_df = trn_df[['user_id', 'click_article_id', 'label']]sub_preds = np.zeros(tst_user_item_feats_df_rank_model.shape[0])# 五折穿插验证,并将两头后果保留用于stakingfor n_fold, valid_user in enumerate(user_set): train_idx = trn_df[~trn_df['user_id'].isin(valid_user)] # add slide user valid_idx = trn_df[trn_df['user_id'].isin(valid_user)] # 模型及参数的定义 lgb_Classfication = lgb.LGBMClassifier(boosting_type='gbdt', num_leaves=31, reg_alpha=0.0, reg_lambda=1, max_depth=-1, n_estimators=100, subsample=0.7, colsample_bytree=0.7, subsample_freq=1, learning_rate=0.01, min_child_weight=50, random_state=2018, n_jobs= 16, verbose=10) # 训练模型 lgb_Classfication.fit(train_idx[lgb_cols], train_idx['label'],eval_set=[(valid_idx[lgb_cols], valid_idx['label'])], eval_metric=['auc', ],early_stopping_rounds=50, ) # 预测验证集后果 valid_idx['pred_score'] = lgb_Classfication.predict_proba(valid_idx[lgb_cols], num_iteration=lgb_Classfication.best_iteration_)[:,1] # 对输入后果进行归一化 分类模型输入的值自身就是一个概率值不须要进行归一化 # valid_idx['pred_score'] = valid_idx[['pred_score']].transform(lambda x: norm_sim(x)) valid_idx.sort_values(by=['user_id', 'pred_score']) valid_idx['pred_rank'] = valid_idx.groupby(['user_id'])['pred_score'].rank(ascending=False, method='first') # 将验证集的预测后果放到一个列表中,前面进行拼接 score_list.append(valid_idx[['user_id', 'click_article_id', 'pred_score', 'pred_rank']]) # 如果是线上测试,须要计算每次穿插验证的后果相加,最初求均匀 if not offline: sub_preds += lgb_Classfication.predict_proba(tst_user_item_feats_df_rank_model[lgb_cols], num_iteration=lgb_Classfication.best_iteration_)[:,1] score_df_ = pd.concat(score_list, axis=0)score_df = score_df.merge(score_df_, how='left', on=['user_id', 'click_article_id'])# 保留训练集穿插验证产生的新特色score_df[['user_id', 'click_article_id', 'pred_score', 'pred_rank', 'label']].to_csv(save_path + 'trn_lgb_cls_feats.csv', index=False) # 测试集的预测后果,屡次穿插验证求均匀,将预测的score和对应的rank特色保留,能够用于前面的staking,这里还能够结构其余更多的特色tst_user_item_feats_df_rank_model['pred_score'] = sub_preds / k_foldtst_user_item_feats_df_rank_model['pred_score'] = tst_user_item_feats_df_rank_model['pred_score'].transform(lambda x: norm_sim(x))tst_user_item_feats_df_rank_model.sort_values(by=['user_id', 'pred_score'])tst_user_item_feats_df_rank_model['pred_rank'] = tst_user_item_feats_df_rank_model.groupby(['user_id'])['pred_score'].rank(ascending=False, method='first')# 保留测试集穿插验证的新特色tst_user_item_feats_df_rank_model[['user_id', 'click_article_id', 'pred_score', 'pred_rank']].to_csv(save_path + 'tst_lgb_cls_feats.csv', index=False) # 预测后果从新排序, 及生成提交后果rank_results = tst_user_item_feats_df_rank_model[['user_id', 'click_article_id', 'pred_score']]rank_results['click_article_id'] = rank_results['click_article_id'].astype(int)submit(rank_results, topk=5, model_name='lgb_cls')DIN模型用户的历史点击行为列表这个是为前面的DIN模型服务的 ...

December 6, 2020 · 10 min · jiezi

关于推荐系统:推荐系统新闻推荐之推荐

特色工程咱们制作特色和标签,将举荐问题转成监督学习问题。咱们先回顾一下现有数据,有哪些特色能够间接利用: 文章的本身特色: category_id示意这文章的类型, created_at_ts示意文章建设的工夫, 这个关系着文章的时效性, words_count是文章的字数, 个别字数太长咱们不太喜爱点击, 也不排除有人就喜爱读长文。文章的内容embedding特色: 这个召回的时候用过, 这里能够抉择应用, 也能够抉择不必, 也能够尝试其余类型的embedding特色, 比方W2V等用户的设施特色信息下面这些间接能够用的特色, 待做完特色工程之后, 间接就能够依据article_id或者是user_id把这些特色退出进去。 然而咱们须要先基于召回的后果,结构一些特色,而后制作标签,造成一个监督学习的数据集。 结构监督数据集的思路, 依据召回后果, 咱们会失去一个{user_id: [可能点击的文章列表]}模式的字典。 那么咱们就能够对于每个用户, 每篇可能点击的文章结构一个监督测试集, 比方对于用户user1, 假如失去的他的召回列表{user1: [item1, item2, item3]}, 咱们就能够失去三行数据(user1, item1), (user1, item2), (user1, item3)的模式, 这就是监督测试集时候的前两列特色。 结构特色的思路是这样, 咱们晓得每个用户的点击文章是与其历史点击的文章信息是有很大关联的, 比方同一个主题, 类似等等。 所以特色结构这块很重要的一系列特色是要联合用户的历史点击文章信息。咱们曾经失去了每个用户及点击候选文章的两列的一个数据集, 而咱们的目标是要预测最初一次点击的文章, 比拟天然的一个思路就是和其最初几次点击的文章产生关系, 这样既思考了其历史点击文章信息, 又得离最初一次点击较近,因为新闻很大的一个特点就是重视时效性。 往往用户的最初一次点击会和其最初几次点击有很大的关联。 所以咱们就能够对于每个候选文章, 做出与最初几次点击相干的特色如下: 候选item与最初几次点击的相似性特色(embedding内积) — 这个间接关联用户历史行为候选item与最初几次点击的相似性特色的统计特色 — 统计特色能够缩小一些稳定和异样候选item与最初几次点击文章的字数差的特色 — 能够通过字数看用户偏好候选item与最初几次点击的文章建设的时间差特色 — 时间差特色能够看出该用户对于文章的实时性的偏好还须要考虑一下5. 如果应用了youtube召回的话, 咱们还能够制作用户与候选item的类似特色 当然, 下面只是提供了一种基于用户历史行为做特色工程的思路, 大家也能够思维风暴一下,尝试一些其余的特色。 上面咱们就实现下面的这些特色的制作, 上面的逻辑是这样: 咱们首先取得用户的最初一次点击操作和用户的历史点击, 这个基于咱们的日志数据集做基于用户的历史行为制作特色, 这个会用到用户的历史点击表, 最初的召回列表, 文章的信息表和embedding向量制作标签, 造成最初的监督学习数据集好了,废话不多说 ...

December 3, 2020 · 8 min · jiezi

关于推荐系统:推荐系统多路召回

介绍在第一局部,曾经介绍协同举荐,并利用它实现了一个简略的举荐零碎,在第二局部,咱们简要的剖析了咱们领有的数据,包含每个字段的散布,常见的统计信息等,为接下来的多路召回提供了很好的指引。 回忆一下baseline的思路,咱们首先计算了item的之间的类似度,而后基于用户的正反馈item列表,找到与列表中每一个item类似度最高的topn个item,组成一个列表,最初间接依照类似度得分进行排序,失去最初的举荐后果。 在理论的举荐场景中,通常会有两个阶段,第一个阶段是召回阶段,第二个阶段是排序阶段。第一个阶段召回那些类似度较高的N个item列表,它更关注的是召回率,较为粗略;而排序阶段会应用更为简单的模型进行监督学习(转化为分类的工作),失去分类概率,也就是置信度,最初依照置信度进行排序,取top K个item作为最初的举荐列表。 baseline中其实只蕴含了召回这个阶段,尽管但就这个工作而言,它曾经够了。本节介绍的是多路召回,什么是多路召回呢,比方在一个举荐场景中,咱们能够抉择ItemCF或者UserCF以及基于热点的召回策略等等,因为咱们召回层的目标是为了尽可能的确保召回,所以基于单个的策略必定是成果不如多个策略的,这里就引出了多路召回的概念,也就是多个策略并行的进行召回。上面这个图示意了多路召回的一个例子。 在多路召回中,每个策略之间息息相关,能够应用多种不同的策略来获取用户排序的候选商品汇合,而具体应用哪些召回策略其实是与业务强相干的 ,针对不同的工作就会有对于该业务实在场景下须要思考的召回规定。例如新闻举荐,召回规定能够是“热门视频”、“导演召回”、“演员召回”、“最近上映“、”风行趋势“、”类型召回“等等。 导入相干库 import pandas as pd import numpy as npfrom tqdm import tqdm from collections import defaultdict import os, math, warnings, math, picklefrom tqdm import tqdmimport faissimport collectionsimport randomfrom sklearn.preprocessing import MinMaxScalerfrom sklearn.preprocessing import LabelEncoderfrom datetime import datetimefrom deepctr.feature_column import SparseFeat, VarLenSparseFeatfrom sklearn.preprocessing import LabelEncoderfrom tensorflow.python.keras import backend as Kfrom tensorflow.python.keras.models import Modelfrom tensorflow.python.keras.preprocessing.sequence import pad_sequencesfrom deepmatch.models import *from deepmatch.utils import sampledsoftmaxlosswarnings.filterwarnings('ignore')data_path = './data_raw/'save_path = './temp_results/'# 做召回评估的一个标记, 如果不进行评估就是间接应用全量数据进行召回metric_recall = False读取数据 ...

November 30, 2020 · 13 min · jiezi

关于推荐系统:推荐系统入门之数据分析天池新闻推荐

数据分析在上一节的内容中,曾经应用了ItemCF构建了一个baseline,并失去了一个后果。如果咱们须要在baseline的根底上进一步晋升,就须要对数据进行进一步的剖析。 导入库 import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsplt.rc('font', family='SimHei', size=13)import osimport reimport warningsimport sys%matplotlib inline# 不打印 ignore 级别的音讯warnings.filterwarnings("ignore")读取数据 data_dir = './data'# train datatrain_user_click_df = pd.read_csv(data_dir+'/train_click_log.csv')item_df = pd.read_csv(data_dir+'/articles.csv')item_df = item_df.rename(columns={'article_id': 'click_article_id'}) #重命名,不便后续matchitem_emb_df = pd.read_csv(data_dir+'articles_emb.csv')# test datatest_user_click_df = pd.read_csv(data_dir+'testA_click_log.csv')数据预处理 对每个用户的点击工夫戳进行降序排序,失去排名 train_user_click_df['rank'] = train_user_click_df.groupby(['user_id'])['click_timestamp'].rank(ascending=False).astype(int)test_user_click_df['rank'] = test_user_click_df.groupby(['user_id'])['click_timestamp'].rank(ascending=False).astype(int)计算用户点击文章的次数,并增加新的一列count train_user_click_df['click_cnts'] = train_user_click_df.groupby(['user_id'])['click_timestamp'].transform('count')test_user_click_df['click_cnts'] = test_user_click_df.groupby(['user_id'])['click_timestamp'].transform('count') 数据浏览用户点击日志文件_训练集 train_user_click_df = trn_click.merge(item_df, how='left', on=['click_article_id'])train_user_click_df.head() train_click_log.csv文件数据中每个字段的含意 1. user_id: 用户的惟一标识2. click_article_id: 用户点击的文章惟一标识3. click_timestamp: 用户点击文章时的工夫戳4. click_environment: 用户点击文章的环境5. click_deviceGroup: 用户点击文章的设备组6. click_os: 用户点击文章时的操作系统7. click_country: 用户点击文章时的所在的国家8. click_region: 用户点击文章时所在的区域9. click_referrer_type: 用户点击文章时,文章的起源#用户点击日志信息train_user_click_df.info() ...

November 27, 2020 · 2 min · jiezi

关于推荐系统:推荐系统入门之协同过滤

[TOC] 协同过滤介绍协同过滤包含基于物品的协同过滤和基于用户的协同过滤两种不同形式。 基于物品的协同过滤:给用户举荐与他之前购买物品类似的其余物品。基于用户的协同过滤:给用户举荐与他趣味类似的其余用户购买的物品了解类似度在下面简略的介绍了协同过滤的概率,咱们发现无论是基于物品的协同过滤还是基于用户的协同过滤,都蕴含一个独特的关键词,就是类似度。类似度掂量了用户与用户之间,物品与物品之间的类似水平。在协同过滤中起着至关重要的作用。 在计算类似度之前,咱们通常都会将物品或者用户用一个向量来示意,比方下表示意了4个用户的购买行为,1示意购买,0示意没有。则用户1能够用向量$[1, 0, 1, 0]$来示意。 商品1商品2商品3商品4用户11010用户20100用户31100用户41101用户500?1常见的类似度计算方法次要有 余弦类似度$i$和$j$示意两个不同的用户向量,则它们之间的余弦间隔能够用下式来示意为 $$Simularity(i,j)=\frac{i\cdot j}{||i||\cdot ||j||}$$ 余弦间隔表征的是向量之间的夹角大小,夹角越小,余弦间隔约小。 皮尔逊相关系数相比于余弦间隔,皮尔逊相关系数应用用户向量的平均值进行了修改,缩小了偏置的影响。 $$Simularity(i,j)=\frac{\sum_{p\in P}(R_{i,p}-\bar{R_i})\cdot (R_{j,p}-\bar{R_j})}{\sqrt{\sum_{p\in P}(R_{i,p}-\bar{R_i})^2}\sqrt{\sum_{p\in P}(R_{j,p}-\bar{R_j})^2}}$$ $P$示意所有的物品,$R_{i,p}$示意用户$i$对物品$p$的评分。$\\bar{R_i}$示意用户$i$对所有物品评分的平均值。 基于皮尔逊系数的其余思路下面的皮尔逊相关系数中,应用了用户的均匀评分对类似度进行了修改,这里同样对类似度进行了修改,只不过应用的是物品的均匀评分。 $$Simularity(i,j)=\frac{\sum_{p\in P}(R_{i,p}-\bar{R_p})\cdot (R_{j,p}-\bar{R_p})}{\sqrt{\sum_{p\in P}(R_{i,p}-\bar{R_p})^2}\sqrt{\sum_{p\in P}(R_{j,p}-\bar{R_p})^2}}$$ $\\bar{R_p}$示意物品$p$的所有评分的平均值。 在类似用户的计算过程中,任何正当的类似度计算过程都能够作为类似用户计算的规范。 最终后果的排序基于用户的协同过滤(UserCF)有了用户之间的类似度,咱们就能够依据类似度来进行排序,取出TopN的最类似的用户。依据这些类似用户的已有评分,咱们就可能对指标用户的偏好进行预测了。 指标用户的评估预测通常应用的是用户之间的类似度加权均匀 $$R_{up}=\frac{\sum_{s\in S}(W_{us}\cdot R_{sp})}{\sum_{s\in S}W_{us}}$$ $R_{up}$示意指标用户$u$对商品$p$的评分,$W_{us}$示意指标用户$u$和用户$s$的类似度,$S$示意与用户$u$类似度最高的TopN用户列表。 失去指标用户对于每个商品的评分预测后,就能够对所有的评分预测进行排序,最终决定要向用户举荐什么物品了。 基于用户的协同过滤思路很简略,就是类似的用户应该具备相似的趣味偏好,但在技术上存在一些问题 互联网平台上,用户数往往远远大于物品数,这使得每次类似度计算须要消耗大量工夫和资源,而且会随着用户的增长,所需的资源和工夫出现$n^2$的增长,这通常是无奈承受的。用户的行为通常是稠密的,找到与指标用户类似的用户是十分困难的,并且很多状况下找到的类似用户并无关系。这使得UserCF很难利用在正样本获取艰难的举荐场景,比如说大件商品或奢侈品等等。基于物品的协同过滤(ItemCF)因为下面提到的UserCF中的两个缺点,在最后的举荐零碎中,都没有采纳UserCF,而是采纳了ItemCF。 ItemCF是基于物品类似度进行举荐的协同举荐算法,通过计算物品之间的类似度来失去物品之间的相似矩阵,而后再找到用户的历史正反馈物品的类似物品进行排序和举荐。 ItemCF的步骤如下: 依据所有用户的历史数据,构建以用户(假如用户数为m)为行坐标,物品(假如物品数为n)为列坐标的$m\\times n$维的共现矩阵。计算共现矩阵列向量之间的类似度,失去一个$n\\times n$的一个类似度矩阵。获取用户的历史行为数据中的正反馈物品列表利用物品的类似度矩阵,针对指标用户的历史行为中的正反馈物品,找出类似的TopK个物品,组成类似物品汇合。对类似物品汇合,利用类似度分值进行排序,生成最终的举荐列表。这里,我用本人艰深的语言来了解它,首先,咱们依据共现矩阵($m \\times n$, m示意用户数,n示意物品数)计算类似度矩阵,有了类似度矩阵,而后咱们依据用户的历史行为数据失去正反馈的物品列表(就是用户的称心的物品),比如说正反馈的物品列表为[1, 3, 4]那么对于物品库中的除正反馈物品外的其余物品,都会计算出一个得分,计算公式如下所示 $$R_{u,p}=\sum_{h\in H }(W_{h,p}R_{u,h})$$ $W_{h,p}$示意物品$h$和物品$p$的类似度,$R_{u,h}$示意用户$u$对物品$h$的评分, $H$示意用户$u$的正反馈物品列表。 将计算出来的得分进行排序,最终失去TopN的后果。 UserCF和ItemCF的利用场景从新回顾一下UserCF和ItemCF的基本概念,一个是基于类似用户,一个是基于类似物品。 因为UserCF的固有个性,使其具备人造的社交属性,对于社交类型的平台,应用UserCF更容易发现趣味类似的好友。另外社交属性为热点新闻的流传同样提供了人造的路径,因为新闻自身的趣味点比拟扩散,相比用户对于不同新闻的趣味偏好,新闻的实时性和热点性显得更为重要。UserCF更容易用来发现热点,跟踪热点。 ItemCF更适宜趣味变动较为稳固的利用,比方购物App等,用户在一段时间内的趣味是绝对固定的。 基于协同过滤的新闻举荐零碎这里以天池平台上的一个新闻举荐我的项目来学习举荐零碎中的协同过滤算法。 赛题简介此次较量是新闻举荐场景下的用户行为预测挑战赛, 该赛题是以新闻APP中的新闻举荐为背景, 目标是要求咱们依据用户历史浏览点击新闻文章的数据信息预测用户将来的点击行为, 即用户的最初一次点击的新闻文章, 这道赛题的设计初衷是疏导大家理解举荐零碎中的一些业务背景, 解决理论问题。 数据详情该数据来自某新闻APP平台的用户交互数据,包含30万用户,近300万次点击,共36万多篇不同的新闻文章,同时每篇新闻文章有对应的embedding向量示意。为了保障较量的公平性,从中抽取20万用户的点击日志数据作为训练集,5万用户的点击日志数据作为测试集A,5万用户的点击日志数据作为测试集B。具体数据表和参数, 大家能够参考赛题阐明。上面说一下拿到这样的数据如何进行了解, 来无效的发展下一步的工作。 ...

November 25, 2020 · 4 min · jiezi

搜索场景下的智能推荐演变之路

摘要:传统的推荐手段主要还是深度挖掘用户行为和内容本身相似性的价值,包括但不限于协同过滤,内容表征+向量召回,以及各式各样的点击率预估模型,然后这样的推荐行为缺乏内在的逻辑性和可解释性,有一种知其然,不知所以然的体感。本文中,阿里巴巴高级算法专家王悦就为大家分享了搜索场景下的智能推荐演变之路。以下内容根据演讲视频以及PPT整理而成。 点击查看阿里巴巴AI智能专场直播 演讲嘉宾简介:王跃(跃神),阿里巴巴高级算法专家。浙江大学硕士毕业,阿里巴巴高级算法专家,加入阿里巴巴以来一直致力于研究搜索推荐相关技术,相关工作包括自然语言处理,查询词分析技术研究,知识图谱数据构建,实体推荐等多个不同方向。当前是夸克浏览器智能推荐业务业务负责人,致力于推动推荐从传统的用户行为推荐向知识化推荐的升级,从而提升用户信息获取信息的边界,加快信息决策的效率。 本次分享将首先介绍神马搜索在推荐领域有哪些应用场景,之后为大家分享在神马搜索的推荐系统中所做的召回和排序相关的工作。 一、概览场景介绍首先为大家介绍神马搜索的推荐场景有哪些,比如大家在向搜索框输入内容之前,搜索框就会提供一些预置的搜索词,这属于没有搜索Query的推荐。其次,如果大家点击网页之后返回结果,神马搜索会在URL下面提供一些相关的Query,这是与URL本身相关的推荐。再次,还有Query推荐和相关搜索,这中推荐的主要目的是引流,国内的搜索引擎基本上都是商业化的产品,因此通过这样的推荐方法就能够很好地吸引一些流量进来。此外,还有体感比较好的实体推荐,以及在内容消费页面所做的相关推荐。 推荐大致可以分为三个阶段,首先在输入之前,神马搜索引擎会基于用户画像以及其他的一些相关推荐技术将一些内容推荐给用户;第二个阶段就是在搜索的结果页进行推荐;最后一个阶段就是在内容页面上做一些相关推荐。从另外一个维度上来看,推荐也可以分为三个部分,分别为没有Query的推荐、有Query的推荐以及基于URL的推荐。 技术大图正如下图所展示的,推荐的业务应用场景非常多,因此无论是从横向还是纵向上进行划分,都可以将推荐划分为多个视角。而如果对于每种推荐都从头到尾搭建一套系统,那么成本将会非常高,而UC团队有一套比较通用的技术体系来支撑如下图所示的推荐相关业务。搜索场景下智能推荐的技术大图可以大致分为三个部分,最底层是数据以及数据相关的梳理;其上层就是通过召回以及排序等手段对于数据进行一定的处理;最上面一层就是使用处理好的数据来支撑业务。 对于上层大部分的推荐场景而言,所采用的召回方法基本都是相同的,而所采用的排序方法往往不同。比如对于预置词这种业务而言,它是没有Query的,因此在做模型设计的时候就无法利用这些信息。 二、召回接下来为大家整体地介绍一下推荐系统中的召回体系,在本次分享中只会涉及其中比较通用的4种召回方法,但实际上召回体系远远不止这4种,一些比较通用的召回方法没有在本文中列出。 用户行为召回在召回部分介绍的第一种方法就是用户行为召回,也就是去深挖用户行为的价值。用户行为的挖掘是搜索引擎推荐的重要环节,这部分会针对于用户行为做两件事情。第一件事情就是从Session的角度来分析哪些Query经常会出现在一起,这样分析也会遇到一些问题,比如首先要去区分Session里面不同的Query类型,在搜索引擎里面可以自己主动地发起一次搜索,也可以自己去点击一些推荐结果。但是这两种行为存在一定的区别,比如主动搜索和被动通过推荐来搜索是不同的,主动搜索行为往往会获得较高的分数,如果在比较靠后的位置点击了推荐结果和在相对比较靠前的位置点击了推荐结果的行为也是不同的。因此,在这里需要对于不同类型的行为做一些权重计算,同时做一些比较机器化的规则,比如在某一个Session里面,某一个Query是用户最后一次搜索,此时就需要去考虑这个Query是不是已经满足了用户需求,因此会对于这些Query加一定的权重。 第二个问题就是时效性优化问题,对于一些头部的Query而言,可能一天之内就能达到几万甚至十万的量级。对于这样的Query,通常的做法就是拉一个时间窗口去看所有Session里面Query的情况如何。但实际上对于这些头部的Query没有任何意义,因为其一天的数据就足够分析了,因此在这种情况下会做一些采样;对于一些长尾的Query则会做一些时间窗口的拉长操作。第三个问题是稀疏优化,对于前面所提到的基于URL的推荐而言,通常的做法就是收集用户点击了URL之后又搜索了哪些Query的行为,但是这种情况下点击的URL往往是很稀疏的,因此会使用URL下面本身的一些与Title相似的Doc共享推荐的List实现基于文本的泛化,或者通过相似Query共享推荐List实现基于行为的泛化,这样一来推荐的效果和覆盖率都会有极大的提升。 行为分析下图展示的是协同过滤算法,但是经典的协同过滤算法往往存在一些问题,比如同一个Item权重的分配而言,在行为非常丰富的用户和行为较少的用户之间,可能更加倾向于前者。 但是这样的做法并不一定合理,因此我们复用了集团的一些成果,做了两点主要的改进,第一个就是尽量地降低行为特别丰富的用户的比重,使得其相对比较平滑。第二个就是构建如上图所示的菱形结构,进而达到闭环的效果,使得推荐的理由更加强烈一些。综上所述,可以从入度出度、行为丰富度不同等闭环的结构上面做优化,来提升整体协同过滤类算法的效果。 标签召回基于标签的召回与基于用户画像的召回非常类似,对于用户画像而言,现在业界比较传统的做法就是在用户身上打上各种各样的标签,比如性别、年龄以及爱好等。因此,这里将基于标签的召回和基于用户画像的召回合在一起讲解。这里列举了一个例子就是在做APP推荐时如何去分析偏长尾的标签,比如搜索“什么软件拍照带耳朵?”时能够发现非常丰富的问答数据,并且发现Faceu这款APP在答案里面。而如果其他的问答网站里面反馈出了其他的APP,就能计算出Faceu和其他拍照APP之间存在非常强大的相关性,这样一来可以做一些关联的推荐,并且可以标注出其推荐者。 标签召回主要包括两个步骤,第一步就是建立比较完整的标签体系,将标签归纳到比较稀疏的链路下面去。在定义好这些链路体系之后,第二步就可以分门别类地去进行挖掘,这里的挖掘相对而言还是比较传统的,比如先分取一些Query,然后去判断有哪些数据,并对于已有的数据进行一些标注,做一些标签的识别,之后进一步扩大。当我们累积到一定量之后,就可以尝试借助有监督的方法实现进一步的泛化。 知识图谱召回基于知识图谱的召回是最近一段时间内在学术界比较火的方法。UC团队在基于知识图谱的召回方面也做了大量的尝试,大致分析了一下有这样几类算法,比如文本建模算法DLA和Doc2vec,知识表示算法tranE、transH、transD以及transR,网络关系算法DeepWalk、Node2Vec以及SNDE等。文本建模算法基本上都是无监督学习,因此没有办法很好地利用关系网络,主要是利用文本信息;知识表示算法对于关系的稠密度要求非常高,如果关系稠密度没有达到要求,那么采样效果就会非常差;基于深度学习的网络关系算法即可以结合文本信息也可以融合关系网络。综上所述,基于深度学习的网络关系算法相对而言比较中庸一点,能够同时利用文本和网络信息,整体效果也会相对好一些。 UC团队主要针对Node2vec的基础版本做了一些优化。之所以优化Node2vec是因为其具有深度优先和广度优先的机制,能够使得其整个训练过程和方向变得可控。Node2vec的过程主要可以分为3部分,主要就是以知识图谱这个图关系网络为基础做随机游走,并且控制随机游走需要深度优先还是广度优先,深度优先会更加关注全局信息,而广度优先则会更加关注Doc信息。UC团队在Node2vec上面主要做了两方面优化,一个是数据增广,也就是增加了用户行为数据以及百科数据和超链接数据,将这些数据抽取出来实现层级化,这样就能够在一定程度上解决网络稀疏的问题。第二个优化点就是利用深度学习中一个比较好的方法,也就是利用文本信息做embedding,比如在知识图谱里面某一个人物有相应的描述,可以对于这些描述信息进行切词并embedding到网络中来。 向量召回基于向量的召回也是最近几年在学术界和工业界中比较热门的方法。向量召回的出发点就是分析输入的Query或者用户与候选的推荐Query之间的文本语义匹配问题。这个模型是YouTube在2016年发的一篇论文中提出的,UC团队在此基础上进行了改进,比如对于Query以不同的粒度进行切词。此外,Query还会有一些文本特征,比如检索切词、语义切词等,还会将用户画像的特征以及实时信息特征一起训练来提升模型的性能。 下图所展示的是向量召回的效果图,左边的第一列是训练的特征,第二列是召回的数据,第三列是真实的搜索Query。对于向量召回方法而言,有一些优化的方法,比如线上存在真实的排序情况,那么可以将线上真实情况和线下召回的情况做一个比较,从而大致了解向量召回的优势情况以及准确率如何。 三、排序基础相关性在排序部分首先介绍基础相关性。下图中展示了一个Query例子“泰勒级数展开公式”。在线上首先会对于这个Query做切词,切词完成之后,每个Token都会召回一系列的候选Doc,此时会出现一系列的问题,因为已经将Query切成Token了,所以极有可能产生的Doc结果和原始的Query是不相关的,因为切分之后无法得到足够的Query信息。此时,需要借助相关性模型大致地控制所获取的文本与原始Query的相关性,将相关性特别低的候选Doc在这一步过滤掉。在模型设计时也会考虑一些应用的场景,比如在做实体推荐时就会将Query里面实体的信息引入进来,进而实现共享网络。 如果将Query分类信息引入进来就能很好地解决一些歧义的问题。 CTR预估UC团队在两年前做了CTR预估的相关工作,那个时候其他的一些方法还没有成熟,因此这部分做的相对比较简单,主要的工作集中在样本的选择以及特征的选择上面。对于样本选择而言,通常会在一个推荐序列里面将点击过的结果作为正样本,将没有被点击过的结果作为负样本。在模型设计方面,比较重要的是CTR类特征,如果这个特征不佳就会使得整个模型的特征打一个比较大的折扣。而UC团队所实现的CTR预估模型能够达到小时级更新,保证线上的效果。 MABMAB的意思就是“多臂老虎机”,比如一个老虎机有多种可以玩的方法,我们一开始不知道哪种方法才能获胜,因此需要逐个实验每种玩法获胜的几率是多少,最终去确定应该以什么顺序来玩。这和排序是非常相关的,因为在推荐时如果直接使用CTR排序可能导致一些比较好的潜在的推荐Item因为刚刚出来,没有被很多用户点击过,就会导致其永远无法排在前面。此时就需要借助一个探索机制来缓解这样的问题,也就是当使用CTR排序完成之后,并不完全按照CTR去提供排序结果,而是使得所有的推荐候选项都有一定的概率被选中。如果经常性地进行探测,那么推荐结果也会逐渐地收敛。 小结这里简单做一个总结,在本文中已经介绍了大部分的推荐算法。对于召回而言,从精准到泛化基本上可以分为基于检索的召回、基于标签的召回、协同过滤、基于知识图谱的召回以及基于向量的召回。对于排序而言,也介绍了基础相关性、语义相关性以及CTR预估和MAB。 本文作者:游客be77vkb76molw阅读原文 本文为云栖社区原创内容,未经允许不得转载。

September 6, 2019 · 1 min · jiezi

推荐系统协同过滤及其利弊

在上一篇文章中,我们谈到了推荐系统中基于内容的过滤及其利弊,今天我们来看看协同过滤。 与基于内容的过滤(CBF)不同,协同过滤(Collaborative Filtering)技术独立于域,适用于无法利用元数据充分描述的项目,如电影、音乐等。 协同过滤技术(CF)首先会构建用户项目偏好的数据库,即user-item矩阵,然后,计算用户画像之间的相似性,匹配具有相似的兴趣爱好的用户,完成整个推荐。这些用户获得的推荐项目,是他之前未评级但已被其它相似用户评价过的项目。 由CF生成的结果可能是预测,也可能是推荐。预测表示用户i的项目j的预测得分的数值Rij,而推荐是用户最喜欢的前N个项目的列表,如图下所示。 协同过滤可以分为两类:1)基于记忆;2)基于模型。 协同过滤过程基于记忆在用户的搜索过程中,与他兴趣爱好相似的用户之前评价过的项目扮演着重要角色。一旦匹配到与该用户兴趣爱好相似的其他用户,就可以使用不同的算法,结合该用户和其他用户的兴趣爱好,生成推荐结果。 基于记忆的CF可以通过基于用户(user-based)和基于项目(item-based)两种技术实现。 基于用户的CF通过比较用户对同一项目的评级来计算用户之间的相似性,然后计算活跃用户对项目的预测评级,并将该预测作为类似的其他用户对项目评级的加权平均值。 基于项目的CF则利用项目之间的相似性预测结果:从用户-项目矩阵中检索活跃用户评价的所有项目,建立项目相似性的模型,计算项目之间的相似度,然后选择前K个最相似的项目,计算前K个项目的加权平均值,生成预测。 计算物品/用户之间的相似性有很多方法: 计算欧几里得距离: 利用欧几里得距离计算相似度时,将相似度定义如下: 皮尔逊相关系数: 其中sx,sy表示x和y的标准差。 Cosine相似度:Tanimoto系数,也称作Jaccard系数: 基于模型基于模型的CF会使用先前的用户评级来建模,提高协同过滤的性能。建模过程可以通过机器学习或数据挖掘来完成。这些技术包括奇异值分解(SVD)、潜在语义分析、回归分析、聚类分析等。 关联规则(Association Rule)常见的推荐算法,由字面意思可知,从大量用户行为数据中发现有强关联的规则,提高存储效率和性能。优点是能够从大量行为数据中挖掘出无法直接感受到的规则,往往能给出意想不到的规则组合。缺点是难以进行模型评估,一般通过行业经验判断结果是否合理。 关联规则最经典的是购物篮分析,啤酒和尿布就是一个经典案例。运用在早期亚马逊、京东、淘宝等购物推荐场景中,往往表现为“买过这本书的人还买了XXX”,“看了这部电影的人还想看XXX”,其推荐结果包含的个性化信息较低,相对简单粗暴。 聚类分析(Clustering Analysis)聚类技术已应用于不同的领域,如模式识别、图像处理、统计数据分析等。聚类就是将数据对象分组成为多个类或者簇 (Cluster),从而让同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别较大。所以,在很多应用中,一个簇中的数据对象可以被作为一个整体来对待,从而减少计算量或者提高计算质量。人们日常生活的“物以类聚,人以群分”,核心的思想就是聚类。通过聚类,人们能意识到密集和稀疏的区域,发现全局的分布模式,以及数据属性之间的有趣的相互关系。在CF中,聚类分析可以作为其他算法的预处理步骤,简化计算量,提高分析效率。 决策树(Decision Tree)机器学习中,决策树是一个预测模型;代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每个叶结点则对应从根节点到该叶节点所经历的路径所表示的对象的值。决策树仅有单一输出,若想要有复数输出,可以建立独立的决策树以处理不同的输出。从数据产生决策树的机器学习技术叫做决策树学习, 通俗说就是决策树。决策树的简单策略好比公司招聘面试,面试官筛选一个人的简历,如果候选人的各项条件都符合,那么进入初面,初面合格再进入下一轮面试。 人工神经网络(Artificial Neural Network)人工神经网络从信息处理角度对人脑神经元网络进行抽象,建立某种简单模型,按不同的连接方式组成不同的网络。在工程与学术界也经常被简称为“神经网络”或“类神经网络”。神经网络是一种运算模型,由大量的节点(或称神经元)之间相互联接构成。每个节点代表一种特定的输出函数,称为激励函数(activation function)。每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重,这相当于人工神经网络的记忆。网络的输出则依网络的连接方式、权重值和激励函数的不同而不同。网络自身通常都是对自然界某种算法或者函数的逼近,也可能是对一种逻辑策略的表达。 回归分析(Regression Analysis)利用数据统计原理,对大量统计数据进行数学处理,并确定因变量与某些自变量的相关关系,建立一个相关性较好的回归方程(函数表达式),并加以外推,用于预测今后的因变量的变化的分析方法,就叫回归分析。回归分析又可以分为两大类,根据因变量和自变量的个数来分类的话,可分为一元回归分析与多元回归分析;根据因变量和自变量的函数表达式来分类的话,可分为线性回归分析与非线性回归分析。 贝叶斯分类器(Bayesian Classifiers)由于推荐问题可以看成分类问题,因此可以使用机器学习领域中的分类算法加以解决。朴素贝叶斯分类算法是贝叶斯分类算法中比较简单的一种,它的基本思想是:对于给出的待分类物品和既定的类别,计算该物品在各个类别中出现的频率,哪个类别计算出的概率大就将物品归于那个类。在推荐系统中,朴素贝叶斯分类能够在已知某些评分的情况下,通过计算概率预测未知评分。 朴素贝叶斯分类器的主要优点是对孤立的噪声点和不相关的属性具有鲁棒性,并且通过在概率估算中忽略实例来处理缺失值。素贝叶斯分类实现起来比较简单,准确率高,但是分类的时候需要学习全部样本的信息。因此,朴素贝叶斯分类适用于数据量不大,类别较少的分类问题。 协同过滤技术的优缺点协同过滤与CBF相比,优势就是可以在根据各个用户的历史信息推荐项目,跟项目本身的内容属性无关。尽管CF技术取得了一定成功,但仍然存在一些问题: 1.冷启动问题在产品刚刚上线、新用户到来的时候,如果没有用户在应用上的行为数据,也无法预测其兴趣爱好。另外,当新商品上架也会遇到冷启动的问题,没有收集到任何一个用户对其浏览,点击或者购买的行为,也无从对商品进行推荐。 2.数据稀疏性问题当用户仅对数据库中可用的项目中的一小部分进行评分时,就会导致这种问题。数据规模越大,一般而言越稀疏。 3.可扩展性问题这是与推荐算法相关的另一个问题,因为计算通常随着用户和项目的数量线性增长。当数据集的量有限时,推荐技术是有效可行的,但当数据集的量增加时,生成推荐的量就不太好。在这种情况下,用于解决可扩展性问题和加速推荐生成的方法会基于降维技术,例如奇异值分解(SVD)。 4.同义问题同义词是指名称不同但非常相似的项目。大多数推荐系统很难区分这些项目之间的不同,如婴儿服装和婴儿布料。协同过滤通常无法在两个术语之间建立匹配,也无法计算二者之间的相似性。自动术语扩展、词库构建、奇异值分解(SVD),尤其是潜在语义索引,能够解决同义问题,但缺点是某些添加的术语可能与预期的含义不同,从而导致推荐性能的快速下降。

August 18, 2019 · 1 min · jiezi

推荐系统混合过滤

在之前的两篇文章中,我们分别讲了推荐系统中的基于内容的过滤和协同过滤技术,今天我们一起看看看混合过滤。 推荐系统为了避免单一推荐技术带来的限制和问题,同时也为了能够获得更好的性能,会结合不同的推荐技术。 混合过滤依据的想法是,一种算法可以弥补另一种算法的缺点,多个算法的组合将比单个算法能更准确、有效地提供推荐。 使用多种推荐技术能够弥补模型中某种技术存在的缺陷。组合方法可以是以下任何一种:分别实现算法后组合推荐结果,在协同过滤中加入基于内容的过滤,在基于内容的过滤中加入协同过滤,或者,把基于内容的过滤和协同过滤整合到一个推荐系统中。 加权式指将多种推荐技术的计算结果加权混合产生推荐。加权混合的好处是在推荐过程中直接利用所有推荐技术的优势,整个系统性能都直接与推荐过程相关。不过这种技术有一个假设的前提是,对于整个空间中所有可能的项,使用不同技术的相关参数值都基本相同。 切换式指根据问题背景和实际情况采用不同的推荐技术。比如,使用基于内容推荐和协同过滤混合的方式,系统首先使用基于内容的推荐技术,如果它不能产生高可信度的推荐,然后再尝试使用协同过滤技术。因为需要各种情况比较转换标准,所以这种方法会增加算法的复杂度和参数化,当然这样做的好处是对各种推荐技术的优点和弱点都比较敏感。 级联式级联式技术在迭代细化过程来构建不同项目之间的偏好顺序。它是一个分阶段的过程:前一种方法的推荐通过另一种方法得到了改进。第一推荐技术输出粗略的推荐列表,该推荐列表又由下一推荐技术改进。由于迭代的粗略到精细的特性,级联式技术非常有效并且能容忍噪声。 合并式同时采用多种推荐技术给出多种推荐结果,为用户提供参考。每个项目都有来自不同推荐技术的推荐。在合并式中,个体项目的表现并不总是影响局部的整体表现。 特征组合特定推荐技术产生的特征被输入到另一种推荐技术。这种技术的好处是,它并不总是完全依赖于协同过滤的数据源。一般会将协同过滤的信息作为增加的特征向量,然后在这增加的数据集上采用基于内容的推荐技术。特征组合的混合方式使得系统不再仅仅考虑协同过滤的数据源,所以它降低了用户对项目评分数量的敏感度,相反,它允许系统拥有项的内部相似信息,其对协同系统是不透明的。 特征递增前一个推荐方法的输出作为后一个推荐方法的输入。在特征递增式中,第二种推荐方法使用的特征包括了第一种的输出。而在级联式中,第二种推荐方法并没有使用第一种产生的任何等级排列的输出,其两种推荐方法的结果以一种优化的方式进行混合。 元层混合由一种推荐技术生成的内部模型用作另一种推荐技术的输入。与单个评级相比,生成的模型总是更丰富的信息。元层混合式能通过使用第一种技术学习的整个模型作为第二种技术的输入,从而解决协同过滤中的稀疏性问题。与特征递增型不同的是,特征递增式使用一个学习模型产生的某些特征作为第二种算法的输入。

August 18, 2019 · 1 min · jiezi

当你打开天猫的那一刻推荐系统做了哪些工作

阿里妹导读:当年打开天猫的那一刻,它为你完成了华丽的变身,成为世上独一无二的“天猫”,这就是智能推荐的力量。今天,来自阿里巴巴搜索推荐事业部的算法工程师陈启伟为你介绍天猫如何玩转首页个性化推荐,揭开搜索推荐的神秘面纱。天猫首页作为用户打开手机天猫App的第一印象,所推荐的商品极大地决定了用户接下来的行为,对用户流量的承接与分发、提升用户购物体验和呈现天猫货品的性价比、品质感及品牌力起到至关重要的作用,成为提升天猫用户体验的关键环节之一。 1、场景介绍天猫首页的场景主要包括大促会场入口和日常频道两大类,如图1所示。其中左图为大促会场入口,包括主会场入口和行业会场入口;主会场入口通过为用户推荐7个商品(3个在中间动态轮播)给大促主会场进行引流,引流 UV 达数千万以上;行业会场入口通过为用户推荐4个个性化会场和商品为数万的会场引流。右图为日常频道,包括限时抢购、天猫好物、聚划算、天猫闪降和精选频道;首页通过个性化推荐商品为各个特色的频道引流,通过各个频道来培养用户心智,让用户在天猫逛起来。 过去的首页推荐更多的是在相关性推荐的单一数据目标上进行优化,如今天猫首页的推荐系统不仅仅考虑推荐结果的相关性,还在推荐结果的发现性、多样性等方面上做了更深度的优化,"效率和体验并重"成为天猫首页新的优化目标。Graph Embedding、Transformer、深度学习、知识图谱等新的技术已先后在天猫首页的推荐系统成功落地,为场景带来了两位数的点击率提升和两位数的疲劳度下降。 2、推荐框架天猫首页的个性化推荐系统可以分为召回、排序和机制三个模块。其中,召回模块主要是从全量的商品素材中检索出用户感兴趣的 TopK 个候选商品,排序模块专注于用户对商品的 CTR 预估,机制模块负责后期的流量调控、体验优化、策略调控等和最终的商品排序。整个推荐系统采用 Graph Embedding、Transformer、深度学习、知识图谱、用户体验建模等新的技术构建起来,后面章节将介绍这个推荐系统的关键技术点。 3、召回3.1 Ranki2i Item-CF 是目前应用最广泛的召回算法,其原理是根据两个商品被同时点击的频率来计算两个商品之间的相似度 simScore,得到 i2i 表;然后通过用户的 trigger 去查询 i2i 表,扩展用户感兴趣的商品。Item-CF 的基本算法虽然简单,但是要获得更好的效果,往往需要根据实际的业务场景进行调优。清除爬虫、刷单等噪声数据,合理选择计算商品之间相似度的数据的时间窗口,引入时间衰减,只考虑同一个类目下商品对,归一化、截断、打散等策略对优化 Item-CF 的效果都有很大的帮助。 Ranki2i 是一种改进的 Item-CF 算法,其在 item-CF 得到的两个商品之间的相似度 simScore 的基础上再乘以该 trigger item 所召回的该 target item 在过去一段时间内的 ctr (注意 ctr 的计算需要进行适当的平滑),对 i2i 的 simScore 进行修正,使得 i2i 表不仅考虑了两个商品的点击共现性,还考虑了召回商品的点击率。 我们基于全网的点击数据和天猫首页场景内的日志来计算 Ranki2i 表,并部署在检索系统 Basic Engine 上,对每个访问天猫首页的用户,从基础特征服务系统 ABFS 中获取用户的 trigger,并以此查询 Ranki2i 表来召回用户感兴趣的商品。 经典 Item-CF 类算法直接根据两个商品被同时点击的频率来计算两个商品之间的相似度,在寻找用户点击商品的相似、相关以及搭配商品上都有很大的优势,且其具有简单、性能高等特点,已成为目前应用使用最为广泛的召回算法。然而由于经典 Item-CF 类算法的召回结果的候选集限定在用户的历史行为类目中,并且算法难以结合商品的 Side Information,导致其推荐结果存在发现性弱、对长尾商品的效果差等问题,容易导致推荐系统出现“越推越窄”的问题,从而制约了推荐系统的可持续发展。为了跟精准地给用户推荐心仪的商品,同时维护推荐系统的可持续发展,解决推荐系统的发现性推荐和长尾推荐等问题,我们团队提出了 S3Graph Embeeding 算法和 MIND 算法。 ...

June 3, 2019 · 2 min · jiezi

阿里搜索推荐系统又双叒叕升级了

阿里妹导读:搜索导购产品作为搜索的流量入口,承载了为用户导购推荐、搜索流量分流的重要功能。主要产品包括:首页底纹、下拉推荐、搜索发现、导航、历史搜索等。经过几年的探索和积累,各个产品越发地成熟,机器学习算法广泛地应用于导购产品中,取得了显著的效果。在支撑好手淘搜索业务的基础上,搜索导购也积极地拓展边界,支持了集团内大量的产品线。因此对搜索导购产品线提出了更高的要求:不仅需要提升本身产品的效率,更好地支持手淘搜索业务,同时也需要有一套灵活的框架,支持更多更广的业务。 一、系统框架导购升级的优化思路从三个方向着手:1.策略升级。利用深度学习及异构网络的思想,对用户个性化进行更深的理解和建模;同时对因马太效应引起的独立query数下降等问题进行优化。 2.导购外投。在包括会场激活页、猜你喜欢等渠道进行搜索导购赋能,为用户打通搜索通路。 3.产品创新。一方面对现有的产品进行创新升级,如激活页、下拉推荐等;另一方面积极尝试新产品形态,如首页热词、搜索动态卡片等。 搜索导购核心解决对消费者关键词推荐的问题,因此虽然产品众多,形态各异,但是在底层架构上有很多共性,因此我们设计了一套通用灵活的框架进行支持。 在召回阶段,我们丰富了召回方式;并根据不同的渠道、场景以及产品形态,选择不同的召回策略得到候选query词candidates。 在排序阶段,我们不仅将深度学习引入导购算法框架中,而且创新的加入了异构网络的思想,将用户不同路径的序列信息结合lstm等模型进行有效融合,对消费者进行更深入的理解。 在业务策略阶段,我们利用 jaccard 系数、编辑距离等进行了对语义重复问题进行了优化,同时结合E&E机制对马太效应较为严重的场景进行了升级,并增加了效率轮播机制使得效率进一步的得到提升。 接下来以几个具体的产品来进行详细的介绍。 二、详细方案2.1 底纹推荐优化 在底纹推荐的算法优化中,我们创新性地提出了基于异构网络(Heterogeneous Information Network,后面简称HIN)的推荐方法,推荐框架如下图所示: user,item 和 query 是手淘中三种基本类型的节点,这三种类型节点之间又有不同的交互关系,比如,user 直接点击 item,user 通过查询 query 进入搜索,并在搜索里发生 item 的点击等。 但是,大多数传统推荐方法只关注特征工程,忽略了这些不同节点之间的关联关系。同时电商领域的大规模数据体量(一亿query,数十亿user和item)也是需要考虑的问题。因此我们设计提出了一种基于元路径embedding 表示的大规模 query 推荐方法,MetaPath-guided Embedding for Large-scale Query Recommendation(MELQR),它采用异构网络对 query推荐进行建模,并利用元路径通过聚合局部邻居信息来指导 user 和 query 的表示学习,此外,我们对异构网络中所有节点用term embedding的某种融合方法来进行表示,从而避免了网络学习中的大规模参数问题。 该模型结合扩召回、动态展示等策略,对线上底纹使用uv提升10%+,引导成交金额提升10%+。值得一提的是,该模型目前也同步使用到了导购的其它产品例如搜索发现、首页热词等,效果的提升同样非常明显。 2.2 首页热词优化 首页热词是今年搜索在手淘首页的一个创新性产品,可以帮助用户通过关键词找到感兴趣的商品,增强用户的搜索心智。 首页热词与底纹推荐共享系统框架与算法框架 2.3 下拉推荐优化 下拉推荐上一个版本的优化目标在于提升下拉引导pv在搜索pv中的占比,即下拉使用率。上个版本试图拟合的是用户对下拉所展示的 query 的偏好程度。但是在其使用的统计类特征中,使用的特征均都是下拉引导的数据。这就带来了一个比较严重的问题,在目前的产品形态下,每次用户输入,只能展示10个候选的 query。因此一开始展示相对较多的 query 会具有相对较高的统计值,而较高的统计值会促进该query 在排序中排到更靠前的位置。因此形成循环,久而久之,在某些特定的 query下,下拉推荐候选词的统计值特征会有非常大的差异。由此形成马太效应。马太效应一个最严重的问题就是会导致下拉展示的 query 会过度收敛到一个较小的集合中,导致引导的独立 query 数下降。 针对这些问题,我们对下拉推荐模型进行了系统的重构,框架如下: ...

May 14, 2019 · 1 min · jiezi

推荐系统召回与评估

召回策略 基于协同过滤 基于item-based:相似的人会有相同的喜好基于user-based:喜欢一个物品的用户会喜欢相似的物品倒排索引 分类关键词topic...基于内容匹配 基于内容标签基于知识图谱...基于热门度评估指标 精确率:表示的是预测为正的样本中有多少是真正的正样本,例如我们给用户推荐了100条新闻,其中10条用户产生了点击,那么准确率为10/100 = 0.1召回率:表示的是样本中的正例有多少被预测正确了, 例如我们给用户推荐了100条新闻,其中10条用户产生了点击,而用户最终在平台上总共点击了200条新闻,那么召回率为10 / 200 = 0.05, 表示的是推荐系统推荐的那些符合用户兴趣并产生点击的新闻量占了用户实际总共点击的新闻 有多少比例

May 5, 2019 · 1 min · jiezi

贾扬清:我对人工智能方向的一点浅见

阿里妹导读:作为 AI 大神,贾扬清让人印象深刻的可能是他写的AI框架Caffe ,那已经是六年前的事了。经过多年的沉淀,成为“阿里新人”的他,对人工智能又有何看法?最近,贾扬清在阿里内部分享了他的思考与洞察,欢迎共同探讨、交流。贾扬清,浙江上虞人,毕业于清华大学自动化系,在加州大学 Berkeley 分校获得计算机博士学位,目前担任阿里计算平台掌门人。最近几年深度学习的流行,大家一般认为是从2012年 AlexNet 在图像识别领域的成功作为一个里程碑。AlexNet 提升了整个业界对机器学习的接受程度:以前很多机器学习算法都处在“差不多能做 demo ”的程度,但是 AlexNet 的效果跨过了很多应用的门槛,造成了应用领域井喷式的兴趣。当然,任何事情都不是一蹴而就的,在2012年以前,很多成功的因素已经开始逐渐显现:2009年的 ImageNet 数据库奠定了大量标注数据的基础;2010年开始,IDSIA 的 Dan Ciresan 首次用 GPGPU 进行物体识别;2011年,北京的 ICDAR 大会上,神经网络在中文离线识别上大放异彩。就算是 AlexNet 中用到的ReLU层,早在2001年神经科学的文献中就有提及过。所以,一定程度上说,神经网络的成功也是一个水到渠成的过程。2012年以后的事情,大家可以读到很多,这里就不再赘述。成功与局限在看待神经网络成功的同时,我们也要进一步深挖其背后的理论背景和工程背景,为什么神经网络和深度学习在几十年前失败,但是现在却成功了?它成功的原因是什么?而它的局限又在什么地方?我们这里只能片面地说几个重点:成功的原因,一点是大数据,一点是高性能计算。局限的原因,一点是结构化的理解,一点是小数据上的有效学习算法。大量的数据,比如说移动互联网的兴起,以及 AWS 这样低成本获得标注数据的平台,使机器学习算法得以打破数据的限制;由于 GPGPU 等高性能运算的兴起,又使得我们可以在可以控制的时间内(以天为单位甚至更短)进行 exaflop 级别的计算,从而使得训练复杂网络变得可能。要注意的是,高性能计算并不仅限于 GPU ,在 CPU 上的大量向量化计算,分布式计算中的 MPI 抽象,这些都和60年代就开始兴起的 HPC 领域的研究成果密不可分。但是,我们也要看到深度学习的局限性。今天,很多深度学习的算法还是在感知这个层面上形成了突破,可以从语音、图像,这些非结构化的数据中进行识别的工作。在面对更加结构化的问题的时候,简单地套用深度学习算法可能并不能达到很好的效果。有的同学可能会问为什么 AlphaGo 和 Starcraft 这样的算法可以成功, 一方面,深度学习解决了感知的问题,另一方面,我们也要看到还有很多传统的非深度学习算法,比如说 Q-learning 和其他增强学习的算法,一起支撑起了整个系统。而且,在数据量非常小的时候,深度学习的复杂网络往往无法取得很好的效果,但是很多领域,特别是类似医疗这样的领域,数据是非常难获得的,这可能是接下去的一个很有意义的科研方向。接下去,深度学习或者更广泛地说,AI 这个方向会怎么走?我个人的感觉,虽然大家前几年一直关注AI框架,但是近年来框架的同质化说明了它不再是一个需要花大精力解决的问题,TensorFlow 这样的框架在工业界的广泛应用,以及各种框架利用 Python 在建模领域的优秀表现,已经可以帮助我们解决很多以前需要自己编程实现的问题,因此,作为 AI 工程师,我们应该跳出框架的桎梏,往更广泛的领域寻找价值。挑战往上走,我们会遇到产品和科研的很多新挑战,比如说:传统的深度学习应用,比如说语音、图像等等,应该如何输出产品和价值?比如说,计算机视觉现在基本还是停留在安防这个层面上,如何深入到医疗、传统工业,甚至社会关爱(如何帮助盲人看见这个世界?)这些领域,是不仅需要技术,还需要产品的思考的。除了语音和图像之外,如何解决更多问题。在阿里和很多互联网企业中有一个“沉默的大多数”的应用,就是推荐系统:它常常占据了超过80%甚至90%的机器学习算力,如何将深度学习和传统推荐系统进一步整合,如何寻找新的模型,如何对搜索和推荐的效果建模,这些可能没有像语音和图像那么为人所知,却是公司不可缺少的技能。即使在科研方向,我们的挑战也刚刚开始:Berkeley 的教授 Jitendra Malik 曾经说,“我们以前是手工调算法,现在是手工调网络架构,如果囿于这种模式,那人工智能无法进步”。如何走出手工调参的老路,用智能提升智能,是个非常有意思的问题。最开始的 AutoML 系统依然停留在用大量算力暴力搜索模型结构的层面上,但是现在各种更高效的 AutoML 技术开始产生,这是值得关注的。机会往下走,我们会发现传统的系统、体系结构等知识,计算机软件工程的实践,会给 AI 带来很多新的机会,比如说:传统的 AI 框架都是手写高性能代码,但是模型如此多变,新的硬件平台层出不穷,我们应该如何进一步提升软件效率?我们已经看到有通过编译器技术和传统的人工智能搜索方法来反过来优化AI框架,比如 Google 的 XLA 和华盛顿大学的 TVM,这些项目虽然处于早期,但是已经展现出它们的潜力。平台如何提升整合能力。在开源领域,大家的做法是一个人,一台机器,几个 GPU ,训练比较学院派的模型。但是在大规模应用中,我们的数据量非常大,模型非常复杂,集群还会出现各种调度的挑战(能不能一下子就要求256个 GPU ?计算资源是否可以弹性调度?),这些对于我们自己的机器学习平台,以及云上向客户提供的服务,都提出了非常多的挑战。如何进行软硬件的协同设计。在深度学习的计算模式开始逐渐固化的时候(比如说 CNN ),新硬件和特殊硬件(比如 ASIC )的优势就开始体现出来了。如何实现软硬件的协同设计,防止“硬件出来了,不知道怎么写程序”或者“模型已经变了,硬件一出来就过时了”这样的问题,会是将来几年中很大的方向。人工智能是一个日新月异的领域,我们有一个笑话说,2012年的科研成果,现在说起来都已经是上古时代的故事了。快速的迭代带来的大量机遇和挑战是非常令人兴奋的,无论是有经验的研究者还是新学 AI 的工程师,在当今云化,智能化的年代,如果能快速学习并刷新算法和工程的各种挑战,就可以通过算法创新引领并且赋能社会各个领域。这方面,人工智能领域开源开放的各种代码,科研文章和平台给大家创造了比以前更容易的入门门槛,机遇都掌握在我们自己手中。本文作者: 贾扬清阅读原文本文来自云栖社区合作伙伴“ 阿里技术”,如需转载请联系原作者。 ...

April 15, 2019 · 1 min · jiezi

推荐系统

推荐系统“推荐系统”第一次出现在大众视野源自美国学者Resnick & Varian,其给出得到定义一直沿用至今,电子商务推荐系统是指利用电子商务网站向客户提供商品信息和建议,帮助客户决定应该购买什么产品,模拟销售人员帮助客户完成购买过程。为什么定义要加上电子商务这个领域范围的限制,难道说只有电子商务领域才有推荐系统。我的理解是,推荐系统设计的初衷是解决信息过载问题,帮助用户在茫茫信息中找到对自己有价值的信息,大大节约时间和精力。而电子商务领域在如今是一个非常火的领域,如阿里巴巴,京东商城,交易信息每天都在产生,数据量大是电子商务领域显著的特点,如何利用这些信息挖掘潜在购买力推动着电子商务企业大胆尝试做这件事。推荐系统如网易云音乐网站、抖音小视频、今日头条资讯APP等也都具有数据量大的特点,所以推荐系统在音乐、视频、资讯等领域也很常见。个性化推荐系统传统意义上的推荐系统还不是真正的个性化推荐系统,顾名思义,个性化推荐系统简单理解就是让推荐系统拥有个性化特征,就像推荐系统就是为你本人定制的,清楚你的喜好,实时为你提供推荐服务。而要做到这一点,你的所有历史记录就是个性化推荐系统能利用的信息,它认为你的行为历史代表了你在某个时间点或者时间段的喜好或者需求,恰当地利用这些信息可以给你意想不到的推荐服务。搜索引擎,广告系统个性化推荐系统这么强,以致于许多人已经对它产生依赖性,就像手机成了不可或缺的工具。那推荐系统出现之前又是谁在为大家服务呢?第一个就是搜索引擎,代表作品就是百度浏览器和谷歌浏览器,以及bing搜索,360浏览器等。搜索引擎的出现也是为了解决信息过载,浩如烟海的信息,不仅仅局限在某个领域了,只需要通过几个关键词就可以大致准确地为你查询到相关信息。但是它不同于推荐系统,搜索引擎旨在用户的主动性,用户主动搜索自己想要的东西,用户的需求十分明确,但是缺乏个性化,你搜索出的东西可能是大众需求,不代表个人兴趣。而推荐系统旨在用户的被动性,推荐系统占主动,在某个合适的时间为你“量身”推荐你想要的东西,这时用户的兴趣是模糊的,如我想听好听的歌,但是不知道具体哪一首,这时候推荐系统的优势就显露出来了。第二个是广告系统,好的广告能给企业带来意想不到的财富,差的广告让人所诟病,甚至葬送公司的美好前程。广告系统也是将合适的信息推荐给合适的受众,但是商业化比较强,广告系统一般包含广告主,平台和用户三部分,平台按照广告投递和相应或者成功交易进行计费。广告系统更准确地说对一类人进行推荐服务,如高考培训机构广告投放到学生视野中,健身广告投放到健身社区等。而个性化推荐系统就是针对个人进行“定制”,更具针对性和有效性。推荐系统的发展如何恰当利用用户历史信息是一个关系到推荐效率的重要举措。推荐系统早期是基于内容的推荐系统,比如我买了一件衣服,推荐系统会根据我买的衣服提取衣服特征,比如颜色,材料,品牌等等,然后根据这些信息推荐一件大部分具备这些信息的相似衣服,推荐系统认为既然你喜欢这件衣服,那也可能喜欢与这件衣服相似的衣服。这种算法也遭受了很大的挑战,如提取信息的难度是巨大的,视频信息的提取就是个代表,视频信息量大,时间长,待提取的特征很多,这就给推荐造成了巨大的难度。再者,提取信息这件事需要专业领域的人去做,门外汉始终没有专业领域的人提取信息准确有效,所以也会给推荐带来挑战。为了减少这种挑战,学者转而关注用户行为,提出基于协同过滤的推荐系统,研究用户行为之间和商品之间的潜在相似性,举个例子,用户A买了一件漂亮裙子,恰好用户B也买了同样的裙子,那么推荐系统认为用户A和B具有一定相似性,那么B购买的其它裙子A有一定可能也会喜欢,因此推荐系统就会推荐用户B购买过而用户A没有购买过的衣服。可以看到基于协同过滤的推荐系统并没有考虑裙子的任何属性,只关注用户的购买行为,这就绕开了提取物品或用户信息的瓶颈。基于协同过滤的推荐系统也是如今研究比较广泛的算法。推荐系统的挑战这部分内容来自Linyuan Lü、Matúš Medo的论文Recommender Systems数据稀疏性:一个网站可能存在许多用户和许多项目,用户对电影的喜好通过评分来反应,高分代表喜欢,低分相对来说不那么喜欢。但是一个用户对电影网站上的电影有效评价个数在少数,绝大部分电影并未评分,所以如果将用户和项目视作一个矩阵的话,这个矩阵是稀疏的。可扩展性:计算复杂度,时间复杂度,空间度复杂度冷启动:对于一个新用户和新项目来说,没有任何历史纪录对于推荐系统的确是个挑战精确性和多样性:当任务是推荐可能被特定用户欣赏的物品时,通常最有效的方法是推荐受欢迎和评价较高的物品。然而,这种推荐对用户来说价值很小,因为没有推荐系统,热门对象很容易找到(通常很难避免)。易受攻击:由于推荐系统在电子商务应用中的重要性,它很可能成为恶意攻击的目标,试图不公正地促进或抑制某些项目。有大量的工具可以防止这种行为,从阻止恶意评估进入系统到复杂的抵抗推荐技术。然而,这并不是一个容易的任务,因为随着防范工具的开发,攻击者的策略也越来越先进。例如,Burke等人介绍了八种攻击策略,进一步分为四类:基本攻击、低认知攻击、核攻击和知情攻击。时间因素:虽然实际用户的兴趣具有广泛的不同时间范围(例如,与计划旅行相关的短期兴趣和与居住地点或政治偏好相关的长期兴趣),但大多数推荐算法忽略了评估的时间戳。老观点的价值是否和如何随时间衰减,以及用户评价和项目相关性中的典型临时模式是什么,这是一个正在进行的研究领域。评估方式:虽然我们有很多不同的度量标准,但是如何选择最适合给定情况和任务的度量标准仍然是一个悬而未决的问题。不同推荐算法的比较也存在问题,因为不同的算法可能只解决不同的任务。最后,给定推荐系统的总体用户体验,包括用户对推荐的满意程度和用户对系统的信任,难以在“在线”评估中衡量。因此,经验用户研究仍然是推荐系统值得欢迎的反馈来源。用户界面:有研究表明,为了方便用户接受建议,建议必须是透明的。当明确为什么向用户推荐某一特定项目时,用户会表示赞赏。另一个问题是,由于潜在有趣项目的列表可能很长,因此需要以简单的方式呈现,并且应该易于浏览,浏览不同的建议,这些建议通常通过不同的方法获得。

April 8, 2019 · 1 min · jiezi

如何准备阿里技术面试?终面官现身说法!

春暖花开的季节,阿里巴巴的春招面试正如火如荼地进行着。相信同学们也在面试这块做了许多准备,那么,参加阿里的面试需要注意些什么?今天,我们特别邀请到资深终面官永叔给同学们送上最实用的面试秘籍。嘉宾简介:永叔,资深算法专家,5届校招终面官,历任职于淘宝、阿里妈妈、搜索、优酷等多个部门,主要研究方向为大规模分布式机器学习算法,多模态交互搜索推荐系统,算法博弈论。Q:面试官看简历,最关注哪些部分?A:导师和实验室、研究方向都会关注,还有他的论文,我们都会提前去下载来看,并提前准备问题。其他信息我们会也看看有没有加分项。细节上,邮箱的名字能看出来有些同学很重视细节。TIPS:简历第一页一定要把最关键的信息写上,简历篇幅不要太长。Q:面试过这么多同学,您对同学们有什么面试忠告?A:面试的基本要点很多,很多同学容易犯的一些小问题,我总结几个点分享给大家:1、一定不要迟到,这是起码的尊重。对面试官也是这样的要求。2、对简历内容要有准备。对自己的突出点,包括技术/个性上的亮点,要练习表达,避免临时组织语言。3、尊重事实,如实回答。每个同学擅长点不同,面试官风格也不同,问到自己不清楚的地方,请不要试图去强掰,实事求是回答就好。4、心态放平。碰到压力面试的时候,不要试图去挑起PK的氛围。在面试过程中,面试官的最终目标是希望帮助面试同学,找到问题最优解。做好自己,平时多加练习。Q:面试到底面哪些维度?同学们需要怎么准备?A:阿里的用人理念是非凡人、平常心、做非凡事。我们期待的人员特质是聪明、乐观、皮实、自省。下面用技术类的同学举个例子:计算机类的同学,我们更关注基础。公司有一套完整的流程体系去培养一个工程师,面试更多是基础素质的考察,比如概率、矩阵等。不用特意准备,但基础的知识还是需要去复习的。此外,我们更多看的是你思考的路径,思考的工具和方法,你应对问题的反应如何,过程中融入一些软技能的考察。当然,我们还会考察学生的潜力。自己的项目经历,论文等,这一块的考察我们首先会确认真实性,更多的会关注细节。千万不要把别人的项目写到自己的项目里面,一旦发现后果很严重。另外,Coding能力是必须的,建议一定要练习,并且我们有速度要求。面试官面试过程中会要求在线写代码,实时同步过程。主要考察编码风格、准确性、熟练程度。毕竟没有哪个面试官会用一个在工作技能上无法和团队合作开展工作的人。Q:学历是不是招聘门槛?A: 我们只以能力论英雄,不会看学历。这几年的面试过程中,我们发现一个现象:很多优秀的同学,在日常学习中会主动去了解、重视企业需要的能力项,并不断通过自学习去拉近自己与目标值的距离。这个是非常好的趋势。Q:哪些因素会导致同学面试不通过?A: 我们不会因为学生某个能力不足就PASS掉。面试是一个逐步肯定的过程,不是一个否定的过程。一般面试官最后都会问,你有什么问题要问我的吗?其实面试官希望知道的是同学对职位/部门/公司是否有了解,基于你了解的信息你有什么样的问题,如何在这个环节提出高质量的问题,也反应出来你对这个面试是否重视。但很遗憾,这个环节能回答好的同学并不多。最后这个提问机会是给到他展示自己综合能力的机会,但很多人却把这当做面试结果“comfirm”的环节。还有同学拿问题去考面试官,或者纠结于某个问题应该怎么去回答,完全忘记了面试是展示自己,不是学习交流,也不是PK。Q:如果碰到特殊情况,同学该怎么做?A:整个面试的节奏是面试官和同学共同营造的,所以需要有明显的节奏感。有些问题同学确实任何想法都没有的,或者觉得题意不清晰,一定要确认清楚,请求面试官的确认。现场状态不OK的情况下,一定要说NO,不用去迎合面试官,比如电话质量很差。我们要的是展示自己,面试官做的是协助同学展示最好的自己。Q:说说您面试过哪个同学,让您印象最深刻?A:2018年,我面试过一个同学,目前他已经入职我的团队,面试的时候他提到自己的生活习惯,对管理自己的时间还是很有想法的,自律程度让人吃惊。入职之后,这个同学他也是这么做的,每天早上6-9点是他的学习时间。每天早上6点钟-8点在家看书,8点到公司后,继续再看1个小时的书,风雨无阻。他学习结束,其他人才刚到公司。工作之余,他还投入在工作论文的发表上,刚投出去2篇。业务上,他现在是我们团队的骨干力量。从对他的观察里面,不难发现,优秀的同学基本都来自于高度的自律。Q:您经历过的最糟糕的面试是什么?A:我曾经面试过一类候选人,2分钟的自我介绍候选人滔滔不绝,没有重点,所有问题都会发散,整个面试的过程一直在show off自己,但没有get到问题的关键点。整个面试体验是非常糟糕的。Q:很多学生困惑于该怎么选择岗位,您有什么建议呢?A:尽可能了解这个岗位未来的职业发展是什么样的,是否具备岗位的敲门砖。阿里不同部门内推信息网上有很多,可以找相关的师兄去问。同时,可以去做一些测评,看看自己是否对自我有足够的认知。本文作者:春招火热进行中的阅读原文本文来自云栖社区合作伙伴“ 阿里技术”,如需转载请联系原作者。

April 8, 2019 · 1 min · jiezi

go推荐系统项目介绍

近期想使用推荐系统实现一些功能,由于不懂Java,担心Python的性能不够,因此就关注了go语言实现的开源项目。推荐系统中的协同过滤算法原理协同过滤的原理很简单,就是根据用户对物品或者信息的偏好,发现物品或者内容本身的相关性, 或者是发现用户的相关性,然后再基于这些关联性进行推荐这里主要实现了基于用户和基于项目的协同过滤两种推荐算法1基于用户的协同推荐(User based Collaborative Filtering Recommendation)基于用户协同推荐的原理是,根据所有用户对物品或者信息的偏好,发现当前用户口味和偏好相似的“邻居”用户群, 基于邻居的偏好信息,对用户进行推荐举例, 假设有以下关系A –> a,c 表示用户A喜欢物品a和cB –> bC –> a,c,d可以发现用户A和C的口味偏好相似(他们是邻居),同时C喜欢物品d,那么我们可以推断 用户A也可能喜欢物品dItem based Collaborative Filtering Recommendation基于项目的协同推荐基于项目的协同推荐的原理是,它使用所有用户对物品或者信息的偏好,发现物品和物品之间的相似度, 然后根据用户的历史偏好信息,将类似的物品推荐给用户举例,假设有以下关系A –> a,cB –> a,b,cC –> a根据基于项目的协同过滤原理,可以发现物品a和物品c相似,用户C喜欢a物品,那么可以把c物品推荐给他在github上搜索,发现项目较少,较为完善的是gorse项目gorse: Go Recommender System Enginegorse使用go语言实现推荐系统,提供以下模块方便构建推荐系统:数据:支持从文件加载(提供内置部分数据可用于测试)分离器:支持K-fold、比率、保留方式分离数据集模型:推荐模型基于协同过滤算法,包括矩阵分解、基于临接的方法、Slope One、Co-Clustering2评估:可使用RMSE、MAE来评分,包括准确率、召回率、 归一化折损累积增益NDCG、平均准确率MAP、 MRR、AUC.参数搜寻:使用网格或随机方式寻找最佳超参持久化:保存模型或加载模型SIMD(可选):理论上在对矢量采用AVX2指令,可以获得比单指令快4倍的速度项目地址:github.com/zhenghaoz/gorse推荐项亮著的推荐系统实践 ↩实现推荐系统引擎(一):评分预测 ↩

April 1, 2019 · 1 min · jiezi

【机器学习PAI实战】—— 玩转人工智能之美食推荐

前言在生活中,我们经常给朋友推荐一些自己喜欢的东西,也时常接受别人的推荐。怎么能保证推荐的电影或者美食就是朋友喜欢的呢?一般来说,你们两个人经常对同一个电影或者美食感兴趣,那么你喜欢的东西就很大程度上朋友也会比较感兴趣。在大数据的背景下,算法会帮我寻找兴趣相似的那些人,并关注他们喜欢的东西,以此来给我们推荐可能喜欢的事物。场景描述某外卖店铺收集了一些用户对本店铺美食的评价和推荐分,并计划为一些新老客户推荐他们未曾尝试的美食。数据分析A B C D E F G H I J K0[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],1[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],2[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],3[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],4[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],5[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],6[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],7[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],8[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],9[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]横轴为美食品种,分为A–K 11中,竖轴为用户序号,有0-9 10个人。表内值为某个用户对某种美食的推荐分,0表示其未曾吃过,5分为最高的推荐分。以上数据为实验虚构数据。场景抽象化给定一个用户i,我们根据上面的数据为其推荐N个推荐分最高的美食。模型选择协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。我们也将采用协同过滤来实现商品推荐,并在下面的章节一步步实现基于协同过滤的商品推荐系统。数据处理以上数据,不存在缺失和无意义推荐分,即不超出范围,格式正确。搭建环境首先进入noteBook建模,链接然后创建新实例之后打开实例现在基础环境以及搞定了,我们可以用terminal安装自己需要的包环境。同时可以选择python2或者python3的开发环境。而且左侧的文件系统,支持本地文件的上传下载等。相似度计算在推荐系统中,我们需要计算两个人或商品的相似度,我们可以采用余弦相似度,皮尔逊相关系数等。余弦相似性通过测量两个向量的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1,表示完全一样,而其他任何角度的余弦值都不大于1;并且其最小值是-1,相似度为0。皮尔逊相关系数( Pearson correlation coefficient),是用于度量两个变量X和Y之间的相关(线性相关),其值介于-1与1之间。新建文件recom.py,实现相似度计算函数def cosSim(inA,inB): num = float(inA.T*inB) denom = la.norm(inA)la.norm(inB) return 0.5+0.5(num/denom)推荐分计算在文件recom.py,实现推荐分计算#dataMat 用户与美食的矩阵#user 用户序号#simMeas 相似度算法#item 美食商品def standEst(dataMat, user, simMeas, item): n = shape(dataMat)[1]#商品数 simTotal = 0.0; ratSimTotal = 0.0 for j in range(n):#所有商品,遍历 userRating = dataMat[user,j]#user对该商品的推荐分 if userRating == 0: continue#如果user 未推荐该商品则过滤 #logical_and逻辑与,nonzero非零判断,overLap为均为商品item,j推荐的用户 overLap = nonzero(logical_and(dataMat[:,item].A>0, \ dataMat[:,j].A>0))[0] if len(overLap) == 0: similarity = 0 #以此overLap,计算两商品的相似度。 else: similarity = simMeas(dataMat[overLap,item], \ dataMat[overLap,j]) print(’the %d and %d similarity is: %f’ % (item, j, similarity)) simTotal += similarity ratSimTotal += similarity * userRating if simTotal == 0: return 0 else: return ratSimTotal/simTotal对于特征向量非常稀疏,或者特征之间关联关系明显,协方差较大则需要对原有维度的特征进行降维。这样既可以节省资源加快运算,也可以避免冗余特征带来的干扰。def svdEst(dataMat, user, simMeas, item): n = shape(dataMat)[1] simTotal = 0.0; ratSimTotal = 0.0 U,Sigma,VT = la.svd(dataMat) #奇异值分解 Sig4 = mat(eye(4)*Sigma[:4]) #构建对角矩阵 xformedItems = dataMat.T * U[:,:4] * Sig4.I #数据维度转换 for j in range(n): userRating = dataMat[user,j] if userRating == 0 or j==item: continue similarity = simMeas(xformedItems[item,:].T,\ xformedItems[j,:].T) print(’the %d and %d similarity is: %f’ % (item, j, similarity)) simTotal += similarity ratSimTotal += similarity * userRating if simTotal == 0: return 0 else: return ratSimTotal/simTotal通过计算待推荐商品与已推荐商品的相似度,并乘以该用户对已推荐商品的推荐分,来计算待推荐商品的推荐分。在文件recom.py,加入recommend函数#dataMat 用户与美食的矩阵#user 用户序号#N 推荐前N个商品#simMeas 相似度计算算法#estMethod 推荐分计算算法def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst): #找出user未评分的商品 unratedItems = nonzero(dataMat[user,:].A==0)[1]#find unrated items if len(unratedItems) == 0: return ‘you rated everything’ itemScores = [] #依次计算这些商品的推荐分 for item in unratedItems: estimatedScore = estMethod(dataMat, user, simMeas, item) itemScores.append((item, estimatedScore)) #返回前N个较好分的结果 return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]算法演示如果是本地编辑的文件,可以通过文件上传方式上传到服务器。新建noteBook演示加载算法模板数据展示为序号为2的用户推荐商品总结通常在计算相似度之前,我们需要确定是计算基于商品的相似度(上面的方式),还是计算基于用户的相似度。在现实情况下,我们要根据用户和商品的数据决定选择哪种计算方式。同时,在数据量变大时,我们通常需要先降维,在做商品推荐。部分代码参考《机器学习实战》,本篇文章主要介绍如何使用PAI-DSW实现算法实验。本文作者:伊逍阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

March 13, 2019 · 2 min · jiezi

蚂蚁金服核心技术:百亿特征实时推荐算法揭秘

小叽导读:文章提出一整套创新算法与架构,通过对TensorFlow底层的弹性改造,解决了在线学习的弹性特征伸缩和稳定性问题,并以GroupLasso和特征在线频次过滤等自研算法优化了模型稀疏性。在支付宝核心推荐业务获得了uvctr的显著提升,并较大地提升了链路效率。0.综述在线学习(Online learning)由于能捕捉用户的动态行为,实现模型快速自适应,进而成为提升推荐系统性能的重要工具。然而它对链路和模型的稳定性,训练系统的性能都提出了很高的要求。但在基于原生TensorFlow,设计Online推荐算法时,我们发现三个核心问题:一些资讯推荐场景,需要大量长尾词汇作为特征,需使用featuremap对低频特征频次截断并连续性编码,但耗时且方法aggressive。使用流式数据后,无法预知特征规模,而是随训练逐渐增长。因此需预留特征空间训练几天后重启,否则会越界。模型稀疏性不佳,体积达到数十GB,导致上传和线上加载耗时长且不稳定。更重要的是,在线学习如火如荼,当流式特征和数据都被打通后,能按需增删特征,实现参数弹性伸缩的新一代训练平台成为大势所趋。为了解决这些问题,从2017年底至今,蚂蚁金服人工智能部的同学,充分考虑蚂蚁的业务场景和链路,对TensorFlow进行了弹性改造, 解决了以上三大痛点,简化并加速离线和在线学习任务。其核心能力如下:弹性特征伸缩体系,支持百亿参数训练。group_lasso优化器和频次过滤,提高模型稀疏性,明显提升线上效果。模型体积压缩90%,完善的特征管理和模型稳定性监控。在与业务线团队的共同努力下,目前已在支付宝首页的多个推荐场景全流量上线。其中某推荐位的个性化online learning桶最近一周相比线上多模型融合最优桶提升4.23% , 相比随机对照提升达34.67% 。 某个性化资讯推荐业务最近一周,相比DNN基准uv-ctr提升+0.77%,pv-ctr提升+4.78%,模型体积压缩90%,链路效率提升50%。1. 弹性改造及优势背景:在原生TensorFlow中,我们通过Variable来声明变量,若变量超过了单机承载的能力,可使用partitioned_variables来将参数分配到不同机器上。 但必须指定shape,声明后即不可改变,通过数组索引查找。由于推荐系统中大量使用稀疏特征,实践中一般采取embedding_lookup_sparse一类的方法在一个巨大的Dense Variable中查找向量并求和,来代替矩阵乘法。开源Tensorflow限定了Variable使用前必须声明维度大小,这带来了两个问题:1)需要预先计算特征到维度范围内的int值的映射表,这一步操作通常在ODPS上完成。因为需要扫描所有出现的特征并编号,计算非常缓慢;2)在online learning场景下,为了容纳新出现的特征,需要预留一部分维度空间,并在线上不断修改映射表,超过预留空间则需要重新启动在线任务。为了突破固定维度限制,实现特征的动态增加和删除,最朴素的优化想法是在TensorFlow底层实现模拟字典行为的Variable,并在此基础上重新实现Tensorflow上层API。由此我们进行了优化,在server新增了基于HashMap的HashVariable,其内存结构如下:在声明该变量时,只需增加一句,其他训练代码皆不需改动:每个特征都通过hash函数映射到一个2的64次方大小的空间内。当需要计算该特征时,PS会按需惰性创建并返回之。但其上层行为与原生TF一致。由于去掉了featuremap转ID的过程,我们内部形象地将其称为“去ID化”。在此之上我们实现了Group Lasso FTRL,频次过滤和模型压缩等一系列算法。备注:弹性特征带来一个显著的优势:只要用足够强的L1稀疏性约束,在单机上就能调试任意大规模的特征训练,带来很多方便。我们的hashmap实现是KV化的,key是特征,value是vector的首地址。离线训练优化经过这样的改造后,在离线批量学习上,带来了以下变化:在线训练优化online learning上,能带来如下变化:除了性能有明显的提升之外,其最大的优势是不需提前申请空间,训练可以无缝稳定运行。2. 特征动态增删技术弹性架构,主要目的就是特征优选,让模型自适应地选择最优特征,进而实现稀疏化,降低过拟合。本节介绍特征优选的两个核心技术:使用流式频次过滤, 对特征进入进行判定。使用Group Lasso优化器,对特征进行筛选和删除。2.1 Group Lasso 优化器稀疏化是算法追求的重要模型特性,从简单的L1正则化和Truncated Gradient[9], 再到讨论累积梯度平均值的RDA(Regularized Dual Averaging)[10], 再到目前常见的 FTRL[2] 。 然而它们都是针对广义线性模型优化问题提出的稀疏性优化算法,没有针对sparse DNN中的特征embedding层做特殊处理。把embedding参数向量当做普通参数进行稀疏化,并不能达到在线性模型中能达到的特征选择效果,进而无法有效地进行模型压缩。例如:当包含新特征的样本进入时,一个特征对应的一组参数(如embedding size为7,则参数数量为7)被激活,FTRL判定特征中的部分参数无效时,也不能安全地将该特征删除。如图:因此,在L1和L2正则的基础上,人们引入L21正则(group lasso)和L2正则(exclusive sparsity),分别表示如下:L21早在2011年已经引入,它最初目的是解决一组高度关联特征(如男女)应同时被保留或删除的问题,我们创新地扩展到embedding的表示上,以解决类似的问题。在L21中,由于内层L2正则将一个特征的所有参数施加相同的约束,能将整组参数清除或保留,由此决定embedding层中的某些特征对应的embedding向量是否完全删除,提升模型泛化性。因此称为group lasso。而L12则正好相反,它迫使每组参数中的非0参数数量一致但值又尽可能不同,但使输出神经元互相竞争输入神经元,进而使特征对目标更具区分性。对于DNN分类网络,底层表示要求有足够的泛化性和特征抽象能力,上层接近softmax层,需要更好的区分性。因此我们通常在最底层的embedding层使用group lasso。即如下的优化目标:直接将L21正则项惩罚加入loss,模型最终也能收敛,但并不能保证稀疏性。因此Group lasso优化器参考了FTRL,将梯度迭代分成两个半步,前半步按梯度下降,后半步微调实现稀疏性。通过调节L1正则项(即公式中的),能有效地控制模型稀疏性。Group lasso是弹性计算改造后,模型性能提升和压缩的关键。值得指出:在我们实现的优化器中,Variable,以及accum和linear两个slot也是KV存储。L12和L21正则相结合的方法也已经有论文讨论[8],但我们还未在业务上尝试出效果。由于篇幅限制,本节不打算详细介绍Group lasso的原理和推导2.2 流式频次过滤讨论完特征动态删除的方法后,我们再分析特征的准入策略。2.2.1 频次过滤的必要性在Google讨论FTRL的文章1中提到, 在高维数据中大部分特征都是非常稀疏的,在亿级别的样本中只出现几次。那么一个有趣的问题是,FTRL或Group FTRL优化器能否能删除(lasso)极低频特征?在RDA的优化公式中,满足以下条件的特征会被置0:若在t步之前,该特征只出现过几次,未出现的step的梯度为0,随着步数增大,满足上述条件变得越来越容易。由此RDA是可以直观处理极稀疏特征的。 但对于FTRL,要满足:其中,不仅和历史梯度有关,还与历史学习率和权重w有关。 因此FTRL虽然也能处理极稀疏特征,但并没有RDA那么aggressive(此处还待详细地分析其下界,Group FTRL与此类似)。由于FTRL在设计和推导时并未明确考虑极低频特征,虽然通过增大,确实能去除大量极低频特征,但由于约束太强,导致部分有效特征也被lasso,在离线实验中被证明严重影响性能。其次,对这些巨量极低频特征,保存历史信息的工程代价是很高昂的(增加几倍的参数空间和存储需求),如下图:因此我们提出,能否在实时数据流上模拟离线频次过滤,为特征提供准入门槛,在不降低模型性能的基础上,尽量去除极低频特征,进一步实现稀疏化?2.2.2 频次过滤的几种实现注意: 由于默认的embedding_lookup_sparse对特征执行了unique操作(特征归一化以简化计算),因此在PS端是不可能获取真实特征和label频次的。需要Python端对placeholder统计后,上传给server端指定的Variable,优化器通过slot获得该Variable后作出联合决策。最naive的思路是模拟离线频次过滤,对特征进行计数,只有达到一定阈值后再进入训练,但这样破坏了数据完整性:如总频次6,而阈值过滤为5,则该特征出现的前5次都被忽略了。为此我们提出了两种优化方案:基于泊松分布的特征频次估计在离线shuffle后的特征满足均匀分布,但对在线数据流,特征进入训练系统可看做泊松过程,符合泊松分布:其中n为当前出现的次数,t为当前的步数,为单位时间发生率,是泊松分布的主要参数,T为训练总步数。为特征最低门限(即最少在T时间内出现的次数)。因此我们能通过前t步的特征出现的次数n,将t时刻当做单位时间,则。 根据泊松分布,我们可以算出剩余时间内事件发生大于等于次的概率。 每次该特征出现时,都可按该概率做伯努利采样,特征在t步进入系统的概率用下式计算:通过真实线上数据仿真,它能接近离线频次过滤的效果,其是随每次特征进入时动态计算的。它的缺陷是:当t越小时,事件发生在t内的次数的variance越大,所以会以一定概率误加或丢弃特征。未来总的训练步数T在在线学习中是未知的。频次过滤与优化器相分离,导致不能获得优化器的统计信息。动态调L1正则方案在经典的FTRL实现中,L1正则对每个特征都是一致的。这导致了2.2.1 中提到的问题:过大的L1虽然过滤了极低频特征,但也影响的了模型的性能。参考各类优化器(如Adam)对learning_rate的改进,我们提出:通过特征频次影响L1正则系数,使得不同频次的特征有不同的lasso效果。特征频次和基于MLE的参数估计的置信度相关,出现次数越低置信度越低。如果在纯频率统计基础上加入一个先验分布(正则项),当频率统计置信度越低的时候,越倾向于先验分布,相应的正则系数要更大。我们经过多个实验,给出了以下的经验公式:其中c是惩罚倍数,为特征最低门限,这两者皆为超参,是当前特征出现的频次。我们在线上环境,使用了动态调节L1正则的方案 。在uvctr不降甚至有些微提升的基础上,模型特征数比不使用频次过滤减少75%,进而从实验证明了频次过滤对稀疏化的正向性。它的缺点也很明显:特征频次和正则系数之间的映射关系缺少严谨证明。频次过滤作为特征管理的一部分,目前还少有相关论文研究,亟待我们继续探索。3. 模型压缩和稳定性3.1 模型压缩在工程上,由于做了优化,如特征被优化器lasso后,只将其置0,并不会真正删除;在足够多步数后才删除。同时引入内存池,避免特征的反复创建和删除带来的不必要的性能损失。 这就导致在训练结束后,模型依然存在大量0向量。导出时要进一步做模型压缩。由于引入了HashPull和HashPush等非TF原生算子,需要将其裁剪后转换为原生TF的op。 我们将这些步骤统称图裁剪(GraphCut), 它使得线上inference引擎,不需要做任何改动即可兼容弹性改造。由于有效特征大大减少,打分速度相比原引擎提升50%以上。我们将图裁剪看做TF-graph的静态优化问题,分为3个步骤:第一遍遍历Graph,搜索可优化子结构和不兼容的op。第二遍遍历,记录节点上下游和元数据,裁剪关键op,并将Variable的非0值转存至Tensorflow原生的MutableDenseHashTable。本步骤将模型体积压缩90%。拼接新建节点,重建依赖关系,最后递归回溯上游节点,去除与inference无关的子图结构我们实现了完整简洁的图裁剪工具,在模型热导出时调用, 将模型从原先的8GB左右压缩到几百兆大小,同时保证模型打分一致。3.2 模型稳定性和监控online learning的稳定性非常重要。我们将线上真实效果,与实时模型生成的效果,进行了严密的监控,一旦样本偏差过多,就会触发报警。由于需捕捉时变的数据变化,因而不能用固定的离线数据集评估模型结果。我们使用阿里流式日志系统sls最新流入的数据作为评估样本,以滑动窗口先打分后再训练,既维持了不间断的训练,不浪费数据,同时尽可能高频地得到最新模型效果。我们对如下核心指标做了监控:样本监控: 正负比例,线上打分值和online-auc(即线上模型打分得到的auc),产出速率,消费速率。训练级监控: AUC, User-AUC(参考备注),loss, 模型打分均值(与样本的正负比例对齐),异常信息。特征级管理: 总特征规模,有效/0/删除特征规模,新增/插入/删除的速率。整体模型和调度:模型导出的时间,大小,打分分布是否正常,是否正常调度。业务指标:uvctr,pvctr(小时级更新,T+1报表)。线上与训练指标之间的对应关系如下表:通过http接口,每隔一段时间发送监控数据,出现异常会及时产生钉钉和邮件报警。下图是对9月20日到27号的监控,从第二张图表来看,模型能较好的适应当前数据流的打分分布。User-AUC:传统的AUC并不能完全描述uvctr,因为模型很可能学到了不同用户间的偏序关系,而非单个用户在不同offer下的点击偏序关系。为此,我们使用了User-AUC,它尽可能地模拟了线上uvctr的计算过程,在真实实验中,监控系统的uvctr小时报表,与实时模型输出的User-AUC高度一致。4. 工程实现和效果目前算法已经在支付宝首页的多个推荐位上线。推荐系统根据用户的历史点击,融合用户画像和兴趣,结合实时特征,预估用户CTR,进而提升系统整体点击率。我们以推荐位业务为例说明,其采用了经典的wide&deep的网络结构,其sparse部分包含百级别的group(见下段备注1)。 一天流入约百亿样本,label的join窗口为固定时长。由于负样本占大多数,上游链路对正负样本做了1:8的降采样(见下文备注2)。训练任务采用蚂蚁统一训练平台构建,并使用工作流进行定时调度,离线和在线任务的其他参数全部一致。Batchsize为512,每200步(即20万样本)评估结果,定时将模型通过图裁剪导出到线上系统。当任务失败时,调度系统会自动拉起,从checkpoint恢复。该推荐业务的online learning桶最近一周相比线上多模型融合最优桶提升4.23% , 相比随机对照提升达34.67% 。 另一资讯推荐业务其最近一周,相比DNN基准uv-ctr提升+0.77%,pv-ctr提升+4.78%。实验效果相比有较大的提升。备注1: group embedding是将相似emb特征分组,各自lookup求和后再concat,使得特征交叉在更高层进行。其设计是考虑到不同group的特征差异很大(如user和item),不应直接对位求和。备注2: inference打分仅做pointwise排序,采样虽改变数据分布但不改变偏序关系,因此并未在训练上做补偿。5. 未来工作弹性特征已经成为蚂蚁实时强化深度学习的核心要素。它只是第一步,在解决特征空间按需创建问题后,它会带来一个充满想象力的底层架构,众多技术都能在此基础上深挖: 在工程上,可继续从分钟级向秒级优化,进一步提升链路实时性并实现模型增量更新; 在算法上,我们正在探索如样本重要性采样,自动特征学习,在线线性规划与DNN的结合,实现优化器联合决策等技术。由于在线学习是个复杂的系统工程,我们在开发和调优时遇到了大量的困难,涉及样本回流,训练平台,模型打分,线上评估等一系列问题,尤其是稳定性,但基本都一一克服。为了保证线上结果稳定可信,我们在观察和优化两三个月后才发布这篇文章。本文作者为蚂蚁金服人工智能部认知计算组的基础算法团队,团队涉及图像、NLP、推荐算法和知识图谱等领域,带头人为国家知名算法专家褚崴,拥有定损宝和理赔宝等核心业务。本文作者:墨眀阅读原文本文来自云栖社区合作伙伴“ 阿里巴巴机器智能”,如需转载请联系原作者。 ...

February 22, 2019 · 1 min · jiezi

推荐系统之信息茧房问题

什么是信息茧房信息茧房其实是现在社会一个很可怕的现象,从字面意思来看的话其实比喻的是信息被虫茧一般封锁住。这个问题反映了现在随着个性化推荐的普及衍射的一个社会问题。平时在浏览新闻或者淘宝的时候,平台会自动根据用户的浏览记录获取用户的偏好,然后推送感兴趣的文章。久而久之,比如用户A是个体育迷,那么A获取的信息大多是跟体育相关的,很难获取音乐或者军事等其它相关的资讯,因为平台追求点击率,会一直推送A感兴趣的内容以获取高广告浏览量。时间长了,因为信息茧房的作用,因为信息获取单一,A的社交圈可能也会变的狭小。如果整个社会陷入了个性化推荐系统的信息茧房效应,将是病态的。所以,真正的个性化推荐绝对不等于只推荐历史感兴趣的内容,这样其实不是一个长期可持续的推荐系统,如果陷入了信息茧房,一定会有用户觉得审美疲劳。那么如何破解信息茧房,因为从推荐模型角度分析,一旦获取了用户的画像,就很难跳出用户习惯的逻辑,比如昨天买个手机,第二天还推荐手机,这个时候可能比较好的一种方法是跨域推荐(cross-domain recommendation)。跨域推荐的概念跨域推荐做的事情就是跳出推荐的信息茧房。不是一个新概念了,我上研究生的时候学校就有实验室做相关的研究,今天主要讲下思路。具体大家想了解的话可以看下这个Paper: 《Cross-Domain Recommendation: An Embedding and Mapping Approach》有几个关键词我觉得可以充分体现跨域推荐的精髓:“diversity” - “novelty” - “serendipity”如果我们做一个推荐系统,说是“individuality”,其实我会觉得很normal,不够高级,现在几乎所有推荐系统都有个性化推荐,但是如果一个推荐系统标榜自己是“novelty”,那我就觉得很有意思了。下面聊聊怎么实现novelty。第一步:确定什么是target & source这里以新闻推荐为例,如果一用户A,经常浏览同一个类型的新闻,比如体育新闻,如何找到A喜欢的其他类别新闻呢?这其实是一个user overlap的场景,推荐系统的主体user不变,有个source源是体育新闻,要找到target是体育以外user感兴趣的文章。这就建立了跨域推荐中的target和source关系。第二步:确定推荐level跨域推荐有多种level,要确定跨域的种类,大体可以分以下三种:其实跨域推荐确定了source和target后只要确定跨域的幅度即可。Attribute level:挖掘target间的相似属性,推荐同一类别的target。比如一个用户很喜欢买红色、大尺寸的诺基亚手机,attribute level推荐是要在推荐物属性层面做跨域,可以试着给用户推荐黑色、小尺寸的其它手机,这样的跨属性的相同物种推荐会在一定程度上给用户新鲜感Type level:挖掘target间的相似属性,然后推荐相同大品类下不同小品类的物品。比如用户喜欢红色、大尺寸的诺基亚手机,手机和电脑都属于电子产品,可以推荐红色、大尺寸的电脑给用户Item level:挖掘target间的相似属性,推荐不同大品类的物品。比如用户喜欢红色、大尺寸的诺基亚手机,直接推荐红色大尺寸的马桶以上3个跨域level由轻到重,大家可以根据自己的需求选用。其实关键点是如何挖掘物品的属性,因为无论是电脑、手机、马桶,他们都有共通的属性,比如大小、颜色、材质等,下面就介绍如何挖掘这些属性。第三步:挖掘target间的属性既然跨域推荐的关键是能挖掘出target间共有的属性,那么有什么办法可以做到这一点呢。首先要根据业务属性人工挖掘出一些隐性特征,比如电商平台可以挖掘出颜色、材质、价格、使用频率等隐性特征,然后可以通过矩阵分解的方式获取具体每个特征的权重(下图中矩阵A和B之间的矩阵)。总结信息茧房效应是因为个性化推荐系统推荐信息的不平衡性,导致用户长期只能浏览限制领域的信息,可以在推荐系统中加入跨域推荐的逻辑来规避信息茧房的影响,具体流程包含确定推荐逻辑中的source和target,确定跨域的粒度,通过矩阵分解找出隐含的共性属性。参考:https://recsys.acm.org/wp-con…本文作者:傲海阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 27, 2018 · 1 min · jiezi

基于深度学习模型Wide&Deep的推荐

本实验选用数据为UCI开源数据集,仅用于学习,请勿商用)Wide&Deep推荐算法出自一篇论文《Wide&Deep Learning for RecommenderSystems》,Wide&Deep由两部分组成,分别是Wide和Deep。先来说wide,表示的是generalized的推荐系统,传统的推荐系统都是通过线性算法基于离散特征来做推荐的。Wide推荐通常是这样的:系统通过获得用户的购物日志数据,包括用户点击哪些商品,购买过哪些商品,然后通过one-hot编码的方式构成离散特征或者通过对业务的理解衍生出一些特征,并进行计算,类似于本系列文章第二篇。这种wide推荐方式有非常多的好处,比如对于大规模的稀疏数据有很好的效果,而且模型的解释性很强。什么叫模型的解释性呢?以逻辑回归为例,每个特征都对应模型中的一个权重值,每个特征的权重值的大小跟这个特征对结果的影响是有关的。那么wide方式同样有很多缺点,比如我们一直强调的,特征衍生需要很多人为操作,需要专家经验,另外这种推荐只对用户操作过的商品有效。接着讲下deep,这里的deep表示的是通过深度学习学习出来的一些向量,这些向量是隐性特征,往往是没有明确可解释性的。这些向量也可以作为特征的一部分参与到训练中。通过deep方式产生的特征会有以下好处,其一可以拟补人为提取特征造成的人力思考维度的限制,试想下一个人可以轻易的思考出二阶乘法的结果,如果是五阶呢?其二这部分特征是深度学习框架自动生成的,无需人力干预。既然Wide和Deep算法各有千秋,那如果可以将两种算法作为组合,那么一定可以生成更有效的推荐场景的模型,本文就介绍如何在PAI-DSW上实现基于Wide&Deep的预测。一、业务场景描述本节使用的是PAI-DSW云端深度学习训练平台和PAI-EAS模型服务平台,使用的是一份开源的基于人的各种背景的统计数据,解决的问题是基于人的各种基础数据预测每个人收入是否会超过50K。本实验的全部代码和数据已经内置于PAI-DSW,只要打开DSW就可以安装下方的教程运行实验。二、数据集介绍数据源:引用UCI开源数据源,https://archive.ics.uci.edu/ml/datasets/Census+Income具体特征字段如下:字段名含义类型描述age对象年龄double对象的年龄大小workclass工作性质string自由职业者、私企、企业人员、政府工作者、无业游民等fnlwgt连续数据double-education学历string学士、说是、博士、11th、10th、1s-4th等等education-num教育年限double教育年限marital-status婚姻状况string单身、未婚、离异等等occupation职业string工程师、农民、销售等等relatonship家庭角色string妻子、父亲、没家庭等等race人种string亚裔、白人、黑人等等sex性别string女性、男性capital-gain连续数据double-capital-loss连续数据double-hours-per-week连续数据double-native-country祖籍国家string美国、哥伦比亚、英格兰、加拿大等等目标字段:income是否超过50k三、数据探索流程首先进入PAI-DSW,找到左侧的Demo文件夹,下载Wide&Deep数据集及代码包。(1)工程描述首先看下整个工程,包含一个census_data文件夹,里面包含一个训练数据和一个测试数据official文件夹是一个工具包census_main.py为训练脚本(2)训练模型打开一个terminal环境,执行python census_main.py –export_dir wide_deep_saved_modelwide_deep_saved_model为输出模型所在的文件夹,训练完在文件目录下会找到相应文件,打开后可以看到checkpoint:把这个checkpoint的号记住。(3)模型预测现在已经生成了模型的checkpoint输出,接下来进入terminal,运行以下脚本:saved_model_cli run –dir wide_deep_saved_model/${模型checkpoint号码}/ –tag_set serve –signature_def=“predict” –input_examples=’${预测数据}‘根据本文的案例可以执行以下脚本拿到预测结果:saved_model_cli run –dir wide_deep_saved_model/1542168326/ –tag_set serve –signature_def=“predict” –input_examples=‘examples=[{“age”:[46.], “education_num”:[10.], “capital_gain”:[7688.], “capital_loss”:[0.], “hours_per_week”:[38.]}, {“age”:[24.], “education_num”:[13.], “capital_gain”:[0.], “capital_loss”:[0.], “hours_per_week”:[50.]}]‘输入了两条预测数据,最终拿到预测结果:输入了两条预测数据,可以得到预测输出,第一条预测结果为1,第二条结果为0,可以通过output key probabilities判断(注:矩阵第一行对应第一个预测结果,第二列0.9599956>第一列0.04000434,所以第一个预测结果是1。同理第二个预测结果是0)。可以通过代码official/wide_deep/census_dataset.py来看具体的特征工程的特征和目标值的构建,目标列>50k时目标值为1,目标列<50k时目标值为0。于是预测结果第一条的人的预测收入为>50k,预测结果第二条的人的预测收入<50k。(4)模型在线部署生成的模型是Tensorflow的标准模型格式,可以通过PAI-EAS将模型部署成Http服务供调用。后续流程可以参考在线预测文档:https://help.aliyun.com/document_detail/92917.html部署成在线服务之后,这样就可以做到模型跟用户自身的业务结合,完成PAI模型训练和业务应用的打通。本文作者:傲海阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 14, 2018 · 1 min · jiezi

基于对象特征的推荐

(本实验选用数据为真实电商脱敏数据,仅用于学习,请勿商用)在上一期基于协同过滤的的推荐场景中,我们介绍了如何通过PAI快速搭建一个基于协同过滤方案的推荐系统,这一节会介绍一些如何基于推荐对象特征的推荐方法。首先看下整个业务流程图,这是一个基于对象特征的推荐场景的通用流程:首先把数据导入Maxcompute,有监督的结构化数据接着做特征工程,在特征工程环节主要做一些数据的预处理以及特征的衍生,特征衍生的作用是扩充数据维度,使得数据能更大限度的表示业务特点接着把数据通过拆分分成两份,一份通过分类算法生成二分类模型,另一份数据对模型效果进行测试最后通过评估组件得到模型效果一、业务场景描述通过一份真实的电商数据的4、5月份做模型训练生成预测模型,通过6月份的购物数据对预测模型进行评估最终选择最优的模型部署为在线http服务供业务方调用。本次实验选用的是PAI-Studio作为实验平台,仅通过拖拽组件就可以快速实现一套基于对象特征的推荐系统。本实验的数据和完整业务流程已经内置在了PAI首页模板,开箱即用:二、数据集介绍数据源:本数据源为天池大赛提供数据,数据按时间分为两份,分别是7月份之前的购买行为数据和7月份之后的。 具体字段如下:字段名含义类型描述user_id用户编号string购物的用户IDitem_id物品编号string被购买物品的编号active_type购物行为string0表示点击,1表示购买,2表示收藏,3表示购物车active_date购物时间string购物发生的时间数据截图: 三、数据探索流程本次实验选用的是PAI-Studio作为实验平台,仅通过拖拽组件就可以快速实现一套基于协同过滤的推荐系统,并且支持自动调参以及模型一键部署的服务。实验流程图:(1)特征工程在特征工程的流程中是把最原始的只有4个字段的数据通过特种工程的方法进行数据维度的扩充。在推荐场景中有两个方面特征,一方面是所推荐的对象的特征,另一方面是被推荐对象的特征。在商品推荐这个案例中:被推荐对象为商品(item),扩充的维度为每个item被购买量、每个item被点击量、每个item被点击购买率(购买量除以点击率)推荐对象为用户(user),扩充的维度为每个user总的购买量、总的点击量、总的点击购买率(点击数除以购买率,可以得出每点击多少次购买一个产品,可以用来描述用户购物的果断性)最终数据由原始的4个字段变成了10个字段:(2)模型训练现在已经构建了一个大宽表,有了做完特征工程的结构化数据,现在就可以训练模型了。这个案例中选用了逻辑回归算法,在做模型训练过程中有一个痛点就是如何找到合适的参数,对于逻辑回归参数(如下图)而言,如何调整以下几个参数,使得模型训练能达到最好的效果是一个非常有挑战的任务。为了解决繁琐的调参工作带来的劳动量问题,PAI产品内置了AutoML引擎帮助调参,在页面上打开AutoML,只要设置下需要调参的算法的参数范围以及评估标准,后台引擎即可在最小的资源消耗下找到最合理的参数,详见:(3)模型评估模型评估模块是用预留的一部分未参与模型训练的数据评估模型质量,通常推荐场景都是二分类实验,可以使用混淆矩阵和二分类评估组件去评估结果。二分类评估:打开组件选择“图表”,会展示下图ROC曲线,其中蓝色区域的面积为AUC值,面积越大表示模型质量越高混淆矩阵:通过混淆矩阵可以确定具体的预测准确率、召回率、F1-Score等指标(4)模型在线部署模型生成后,如果效果也达到预期,可以使用PAI-EAS将模型一键部署为在线服务,通过http访问。点击画布上的“部署”按钮,选择“模型在线部署”功能,选择需要部署的模型。后续流程可以参考在线预测文档:https://help.aliyun.com/document_detail/92917.html部署成在线服务之后,模型服务可以通过http请求访问,这样就可以做到模型跟用户自身的业务结合,完成PAI模型训练和业务应用的打通。本文作者:傲海阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 12, 2018 · 1 min · jiezi

学习这篇总结后,你也能做出头条一样的推荐系统

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦本文由jj发表于云+社区专栏一、推荐系统概述1.1 概述推荐系统目前几乎无处不在,主流的app都基本应用到了推荐系统。例如,旅游出行,携程、去哪儿等都会给你推荐机票、酒店等等;点外卖,饿了么、美团等会给你推荐饭店;购物的时候,京东、淘宝、亚马逊等会给你推荐“可能喜欢”的物品;看新闻,今日头条、腾讯新闻等都会给你推送你感兴趣的新闻….几乎所有的app应用或网站都存在推荐系统。究其根本的原因,推荐系统的流行是因为要去解决一个问题:物品越来越多,信息越来越多,而人的精力和时间是有限的,需要一个方式去更有效率地获取信息,链接人与信息。推荐系统就是为了解决这一问题而诞生的,在海量的物品和人之间,架起来一条桥梁。它就像一个私人的专属导购,根据你的历史行为、个人信息等等,为每个人diy进行推荐,千人前面,帮助人们更好、更快地选择自己感兴趣的、自己需要的东西。今日头条系的feed流在推荐算法的加持下,短短几年的用户增长速度和使用时长数据令人咂舌,受到了市场的追捧和高估值。一夜之间,几乎所有的app都开始上feed流、上各种推荐,重要性可见一斑。1.2 基本架构我们先把推荐系统简单来看,那么它可以简化为如下的架构。图1 推荐系统一般流程不管是复杂还是简单的推荐系统,基本都包含流程:1)结果展示部分。不管是app还是网页上,会有ui界面用于展示推荐列表。2)行为日志部分。用户的各种行为会被时刻记录并被上传到后台的日志系统,例如点击行为、购买行为、地理位置等等。这些数据后续一般会被进行ETL(extract抽取、transform转换、load加载),供迭代生成新模型进行预测。3)特征工程部分。得到用户的行为数据、物品的特征、场景数据等等,需要人工或自动地去从原始数据中抽取出特征。这些特征作为输入,为后面各类推荐算法提供数据。特征选取很重要,错的特征必定带来错误的结果。4)召回部分。 有了用户的画像,然后利用数据工程和算法的方式,从千万级的产品中锁定特定的候选集合,完成对推荐列表的初步筛选,其在一定程度上决定了排序阶段的效率和推荐结果的优劣。5)排序部分。针对上一步的候选集合,会进行更精细化地打分、排序,同时考虑新颖性、惊喜度、商业利益等的一系列指标,获得一份最终的推荐列表并进行展示。完整的推荐系统还会包括很多辅助模块,例如线下训练模块,让算法研究人员利用真实的历史数据,测试各类不同算法,初步验证算法优劣。线下测试效果不错的算法就会被放到线上测试,即常用的A/B test系统。它利用流量分发系统筛选特定的用户展示待测试算法生成的推荐列表,然后收集这批特定用户行为数据进行线上评测。图2 蘑菇街推荐系统架构推荐系统每个部分可大可小,从图2可知,各部分涉及的技术栈也较多。终端app每时每刻都在不断上报各类日志,点击、展示、时间、地理位置等等信息,这些海量信息需要依赖大数据相关软件栈支持,例如Kafka、spark、HDFS、Hive等,其中Kafka常被用于处理海量日志上报的消费问题。将数据进行ETL后存入Hive数据仓库,就可进行各类线上、线下测试使用。线下的算法会上线到线上环境进行ABtest,ABtest涉及完整的测试回路打通,不然拿不到结果,也无法快速开发迭代算法。线上推荐系统还要关注实时特征、离线特征,在性能和各类指标、商业目标间取均衡。1.3 评测指标一个东西做得好还是不好,能不能优化,首要前提是确定评测指标。只有确定了评测指标,才能有优化的方向。评测推荐系统的指标可以考虑以下几个方面:1.3.1 用户满意度用户作为推进系统的主要参与者,其满意度是评测系统的最重要指标。满意度可以通过做用户调查或线上实验获得。在在线系统中,一般通过对用户行为的统计得到,例如点击率、用户停留时间和转化率等指标度量用户的满意度。1.3.2 预测精确度precision预测准确度度量一个推荐系统或者推荐算法预测用户行为的能力。这个指标是最重要的离线评测指标。由于离线数据可计算,绝大部分科研人员都在讨论这个指标。评分预测问题一般使用RMSE、MAE等,TopN预测问题一般使用Recall、Precision等。图3 常见的指标准确率(Precision)、召回率(Recall)、误检率其实目前国内很多地方和资料混淆了两个指标的叫法,把准确度对应英文precision指标。不过尽量还是用英文比较好。准确度Accuracy = (TP + TN) / (TP + FP + TN + FN)精确度Precision=TP/(TP+FP)1.3.3 覆盖率coverage覆盖率描述一个推荐系统对物品长尾的发掘能力。覆盖率有很多定义方法,最简单的计算就是推荐列表中的物品数量,除以所有的物品数量。在信息论和经济学中有两个著名的指标用来定义覆盖率,一个是信息熵,一个是基尼系数。具体公式和介绍可以google。ps:长尾在推荐系统中是个常见的名词。举个例子帮助大家理解,在商店里,由于货架和场地有限,摆在最显眼的地方的物品通常是出名的、热门的,从而销量也是最好的。很多不出名或者小知名度的商品由于在货架角落或者根本上不了货架,这些商品销量很差。在互联网时代,这一现象会被打破。电子商城拥有几乎无限长的“货架”,它可以为用户展现很多满足他小众需求的商品,这样总的销量加起来将远远超过之前的模式。Google是一个最典型的“长尾”公司,其成长历程就是把广告商和出版商的“长尾”商业化的过程。数以百万计的小企业和个人,此前他们从未打过广告,或从没大规模地打过广告。他们小得让广告商不屑一顾,甚至连他们自己都不曾想过可以打广告。但Google的AdSense把广告这一门槛降下来了:广告不再高不可攀,它是自助的,价廉的,谁都可以做的;另一方面,对成千上万的Blog站点和小规模的商业网站来说,在自己的站点放上广告已成举手之劳。Google目前有一半的生意来自这些小网站而不是搜索结果中放置的广告。数以百万计的中小企业代表了一个巨大的长尾广告市场。这条长尾能有多长,恐怕谁也无法预知。无数的小数积累在一起就是一个不可估量的大数,无数的小生意集合在一起就是一个不可限量的大市场。图4 长尾曲线1.3.4多样性用户的兴趣是多样的,推荐系统需要能覆盖用户各种方面的喜好。这里有个假设,如果推荐列表比较多样,覆盖了用户各种各样的兴趣,那么真实命中用户的兴趣概率也会越大,那么就会增加用户找到自己感兴趣的物品的概率。1.3.5 新颖性新颖的推荐是指给用户推荐那些他们以前没有听说过的物品。要准确地统计新颖性需要做用户调查。1.3.6 惊喜度如果推荐结果和用户的历史兴趣不相似,但却让用户觉得满意,那么就可以说推荐结果的惊喜度很高,而推荐的新颖性仅仅取决于用户是否听说过这个推荐结果。1.3.7 信任度用户对推荐系统的信任程度。如果用户信任推荐系统,那就会增加用户和推荐系统的交互。特别是在电子商务推荐系统中,让用户对推荐结果产生信任是非常重要的。同样的推荐结果,以让用户信任的方式推荐给用户就更能让用户产生购买欲,而以类似广告形式的方法推荐给用户就可能很难让用户产生购买的意愿。提高推荐系统的信任度主要有两种方法。首先需要增加推荐系统的透明度(transparency),而增加推荐系统透明度的主要办法是提供推荐解释。其次是考虑用户的社交网络信息,利用用户的好友信息给用户做推荐,并且用好友进行推荐解释。1.3.8 实时性在很多网站中,因为物品(新闻、微博等)具有很强的时效性,所以需要在物品还具有时效性时就将它们推荐给用户。因此,在这些网站中,推荐系统的实时性就显得至关重要。推荐系统的实时性包括两个方面。首先,推荐系统需要实时地更新推荐列表来满足用户新的行为变化。实时性的第二个方面是推荐系统需要能够将新加入系统的物品推荐给用户。这主要考验了推荐系统处理物品冷启动的能力。1.3.9 健壮性衡量了一个推荐系统抗击作弊的能力。算法健壮性的评测主要利用模拟攻击。首先,给定一个数据集和一个算法,可以用这个算法给这个数据集中的用户生成推荐列表。然后,用常用的攻击方法向数据集中注入噪声数据,然后利用算法在注入噪声后的数据集上再次给用户生成推荐列表。最后,通过比较攻击前后推荐列表的相似度评测算法的健壮性。如果攻击后的推荐列表相对于攻击前没有发生大的变化,就说明算法比较健壮。1.3.10 商业目标很多时候,评测推荐系统更加注重商业目标是否达成,而商业目标和盈利模式是息息相关的。一般来说,最本质的商业目标就是平均一个用户给公司带来的盈利。不过这种指标不是很难计算,只是计算一次需要比较大的代价。因此,很多公司会根据自己的盈利模式设计不同的商业目标。1.3.11 参考资料推荐系统的评测问题有很多的相关研究和资料,预详细研究可阅读参考:《推荐系统实战》《Evaluating Recommendation Systems》What metrics are used for evaluating recommender systems?二、常用算法推荐算法的演化可以简单分为3个阶段,也是推荐系统由简单到复杂的迭代。2.1 推荐算法演化2.1.1 人工运营这个阶段是随机的,人工根据运营目的,手工给特定类别的用户推送特定的内容。优点是:方便推广特定的内容;推荐的内容易解释;缺点是:千人一面,推送的内容一样;人工筛选,推送,耗费人力巨大;运营根据自己的知识,主观性比较大;2.1.2 基于统计的推荐会基于一些简单的统计学知识做推荐,例如某个内别卖得最好的热门榜;再细致一些,将用户按个人特质划分,再求各种热度榜等。优点是:热门就是大部分用户喜好的拟合,效果好;推荐的内容易解释;缺点是:千人一面,推送的内容一样;马太效应,热门的会越来越热门,冷门的越来越冷门;效果很容易达到天花板;2.1.3 个性化推荐当前阶段的推荐,会基于协同过滤算法、基于模型的算法、基于社交关系等,机器学习、深度学习逐渐引入,提高了推荐效果。优点是:效果要相对于之前,要好很多;千人前面,每个人都有自己独特的推荐列表;缺点是:门槛较高,推荐系统搭建、算法设计、调优等等,都对开发者有较高的要求;成本较高,而且是个长期迭代优化的过程,人力物力投入很高;2.2 推荐算法汇总内部一个分享这样分类常用的推荐算法:图5 推荐算法分类这里提到的Memory-based算法和Model-based算法的差别是什么?这也是我之前关注的问题,找到个资料,讲解得比较透彻。Memory-based techniques use the data (likes, votes, clicks, etc) that you have to establish correlations (similarities?) between either users (Collaborative Filtering) or items (Content-Based Recommendation) to recommend an item i to a user u who’s never seen it before. In the case of collaborative filtering, we get the recommendations from items seen by the user’s who are closest to u, hence the term collaborative. In contrast, content-based recommendation tries to compare items using their characteristics (movie genre, actors, book’s publisher or author… etc) to recommend similar new items.In a nutshell, memory-based techniques rely heavily on simple similarity measures (Cosine similarity, Pearson correlation, Jaccard coefficient… etc) to match similar people or items together. If we have a huge matrix with users on one dimension and items on the other, with the cells containing votes or likes, then memory-based techniques use similarity measures on two vectors (rows or columns) of such a matrix to generate a number representing similarity.Model-based techniques on the other hand try to further fill out this matrix. They tackle the task of “guessing” how much a user will like an item that they did not encounter before. For that they utilize several machine learning algorithms to train on the vector of items for a specific user, then they can build a model that can predict the user’s rating for a new item that has just been added to the system.Since I’ll be working on news recommendations, the latter technique sounds much more interesting. Particularly since news items emerge very quickly (and disappear also very quickly), it makes sense that the system develops some smart way of detecting when a new piece of news will be interesting to the user even before other users see/rate it.Popular model-based techniques are Bayesian Networks, Singular Value Decomposition, and Probabilistic Latent Semantic Analysis (or Probabilistic Latent Semantic Indexing). For some reason, all model-based techniques do not enjoy particularly happy-sounding names.《携程个性化推荐算法实践》一文中梳理了工业界应用的排序模型,大致经历三个阶段:图6 排序模型演进本文不对上面的这些算法进行详细的原理探讨,会比较复杂,有兴趣可以再自行学习。2.3 CF算法示例为了学习这块的技术知识,跟着参加了下内部举办的srtc推荐比赛。重在参与,主要是学习整个基本流程,体会下推荐场景,了解腾讯内部做得好的团队和产品是什么样子。2.3.1(内部敏感资料,删除)2.3.2 CF算法在web平台上点一点,可能失去了学习的意义。所以本着学习的态度,我在线下自己的机器上实现了一些常用的算法,例如CF等。推荐算法里CF算是比较常见的,核心还是很简单的。user-cf基本原理A.找到和目标用户兴趣相似的的用户集合; B.找到这个集合中的用户喜欢的,且目标用户没听过的物品推荐给目标用户。item-cf基本原理A.计算物品之间的相似度; B.根据物品的相似度和用户的历史行为给用户生成推荐列表。结合前面总结的,cf属于memory-base的算法,很大一个特征就是会用到相似度的函数。这个user-cf需要计算用户兴趣的相似度,item-cf需要计算物品间的相似度。基于相似度函数的选择、编程语言的选择、实现方式的选择、优化的不同,结果和整个运行时间会很大不同。当时就简单用python实现的,8个process跑满cpu同时处理,需要近10个小时跑完。后面了解到有底层进行过优化的pandas、numpy等,基于这些工具来实现速度会快很多。2.3.3 收获哈哈,第一次参加这种比赛,虽然成绩很差,但自己觉得很是学到很多东西,基本达到了参赛的目的。在真实的场景和数据下去思考各种影响因素,体会各种算法从设计、实现、训练、评价等各阶段,很多东西确实比看资料和书来得更深入。果然实践才是学习的最好手段。如果想更深入去搞推荐算法这块,感觉需要继续学习目前各种热门算法的原理、潜规则,kaggle上多练手,以及锻炼相关的平台及工程化能力。三、业界推荐系统调研收集、研究了下网上一些推荐系统落地总结的文章,可以开拓视野,加深整体理解。以下只是一些重要内容,有兴趣可以阅读原文:《今日头条算法原理》,原文链接《推荐算法在闲鱼小商品池的探索与实践》,原文链接《饿了么推荐系统:从0到1》,原文链接《爱奇艺个性化推荐排序实践》,原文链接《携程个性化推荐算法实践》,原文链接《蘑菇街推荐工程实践》,原文链接3.1 今日头条推荐系统今日头条算法架构师曹欢欢博士,做过一次 《今日头条算法原理》的报告。主要涉及4部分:系统概览、内容分析、用户标签、评估分析。四类典型推荐特征第一类是相关性特征,就是评估内容的属性和与用户是否匹配。 第二类是环境特征,包括地理位置、时间。这些既是bias特征,也能以此构建一些匹配特征。 第三类是热度特征。包括全局热度、分类热度,主题热度,以及关键词热度等。 第四类是协同特征,它可以在部分程度上帮助解决所谓算法越推越窄的问题。模型的训练上,头条系大部分推荐产品采用实时训练模型的训练上,头条系大部分推荐产品采用实时训练。实时训练省资源并且反馈快,这对信息流产品非常重要。用户需要行为信息可以被模型快速捕捉并反馈至下一刷的推荐效果。我们线上目前基于storm集群实时处理样本数据,包括点击、展现、收藏、分享等动作类型。模型参数服务器是内部开发的一套高性能的系统,因为头条数据规模增长太快,类似的开源系统稳定性和性能无法满足,而我们自研的系统底层做了很多针对性的优化,提供了完善运维工具,更适配现有的业务场景。目前,头条的推荐算法模型在世界范围内也是比较大的,包含几百亿原始特征和数十亿向量特征。整体的训练过程是线上服务器记录实时特征,导入到Kafka文件队列中,然后进一步导入Storm集群消费Kafka数据,客户端回传推荐的label构造训练样本,随后根据最新样本进行在线训练更新模型参数,最终线上模型得到更新。这个过程中主要的延迟在用户的动作反馈延时,因为文章推荐后用户不一定马上看,不考虑这部分时间,整个系统是几乎实时的。但因为头条目前的内容量非常大,加上小视频内容有千万级别,推荐系统不可能所有内容全部由模型预估。所以需要设计一些召回策略,每次推荐时从海量内容中筛选出千级别的内容库。召回策略最重要的要求是性能要极致,一般超时不能超过50毫秒。用户标签工程挑战更大内容分析和用户标签是推荐系统的两大基石。内容分析涉及到机器学习的内容多一些,相比而言,用户标签工程挑战更大。 今日头条常用的用户标签包括用户感兴趣的类别和主题、关键词、来源、基于兴趣的用户聚类以及各种垂直兴趣特征(车型,体育球队,股票等)。还有性别、年龄、地点等信息。性别信息通过用户第三方社交账号登录得到。年龄信息通常由模型预测,通过机型、阅读时间分布等预估。常驻地点来自用户授权访问位置信息,在位置信息的基础上通过传统聚类的方法拿到常驻点。常驻点结合其他信息,可以推测用户的工作地点、出差地点、旅游地点。这些用户标签非常有助于推荐。当然最简单的用户标签是浏览过的内容标签。但这里涉及到一些数据处理策略。主要包括:一、过滤噪声。通过停留时间短的点击,过滤标题党。二、热点惩罚。对用户在一些热门文章(如前段时间PG One的新闻)上的动作做降权处理。理论上,传播范围较大的内容,置信度会下降。三、时间衰减。用户兴趣会发生偏移,因此策略更偏向新的用户行为。因此,随着用户动作的增加,老的特征权重会随时间衰减,新动作贡献的特征权重会更大。四、惩罚展现。如果一篇推荐给用户的文章没有被点击,相关特征(类别,关键词,来源)权重会被惩罚。当然同时,也要考虑全局背景,是不是相关内容推送比较多,以及相关的关闭和dislike信号等。Hadoop集群压力过大,上线 Storm集群流式计算系统面对这些挑战。2014年底今日头条上线了用户标签Storm集群流式计算系统。改成流式之后,只要有用户动作更新就更新标签,CPU代价比较小,可以节省80%的CPU时间,大大降低了计算资源开销。同时,只需几十台机器就可以支撑每天数千万用户的兴趣模型更新,并且特征更新速度非常快,基本可以做到准实时。这套系统从上线一直使用至今。很多公司算法做的不好,并非是工程师能力不够,而是需要一个强大的实验平台,还有便捷的实验分析工具A/B test系统原理这是头条A/B Test实验系统的基本原理。首先我们会做在离线状态下做好用户分桶,然后线上分配实验流量,将桶里用户打上标签,分给实验组。举个例子,开一个10%流量的实验,两个实验组各5%,一个5%是基线,策略和线上大盘一样,另外一个是新的策略。实验过程中用户动作会被搜集,基本上是准实时,每小时都可以看到。但因为小时数据有波动,通常是以天为时间节点来看。动作搜集后会有日志处理、分布式统计、写入数据库,非常便捷。3.2 推荐算法在闲鱼小商品池的探索与实践闲鱼中个性化推荐流程商品个性化推荐算法主要包含Match和Rank两个阶段:Match阶段也称为商品召回阶段,在推荐系统中用户对商品的行为称为用户Trigger,通过长期收集用户作用在商品上的行为,建立用户行为和商品的矩阵称为X2I,最后通过用户的Trigger和关系矩阵X2I进行商品召回。Rank阶段利用不同指标的目标函数对商品进行打分,根据推荐系统的规则对商品的多个维度进行综合排序。下面以闲鱼的首页feeds为例,简单介绍闲鱼的个性化推荐流程。所示步骤1.1,利用用户的信息获取用户Trigger,用户信息包括用户的唯一标识userId,用户的设备信息唯一标识uttid。所示步骤1.2,返回用户Trigger其中包括用户的点击、购买过的商品、喜欢的类目、用户的标签、常逛的店铺、购物车中的商品、喜欢的品牌等。所示步骤1.3,进行商品召回,利用Trigger和X2I矩阵进行join完成对商品的召回。所示步骤1.4,返回召回的商品列表,在商品召回中一般以I2I关系矩阵召回的商品为主,其他X2I关系矩阵召回为辅助。步骤2.1,进行商品过滤,对召回商品进行去重,过滤购买过的商品,剔除过度曝光的商品。所示步骤2.2,进行商品打分,打分阶段利用itemInfo和不同算法指标对商品多个维度打分。步骤2.3,进行商品排序,根据规则对商品多个维度的分数进行综合排序。步骤2.4,进行返回列表截断,截断TopN商品返回给用户。闲鱼通过以上Match和Rank两个阶段八个步骤完成商品的推荐,同时从图中可以看出为了支持商品的个性化推荐,需要对X2I、itemInfo、userTrigger数据回流到搜索引擎,这些数据包含天级别回流数据和小时级别回流数据。小商品的特点小商品池存在以下几个特点。实时性:在闲鱼搭建的小商品池中要求商品可以实时的流入到该规则下的商品池,为用户提供最新的优质商品。周期性:在小商品池中,很多商品拥有周期属性,例如免费送的拍卖场景,拍卖周期为6小时,超过6小时后将被下架。目前频道导购页面大多还是利用搜索引擎把商品呈现给用户,为了保证商品的曝光,一般利用搜索的时间窗口在商品池中对商品进一步筛选,但是仍存在商品曝光的问题,如果时间窗口过大,那么将会造成商品过度曝光,如果商品窗口过小那么就会造成商品曝光不足,同时还存在一个搜索无法解决的问题,同一时刻每个用户看到的商品都是相同的,无法针对用户进行个性化推荐,为了进一步提升对用户的服务,小商品池亟需引入个性化推荐。推荐在小商品池的解决方案在上文中利用全站X2I数据对小商品池的商品进行推荐过程中,发现在Match阶段,当小商品池过小时会造成商品召回不足的问题,为了提升小商品池推荐过程中有效召回数量,提出了如下三种解决方案。提前过滤法:数据回流到搜索引擎前,小商品池对数据进行过滤,产生小商品池的回流数据,在商品进行召回阶段,利用小商品池的X2I进行商品召回,以此提升商品的召回率。商品向量化法: 在Match阶段利用向量相似性进行商品召回,商品向量化是利用向量搜索的能力,把商品的特性和规则通过函数映射成商品向量,同时把用户的Trigger和规则映射成用户向量,文本转换向量常用词袋模型和机器学习方法,词袋模型在文本长度较短时可以很好的把文本用词向量标识,但是文本长度过长时受限于词袋大小,如果词袋过小效果将会很差,机器学习的方法是利用Word2Vector把文本训练成向量,根据经验值向量维度一般为200维时效果较好。然后利用向量搜索引擎,根据用户向量搜索出相似商品向量,以此作为召回的商品。如图5所示商品的向量分两部分,前20位代表该商品的规则,后200位代表商品的基本特征信息。 商品搜索引擎法: 在Match阶段利用商品搜索引擎对商品进行召回,如图6所示在商品进入搜索引擎时,对商品结构进行理解,在商品引擎中加入Tag和规则,然后根据用户的Trigger和规则作为搜索条件,利用搜索引擎完成商品的召回。搜索引擎的天然实时性解决了小商品池推荐强实时性的问题。3.3 饿了么推荐系统:从0到1对于任何一个外部请求, 系统都会构建一个QueryInfo(查询请求), 同时从各种数据源提取UserInfo(用户信息)、ShopInfo(商户信息)、FoodInfo(食物信息)以及ABTest配置信息等, 然后调用Ranker排序。以下是排序的基本流程(如下图所示):#调取RankerManager, 初始化排序器Ranker:根据ABTest配置信息, 构建排序器Ranker;调取ScorerManger, 指定所需打分器Scorer(可以多个); 同时, Scorer会从ModelManager获取对应Model, 并校验;调取FeatureManager, 指定及校验Scorer所需特征Features。#调取InstanceBuilder, 汇总所有打分器Scorer的特征, 计算对应排序项EntityInfo(餐厅/食物)排序所需特征Features;#对EntityInfo进行打分, 并按需对Records进行排序。这里需要说明的是:任何一个模型Model都必须以打分器Scorer形式展示或者被调用。主要是基于以下几点考虑:模型迭代:比如同一个Model,根据时间、地点、数据抽样等衍生出多个版本Version;模型参数:比如组合模式(见下一小节)时的权重与轮次设定,模型是否支持并行化等;特征参数:特征Feature计算参数,比如距离在不同城市具有不同的分段参数。3.4 爱奇艺个性化推荐排序实践我们的推荐系统主要分为两个阶段,召回阶段和排序阶段。召回阶段根据用户的兴趣和历史行为,同千万级的视频库中挑选出一个小的候选集(几百到几千个视频)。这些候选都是用户感兴趣的内容,排序阶段在此基础上进行更精准的计算,能够给每一个视频进行精确打分,进而从成千上万的候选中选出用户最感兴趣的少量高质量内容(十几个视频)。推荐系统的整体结构如图所示,各个模块的作用如下:用户画像:包含用户的人群属性、历史行为、兴趣内容和偏好倾向等多维度的分析,是个性化的基石特征工程:包含了了视频的类别属性,内容分析,人群偏好和统计特征等全方位的描绘和度量,是视频内容和质量分析的基础召回算法:包含了多个通道的召回模型,比如协同过滤,主题模型,内容召回和SNS等通道,能够从视频库中选出多样性的偏好内容排序模型:对多个召回通道的内容进行同一个打分排序,选出最优的少量结果。除了这些之外推荐系统还兼顾了推荐结果的多样性,新鲜度,逼格和惊喜度等多个维度,更能够满足用户多样性的需求。 然后,介绍了推荐排序系统架构、推荐机器学习排序算法演进。3.5 携程个性化推荐算法实践推荐流程大体上可以分为3个部分,召回、排序、推荐结果生成,整体的架构如下图所示。召回阶段,主要是利用数据工程和算法的方式,从千万级的产品中锁定特定的候选集合,完成对产品的初步筛选,其在一定程度上决定了排序阶段的效率和推荐结果的优劣。业内比较传统的算法,主要是CF1、基于统计的Contextual推荐和LBS,但近期来深度学习被广泛引入,算法性取得较大的提升,如:2015年Netflix和Gravity R&D Inc提出的利用RNN的Session-based推荐[5],2016年Recsys上提出的结合CNN和PMF应用于Context-aware推荐[10],2016年Google提出的将DNN作为MF的推广,可以很容易地将任意连续和分类特征添加到模型中[9],2017年IJCAI会议中提出的利用LSTM进行序列推荐[6]。2017年携程个性化团队在AAAI会议上提出的深度模型aSDAE,通过将附加的side information集成到输入中,可以改善数据稀疏和冷启动问题[4]。对于召回阶段得到的候选集,会对其进行更加复杂和精确的打分与重排序,进而得到一个更小的用户可能感兴趣的产品列表。携程的推荐排序并不单纯追求点击率或者转化率,还需要考虑距离控制,产品质量控制等因素。相比适用于搜索排序,文本相关性检索等领域的pairwise和listwise方法,pointwise方法可以通过叠加其他控制项进行干预,适用于多目标优化问题。工业界的推荐方法经历从线性模型+大量人工特征工程[11] -> 复杂非线性模型-> 深度学习的发展。Microsoft首先于2007年提出采用Logistic Regression来预估搜索广告的点击率[12],并于同年提出OWLQN优化算法用于求解带L1正则的LR问题[13],之后于2010年提出基于L2正则的在线学习版本Ad Predictor[14]。Google在2013年提出基于L1正则化的LR优化算法FTRL-Proximal[15]。2010年提出的Factorization Machine算法[17]和进一步2014年提出的Filed-aware Factorization Machine[18]旨在解决稀疏数据下的特征组合问题,从而避免采用LR时需要的大量人工特征组合工作。阿里于2011年提出Mixture of Logistic Regression直接在原始空间学习特征之间的非线性关系[19]。Facebook于2014年提出采用GBDT做自动特征组合,同时融合Logistic Regression[20]。近年来,深度学习也被成功应用于推荐排序领域。Google在2016年提出wide and deep learning方法[21],综合模型的记忆和泛化能力。进一步华为提出DeepFM[15]模型用于替换wdl中的人工特征组合部分。阿里在2017年将attention机制引入,提出Deep Interest Network[23]。携程在实践相应的模型中积累了一定的经验,无论是最常用的逻辑回归模型(Logistic Regression),树模型(GBDT,Random Forest)[16],因子分解机(FactorizationMachine),以及近期提出的wdl模型。同时,我们认为即使在深度学习大行其道的今下,精细化的特征工程仍然是不可或缺的。基于排序后的列表,在综合考虑多样性、新颖性、Exploit & Explore等因素后,生成最终的推荐结果。四、总结之前没有接触过推荐系统,现在由于工作需要开始接触这块内容。很多概念和技术不懂,需要补很多东西。近期也去参加了内部推荐大赛真实地操作了一轮,同时开始学习推荐系统的基础知识,相关架构等,为下一步工作打下必要的基础。推荐系统是能在几乎所有产品中存在的载体,它几乎可以无延时地以用户需求为导向,来满足用户。其代表的意义和效率,远远超过传统模式。毋庸置疑,牛逼的推荐系统就是未来。但这里有个难点就在于,推荐系统是否做得足够的好。而从目前来看,推荐算法和推荐系统并没有达到人们的预期。因为人的需求是极难猜测的。又想到之前知乎看到一篇文章,说的是国内很多互联网公司都有的运营岗位,在国外是没有专设这个岗位的。还记得作者分析的较突出原因就是:外国人比较规矩,生活和饮食较单调,例如高兴了都点披萨。而中国不一样,从千千万万的菜品就能管中窥豹,国人的爱好极其广泛,众口难调。加上国外人工时很贵,那么利用算法去拟合用户的爱好和需求,自动地去挖掘用户需求,进行下一步的深耕和推荐就是一个替代方案。这也是国外很推崇推荐系统的侧面原因。而在中国,人相对来说是便宜的,加上国人的口味更多更刁钻,算法表现不好,所以会设很多专门的运营岗位。但慢慢也开始意识到这将是一个趋势,加上最近ai大热,各家大厂都在这块不断深耕。回到推荐系统上,从现实中客观的原因就可以看到,真正能拟合出用户的需求和爱好确实是很困难的事情。甚至有时候用户都不知道自己想要的是啥,作为中国人,没有主见和想法是正常的,太有主见是违背标准答案的。但推荐系统背后代表的意义是:你的产品知道用户的兴趣,能满足用户的兴趣,那么必定用户就会离不开你。用户离不开的产品,肯定会占领市场,肯定就有极高的估值和想象空间。这也就是大家都在做推荐系统,虽然用起来傻傻的,效果也差强人意,依然愿意大力投入的根本原因。几句胡诌,前期学习过后的简单总结,自己还有很多东西和细节需要继续学习和研究。能力有限,文中不妥之处还请指正(ps:文中一些截图和文字的版权归属原作者,且均已标注引用资料来源地址,本文只是学习总结之用,如有侵权,联系我删除)问答推荐系统如何实现精准推荐?相关阅读推荐系统基础知识储备量化评估推荐系统效果基于用户画像的实时异步化视频推荐系统 【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识 ...

October 9, 2018 · 2 min · jiezi