基于LDA主题+协同过滤+矩阵分解算法的智能电影推荐系统——机器学习算法应用(含python、JavaScript工程源码)+MovieLens数据集(二)

news2025/2/21 4:57:21

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
  • 模块实现
    • 1. 数据爬取及处理
  • 相关其它博客
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

前段时间,博主分享过关于一篇使用协同过滤算法进行智能电影推荐系统的博文《基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集》,有读者反映该项目有点复杂,于是我决定再给大家分享个使用机器学习算法简单实现电影推荐的项目。

本项目基于Movielens数据集,采用协同过滤、矩阵分解以及建立LDA主题模型等机器学习算法,旨在设计和训练一个合适的智能电影推荐模型。最终的目标是根据电影的相似性以及用户的历史行为,生成一个个性化的电影推荐列表,从而实现网站为用户提供精准电影推荐的功能。

首先,项目收集了Movielens数据集,其中包含了大量用户对电影的评分和评论。这个数据集提供了有关用户和电影之间互动的信息,是推荐系统的核心数据。

然后,项目使用协同过滤算法,这可以是基于用户的协同过滤(User-Based Collaborative Filtering)或基于item的协同过滤(Item-Based Collaborative Filtering)。这些算法分析用户之间的相似性或电影之间的相似性,以提供个性化推荐。

此外,矩阵分解技术也被应用,用于分解用户-电影交互矩阵,以发现潜在的用户和电影特征。这些特征可以用于更准确地进行推荐。

另外,项目还使用了LDA主题模型,以理解电影的主题和用户的兴趣。这有助于更深入地理解电影和用户之间的关联。

最终,根据电影的相似性和用户的历史行为,系统生成了一个个性化的电影推荐列表。这个列表可以根据用户的兴趣和偏好提供电影推荐,从而提高用户体验。

总结来说,这个项目结合了协同过滤、矩阵分解和主题建模等技术,以实现一个个性化电影推荐系统。这种系统有助于提高用户在网站上的互动和满意度,同时也有助于电影网站提供更精准的内容推荐。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括 Python 环境、Pycharm 环境及数据库环境。

详见博客。

模块实现

本项目包括5个模块:数据爬取及处理、模型训练及保存、接口实现、收集数据、界面设计。下面分别介绍各模块的功能及相关代码。

1. 数据爬取及处理

在Python环境下执行命令,生成数据库表。

python  manage.py makemigrations
python  manage.py migrate --run-syncdb

安装所需第三方库。

python -m pip install -r requirement.txt

数据来源:爬取Movielens上相关电影数据、简介及评分。也可以直接从下面网址进行下载:数据集网站地址为http://files.grouplens.org/datasets/movielens/ml-1m-README.txt

python populate_ratings.py
python populate_movie.py
python populate_movie_description.py
python populate_ratings.py

相关代码如下:

#导入需要的库
import os
import urllib.request
import django
import datetime
import decimal
from tqdm import tqdm
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Recs.settings')
django.setup()
from Analytics.models import Rating
#插入评分记录
defcreate_rating(user_id,content_id,rating,timestamp):ating=Rating(user_id=user_id,movie_id=content_id,rating=decimal.Decimal(rating),        rating_timestamp=datetime.datetime.fromtimestamp(float(timestamp)))
    rating.save()
    return rating
#爬取评分记录
def download_ratings():
    URL= 'https://raw.githubusercontent.com/sidooms/MovieTweetings/master/latest/ratings.dat'
    response = urllib.request.urlopen(URL)
    data = response.read()
    print('download finished')
    return data.decode('utf-8')
#删除已有的评分数据
def delete_db():
    print('truncate db')
    Rating.objects.all().delete()
    print('finished truncate db')
def populate():
    delete_db()
    ratings = download_ratings()
    for rating in tqdm(ratings.split(sep="\n")):
        r = rating.split(sep="::")
        if len(r) == 4:
            create_rating(r[0], r[1], r[2], r[3])
if __name__ == '__main__':
    print("Starting MovieRecs Population script...")
    populate()
