数据挖掘实战-基于内容协同过滤算法的电影推荐系统

news2024/11/18 17:43:06

 

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+


目录

1.项目背景

2.数据集介绍

3.技术工具

4.实验过程

4.1导入数据

4.2词云图可视化

4.3基于内容的协同过滤

4.4基于投票的过滤:人口统计学过滤

5.总结

6.源代码


1.项目背景

        随着信息技术的迅猛发展和数字化媒体的普及,人们每天面临着海量的信息选择。特别是在线电影平台,如腾讯视频、爱奇艺、优酷等,拥有数以万计的电影资源。用户在如此庞大的电影库中寻找感兴趣的内容变得愈发困难,因此,一个高效、精准的推荐系统显得尤为重要。

        传统的电影推荐方法,如基于流行度或者最新发布进行推荐,往往不能满足用户个性化的需求。为了提供更加个性化的电影推荐,推荐系统需要能够理解和预测用户的喜好。基于内容的推荐系统和协同过滤推荐系统是两种主流的方法。基于内容的推荐主要是通过分析用户过去的行为和电影的内容(如类型、导演、演员等)来推荐类似的电影。而协同过滤则是通过分析用户的行为和其他相似用户的行为来进行推荐。

        然而,单一的推荐方法往往有其局限性。基于内容的推荐可能过于依赖电影的特征描述,而忽略了用户的个性化需求;而协同过滤则可能受限于数据的稀疏性和冷启动问题。为了克服这些问题,可以考虑将基于内容的推荐和协同过滤结合起来,形成一种混合推荐方法,即基于内容协同过滤的推荐系统。

        本研究旨在构建一个基于内容协同过滤算法的电影推荐系统,通过结合电影的内容特征和用户的行为数据,为用户提供更加精准和个性化的电影推荐。通过这种方法,我们期望能够提高用户对推荐电影的满意度,并进一步提升在线电影平台的用户体验。

        在上述背景下,本研究将深入探索内容协同过滤算法在电影推荐系统中的应用,以期为用户提供更加精准、个性化的电影推荐服务。

2.数据集介绍

本数据集来源于Kaggle,原始数据集共有2个文件,一个是movies.csv,一个是credits.csv。

movies.csv如下:

credits.csv如下:

3.技术工具

Python版本:3.9

代码编辑器:jupyter notebook

4.实验过程

4.1导入数据

导入第三方库并加载数据集

查看数据前五行

合并数据集

查看数据基本信息

4.2词云图可视化

自定义一个画词云图的函数

画出标题列的词云图 

填充overview变量中的缺失值并可视化

4.3基于内容的协同过滤

        这种类型的过滤器不涉及其他用户,如果不是我们自己。根据我们的喜好,算法会简单地挑选内容相似的商品推荐给我们。在这种情况下,推荐的多样性将会减少,但无论用户评分与否,这都是有效的。如果我们将其与上面的例子进行比较,也许用户B可能喜欢黑色喜剧,但他/她永远不会知道,除非他/她决定自主尝试,因为这个过滤器只会继续推荐反乌托邦电影或类似的电影。当然,我们可以计算许多类别的相似性:在电影的情况下,我们可以决定仅基于类型构建我们自己的推荐系统,或者我们想要包括导演,主要演员等。

向量化

我们将使用sklearn的linear_kernel()而不是cosine_similarity(),因为它更快。 

自定义一个推荐函数 

如果你搜索“Spectre”,下面的电影名称将被推荐 

如果你搜索“John Carter”,下面的电影名称将被推荐 

 将字符串化后的特征解析为对应的python对象

提取类型和关键词列表 

结合类型和关键词

 向量化

余弦相似度

余弦相似度度量了内积空间中两个向量之间的相似度。它是由两个向量之间夹角的余弦来测量的,并确定两个向量是否大致指向相同的方向。在文本分析中,它常用于度量文档的相似度。文档可以由数千个属性表示,每个属性记录文档中特定单词(如关键字)或短语的频率。因此,每个文档都是由术语频率向量表示的对象。

我们都熟悉向量:它们可以是2D, 3D或任何d。让我们用2D来思考一下,因为它更容易在我们的脑海中描绘出来,让我们先复习一下点积的概念。两个向量的点积等于其中一个向量在另一个向量上的投影。因此,两个相同向量(即具有相同分量)之间的点积等于它们的平方模,而如果两个向量垂直(即它们不共享任何方向),则点积为零。通常,对于n维向量,点积的计算方法如下所示。

