基于内容的电影推荐:物品画像&用户画像&为用户产生top-n推荐结果(代码片段)

ZSYL ZSYL     2023-01-27     569

关键词:

基于内容的电影推荐:物品画像

物品画像构建步骤:

  • 利用tags.csv中每部电影的标签作为电影的候选关键词
  • 利用TF·IDF计算每部电影的标签的tfidf值,选取TOP-N个关键词作为电影画像标签
  • 将电影的分类词直接作为每部电影的画像标签

基于TF-IDF的特征提取技术

前面提到,物品画像的特征标签主要都是指的如电影的导演、演员、图书的作者、出版社等结构话的数据,也就是他们的特征提取,尤其是体征向量的计算是比较简单的,如直接给作品的分类定义0或者1的状态。

但另外一些特征,比如电影的内容简介、电影的影评、图书的摘要等文本数据,这些被称为非结构化数据,首先他们本应该也属于物品的一个特征标签,但是这样的特征标签进行量化时,也就是计算它的特征向量时是很难去定义的。

因此这时就需要借助一些自然语言处理、信息检索等技术,将如用户的文本评论或其他文本内容信息的非结构化数据进行量化处理,从而实现更加完善的物品画像/用户画像

TF-IDF算法便是其中一种在自然语言处理领域中应用比较广泛的一种算法。可用来提取目标文档中,并得到关键词用于计算对于目标文档的权重,并将这些权重组合到一起得到特征向量。

算法原理

TF-IDF自然语言处理领域中计算文档中词或短语的权值的方法,是词频(Term Frequency,TF)和逆转文档频率(Inverse Document Frequency,IDF)的乘积。TF指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被正规化,以防止它偏向长的文件(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否)。IDF是一个词语普遍重要性的度量,某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。

TF-IDF算法基于一个这样的假设:若一个词语在目标文档中出现的频率高而在其他文档中出现的频率低,那么这个词语就可以用来区分出目标文档。这个假设需要掌握的有两点:

  • 在本文档出现的频率高;
  • 在其他文档出现的频率低。

因此,TF-IDF算法的计算可以分为词频(Term Frequency,TF)和逆转文档频率(Inverse Document Frequency,IDF)两部分,由TF和IDF的乘积来设置文档词语的权重。

TF指的是一个词语在文档中的出现频率。假设文档集包含的文档数为 N N N,文档集中包含关键词 k i k_i ki的文档数为 n i n_i ni f i j f_ij fij表示关键词 k i k_i ki在文档 d j d_j dj中出现的次数, f d j f_dj fdj表示文档 d j d_j dj中出现的词语总数, k i k_i ki在文档dj中的词频 T F i j TF_ij TFij定义为: T F i j = f i j f d j TF_ij=\\frac f_ijf_dj TFij=fdjfij。并且注意,这个数字通常会被正规化,以防止它偏向长的文件(指同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否)。

IDF是一个词语普遍重要性的度量。表示某一词语在整个文档集中出现的频率,由它计算的结果取对数得到关键词 k i k_i ki的逆文档频率 I D F i IDF_i IDFi I D F i = l o g N n i IDF_i=log\\frac Nn_i IDFi=logniN

由TF和IDF计算词语的权重为: w i j = T F i j w_ij=TF_ij wij=TFij· I D F i = f i j f d j IDF_i=\\frac f_ijf_dj IDFi=fdjfij· l o g N n i log\\frac Nn_i logniN

结论:TF-IDF与词语在文档中的出现次数成正比,与该词在整个文档集中的出现次数成反比。

用途:在目标文档中,提取关键词(特征标签)的方法就是将该文档所有词语的TF-IDF计算出来并进行对比,取其中TF-IDF值最大的k个数组成目标文档的特征向量用以表示文档。

注意:文档中存在的停用词(Stop Words),如“是”、“的”之类的,对于文档的中心思想表达没有意义的词,在分词时需要先过滤掉再计算其他词语的TF-IDF值。

算法举例

