热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

推荐系统基础纪要

推荐系统纪要推荐概念Lambda架构介绍推荐算法架构推荐模型构建流程协同过滤思路介绍相似度计算使用不同相似度计算方式实现协同过滤协同过滤基于模型的算法推荐系统的评价推荐系统的冷启动

推荐系统纪要

      • 推荐概念
      • Lambda 架构介绍
      • 推荐算法架构
      • 推荐模型构建流程
      • 协同过滤思路介绍
      • 相似度计算
      • 使用不同相似度计算方式实现协同过滤
      • 协同过滤 基于模型的算法
      • 推荐系统的评价
      • 推荐系统的冷启动
      • 基于内容的推荐
      • 基于内容的推荐 基于物品的协同过滤 区别
      • 矩阵分解
      • 基于内容的推荐
      • 基于内容推荐流程
      • 词向量

7天 基础

  • 推荐系统相关概念 基本算法
  • 推荐算法
    • 原生python 实现推荐算法
  • lambda架构 5天
    • hadoop
    • hive hbase
    • spark core
    • spark sql spark streaming
    • 案例 基于电商用户行为

7天 项目

推荐概念


  • 信息过滤系统 解决 信息过载 用户需求不明确的问题
    • 利用一定的规则将物品排序 展示给需求不明确的用户
  • 推荐 搜索区别
    • 推荐个性化较强,用户被动的接受,希望能够提供持续的服务
    • 搜索个性化弱,用户主动搜索,快速满足用户的需求
  • 推荐和 web项目区别
    • 构建稳定的信息流通通道
    • 推荐 信息过滤系统
    • web 对结果有明确预期
    • 推荐 结果是概率问题

Lambda 架构介绍


  • 离线计算和实时计算共同提供服务的问题
  • 离线计算优缺点
    • 优点 能够处理的数据量可以很大 比如pb级别
    • 缺点 速度比较慢 分钟级别的延迟
  • 实时计算
    • 优点 响应快 来一条数据处理一条 ms级别响应
    • 缺点 处理的数据量小一些
  • 离线计算的框架
    • hadoop hdfs mapreduce
    • spark core , spark sql
    • hive
  • 实时计算框架
    • spark streaming
    • storm
    • flink
  • 消息中间件
    • flume 日志采集系统
    • kafka 消息队列
  • 存储相关
    • hbase nosql数据库
    • hive sql操作hdfs数据

推荐算法架构


  • 召回

    • 协同过滤 算相似度 memory base

      ​ 基于模型的 model base 矩阵分解

    • 基于内容

      • 分词
      • 词权重(提取关键词) tf-idf
      • word2Vec 词向量
      • 物品向量
  • 排序

    • 逻辑回归
  • 策略调整


推荐模型构建流程


  • 数据收集

    • 显性评分
    • 隐性数据
  • 特征工程

    • 协同过滤:用户-物品 评分矩阵
    • 基于内容:分词 tf-idf word2Vec
  • 训练模型

    • 协同过滤
      • kNN
      • 矩阵分解 梯度下降 ALS
  • 评估、模型上线


协同过滤思路介绍


  • CF 物以类聚人以群分
  • 做协同过滤的话 首先特征工程把 用户-物品的评分矩阵创建出来
  • 基于用户的协同过滤
    • 给用户A 找到最相似的N个用户
    • N个用户消费过哪些物品
    • N个用户消费过的物品中-A用户消费过的就是推荐结果
  • 基于物品的协同过滤
    • 给物品A 找到最相似的N个物品
    • A用户消费记录 找到这些物品的相似物品
    • 从这些相似物品先去重-A用户消费过的就是推荐结果

相似度计算


  • 余弦相似度、皮尔逊相关系数
    • 向量的夹角余弦值
    • 皮尔逊会对向量的每一个分量做中心化
    • 余弦只考虑方向 不考虑向量长度
    • 如果评分数据是连续的数值比较适合中余弦、皮尔逊计算相似度
  • 杰卡德相似度
    • 交集/并集
    • 计算评分是0 1 布尔值的相似度

