推荐系统数据集之MovieLens

news2024/11/17 11:26:00

1.概述

  MovieLens其实是一个推荐系统和虚拟社区网站,它由美国 Minnesota 大学计算机科学与工程学院的GroupLens项目组创办,是一个非商业性质的、以研究为目的的实验性站点。GroupLens研究组根据MovieLens网站提供的数据制作了MovieLens数据集合,这个数据集合里面包含了多个电影评分数据集,分别具有不同的用途。本文均用MovieLens数据集来代替整个集合。MoveieLens数据集可以说是推荐系统领域最为经典的数据集之一,其地位类似计算机视觉领域里的MNIST数据集。

2. MovieLens

  MoveLens是一个数据集合,其中根据创建时间、数据集大小等分为了若干个子数据集。每个数据集的格式、大小、用途均有所差异。本文以MovieLens 1M Dataset为例,具体介绍下此数据集,其它MovieLens数据集也大都类似,本文使用的数据集下载链接为ml-1m.zip。

2.1 数据集概览

ml-1m.zip文件解压之后,可以得到4个文件,分别是:

  • movies.dat
  • ratings.dat
  • user.dat
  • README

1M数据集有rating.dat、movies.dat、users.data三份数据集。ratings是6040位用户对3900部电影的评分数据(共计1000209)。

在这里插入图片描述

2.2 ratings.dat数据文件

rating.dat文件存放的是用户对电影的评分信息,该文件中每条记录形式:

UserID::MovieID::Rating::Timestamp,即用户id、电影id、该用户对此电影的评分、时间戳。

在这里插入图片描述

  • - 用户id:从1~6040, 代表了6040个MovieLens用户
  • - 电影id: 从1~3952, 代表了3952部电影
  • - rating: 从1-5的整数, 代表了用户对电影的评级,最高5颗星,不允许半颗星存在
  • - Timestamp:以秒为单位的时间戳

注意: 每个用户至少会对20部电影进行评级。

2.3 users.dat数据文件

users.dat文件存放的是用户的相关信息,包括性别、年龄、职业,该文件中每条记录形式:

UserID::Gender::Age::Occupation::Zip-code,即用户id、性别、年龄、职业、Zip编码

在这里插入图片描述

  • -用户id:从1~6040, 代表了6040个MovieLens用户

  • - 性别(gender):M代表男性,F代表女性

  • -年龄(Age)分成了7组

    	*  1:  "Under 18"
    	* 18:  "18-24"
    	* 25:  "25-34"
    	* 35:  "35-44"
    	* 45:  "45-49"
    	* 50:  "50-55"
    	* 56:  "56+"
    
  • - 职业(occupation)分成了21种类别

    	*  0:  "other" or not specified
    	*  1:  "academic/educator"
    	*  2:  "artist"
    	*  3:  "clerical/admin"
    	*  4:  "college/grad student"
    	*  5:  "customer service"
    	*  6:  "doctor/health care"
    	*  7:  "executive/managerial"
    	*  8:  "farmer"
    	*  9:  "homemaker"
    	* 10:  "K-12 student"
    	* 11:  "lawyer"
    	* 12:  "programmer"
    	* 13:  "retired"
    	* 14:  "sales/marketing"
    	* 15:  "scientist"
    	* 16:  "self-employed"
    	* 17:  "technician/engineer"
    	* 18:  "tradesman/craftsman"
    	* 19:  "unemployed"
    	* 20:  "writer"
    

    - Zip-code:邮政编码

2.4 movies.dat数据文件

movies.dat文件存放的是电影的相关信息,该文件中每条记录形式:

MovieID::Title::Genres ,即电影id、电影标题、电影类型

在这里插入图片描述

  • -MovieID :从1到3952,代表了3952部电影

  • -Title :电影名称,由IMDB提供,包括了发行年份

  • -Genres :电影题材由竖线分开, 包括动作喜剧等18种电影类型

    	* Action
    	* Adventure
    	* Animation
    	* Children's
    	* Comedy
    	* Crime
    	* Documentary
    	* Drama
    	* Fantasy
    	* Film-Noir
    	* Horror
    	* Musical
    	* Mystery
    	* Romance
    	* Sci-Fi
    	* Thriller
    	* War
    	* Western
    

3.数据处理

3.1 转化DataFrame对象

通过pandas.read_csv将各表转化为pandas 的DataFrame对象。