对于计算影评的TF-IDF,以电影“加勒比海盗:黑珍珠号的诅咒”为例,假设它总共有1000篇影评,其中一篇影评的总词语数为200,其中出现最频繁的词语为“海盗”、“船长”、“自由”,分别是20、15、10次,并且这3个词在所有影评中被提及的次数分别为1000、500、100,就这3个词语作为关键词的顺序计算如下。

  1. 将影评中出现的停用词过滤掉,计算其他词语的词频。以出现最多的三个词为例进行计算如下:

    • “海盗”出现的词频为20/200=0.1
    • “船长”出现的词频为15/200=0.075
    • “自由”出现的词频为10/200=0.05;
  2. 计算词语的逆文档频率如下:

    • “海盗”的IDF为:log(1000/1000)=0
    • “船长”的IDF为:log(1000/500)=0.3
      “自由”的IDF为:log(1000/100)=1
  3. 由1和2计算的结果求出词语的TF-IDF结果,“海盗”为0,“船长”为0.0225,“自由”为0.05。

通过对比可得,该篇影评的关键词排序应为:“自由”、“船长”、“海盗”。把这些词语的TF-IDF值作为它们的权重按照对应的顺序依次排列,就得到这篇影评的特征向量,我们就用这个向量来代表这篇影评,向量中每一个维度的分量大小对应这个属性的重要性。

将总的影评集中所有的影评向量与特定的系数相乘求和,得到这部电影的综合影评向量,与电影的基本属性结合构建视频的物品画像,同理构建用户画像,可采用多种方法计算物品画像和用户画像之间的相似度,为用户做出推荐。

加载数据集

import pandas as pd
import numpy as np
'''
- 利用tags.csv中每部电影的标签作为电影的候选关键词
- 利用TF·IDF计算每部电影的标签的tfidf值,选取TOP-N个关键词作为电影画像标签
- 并将电影的分类词直接作为每部电影的画像标签
'''

def get_movie_dataset():
    # 加载基于所有电影的标签
    # all-tags.csv来自ml-latest数据集中
    # 由于ml-latest-small中标签数据太多,因此借助其来扩充
    _tags = pd.read_csv("datasets/ml-latest-small/all-tags.csv", usecols=range(1, 3)).dropna()
    tags = _tags.groupby("movieId").agg(list)

    # 加载电影列表数据集
    movies = pd.read_csv("datasets/ml-latest-small/movies.csv", index_col="movieId")
    # 将类别词分开
    movies["genres"] = movies["genres"].apply(lambda x: x.split("|"))
    # 为每部电影匹配对应的标签数据,如果没有将会是NAN
    movies_index = set(movies.index) & set(tags.index)
    new_tags = tags.loc[list(movies_index)]
    ret = movies.join(new_tags)

    # 构建电影数据集,包含电影Id、电影名称、类别、标签四个字段
    # 如果电影没有标签数据,那么就替换为空列表
    # map(fun,可迭代对象)
    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.set_index("movieId", inplace=True)
    return movie_dataset

movie_dataset = get_movie_dataset()
print(movie_dataset)

基于TF·IDF提取TOP-N关键词,构建电影画像

from gensim.models import TfidfModel

import pandas as pd
import numpy as np

from pprint import pprint

# ......

def create_movie_profile(movie_dataset):
    '''
    使用tfidf,分析提取topn关键词
    :param movie_dataset: 
    :return: 
    '''
    dataset = movie_dataset["tags"].values

    from gensim.corpora import Dictionary
    # 根据数据集建立词袋,并统计词频,将所有词放入一个词典,使用索引进行获取
    dct = Dictionary(dataset)
    # 根据将每条数据,返回对应的词索引和词频
    corpus = [dct.doc2bow(line) for line in dataset]
    # 训练TF-IDF模型,即计算TF-IDF值
    model = TfidfModel(corpus)

    movie_profile = 
    for i, mid in enumerate(movie_dataset.index):
        # 根据每条数据返回,向量
        vector = model[corpus[i]]
        # 按照TF-IDF值得到top-n的关键词
        movie_tags = sorted(vector, key=lambda x: x[1], reverse=True)[:30]
        # 根据关键词提取对应的名称
        movie_profile[mid] = dict(map(lambda x:(dct[x[0]], x[1]), movie_tags))

    return movie_profile

movie_dataset = get_movie_dataset()
pprint(create_movie_profile(movie_dataset))

完善画像关键词

from gensim.models import TfidfModel

import pandas as pd
import numpy as np

from pprint import pprint

# ......