使用不同相似度计算方式实现协同过滤


  • 如果 买/没买 点/没点数据 0/1 适合使用杰卡德相似度

    • from sklearn.metrics import jaccard_similarity_score
    • jaccard_similarity_score(df[‘Item A’],df[‘Item B’])
    • from sklearn.metrics.pairwise import pairwise_distances
    • user_similar = 1-pairwise_distances(df,metric=‘jaccard’)
  • 一般用评分去做协同过滤 推荐使用皮尔逊相关系数

    • 评分预测

    • pred(u,i)=r^ui=∑v∈Usim(u,v)∗rvi∑v∈U∣sim(u,v)∣pred(u,i)=\hat{r}_{ui}=\cfrac{\sum_{v\in U}sim(u,v)*r_{vi}}{\sum_{v\in U}|sim(u,v)|} pred(u,i)=r^ui=vUsim(u,v)vUsim(u,v)rvi

  • 基于用户和基于物品的协同过滤 严格上说,属于两种算法,实践中可以都做出来,对比效果,选择最靠谱的


协同过滤 基于模型的算法


  • 用户-物品矩阵比较稀疏的时候 直接去取物品向量 用户向量计算相似度 不太适合
  • 基于模型的方法可以解决用户-物品矩阵比较稀疏的问题
  • 矩阵分解
    • 把大的矩阵拆成两个小的 用户矩阵 物品矩阵 MXN 大矩阵 M X K K X N K<
    • 大矩阵 约等于 用户矩阵 乘 物品矩阵
    • 使用als 交替最小二乘法来优化损失 spark ML recommandation 包封装了als
    • 优化之后的用户矩阵 取出用户向量
    • 优化之后的物品矩阵 取出物品向量
    • 用户向量点乘物品向量 得到最终评分的预测

推荐系统的评价


  • 准确率 覆盖率

    • 准确率
      • 学术 rmse mas 点击率预估 精准率
      • 工程 A/B test 对比不同的算法 在线上运行对关键指标的影响
        • baseline 基准线 热门排行
        • 灰度发布
  • EE

    • Exploitation & Exploration 探索与利用问题
    • Exploitation 利用用户的历史行为 只给他曾经看过的/消费过的相似物品
    • Exploration(探测 搜索) 发现用户的新兴趣
    • ee问题 实际上是矛盾
  • 评估手段

    • 离线评估和在线评估结合, 定期做问卷调查
      • 在线评估
        • 灰度发布 & A/B测试

推荐系统的冷启动


  • 用户冷启动
    • 尽可能收集用户信息 构建用户画像&#xff08;打标签&#xff09;
    • 根据用户的标签可以做人群聚类 用以有用户的行为做推荐
    • 更多的使用流行度推荐
  • 物品冷启动
    • 物品打标签 构建物品画像
    • 基于内容的推荐
  • 系统冷启动
    • 如果应用缺少用户行为数据->基于内容的推荐
    • 随着用户行为积累的越来越多->协同过滤
    • 基于内容和协同过滤共同工作

基于内容的推荐


  • 给物品打标签
    • 系统自己提取从业务数据库中提取
    • 用户填写
    • 中文分词 利用算法计算词的权重
      • tf-idf tf term frequency 词频 5/100 *2
        • idf 逆文档频率 log 10 文本库篇数/出现关键词的文章篇数
        • 1000 10python 1000/10 100 2
        • 1000/1000 log(1) &#61; 0
      • textrank
  • 利用标签的文字 转换成词向量
    • word2Vec 词->向量
    • 用向量来表示语义
    • 如果两个词的词向量相似度比较高 认为这两个词的语义相近
  • 利用词向量 构建物品的向量
    • 一个物品有N个关键词 每一个关键词对应一个词向量
    • 求和&#xff08;权重*词向量&#xff09;/N
    • 利用N个关键词的词向量获取物品向量
  • 通过物品向量计算相似度
    • 皮尔逊 相关系数 计算物品向量的相似度

基于内容的推荐 基于物品的协同过滤 区别


  • content_base &#xff1a;词向量->物品向量->计算相似度

  • item_based cf :user-item matrix->物品向量->相似度

  • content_base item_based cf 不一样

    • 物品向量构建过程有区别
    • 基于内容的推荐
      • 物品向量 文本&#xff08;物品描述信息&#xff0c;系统填标签&#xff0c;用户填标签&#xff09;
    • 基于物品的协同过滤
      • 用户对物品的评分矩阵 用户的行为数据中来
  • baseline思想来解决协同过滤的问题

    • 计算出所有用户对所有物品评分的平均值

    • 预测的评分&#61; 在平均值的基础上 &#43; 用户评分偏置 &#43;物品的评分偏置

    • 求解所有用户的评分偏置 和 所有物品的得分偏置

    • 这个问题可以转换成损失优化的过程

  • 梯度下降

  • 交替最小二乘法