engine参数有C和Python,C引擎速度更快,而Python引擎目前功能更完整。

# 用户基本信息
unames = ['user_id', 'gender', 'age', 'occupation', 'zip']
user_df = pd.read_csv('./ml-1m/users.dat',
                      sep='::',
                      header=None,
                      names=unames,
                      engine='python')

# 电影信息
mnames = ['movie_id', 'title', 'genres']
movies_df = pd.read_csv('./ml-1m/movies.dat',
                        sep='::',
                        header=None,
                        names=mnames,
                        engine='python',
                        encoding='ISO-8859-1')

# 评分信息
rnames = ['user_id', 'movie_id', 'imdbId', 'timestamp']
ratings_df = pd.read_csv('./ml-1m/ratings.dat',
                         sep='::',
                         header=None,
                         engine='python',
                         names=rnames)

在这里插入图片描述

3.2 查看数据集基本信息

通过dataframe.info()方法查看不同数据集的基本信息

========users_info===================
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6040 entries, 0 to 6039
Data columns (total 5 columns):
 #   Column      Non-Null Count  Dtype 
---  ------      --------------  ----- 
 0   user_id     6040 non-null   int64 
 1   gender      6040 non-null   object
 2   age         6040 non-null   int64 
 3   occupation  6040 non-null   int64 
 4   zip         6040 non-null   object
dtypes: int64(3), object(2)
memory usage: 236.1+ KB
None

======movies_info=================
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3883 entries, 0 to 3882
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype 
---  ------    --------------  ----- 
 0   movie_id  3883 non-null   int64 
 1   title     3883 non-null   object
 2   genres    3883 non-null   object
dtypes: int64(1), object(2)
memory usage: 91.1+ KB
None

======ratings_info=================
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000209 entries, 0 to 1000208
Data columns (total 4 columns):
 #   Column     Non-Null Count    Dtype
---  ------     --------------    -----
 0   user_id    1000209 non-null  int64
 1   movie_id   1000209 non-null  int64
 2   imdbId     1000209 non-null  int64
 3   timestamp  1000209 non-null  int64
dtypes: int64(4)
memory usage: 30.5 MB
None

3.3 去掉 movies.dat数据文件 title中的年份

通过正则表达式去掉 title 中的年份

import re
patter = re.compile(r'^(.*)\((\d+)\)$')
title = {val:patter.match(val).group(1) for i,val in enumerate(set(movies_df['title']))}
movies_df['title'] = movies_df['title'].map(title)  
movies_df.head()

在这里插入图片描述

3.4 将ratings.dat文件中的时间戳转换为具体时间

通过 Pandas 中的 pd.to_datetime 函数将 timestamp 转换成具体时间

ratings_df['timestamp'] = pd.to_datetime(ratings_df['timestamp'],unit='s')
ratings_df.head()

在这里插入图片描述

3.5 更改DataFrame列名

通过 pandas.DataFrame.rename 函数更改列名,具体代码如下:

ratings_df.rename(columns={'timestamp':'time'},inplace=True)
ratings_df.tail()

在这里插入图片描述

3.6 将时间格式变更为‘年-月-日’

  • 1.使用 Pandas 中的 to_datetime 函数将 date 列从 object 格式转化为 datetime 格式
    1. 通过 strftime(‘%Y%m%d’) 取出年月日,把这个函数用 apply lambda 应用到 ratings_df[‘timestamp’] 的这一列
import datetime
date_df = pd.DataFrame({'time':ratings_df['time']})
data_df['date']=pd.to_datetime(date_df['time'])
ratings_df = date_df['date'].apply(lambda x:x.strftime('%Y-%m-%d'))
ratingd_df.tail()

在这里插入图片描述

3.7 合并数据

pandas.merge 将所有数据都合并到一个表中。merge有四种连接方式(默认为inner)

DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=None, indicator=False, validate=None)
  • 内连接(inner),取交集
  • 外连接(outer),取并集,并用NaN填充;
  • 左连接(left),左侧DataFrame取全部,右侧DataFrame取部分;
  • 右连接(right),右侧DataFrame取全部,左侧DataFrame取部分;

将movies_df与ratings_df合并成movies_rating_df数据集(两个数据集合并)

# 子数据合并
movies_ratings_df = pd.merge(ratings_df,movies_df,on='movie_id')
movies_ratings_df.head()

在这里插入图片描述