#python populate_movie.py相关代码
#导入需要的库
import os
import urllib.request
from tqdm import tqdm
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Recs.settings')
import django
django.setup()
from Movies.models import Movie, Genre
#创建每一条电影数据并保存
def create_movie(movie_id, title, genres):
    movie = Movie.objects.get_or_create(movie_id=movie_id)[0]
    title_and_year = title.split(sep="(")
    movie.title = title_and_year[0]
    movie.year = title_and_year[1][:-1]
    if genres:
        for genre in genres.split(sep="|"):
            g = Genre.objects.get_or_create(name=genre)[0]
            movie.genres.add(g)
            g.save()
    movie.save()
    return movie
#爬取电影数据
def download_movies(URL='https://raw.githubusercontent.com/sidooms/MovieTweetings/master/latest/movies.dat'):  #下载电影数据
    response = urllib.request.urlopen(URL)
    data = response.read()
    return data.decode('utf-8')
#如果之前存在数据则先删除
def delete_db():
    print('truncate db')
    movie_count = Movie.objects.all().count()
    if movie_count > 1:
        Movie.objects.all().delete()
        Genre.objects.all().delete()
    print('finished truncate db')
def populate():  
    movies = download_movies()
    if len(movies) == 0:
        print('The latest dataset seems to be empty. Older movie list downloaded.')
        print('Please have a look at https://github.com/sidooms/MovieTweetings/issues and see if there is an issue')
        movies = download_movies(
'https://raw.githubusercontent.com/sidooms/MovieTweetings/master/snapshots/100K/movies.dat')
    print('movie data downloaded')
    for movie in tqdm(movies.split(sep='\n')):
        m = movie.split(sep="::")
        if len(m) == 3:
            create_movie(m[0], m[1], m[2])
if __name__ == '__main__':
    print("Starting MovieGeeks Population script...")
    delete_db()
    populate()
#python populate_movie_description.py相关代码
#导入需要的库
import os
import django
import json
import pandas as pd
import requests
from tqdm import tqdm
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Recs.settings')
django.setup()
from Recommender.models import MovieDecriptions
#获取电影数据并保存
from Analytics.models import Rating
def get_descriptions_with_movieid(movie_id):
    url = "https://api.themoviedb.org/3/find/tt{}?external_source=imdb_id&api_key={}"
    api_key = get_api_key()
    format_url = url.format(movie_id, api_key)
    r = requests.get(format_url)
    for film in r.json()['movie_results']:
        md = MovieDecriptions.objects.get_or_create(movie_id=movie_id)[0]
#保存电影名
        md.imdb_id = movie_id
        if 'title' in film:
            md.title = film['title']
#保存电影简介
        if 'overview' in film:
            md.description = film['overview']
#保存电影类型
        if 'genre_ids' in film:
            md.genres = film['genre_ids']
        if len(md.description) > 0:
            md.save()
            # print("{}: {}".format(movie_id, r.json()))
#如果之前存在数据则先删除
def delete_db():
    print('truncate db')
    MovieDecriptions.objects.all().delete()
    print('finished truncate db')
def get_api_key():  #获取API的KEY
    cred = json.loads(open(".prs").read())
    return cred['themoviedb_apikey']
#加载评分数据
def load_all_ratings():
    #提取相关列的数据
    columns = ['movie_id']
    ratings_data = Rating.objects.all().values(*columns)
    movie_ids = pd.DataFrame.from_records(ratings_data, columns=columns)
    movie_ids = movie_ids.drop_duplicates(subset=None, keep='first', inplace=False)
    movie_ids = movie_ids.reset_index()
    return movie_ids
if __name__ == '__main__':  #主函数
    print("Starting MovieRecs Population script...")
    delete_db()
    movie_ids = load_all_ratings()
    movie_ids = movie_ids.iloc[:, 1]
    for movie_id in tqdm(movie_ids.values):
        get_descriptions_with_movieid(movie_id)

爬取的数据保存在pgAdmin4中,如图所示。
在这里插入图片描述