def create_movie_profile(movie_dataset):
    '''
    使用tfidf,分析提取topn关键词
    :param movie_dataset:
    :return:
    '''
    dataset = movie_dataset["tags"].values

    from gensim.corpora import Dictionary
    # 根据数据集建立词袋,并统计词频,将所有词放入一个词典,使用索引进行获取
    dct = Dictionary(dataset)
    # 根据将每条数据,返回对应的词索引和词频
    corpus = [dct.doc2bow(line) for line in dataset]
    # 训练TF-IDF模型,即计算TF-IDF值
    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]]
        movie_tags = sorted(vector, key=lambda x: x[1], reverse=True)[:30]
        topN_tags_weights = dict(map(lambda x: (dct[x[0]], x[1]), movie_tags))
        # 将类别词的添加进去,并设置权重值为1.0
        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_profile

movie_dataset = get_movie_dataset()
pprint(create_movie_profile(movie_dataset))

为了根据指定关键词迅速匹配到对应的电影,因此需要对物品画像的标签词,建立倒排索引

倒排索引介绍

通常数据存储数据,都是以物品的ID作为索引,去提取物品的其他信息数据

而倒排索引就是用物品的其他数据作为索引,去提取它们对应的物品的ID列表

# ......

'''
建立tag-物品的倒排索引
'''

def create_inverted_table(movie_profile):
    inverted_table = 
    for mid, weights in movie_profile["weights"].iteritems():
        for tag, weight in weights.items():
            #到inverted_table dict 用tag作为Key去取值 如果取不到就返回[]
            _ = inverted_table.get(tag, [])
            _.append((mid, weight))
            inverted_table.setdefault(tag, _)
    return inverted_table

inverted_table = create_inverted_table(movie_profile)
pprint(inverted_table)

基于内容的电影推荐:用户画像

用户画像构建步骤:

  • 根据用户的评分历史,结合物品画像,将有观影记录的电影的画像标签作为初始标签反打到用户身上
  • 通过对用户观影标签的次数进行统计,计算用户的每个初始标签的权重值,排序后选取TOP-N作为用户最终的画像标签

用户画像建立

import pandas as pd
import numpy as np
from gensim.models import TfidfModel

from functools import reduce
import collections

from pprint import pprint

# ......

'''
user profile画像建立:
1. 提取用户观看列表
2. 根据观看列表和物品画像为用户匹配关键词,并统计词频
3. 根据词频排序,最多保留TOP-k个词,这里K设为100,作为用户的标签
'''

def create_user_profile():
    watch_record = pd.read_csv("datasets/ml-latest-small/ratings.csv", usecols=range(2), dtype="userId":np.int32, "movieId": np.int32)

    watch_record = watch_record.groupby("userId").agg(list)
    # print(watch_record)

    movie_dataset = get_movie_dataset()
    movie_profile = create_movie_profile(movie_dataset)

    user_profile = 
    for uid, mids in watch_record.itertuples()查看详情  

07_推荐系统算法详解

参考技术A   基于人口统计学的推荐与用户画像、基于内容的推荐、基于协同过滤的推荐。1、基于人口统计学的推荐机制(Demographic-basedRecommendation)是一种最易于实现的推荐方法,它只是简单的根据系统用户的基本信息... 查看详情

阿里pai_基于用户画像的物品推荐

通过PAI中的流程,学习到本实例中的流程。数据预处理——特征扩充——数据切分——类型转换——归一化——缺失值填充——模型训练——预测(可视化)通过不同特征之间的组合产生新的特征用户购买就是一个二分类,即:... 查看详情

关于算法

...,希望多多交流,改正瑕疵。算法推荐主要有5种方式:基于内容推荐:这是基于用户个人兴趣的推荐。根据用户个体的历史行为,计算对内容特征的偏好程度,进而推荐出与用户特征偏好匹配的内容。协同过滤算法:这是基于... 查看详情

django基于用户画像的电影推荐系统源码(项目源代码)(代码片段)

...;以从豆瓣平台爬取的电影数据作为基础数据源,主要基于用户的基本信息和使用操作记录等行为信息来开发用户标签,并使用Hadoop、Spark大数据组件进行分析和处理的推荐系统。管 查看详情

推荐系统(029~036)(代码片段)

文章目录推荐系统算法基于人口统计学的推荐算法基于内容的推荐算法基于内容推荐系统的高层次结构相似度计算特征工程数值型特征处理类别型特征处理时间型特征处理统计型特征处理推荐系统常见反馈数据基于UGC的推荐基于... 查看详情