将movies_df、ratings_df与user_df合并成movies_rating_user_df数据集(多个数据集合并)

movies_ratings_user_df = pd.merge(pd.merge(ratings_df,movies_df),user_df)
movies_ratings_user_df.head()

在这里插入图片描述

4.数据分析

4.1 统计变量

Pandas 中提供 describe 函数来统计变量,查看 user_df 的变量统计情况。

变量描述
count数量统计,此列有效值的数量
std标准差
min最小值
25%四分之一分位数
50%二分之一分位数
75%四分之三分位数
max最大值
mean均值
user_df.describe()

在这里插入图片描述

4.2 分组统计

  Pandas 中使用 groupby 函数进行分组统计,groupby 分组实际上就是将原有的 DataFrame 按照 groupby 的字段进行划分,groupby 之后可以添加计数(count)、求和(sum)、求均值(mean)等操作。

DataFrame.groupby(by=None(分组标准), axis=0(), level=None, as_index=True(对于聚合输出,返回具有组标签作为索引的对象), sort=True, group_keys=True, observed=False, dropna=True)

4.2.1 统计评分最多的5部电影

首先根据电影名称(title)进行分组,然后使用 size 函数计算每组样本的个数,最后采用降序的方式输出前 5 条观测值。

top_5_ratings_movies_df = movies_ratings_df.groupby('title').size().sort_values(ascending=False)[:5]
top_5_ratings_movies_df

在这里插入图片描述

4.2.2 统计电影评分的均值(按照用户分组)

# 按照用户id统计看过电影评分的均值
movie_ratings_by_user_mean_df= movies_ratings_df.groupby('user_id',as_index=False)['imdbId'].mean()
movie_ratings_by_user_mean_df.head()

在这里插入图片描述

movie_ratings_by_user_mean_df.info()
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6040 entries, 0 to 6039
Data columns (total 2 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   user_id  6040 non-null   int64  
 1   imdbId   6040 non-null   float64
dtypes: float64(1), int64(1)
memory usage: 94.5 KB

"""

4.2.3 统计每部电影评分的均值(按照电影分组)

# 按照电影id统计每一部电影评分的均值
every_movie_ratings_mean_df= movies_ratings_df.groupby('movie_id',as_index=False)['imdbId'].mean()
every_movie_ratings_mean_df.head()

在这里插入图片描述

every_movie_ratings_mean_df.info()
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3706 entries, 0 to 3705
Data columns (total 2 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   movie_id  3706 non-null   int64  
 1   imdbId    3706 non-null   float64
dtypes: float64(1), int64(1)
memory usage: 58.0 KB
"""

4.2.4 分组聚合统计

Pandas 提供 aggregate 函数实现聚合操作,可简写为 agg,可以与 groupby 一起使用,作用是将分组后的对象使给定的计算方法重新取值,支持按照字段分别给定不同的统计方法。
按照 movie_id 和 title 进行分组,并计算评分均值,取前 5 个数据。

# 按照 movie_id 和 title 进行分组,并计算评分均值,取前 5 个数据。 
import numpy as np
movies_ratings_by_movie_title_df = movies_ratings_df.groupby(['movie_id','title'],as_index=False)['imdbId'].aggregate(np.mean)
movies_ratings_by_movie_title_df.head()

在这里插入图片描述

4.2.5 统计每部电影评分的均值(按照性别)

数据透视表 pivot_table 是一种类似 groupby 的操作方法,常见于 EXCEL 中,数据透视表按列输入数据,输出时,不断细分数据形成多个维度累计信息的二维数据表。

DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False, sort=True)
- values : 对目标数据进行筛选,默认是全部数据,可通过 values 参数设置我们想要展示的数据列。
-  index : 行索引,必要参数
- columns :透视表的列索引,非必要参数,同 index 使用方式一样
- aggfunc :对数据聚合时进行的函数操作,默认是求平均值,也可以 sum、count 等
- fill_value : 对于空值进行填充
- margins :额外列,默认对行列求和
- dropna : 默认开启去重 
# 根据性别获取相同电影的评分均值
mean_rating = movies_ratings_user_df.pivot_table('imdbId',index='title',columns='gender',aggfunc='mean')
mean_rating.head()

在这里插入图片描述