在定义相似度时,点积很重要,因为它与相似度直接相关。两个向量u和v之间相似度的定义,实际上是它们的点积和它们的大小之积的比值。

通过应用相似性的定义,如果这两个向量相同,它等于1,如果这两个向量正交,它等于0。换句话说,相似度是一个介于0到1之间的数字它告诉我们两个向量有多相似。

使用余弦相似度

如果你搜索“John Carter”,下面的电影名称将被推荐 

 

如果你搜索“Soldier”,下面的电影名称将被推荐

4.4基于投票的过滤:人口统计学过滤

计算avarage评级

筛选符合条件的电影

根据上面计算的分数对电影进行排序 

热门电影 

5.总结

        本研究通过构建并优化基于内容协同过滤算法的电影推荐系统,成功实现了对用户个性化电影推荐需求的精准满足。实验结果表明,该系统能够结合电影内容特征和用户行为数据,为用户提供更加符合其兴趣和偏好的电影推荐。相较于单一的推荐方法,该系统展现出了更高的推荐准确性和用户满意度,从而验证了内容协同过滤算法在电影推荐系统中的有效性和优越性。因此,该算法对于提升在线电影平台的用户体验和服务质量具有重要的应用价值。

6.源代码

import numpy as np 
import pandas as pd 
pd.set_option('display.max_columns', 25)
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

movie = pd.read_csv('tmdb_5000_movies.csv')
credit = pd.read_csv('tmdb_5000_credits.csv')
movie.head()
credit.head()
# 合并两个数据集
credit.columns = ['id','cast', 'title', 'crew']
movie= movie.merge(credit, on='id')
movie.head()
movie.info()
# 词云图
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
import matplotlib.pyplot as plt
# 自定义一个画词云图的函数
def cloud(col):    
    wcloud = " ".join(f for f in movie[col])
    wc_ = WordCloud(width = 2000, height = 1000, random_state=1, background_color='black', colormap='Set2', collocations=False, stopwords = STOPWORDS)
    wc_.generate(wcloud)
    plt.subplots(figsize=(10,6))
    plt.imshow(wc_, interpolation="bilinear")
    plt.axis("off")
# 画出标题列的词云图
cloud("original_title")
# 填充overview变量中的缺失值
movie["overview"] = movie["overview"].fillna("")
cloud("overview")
# Tfidf向量化
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(stop_words="english")
tfidf_matrix = tfidf.fit_transform(movie["overview"])
tfidf_matrix
# 我们将使用sklearn的linear_kernel()而不是cosine_similarity(),因为它更快。
from sklearn.metrics.pairwise import linear_kernel
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
# 索引和电影original_title的反向映射
indices = pd.Series(movie.index, index=movie['original_title']).drop_duplicates()
# 自定义一个推荐函数
def get_recommendation(title, cosine_sim):
    idx = indices[title]
    sim_scores = list(enumerate(cosine_sim[idx]))
    sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
    sim_scores = sim_scores[1:11]
    movies = [i[0] for i in sim_scores]
    movies = movie["original_title"].iloc[movies]
    return movies
# 如果你搜索“Spectre”,下面的电影名称将被推荐
get_recommendation('Spectre', cosine_sim)
# 如果你搜索“John Carter”,下面的电影名称将被推荐
get_recommendation("John Carter", cosine_sim)
# 将字符串化后的特征解析为对应的python对象
from ast import literal_eval

features = ['keywords', 'genres']
for feature in features:
    movie[feature] = movie[feature].apply(literal_eval)

movie[['original_title', 'keywords', 'genres']].head(3)
# 提取类型列表
def list_genres(x):
    l = [d['name'] for d in x]
    return(l)
movie['genres'] = movie['genres'].apply(list_genres)

# 提取关键字列表
def list_keyword(y):
    i = [a['name'] for a in y]
    return(i)
movie['keywords'] = movie['keywords'].apply(list_keyword)
# 结合类型和关键词
def genre(x):
    return ''.join(' '.join(x['genres']) + ' ' + ' '.join(x['keywords']))