大数据技术之_24_电影推荐系统项目_04_推荐系统算法详解

第九章推荐系统算法详解9.1常用推荐算法分类9.1.1基于人口统计学的推荐与用户画像9.1.2基于内容的推荐与特征方程9.1.3基于协同过滤的推荐第九章推荐系统算法详解9.1常用推荐算法分类9.1.1基于人口统计学的推荐与用户画像9.1.2... 查看详情

django基于用户画像的电影推荐系统源码(项目源代码)(代码片段)

...;以从豆瓣平台爬取的电影数据作为基础数据源,主要基于用户的基本信息和使用操作记录等行为信息来开发用户标签,并使用Hadoop、Spark大数据组件进行分析和处理的推荐系统。管理系统使用的是Django自带的管理系统ÿ... 查看详情

个性化推荐是怎么做的?

...。  目前比较流行的个性化推荐算法有以下几种:  基于内容的推荐:根据内容本身的属性(特征向量)所作的推荐。  基于关联规则的推荐:“啤酒与尿布”的方式,是一种动态的推荐,能够实时对用户的行为作出推荐。... 查看详情

推荐算法简介

...荐的成功应用需要两个条件:在推荐系统的众多算法中,基于协同的推荐和基于内容的推荐在实践中得到了最广泛的应用。本文也将从这两种算法开始,结合时间、地点上下文环境以及社交环境,对常见的推荐算法做一个简单的... 查看详情

推荐算法---模式场景

一、       基于内容推荐概念:根据物品的相关信息发现不同物品的相关程度,根据用户以往的喜好记录,推荐给用户相似的物品。例如,在电影推荐中,基于内容的系统首先分析用户已经看过的打分比较... 查看详情

推荐系统实战——自动化构建用户以及物料画像

自动化构建用户以及物料画像​​自动化构建用户以及物料画像​​​​意义​​​​新物料来源​​​​物料画像的更新​​​​物料更新添加入redis​​​​合并,物料画像构建逻辑​​​​用户侧画像的构建​​​​画像... 查看详情

基于内容的电影推荐:物品冷启动处理(代码片段)

基于内容的电影推荐:物品冷启动处理基于内容的电影推荐:物品冷启动处理word2vec原理简介Word2Vec两个重要模型:CBOW和Skip-GramWord2Vec使用Doc2Vec使用基于内容的电影推荐:物品冷启动处理利用Word2Vec可以计算电影所... 查看详情

2021年科大讯飞基于用户画像的商品推荐挑战赛前三名队伍分享

文章目录1.第一名喔嚯1.1团队介绍1.2赛题方案解析1.2.1赛题介绍1.2.2解题思路1.2.3数据探索性分析1.2.4CatBoost分析1.2.5Fasttext分析1.2.6数据分析小结1.2.7数据预处理1.2.8文本特征构造1.2.9算法模型1.2.10模型训练1.2.11模型融合1.3模型结果1.4... 查看详情

以头条为例:谈谈推荐策略

...好注册一个头条号并登陆到后台)这款产品为例输出一些内容推荐(分发)相关的“干货”。回到标题,何为推荐?简言之:“物以类聚,人以群分”。那何为物,何为人呢?答:物为内容(文章/图文/视频等),人为用户(刷... 查看详情

推荐算法简介:基于用户的协同过滤基于物品的协同过滤基于内容的推荐

...,而根本不会考虑到物品本身的属性。可分成两类:1、基于用户(user-based)的协同过滤2、基于商品(item-based)的协同过滤1.1.1、基于用户的协同过滤基本思想:基于用户对物品的偏好找到邻居用户(相似用户),然后将邻居用... 查看详情

画像分析-概述

1、功能概述:   基于结构化数据(如:销售明细数据)、非结构化数据(物品描述)的标签建模和服务化提供。     2、过程概述:a、通过对多源的明细数据进行标签建模   根据需要,对... 查看详情

产品方法论总结——用户画像&用户场景

...为产品人,在逛专业网站看前辈分析产品时都会分析用户画像,一般都是分析用户的年龄、性别、地域分布等特点。今天想分享一下梁宁老师的两个用户画像分析模式,一个是:第一只羊,头羊,狼;另一个是:大明,笨笨,小... 查看详情