Python命令行爬取数据成功,如图所示。

在这里插入图片描述

相关其它博客

基于LDA主题+协同过滤+矩阵分解算法的智能电影推荐系统——机器学习算法应用(含python、JavaScript工程源码)+MovieLens数据集(一)

基于LDA主题+协同过滤+矩阵分解算法的智能电影推荐系统——机器学习算法应用(含python、JavaScript工程源码)+MovieLens数据集(三)

基于LDA主题+协同过滤+矩阵分解算法的智能电影推荐系统——机器学习算法应用(含python、JavaScript工程源码)+MovieLens数据集(四)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

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

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

相关文章

文献查询辅助工具,查看文献影响因子期刊,显示文献排名,翻译文献

插件工具:easyScholar 适配浏览器(Edge、chrome、Firefox),本文以Edge为例: 1.打开Edge浏览器,输入: edge://extensions/ 2.点击获取Microsoft Edge扩展 3.搜索 easyscholar,然后…

Hive【Hive(八)自定义函数】

自定义函数用的最多的是单行函数&#xff0c;所以这里只介绍自定义单行函数。 Coding 导入依赖 <dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>3.1.3</version></dependency>…

路由器基础(十):防火墙配置

一、防火墙默认的区域 防火墙是基于安全区域进行工作的安全设备。 一个安全区域是若干接口所连网络的集合&#xff0c;这些网络中的用户具有相同的安全属性。 通常防火墙认为在同一安全区域内部发生的数据流动是不存在安全风险的&#xff0c;不需要实施任何安全策略。只有当不同…

代码随想录Day36 动态规划05 LeetCode T1049最后一块石头的重量II T494 目标和 T474 一和零

前言 : 动规五部曲 理论基础 : 代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树-CSDN博客 1.明白dp数组的含义 2.明白递推公式的含义 3.初始化dp数组 4.注意dp数组的遍历顺序 5.打印dp数组排错 LeetCode T1049 最后一块石头的重量II 题目链接:1049. 最后一块石头…

LeetCode:117. 填充每个节点的下一个右侧节点指针 II(C++)

117. 填充每个节点的下一个右侧节点指针 II 题目描述&#xff1a; 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将…

Promise的并发控制 - 从普通并发池到动态并发池

一、场景 给你一个有200个URL的数组&#xff0c;通过这些URL来发送请求&#xff0c;要求并发请求数不能超过五个。 这是一道很常考的面试题&#xff0c;接下来让我们来学习一下Promise并发控制 二、普通并发池的实现 主要思路就是&#xff0c;判断当前队列是否满&#xff0c;…

【IDEA】在工具栏设置快速创建包和类的图表

页面效果&#xff1a; 操作步骤&#xff1a; 设置 --> 外观与行为 --> 菜单与工具栏 --> 点击 主工具栏 --> 点击 ---- --> 点击 号 --> 添加操作 主菜单 --> 文件 --> 文件打开操作 --> 打开项目操作 --> 新建 --> 往下找 找到 clas…

单行自动横向滚动——css实现

效果 封装组件 <template><div ref"container" class"scroll-area"><divref"content":class"[isScroll ? scroll : no-scroll]":style"{ color: fontColor }">{{ content }}</div></div> &…

c++值deque容器

1.deque容器介绍 deque 是 double-ended queue 的缩写&#xff0c;又称双端队列容器。deque容器支持从头部和尾部双端插入、删除数据。与vector容器不同的是&#xff0c;vector容器是一段连续的空间&#xff0c;而deque没有所谓容量的概念&#xff0c;因为它是动态的以分段连续…

Spring Boot 常见面试题

目录 1.Spring Boot 快速入门什么是 Spring Boot&#xff1f;有什么优点&#xff1f;Spring Boot 与 Spring MVC 有什么区别&#xff1f;Spring 与 Spring Boot 有什么关系&#xff1f;✨什么是 Spring Boot Starters?Spring Boot 支持哪些内嵌 Servlet 容器&#xff1f;如何设…

掌握RESTful API:规范与设计详解