movie['mix'] = movie.apply(genre, axis=1)
movie["mix"]
# 向量化
from sklearn.feature_extraction.text import CountVectorizer
countvect = CountVectorizer(stop_words="english")
countvect_mat = tfidf.fit_transform(movie["mix"])
countvect_mat
from sklearn.metrics.pairwise import cosine_similarity
cos_sim = cosine_similarity(countvect_mat, countvect_mat)
# 索引和电影original_title的反向映射
movie = movie.reset_index()
indices = pd.Series(movie.index, index=movie['original_title'])
# 如果你搜索“John Carter”,下面的电影名称将被推荐
get_recommendation("John Carter", cos_sim)
# 如果你搜索“Soldier”,下面的电影名称将被推荐
get_recommendation("Soldier", cos_sim)
基于投票的过滤:人口统计学过滤
# avarage评级
avg = movie["vote_average"].mean()
#  我们将使用第90个百分位数作为截止点。换句话说,一部电影要想进入榜单,它必须比榜单上至少90%的电影获得更多的选票。
q = movie["vote_count"].quantile(0.9)
print(avg)
print(q)
# 符合条件的电影
movies = movie[movie["vote_count"] >= q]
# weighted_rating函数
def weighted_rating(x, q=q, avg=avg):
    v = x['vote_count']
    R = x['vote_average']
    # 根据IMDB公式计算
    return (v/(v+q) * R) + (q/(q+v) * avg)

# 符合条件的影片
movies["score"] = movies.apply(weighted_rating, axis=1)
# 根据上面计算的分数对电影进行排序
movies = movies.sort_values('score', ascending=False)
# 打印前10部电影
listed = movies[['original_title', 'vote_count', 'vote_average', 'score', "popularity"]].head(10)
# 可视化
import seaborn as sns
plt.subplots(figsize=(10,6))
sns.barplot(listed["score"], listed["original_title"], palette="Set2")
plt.title("Movie Vs Score")
plt.show()
# 热门电影
popular= movies.sort_values('popularity', ascending=False)
plt.figure(figsize=(12,4))

plt.barh(popular['original_title'].head(10),popular['popularity'].head(10), align='center',
        color="#313131")
plt.gca().invert_yaxis()
plt.xlabel("Popularity")
plt.title("Popular Movies")
plt.show()

资料获取,更多粉丝福利,关注下方公众号获取

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1687553.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[JAVASE] 类和对象(五) -- 抽象类和接口

目录 一. 抽象类 1.1 抽象类的定义 1.2 抽象类的实现 1.3 抽象类的作用 1.4 抽象类注意事项 二. 接口 2.1 接口的定义 2.2 接口的实现 2.3 接口的作用 2.4 接口注意事项 三. 总结 一. 抽象类 1.1 抽象类的定义 如果一个类中没有包含足够的信息来描绘一个具体的对象, 那么…

Apache无法确定服务器的完全合格域名(FQDN)报错解决方法

文章目录 一、apache语法检查报错二、报错原因分析三、报错解决办法 一、apache语法检查报错 当我们在进行apache配置时,需要检查配置是否存在语法错误: sudo apache2ctl configtestAH00558: apache2: Could not reliably determine the servers fully…

图解CPU、内存、硬盘的工作原理

1、简要概括 硬件作用cpu 负责执行计算机程序的指令内存用于临时存储程序和数据。硬盘将数据从硬盘读取到内存或将数据从内存写入硬盘的过程。联系三者协同工作,CPU执行程序指令,将需要的数据从硬盘读取到内存,进行计算后再将结果写回内存或…

JDBC访问数据库

JDBC学习笔记代码jar包等连接 链接:https://pan.baidu.com/s/1NqgMucUk7JjoSZXEkA-PPQ?pwd60kv 提取码:60kv –来自百度网盘超级会员V3的分享 下载驱动 不管是连接mysql还是sqlserver都需要Java的一个驱动包,及XXX.jar包,这个包…

扩散模型学习1

DDPM 总体训练原理 https://www.bilibili.com/video/BV1nB4y1h7CN/?spm_id_from333.337.search-card.all.click&vd_sourcef745c116402814185ab0e8636c993d8f 讲得很好:每次都是输入t和noise-x的图像,预测noise之后得到和加入的noise比较&#xff1b…

如何搭建springBoot项目中的全局异常处理和自定义异常处理

目录 1 什么是异常 2 异常的种类 3 解决异常的方式 4 全局异常处理器和自定义异常处理器 5 测试异常处理 1 什么是异常 异常(Exception)是在程序执行过程中出现的一种特殊情况或错误。它可以是由于程序逻辑错误、运行环境问题、用户输入错误等原因…