5.总结

  • 1M数据集有rating.dat、movies.dat、users.data三份数据集。ratings是6040位用户对3900部电影的评分数据(共计1000209)
  • rating.dat文件存放的是用户对电影的评分信息,UserID::MovieID::Rating::Timestamp
  • users.dat文件存放的是用户的相关信息,UserID::Gender::Age::Occupation::Zip-code
  • movies.dat文件存放的是电影的相关信息,MovieID::Title::Genres

本文仅仅作为个人学习记录,不作为商业用途,谢谢理解。

参考:

1.https://cloud.tencent.com/developer/article/1474293

2.https://www.jianshu.com/p/a59ff0dc22a3

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

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

相关文章

带有MCU算法的多功能语音交互芯片,OTA升级语音ic,WTV380-32N

几年来&#xff0c;随着智能家居、安防报警、医疗器械 等领域的快速发展&#xff0c;语音交互技术越来越受到人们的关注和青睐。作为智能硬件的重要组成部分&#xff0c;语音芯片的发展也变得越来越重要&#xff0c;针对这一市场需求&#xff0c;我们推出了一款多功能的语音芯片…

layout布局input框输入中文出现撑开/换行

layout布局input框输入中文出现撑开/换行 问题 element ui组件库中提供了layout布局&#xff0c;但是在使用中出现了一个奇奇怪怪的问题 我想要实现的布局是两个输入框排成一行&#xff0c;行与行之间样式布局不会互相影响 直接上代码&#xff1a; <el-row :gutter&quo…

海康相机通过MVS达不到标称最大帧率的解决办法

目录 1.相机参数设置1.1 取消相机帧率限制1.2 修改相机图像格式1.3 调整相机曝光时间1.4 检查相机数据包大小&#xff08;网口相机特有参数&#xff09;1.5 恢复相机默认参数1.6 相机 ADC 输出位深调整 2.系统环境设置2.1 网口相机设置2.2 USB 相机设置 1.相机参数设置 1.1 取…

pycharm flask断点调试失效

问题描述 在升级本地pycharm为最新版pycharm2023.1后&#xff0c;发现原有的flask项目下的断点怎么都无法进入调试。同时&#xff0c;如果是debug某个py文件是可以正常进入调试的&#xff0c;因此推断这与flask有关。 pycharm&#xff1a;PyCharm 2023.1 (Professional Editio…

STM32HAL库 OLED显示屏的使用

文章目录 前言一、CubeIDE配置OLED显示屏iic引脚二、OLED驱动库1.引入库2.main.c中使用 总结 前言 本文主要讲解hal库配置与0.96寸oled屏的使用。 一、CubeIDE配置OLED显示屏iic引脚 OLED显示屏需要用到iic通信&#xff0c;此处选择了选择pb8为SCL、pb9为SDA 二、OLED驱动…

vue2数据响应式原理(1) view-model概念,侵入式和非侵入式对比

都是练拳不练功 到头一场空 在更新技术视野的前提下 还是要去多学原理 掌握更深的技术范畴 我会先出文后续持续更新 讲解vue2响应式原理 至于vue3 后续有机会 也会弄 这些文章不会直降理论 到一定阶段 也会带大家手写代码去实现一下效果 首先是 view-model 大家在实际开发中应…

SpringBoot集成Mybatis-Plus实现多租户动态数据源

1. 概述 最近接手一个多租户系统&#xff0c;多租户主要的就是租户之间的数据是相互隔离的&#xff0c;每个租户拥有自己独立的数据&#xff0c;相互之间不干扰。目前实现多租户主要有三种方案&#xff1a; 独立数据库 每个租户拥有自己单独的数据库&#xff0c;从物理上隔离了…

Java语言数据类型与c语言数据类型的不同

目录 一、c语言数据类型 1.基本类型&#xff1a; 2.枚举类型&#xff1a; 3.空类型&#xff1a; 4.派生类型&#xff1a; 二、C语言编程需要注意的64位和32机器的区别 三、 不同之处 一、c语言数据类型 首先&#xff0c;先来整体介绍一下C语言的数据类型分类。 1.基…

空间金字塔池化(Spatial Pyramid Pooling)

1. 前言 当前的深度神经网络一般都需要固定的输入图像尺寸&#xff08;如224*224&#xff09;。这种需求很明显是人为的&#xff0c;潜在性的弊端会降低识别精度&#xff08;为了使图像尺寸相同&#xff0c;一定会涉及到图像的比例/非比例放缩&#xff0c;这就引入了尺度误差和…

