关于推荐算法:推荐一款优秀电商开源项目

简介本文给大家举荐博主本人开源的电商我的项目newbee-mall-pro。在newbee-mall我的项目的根底上搭建而来, 应用 mybatis-plus 作为 orm 层框架,并增加了一系列高级性能以及代码优化,个性如下: 商城首页 【为你举荐】 栏目增加协同过滤算法。依照 UserCF 基于用户的协同过滤、ItemCF 基于物品的协同过滤,实现了两种不同的举荐逻辑。RedisSearch:反对中文分词搜寻,反对商品名称、简介、标签作为搜寻项,以及新品、价格排序。 RediSearch 是一个源码可用的 Redis 模块,能够对 Redis 进行查问、二级索引和全文搜寻。这些性能反对在文本查问之上进行多字段查问、聚合、准确短语匹配、数字过滤、天文过滤和矢量相似性语义搜寻。秒杀专区:反对性能齐备,生产可用的高级秒杀性能。优惠卷专区:反对优惠卷后盾配置、用户注册赠卷、下单页面优惠卷应用等性能。商城首页反对应用滑块验证码登录。领取时集成了支付宝沙箱领取,能够在开发环境体验支付宝领取成果。集成 Pace 页面,增加网页进度条,页面跳转丑化。增加 Spring 事件监听机制,异步解耦下单流程。集成spring-session-redis,反对分布式部署。集成mybatis-xmlreload,反对xml文件热加载。newbee-mall-pro 我的项目地址: 源码地址:https://github.com/wayn111/newbee-mall-pro在线地址:http://121.4.124.33/newbeemall一、开发部署# 1. 克隆我的项目git clone git@github.com:wayn111/newbee-mall-pro.git# 2. 导入我的项目依赖将newbee-mall-pro目录用idea关上,导入maven依赖# 3. 装置Mysql8.0+、Redis3.0+(RediSearch2.0+)、Jdk8+、Maven3.5+docker装置RediSearchdocker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:lates# 4. 导入sql文件在我的项目根目录下sql文件夹下,找到`newbee_mall_db_蕴含秒杀and优惠卷.sql`文件,新建mysql数据库newbee_mall_db,导入其中# 5. 解压我的项目图片将我的项目根目录下upload.zip文件加压缩到D盘upload文件夹中,eg:D:\\upload# 6. 批改Mysql、Redis连贯配置批改`application-dev.yml`文件中数据连贯配置相干信息# 7. 启动我的项目找到NewBeeMallApplication文件,右键`run AdminApplication`,启动我的项目# 8. 拜访关上浏览器输出:http://localhost:84/newbeemall二、更新日志2023年4月08日更新日志newbee-mall-pro V2.4.2公布 更新内容: 商城首页为你举荐栏目增加协同过滤算法。依照UserCF基于用户的协同过滤、ItemCF基于物品的协同过滤。 实现了两种不同的举荐逻辑。 UserCF:基于用户的协同过滤。当一个用户A须要个性化举荐的时候,咱们能够先找到和他有类似趣味的其余用户,而后把那些用户喜爱的,而用户A没有据说过的物品举荐给A。具体代码在 ltd.newbee.mall.recommend.core.UserCF 中。itemCF:基于物品的协同过滤。事后依据所以用户的历史偏好数据计算物品之间的类似度,而后把与用户喜爱的物品相相似的物品举荐给用户。具体代码在 ltd.newbee.mall.recommend.core.ItemCF 中。2023年3月27日更新日志newbee-mall-pro V2.4.1公布 更新内容: 集成mybatis-xmlreload,反对xml文件热加载代码优化,通过阿里巴巴代码标准检测降级局部依赖至最新2023年1月2日更新日志newbee-mall-pro V2.4.0公布 更新内容: Springboot版本升级至3.0.2Mybatis plus降级至3.5.3.1反对Springboot3.02022年11月17日更新日志newbee-mall-pro V2.3.0公布 更新内容: Springboot版本升级至2.7.5,jdk降级至17应用switch表达式语法扩大,优化switch语句应用instanceof类型匹配语法简化,间接给对象赋值应用文本块优化现有lua脚本显示增加@Serial注解示意序列化字段和办法代码优化,删除无用导入降级我的项目依赖bug修复: ...

April 8, 2023 · 1 min · jiezi

关于推荐算法:高效压缩位图在推荐系统中的应用