Unity中计数器的实现

Unity中计数器的实现 一、前言二、效果与逻辑(一) 实现效果(二)功能逻辑 三、功能代码四、应用实现五、结语 一、前言 最近在开发中用到计数器,但是unity自带的UI组件中没有,所以只好自己手撸了一个&#x…

亚马逊云科技介绍

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 一、亚马逊云科技云计算1.1 云计算的优势 二、领先的云平台三、亚马逊云科技区域的全球网络…

1Panel应用推荐:code-server

1Panel(github.com/1Panel-dev/1Panel)是一款现代化、开源的Linux服务器运维管理面板,它致力于通过开源的方式,帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用,1Panel特别开通应用商店&am…

Redis常见数据类型(3)-String, Hash

目录 String 命令小结 内部编码 典型的使用场景 缓存功能 计数功能 共享会话 手机验证码 Hash 哈希 命令 hset hget hexists hdel hkeys hvals hgetall hmget hlen hsetnx hincrby hincrbyfloat String 上一篇中介绍了了String里的基本命令, 接下来总结一…

XV4001系列陀螺仪传感器广泛用于车载导航系统

随着汽车电子化趋势的加速,越来越多的汽车配备一系列先进的车载导航系统,这些导航系统功能的实现都依赖于精确的传感器数据(位置、车速、转向角度、车轮转速等)。传感器作为这些系统的核心组件,其准确性和可靠性直接影响到整个导航系统的性能…

OSPF问题

.ospf 选路 域内 --- 1类,2类LSA 域间 --- 3类LSA 域外 --- 5类,7类LSA --- 根据开销值的计算规则不同,还分为类型1和类型2 ospf 防环机制 区域内防环:在同一OSPF区域内,所有路由器通过交换链路状态通告&#xff…

鸿蒙原生应用元服务开发-鸿蒙真机运行项目实战与注意事项

一、解压项目注意项目包不能为中文 二、用数据线将装好DevEco Studio的电脑与设置为开发者模式的鸿蒙手机相连接。 三、将项目包托进DevEco Studio 中 注意项目包文件不能有嵌套 四、查看设备运行 五、点击项目结构 六、勾选红色框圈部分 登录开发者账号 七、选择好公司 八、等…

2024年人文艺术与创新教育国际学术会议(ICHAIE 2024)

2024年人文艺术与创新教育国际学术会议(ICHAIE 2024) 2024 International Conference on Humanities, Arts and Innovation Education 一、【会议简介】 随着全球化的推进和科技的迅猛发展,人文艺术与创新教育在培养未来人才方面扮演着越来越重要的角色…

Django继承User表实现注册和登录

Django继承User表实现注册和登录 django中已经有了user表,这篇文章将为大家详细讲解有关Django如何继承自带user表并重写。 一、后端部分 1、引入AbstractUser并继承 (1)、引入 from django.contrib.auth.models import AbstractUser**&…

【设计模式深度剖析】【1】【结构型】【代理模式】| 玩游戏打怪、升级为例加深理解

👈️上一篇:创建型设计模式对比 | 下一篇:装饰器模式👉️ 目 录 代理模式定义英文原话直译如何理解? 3个角色UML类图1. 抽象主题(Subject)角色2. 代理类:代理主题(Proxy Subject&#xff0…

Google Earth Engine(GEE)深度学习入门教程-Python数据读入篇

Python数据读入篇 前置条件: GEE预处理影像导出保存为tfrecord的数据包,并下载到本地tensorflow的深度学习环境 本篇文章的目的主要是把Tfrecord格式的数据加载为tf可使用的数据集格式 设定超参数 首先需要设定导出时的波段名称和数据格式&#xff…

leetcode437 路径总和III-哈希表+前缀和

题目 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节…

nginx开启资源目录

nginx开启资源目录表 可访问开放资源目录下的任何文件以及视频,图片等。可以作为一个妥妥的线上网盘资源托管空间使用。 上一篇文档揭示了nginx的神秘面纱,初步介绍与启动了nginx的基本功能和使用前端nginx学习配置开发验证,对各种配置已经…

Flutter容器

内边距padding class MyBody extends StatelessWidget {overrideWidget build(BuildContext context) {return Container(//为了可以看出内边距,将容器设置成红色color: Colors.red,child: Padding(padding: EdgeInsets.all(15),child: MyImage(https://raw.github…