矩阵分解


  • SVD 奇异值分解
    • 一个大矩阵 分成3个小矩阵 中间的是一个k方阵
    • SVD只适用于没有缺失 必须是稠密矩阵
  • Funk SVD
    • 一个大的 分成两个小矩阵
    • LFM 原理
  • BiasSVD 矩阵分解&#43;baseline
  • SVD&#43;&#43; 矩阵分解&#43;baseline&#43;其它影响&#xff08;点击&#xff0c;收藏&#xff0c;购买&#xff09;

基于内容的推荐


  • 画像构建 给用户/物品打标签
    • 物品画像
      • 分类信息
      • 标题
      • 电影/音乐 主演、歌手
    • 用户画像
      • 喜好的物品类别 行为偏好
      • 基本人口学属性
      • 活跃程度
      • 风控纬度
  • PGC 应用自己生成
  • UGC 用户来生成
  • 基于内容推荐的算法流程
    • 用户画像/物品画像
    • 匹配用户画像 物品画像
  • 物品冷启动问题
    • 画像->词向量->物品向量->计算物品相似度了
    • 从文本描述的角度找相似的物品
    • 当用户在浏览A的时候 通过上述套路找到跟物品A相似的一系列物品

基于内容推荐流程

① 建立物品画像

  • ①用户打tag ②电影的分类值
  • 根据电影的id 把tag和分类值合并起来 求tf-idf
  • 根据tf-idf的结果 为每一部电影筛选出 top-n&#xff08;tf-idf比较大的&#xff09;个关键词
  • 电影id-关键词-关键词权重

② 建立倒排索引

  • 通过关键词找到电影
  • 遍历 电影id-关键词-关键词权重 数据&#xff0c; 读取每一个关键词&#xff0c;用关键词作为key [(关键词对应的电影id,tfidf)] 作为value 保存到dict当中

③ 用户画像

  • 看用户看过那些电影&#xff0c; 到电影的 电影id-关键词-关键词权重 数据中 找到电影所对应的关键词
  • 把用户看过的所有的关键词放到一起 统计词频 每个词出现了几次
  • 出现次数多的关键词 作为用户的兴趣词&#xff0c;这个兴趣词实际上就是用户画像的关键词

④ 根据用户的兴趣词 找到兴趣词对应的电影 多个兴趣词可能对应一个电影 {电影id&#xff1a;[关键词1权重&#xff0c;关键词2权重]}

  • 把每一个部电影对应的关键词权重求和之后 排序 权重比较高的排在前面 推荐给用户

词向量


  • 用向量来表示词语 可以表示语义层面的含义

  • 如果用word2vec模型创建的词向量&#xff0c; 两个词向量相似度比较高&#xff0c;说明这两个词是近义词

  • 词向量作用 把含义相近的判断转换成 向量的相似度计算

  • 使用 gensim Word2Vec模块训练词向量模型

import gensim
#准备所有用来训练词向量模型的文本内容
sentences &#61; list(movie_profile["profile"].values)
# 参数1 文本 参数2 window 观察上下文关系的窗口长度
# min_count 训练模型时要保留下的词语出现的频率 iter&#61;20 迭代20词
model &#61; gensim.models.Word2Vec(sentences, window&#61;3, min_count&#61;1, iter&#61;20)

  • 通过词向量模型找到topn相似词

    model.wv.most_similar(positive&#61;[&#39;要找到相似的词的词语&#39;], topn&#61;10)

  • 文档向量

from gensim.models.doc2vec import Doc2Vec,TaggedDocument
documents &#61; [TaggedDocument(words, [movie_id]) for movie_id, words in movie_profile["profile"].iteritems()]
# 训练模型并保存 Doc2Vec 通过向量来表示一篇文档 一篇文档就对应一个电影
#向量的相似度 代表了电影额相似程度
model &#61; Doc2Vec(documents, vector_size&#61;100, window&#61;3, min_count&#61;1, workers&#61;4, epochs&#61;20)
words &#61; movie_profile["profile"].loc[6]
inferred_vector &#61; model.infer_vector(words) #传入电影的标签 找到电影文档所对应的向量# 通过docvecs找到传入的向量最相似的n个向量 每一个向量代表了一个电影
sims &#61; model.docvecs.most_similar([inferred_vector], topn&#61;10)


加油!

感谢!

努力!


推荐阅读
author-avatar
manly213
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有