作者:vivo互联网技术-Ke Jiachen一、背景用户在浏览游戏核心/利用商店的某些模块内容时,会进行一系列滑屏操作并屡次申请游戏举荐业务来进行游戏举荐展现,这段时间咱们称之为一个用户session。 一个session内用户个别会进行十几次滑屏操作,每次滑屏操作都会申请举荐业务,所以在这个session内游戏举荐须要对举荐过的游戏进行去重,避免出现反复举荐同一款游戏影响用户体验。 精简后的业务流程如下所示:用户进行滑屏操作时会触发一次举荐申请,此时客户端会将上一页的黑名单游戏通过游戏核心服务端透传给举荐零碎,举荐零碎将一个session内每次申请的黑名单信息都累加存储到Redis中作为一个总的过滤汇合,在召回打分时就会过滤掉这些黑名单游戏。 以理论业务场景为例,用户浏览某模块的session时长个别不会超过10分钟,模块每页显示的游戏为20个左右,假如每个用户session内会进行15次的滑屏操作,那么一个session就须要存储300 个黑名单游戏的appId(整数型Id)。因而该业务场景就不适宜长久化存储,业务问题就能够归结为如何应用一个适合的数据结构来缓存一系列整数汇合以达到节俭内存开销的目标。 二、技术选型剖析接下来咱们随机选取300个游戏的appId([2945340, ....... , 2793501,3056389])作为汇合来别离试验剖析intset,bloom filter,RoaringBitMap对存储成果的影响。 2.1 intset试验结果表明用 intset保留300个游戏汇合,失去占用的空间大小为1.23KB。这是因为对于300个整数型appId游戏,每个appId用4Byte的int32就能示意。依据intset的数据结构,其开销仅为encoding + length + 400 个int所占的空间。 typedef struct intset{ unit32_t encoding; // 编码类型 unit32_t length; // 元素个数 int8_t contents[]; // 元素存储} intset;2.2 bloom filter布隆过滤器底层应用的是bitmap,bitmap自身就是一个数组能够存储整形数字,arr[N] = 1 示意数组里存储了N这个数字。 bloom filter会先用hash函数对数据进行计算,映射到bitmap相应的地位,为缩小碰撞(不同的数据可能会有雷同的hash值),会应用多个hash算子对同一份数据进行屡次映射。在业务中咱们假如线上有一万个游戏,同时业务场景不容许呈现误判,那么误差就必须管制在10^-5,通过bloom filter的计算工具https://hur.st/bloomfilter/?n...得出,须要17个hash算子,且bitmap空间要达到29KB能力满足业务需要,显然这样微小的开销并不是咱们想要的后果。 2.3 RoaringBitMapRoaringBitMap和bloom filter实质上都是应用bitmap进行存储。但bloom filter 应用的是多个hash函数对存储数据进行映射存储,如果两个游戏appId通过hash映射后得出的数据统一,则断定两者反复,这两头有肯定的误判率,所以为满足在该业务场景其空间开销会十分的大。而RoaringBitMap是间接将元数据进行存储压缩,其准确率是100%的。 试验结果表明:RoaringBitMap对300个游戏汇合的开销仅为0.5KB,比间接用intset(1.23KB)还小,是该业务场景下的首选。所以下文咱们来着重剖析下RoaringBitMap为什么为如此高效。 2.3.1 数据结构每个RoaringBitMap中都蕴含一个RoaringArray,存储了全副的数据,其构造如下: short[] keys;Container[] values;int sizer;它的思路是将32位无符号整数依照高16位分桶(container),并做为key存储到short[] keys中,最多能存储2^16 = 65536 个桶(container)。存储数据时依照数据的高16位找到container,再将低16位放入container中,也就是Container[] values。size则示意了以后keys和values中无效数据的数量。 为了不便了解,下图展现了三个container: 图片援用自:https://arxiv.org 高16位为0000H的container,存储有前1000个62的倍数。高16位为0001H的container,存储有[2^16, 2^16+100)区间内的100个数。高16位为0002H的container,存储有[2×2^16, 3×2^16)区间内的所有偶数,共215个。当然该数据结构的细节不是咱们关注的重点,有趣味的同学能够去查阅相干材料学习。当初咱们来剖析一下在举荐业务中RoaringBitMap是如何帮忙咱们节俭开销的。RoaringBitMap中的container分为ArrayContainer,BitmapContainer 和 RunContainer 但其压缩形式次要分为两种,权且就称为可变长度压缩和固定长度压缩, 这两种形式在不同的场景下有不同的利用。 ...

April 19, 2022 · 2 min · jiezi

关于推荐算法:推荐系统入门笔记九-基于内容的推荐算法

一. 简介基于内容的举荐办法是以物品的内容形容信息为根据来做出的举荐,实质上是基于对物品和用户本身的特色或属性的间接剖析和计算。 例如,假如已知电影A是一部悲剧,而凑巧咱们得悉某个用户喜爱看喜剧电影,那么咱们基于这样的已知信息,就能够将电影A举荐给该用户。 二. 基于内容举荐的实现步骤画像构建(画像就是刻画物品或用户的特色。实质上就是给用户或物品贴标签) 物品画像 : 给物品贴标签用户画像 : 给用户贴标签构建画像的办法: 依据PGC/UGC 内容构建物品画像,(PGC:物品自带的标签,UGC:用户提供的标签)依据用户记录构建用户画像依据用户画像从物品中寻找最匹配的TOP-N物品进行举荐三. 基于内容的电影举荐: 物品画像1. 构建步骤利用tags.csv中每部电影的标签作为电影的候选关键词利用Tf-IDF 或者word2vec 计算每个词的权重选取权重top-n的标签作为电影画像2. TF-IDF 算法1. 算法原理TF-IDF自然语言解决畛域中计算文档中词或短语的权值的办法,是词频(Term Frequency,TF)和逆转文档频率(Inverse Document Frequency,IDF)的乘积。TF指的是某一个给定的词语在该文件中呈现的次数。这个数字通常会被正规化,以避免它偏差长的文件(同一个词语在长文件里可能会比短文件有更高的词频,而不论该词语重要与否)。IDF是一个词语广泛重要性的度量,某一特定词语的IDF,能够由总文件数目除以蕴含该词语之文件的数目,再将失去的商取对数失去。 2. 算法举例对于计算影评的TF-IDF,以电影“加勒比海盗:黑珍珠号的咒骂”为例,假如它总共有1000篇影评,其中一篇影评的总词语数为200,其中呈现最频繁的词语为“海盗”、“船长”、“自在”,别离是20、15、10次,并且这3个词在所有影评中被提及的次数别离为1000、500、100,就这3个词语作为关键词的程序计算如下。 将影评中呈现的停用词过滤掉,计算其余词语的词频。以呈现最多的三个词为例进行计算如下: “海盗”呈现的词频为20/200=0.1“船长”呈现的词频为15/200=0.075“自在”呈现的词频为10/200=0.05;计算词语的逆文档频率如下: “海盗”的IDF为:log(1000/1000)=0“船长”的IDF为:log(1000/500)=0.3“自在”的IDF为:log(1000/100)=1由1和2计算的后果求出词语的TF-IDF后果,“海盗”为0,“船长”为0.0225,“自在”为0.05。3. 算法实现import pandas as pdimport numpy as npfrom gensim.corpora import Dictionaryfrom gensim.models import TfidfModeldef get_movie_dataset(tag_path, movie_path): # 读取电影标签文件,去第2,第3列 _tags = pd.read_csv(tag_path, usecols=[1, 2]).dropna() # 对标签数据进行汇合 tags = _tags.groupby('movieId').agg(list) # 读取电影文件,将tags标签 和电影数据组合 movies = pd.read_csv(movie_path, index_col='movieId') # 须要应用到电影的分类,所以对电影分类进行解决 movies['genres'] = movies['genres'].apply(lambda x: x.split('|')) # 将标签数据和电影数据组合,取tags 和 movies 都存在的movieId movie_index = set(movies.index) & set(tags.index) # 取标签中的值 new_tags = tags.loc[movie_index] # 组合数据 ret = movies.join(new_tags) # 将数据转换成pd movie_dataset = pd.DataFrame( map(lambda x: (x[0], x[1], x[2], x[2] + x[3]) if x[3] is not np.nan else (x[0], x[1], x[2], []), ret.itertuples()), columns=["movieId", "title", "genres", "tags"]) # 设置movie_dataset 的index为 movieId movie_dataset.set_index('movieId', inplace=True) return movie_datasetdef create_movie_profile(movie_dataset): # 1. 对数据集进行迭代 # 2. 对每个电影的现有标签进行tf-idf计算权重 # 3. 对标签进行权重排序, # 4. 取top-n 个tag 作为电影的标签 # 取出所有电影的标签 dataset = movie_dataset['tags'].values # 应用gensim计算tf-idf ,将所有词放入一个词典 dct = Dictionary(dataset) # 依据每条数据,计算对应的词索引和词频 corpus = [dct.doc2bow(line) for line in dataset] model = TfidfModel(corpus) # 给每个电影贴标签 _movie_profile = [] for i, data in enumerate(movie_dataset.itertuples()): mid = data[0] title = data[1] genres = data[2] # 依据每条数据返回标签,权重向量 vector = model[corpus[i]] # 对标签进行权重排序并去前30个作为电影标签 movie_tags = sorted(vector, key=lambda x: x[1], reverse=True)[:30] # 前30个电影-权重 topN_tags_weights = dict(map(lambda x: (dct[x[0]], x[1]), movie_tags)) # 将类别词退出tags 设置权重为1 for g in genres: topN_tags_weights[g] = 1.0 topN_tags = [i[0] for i in topN_tags_weights.items()] _movie_profile.append((mid, title, topN_tags, topN_tags_weights)) movie_profile = pd.DataFrame(_movie_profile, columns=["movieId", "title", "profile", "weights"]) movie_profile.set_index("movieId", inplace=True) return movie_profiledef create_inverted_table(movie_profile): # 对电影画像做tag-movies倒排表: # 每个关键词对应的电影,以及该词的权重 inverted_table = {} # 对所有电影的标签权重循环 for mid, weights in movie_profile['weights'].iteritems(): # 取每个电影标签 for tag, weight in weights.items(): # 获取inverted_table 中 tag的值如果不存在,返回[] _ = inverted_table.get(tag, []) # 将 电影和权重增加到标签的列表中 _.append((mid, weight)) # 增加标签对应的电影和权重 inverted_table.setdefault(tag, _) return inverted_tableif __name__ == '__main__': tag_path = 'E:/ml/recommand/ml-latest-small/all-tags.csv' movie_path = 'E:/ml/recommand/ml-latest-small/movies.csv' watch_path = 'E:/ml/recommand/ml-latest-small/ratings.csv' # 1. 获取数据,解决数据集 movie_dataset = get_movie_dataset(tag_path, movie_path) # 2. 对电影构建画像 movie_profile = create_movie_profile(movie_dataset) inverted_table = create_inverted_table(movie_profile) print(inverted_table)三. 基于内容的电影举荐: 用户画像用户画像构建步骤: ...

November 16, 2021 · 5 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

surprise库文档翻译

这里的格式并没有做过多的处理,可参考于OneNote笔记链接 由于OneNote取消了单页分享,如果需要请留下邮箱,我会邮件发送pdf版本,后续再解决这个问题 推荐算法库surprise安装 pip install surprise基本用法 • 自动交叉验证 # Load the movielens-100k dataset (download it if needed),data = Dataset.load_builtin('ml-100k') # We'll use the famous SVD algorithm.algo = SVD() # Run 5-fold cross-validation and print resultscross_validate(algo, data, measures=['RMSE', 'MAE'], cv=5, verbose=True) load_builtin方法会自动下载“movielens-100k”数据集,放在.surprise_data目录下面 • 使用自定义的数据集 # path to dataset filefile_path = os.path.expanduser('~/.surprise_data/ml-100k/ml-100k/u.data') # As we're loading a custom dataset, we need to define a reader. In the# movielens-100k dataset, each line has the following format:# 'user item rating timestamp', separated by '\t' characters.reader = Reader(line_format='user item rating timestamp', sep='\t') data = Dataset.load_from_file(file_path, reader=reader) # We can now use this dataset as we please, e.g. calling cross_validatecross_validate(BaselineOnly(), data, verbose=True)• 交叉验证 ○ cross_validate(算法,数据集,评估模块measures=[],交叉验证折数cv) ○ 通过test方法和KFold也可以对数据集进行更详细的操作,也可以使用LeaveOneOut或是ShuffleSplit from surprise import SVD from surprise import Dataset from surprise import accuracy from surprise.model_selection import Kfold # Load the movielens-100k dataset data = Dataset.load_builtin('ml-100k') # define a cross-validation iterator kf = KFold(n_splits=3) algo = SVD() for trainset, testset in kf.split(data): # train and test algorithm. algo.fit(trainset) predictions = algo.test(testset) # Compute and print Root Mean Squared Error accuracy.rmse(predictions, verbose=True)• 使用GridSearchCV来调节算法参数 ○ 如果需要对算法参数来进行比较测试,GridSearchCV类可以提供解决方案 ○ 例如对SVD的参数尝试不同的值 from surprise import SVD from surprise import Dataset from surprise.model_selection import GridSearchCV # Use movielens-100K data = Dataset.load_builtin('ml-100k') param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005], 'reg_all': [0.4, 0.6]} gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=3) gs.fit(data) # best RMSE score print(gs.best_score['rmse']) # combination of parameters that gave the best RMSE score print(gs.best_params['rmse']) # We can now use the algorithm that yields the best rmse: algo = gs.best_estimator['rmse'] algo.fit(data.build_full_trainset())• 使用预测算法 ○ 基线估算配置 § 在使用最小二乘法(ALS)时传入参数: 1) reg_i:项目正则化参数,默认值为10 2) reg_u:用户正则化参数,默认值为15 3) n_epochs:als过程中的迭代次数,默认值为10 print('Using ALS') bsl_options = {'method': 'als', 'n_epochs': 5, 'reg_u': 12, 'reg_i': 5 } algo = BaselineOnly(bsl_options=bsl_options) § 在使用随机梯度下降(SGD)时传入参数: 1) reg:优化成本函数的正则化参数,默认值为0.02 2) learning_rate:SGD的学习率,默认值为0.005 3) n_epochs:SGD过程中的迭代次数,默认值为20 print('Using SGD') bsl_options = {'method': 'sgd', 'learning_rate': .00005, } algo = BaselineOnly(bsl_options=bsl_options) § 在创建KNN算法时候来传递参数 bsl_options = {'method': 'als', 'n_epochs': 20, } sim_options = {'name': 'pearson_baseline'} algo = KNNBasic(bsl_options=bsl_options, sim_options=sim_options) ○ 相似度配置 § name:要使用的相似度名称,默认是MSD § user_based:是否时基于用户计算相似度,默认为True § min_support:最小的公共数目,当最小的公共用户或者公共项目小于min_support时候,相似度为0 § shrinkage:收缩参数,默认值为100 i. sim_options = {'name': 'cosine', 'user_based': False # compute similarities between items } algo = KNNBasic(sim_options=sim_options) ii. sim_options = {'name': 'pearson_baseline', 'shrinkage': 0 # no shrinkage } algo = KNNBasic(sim_options=sim_options)• 其他一些问题 ○ 如何获取top-N的推荐 from collections import defaultdict from surprise import SVD from surprise import Dataset def get_top_n(predictions, n=10): '''Return the top-N recommendation for each user from a set of predictions. Args: predictions(list of Prediction objects): The list of predictions, as returned by the test method of an algorithm. n(int): The number of recommendation to output for each user. Default is 10. Returns: A dict where keys are user (raw) ids and values are lists of tuples: [(raw item id, rating estimation), ...] of size n. ''' # First map the predictions to each user. top_n = defaultdict(list) for uid, iid, true_r, est, _ in predictions: top_n[uid].append((iid, est)) # Then sort the predictions for each user and retrieve the k highest ones. for uid, user_ratings in top_n.items(): user_ratings.sort(key=lambda x: x[1], reverse=True) top_n[uid] = user_ratings[:n] return top_n # First train an SVD algorithm on the movielens dataset. data = Dataset.load_builtin('ml-100k') trainset = data.build_full_trainset() algo = SVD() algo.fit(trainset) # Than predict ratings for all pairs (u, i) that are NOT in the training set. testset = trainset.build_anti_testset() predictions = algo.test(testset) top_n = get_top_n(predictions, n=10) # Print the recommended items for each user for uid, user_ratings in top_n.items(): print(uid, [iid for (iid, _) in user_ratings]) ○ 如何计算精度 from collections import defaultdict ...

May 15, 2019 · 7 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

协同过滤推荐中利用SVD提高推荐的效果

1.什么是SVD :SVD指的是奇异值分解 SVD SVD的物理意义2.利用Python实现SVDfrom numpy import linalg as la# Numpy有一个称为linalg的线性代数工具,其中svd计算方法如下U,Sigma,VT = la.svd(dataMat)3.利用SVD提高效率生产实际中的数据比较稀疏,在生产中不管是基于用户的相似度计算还是基于物品的相似度计算都需要较多的时间和很多的计算力,通过SVD可以将映射到低纬空间中去4.基于SVD的评估方法Python实现(参考自机器学习实战)def svdEst(dataMat, user, simMeas, item): n = shape(dataMat)[1] simTotal = 0.0; ratSimTotal = 0.0 U,Sigma,VT = la.svd(dataMat)# numpy 的svd计算 Sig4 = mat(eye(4)*Sigma[:4]) #numpy.eye() 生成对角矩阵 # 机器学习实战的P264中代码对应的公式推导 https://blog.csdn.net/appleyuchi/article/details/82913217 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其中计算按照奇异值能到达总能量的90% 计算;dataMat.T U[:,:4] Sig4.I 的推导请参见:推导 ...

January 1, 2019 · 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