机器学习中的三个重要环节:训练、验证、测试

本文重点 模型训练、验证和测试是机器学习中的三个重要环节。这三个环节之间存在着紧密的关系,它们相互作用,共同构建出一个完整的机器学习模型。在本文中,我们将详细介绍模型训练、验证和测试之间的关系。 模型训练、验证和测试之间的关系 模型训练是机器学习中最基本的…

原生Java使用Mybatis操作数据库接口注解形式,与SpringBoot类似且无需管理SqlSession连接的工具类

Hi I’m Shendi https://sdpro.top/blog/html/article/1044.html 需求描述 用 SpringBoot 整合 Mybatis 使用久了&#xff0c;再编写没有Spring但需要操作数据库的程序时就会想着使用接口注解的形式&#xff0c;这样效率比较高和简单 Spring 中只需要编写好接口映射&#xff…

字节跳动正式开源分布式训练调度框架 Primus

动手点关注 干货不迷路 项目地址&#xff1a;https://github.com/bytedance/primus 随着机器学习的发展&#xff0c;模型及训练模型所需的数据量越来越大&#xff0c;也都趋向于通过分布式训练实现。而算法工程师通常需要对这些分布式框架涉及到的底层文件存储和调度系统有较深…

剑指 Offer 52. 两个链表的第一个公共节点 / LeetCode 160. 相交链表(双指针 / 哈希集合)

题目&#xff1a; 链接&#xff1a;剑指 Offer 52. 两个链表的第一个公共节点&#xff1b;LeetCode 160. 相交链表 难度&#xff1a;简单 输入两个链表&#xff0c;找出它们的第一个公共节点。 如下面的两个链表&#xff1a; 在节点 c1 开始相交。 示例 1&#xff1a; 输入…

Spring MVC Bean加载控制

回顾一下我们一般写的项目包括那些包吧&#xff1a; config目录存入的是配置类,写过的配置类有: ServletContainersInitConfigSpringConfigSpringMvcConfigJdbcConfigMybatisConfig controller目录存放的是SpringMVC的controller类service目录存放的是service接口和实现类dao目…

Doo Prime 德璞资本:股指期货交易如何管理好个人情绪

在股指期货交易中&#xff0c;我们可以感觉到心态随着交易的成败而变化。有时心态对交易影响不大&#xff0c;但有时影响很大&#xff0c;一个好的心态&#xff0c;能够应对各种变化&#xff0c;各种损益和市场判断的正确和错误&#xff0c;不会对心态产生很大的影响&#xff0…

ArcGIS中的土地利用变化分析详解

本篇主要是针对矢量数据的分析。 一、不同时期的土地利用矢量数据&#xff0c;如何分析其图形及属性变化&#xff1f; 土地利用图&#xff08;左图为1993年&#xff0c;右图为2003年&#xff09; 思路如下&#xff1a; 可以先对2个图层进行Union操作&#xff0c;然后在结果中…

【三十天精通Vue 3】第十四天 Vue 3 的单元测试详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录 引言一、为什么要进行单元测试1.1 单元测试的概念1.2 单元测试的优…

Javase学习文档------面象对象再探

再续前缘面向对象 书接上回构造器 在Java中&#xff0c;可以通过在空参构造方法中使用 this() 关键字来调用类中其它的构造方法。 使用 this() 关键字来调用其它构造方法时&#xff0c;需要注意以下几点&#xff1a;1.this() 必须是构造方法的第一条语句&#xff1b; 2.一个构…

经典文献阅读之--NORLAB-ICP(重力约束ICP)

0. 简介 最近几年IPC相关的文章也出了不少&#xff0c;最近作者有看到了一篇比较有意思的ICP论文—《Gravity-constrained point cloud registration》&#xff0c;这篇论文将传统的ICP考虑了重力因素&#xff0c;高频率的IMU数据弥补了低频的传感器数据。除此之外&#xff0c…

4K分辨率搭配光学变焦功能,极米H6成旗舰家用投影首选

近几年&#xff0c;我国投影机市场产品竞争日趋激烈&#xff0c;以极米为代表的国产品牌迅速崛起并逐步超越国际品牌成为中国投影机市场的领跑者。虽然目前国产投影仪品牌比较多&#xff0c;但其中极米科技旗下的产品最受消费者青睐。IDC数据显示&#xff0c;2022年上半年&…