前言 RAML (RESTful API Modeling Language) 和 OAS (OpenAPI Specification) 都是用于描述和定义 RESTful API 的规范。它们分别提供了不同的功能和优势。 RAML&#xff08;RESTful API Modeling Language&#xff09;&#xff1a; RAML简介 RAML&#xff08;RESTful API M…

CSC公派研究生项目|北语北外2024年寒假英语培训班正在招生

北京语言大学出国部、北京外国语大学出国部近期发布了2024年寒假“国家建设高水平大学公派研究生项目”英语培训的通知&#xff0c;知识人网小编特归纳整理&#xff0c;供有需求的同学参考。 北京语言大学 我部将于2024年寒假举办“国家建设高水平大学公派研究生项目”英语培训…

银行账单转换beancount

用了beancount来记账后&#xff0c;发现每月的账单手动记是一件极其麻烦的事情。 然后再github搜索一通后&#xff0c;有double-entry-generator&#xff08;https://github.com/deb-sig/double-entry-generator&#xff09;能转换支付宝/微信的账单&#xff0c;但是没有自己用…

基于STM32F412RET6的智能桶硬件设计

一、智能桶功能需求&#xff1a; 智能桶是一直采用Cortex-M4 嵌入式平台&#xff0c;搭载NB-IotTO通讯模组、智能称重采集、智能门锁监控以及温度监测等装置。主要功能如下&#xff1a; ▲ 具有GPS定位功能&#xff0c;可以通过后台APP实时定位智能桶的位置。 ▲ 具有温度监测功…

大厂面试题-Netty中Reactor模式的理解

Reactor其实是在NIO多路复用的基础上提出的一个高性能IO设计模式。 它的核心思想是把响应IO事件和业务处理进行分离&#xff0c;通过一个或者多个线程来处理IO事件。 然后把就绪的事件分发给业务线程进行异步处理。 Reactor模型有三个重要的组件&#xff1a; Reactor&#…

基于单片机的可穿戴个人健康监测仪-智能手环

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、方案的设计与论证2.1设计任务及要求2.2 模块技术和方法综述2.3 设计可能遇到的困难 二、 系统总体框架3.1 硬件设计 三 软件部分4.1 主程序流程框 四、 结论五、 文章目录 概要 近几年智能化的不断发展&#…

GEE——提取制定多波段影像的属性值(按照制定属性名称和属性值)输出格式为矢量格式

简介: 这里我们很多时候,需要提取制定影像,或者多波段影像制定区域的值,这里有一个问题是我们一般输出的结果仅仅是一个字典类型的对象,而我们不知道如何按照一个矢量输入,这里我们首先要做的就是进行多波段值在制定区域的提取,随后就是分别对其新的字典的键、值的设定…

Leetcode76最小覆盖子串

思路&#xff1a;滑动窗口思想 1. 滑动窗口是什么&#xff1a;用一个滑动窗口为覆盖目标子串的字符串 2.怎么移动窗口&#xff1a;当不满足覆盖时右指针移动扩大范围&#xff0c;当覆盖了就移动左指针缩减范围直到再次不覆盖 3. 怎么判断是否覆盖&#xff1a;这里使用两个哈…

Qt封装的Halcon显示控件,支持ROI绘制

前言 目前机器视觉ROI交互控件在C#上做的比较多&#xff0c;而Qt上做的比较少&#xff0c;根据作者 VSQtHalcon——显示图片&#xff0c;实现鼠标缩放、移动图片的文章&#xff0c;我在显示和移动控件的基础上&#xff0c;增加了ROI设置功能&#xff0c;并封装成了一个独立的Q…

记录一次normal diskgroup添加磁盘组操作

客户的一个磁盘组空间快满&#xff0c;需要添加一下磁盘&#xff0c;磁盘组的冗余模式为normal&#xff0c;本来觉得是一件不难的事情&#xff0c;在添加过程中还是遇到了一些问题。 本来为2个500G的磁盘组成的normal模式磁盘组&#xff0c;目前可用空间只剩下170G左右的空间&…