数据集的获取:
1、grouplens官方网址
或者
2、
链接: https://pan.baidu.com/s/1wfU20GH2gLd1Ok262v_X2Q
提取码: us6i
使用上述压缩包中的以下三个文件
有关上述三个文件的介绍:
u.data -- The full u data set, 100000 ratings by 943 users on 1682 items.
Each user has rated at least 20 movies. Users and items are
numbered consecutively from 1. The data is randomly
ordered. This is a tab separated list of
user id | item id | rating | timestamp.
The time stamps are unix seconds since 1/1/1970 UTC
u.item -- Information about the items (movies); this is a tab separated
list of
movie id | movie title | release date | video release date |
IMDb URL | unknown | Action | Adventure | Animation |
Children's | Comedy | Crime | Documentary | Drama | Fantasy |
Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi |
Thriller | War | Western |
The last 19 fields are the genres, a 1 indicates the movie
is of that genre, a 0 indicates it is not; movies can be in
several genres at once.
The movie ids are the ones used in the u.data data set.
u.user -- Demographic information about the users; this is a tab
separated list of
user id | age | gender | occupation | zip code
The user ids are the ones used in the u.data data set.
读入user数据
通过描述,可以看出,user文件的数据集格式是这样,也就是用来描述用户的数据集。
# 用户ID | 年龄 | 性别 | 职业 | 邮编
user id | age | gender | occupation | zip code
使用pandas提供的read_table()方法来读取:
# 表头设置
unames = ['user id', 'age', 'gender', 'occupation', 'zip code']
# header为None指的是读取的数据没有表头,names传入的是我们之前设置好的表头
user = pd.read_table('u.user', sep='|', header=None, names=unames)
# 数据预览
print(user.head(5))
读入data数据
data数据集包含了10万条评分数据,数据格式如下,分隔符采用tab:
# 用户ID tab 电影ID tab 评分 tab 时间戳
user id tab item id tab rating tab timestamp
同理,使用read_table()读取,注意设置sep='\t'
rnames = ['user id', 'item id', 'rating', 'timestamp']
data= pd.read_table('u.data', sep='\t', header=None, names=rnames)
print(data.head(5))
读入item数据
item数据集是描述电影的数据集,数据格式如下:
# 电影ID | 电影标题 | 上映日期 | 视频上映日期 | IMDb网址 | (后面16个0、1代表的是电影的分类)
movie id | movie title | release date | video release date |IMDb URL | unknown | Action | Adventure | Animation |Children's | Comedy | Crime | Documentary | Drama | Fantasy |Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi |Thriller | War | Western |
这个数据集我们主要在意的就是电影ID、电影标题这两个列。
采用上述方法进行读取:
结果出现了Error:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3: invalid continuation byte
因为item数据集中出现了中文,读取时就很容易出现编码错误,因此,需要加入encoding参数:
mnames = ['movie id', 'movie title', 'release date', 'video release date', 'IMDb URL', 'unknown', 'Action', 'Adventure',
'Animation', "Children's", 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror',
'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western']
item = pd.read_table('u.item', sep='|', header=None, names=mnames, encoding="ISO-8859-1")
print(item.head(5))
注:添加以下代码,不省略显示
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 显示宽度为1000
pd.set_option('display.width', 1000)
数据连接
通过上述操作已经把三个数据读入了,如果想继续进行分析,把三个数据集连接起来是很好的方法。
# 首先合并user和data,因为都含有共同的user id列,所以直接合并就可以。
df = pd.merge(user, data)
# 把user和data合并后的数据与item数据合并,这里的item的movie id其实就是data中的item id,这种情况要手动传入两个参数
df = pd.merge(df, item, left_on='item id', right_on='movie id')
至此,数据的读取、连接完毕,接下来进行数据的分析
查看不同职业的平均打分
# 对df按照occupation分组,agg函数作用于df的rating,传入的函数是求平均值
df = df['rating'].groupby(by=df['occupation']).agg(['mean'])
# 对df进行排序
print(df.sort_values(by='mean', ascending=False))
查看不同职业、性别的平均打分
# 上述操作的合并操作
print(df['rating'].groupby(by=[df['occupation'], df['gender']]).agg(['mean']))
电影评分排名
print(df['rating'].groupby(by=df['movie title']).agg(['mean']).sort_values(ascending=False))
电影评分排名的进一步优化
可以看到,前几位的电影竟然出现了平均分5分,这种情况很有可能是评分人数过少,或者数据有错,因此,我们需要统计一下评分次数。
同时采用mean() count()函数时,可以采用一下方法:
# 使用agg来传入多个函数,排序函数中也新增by参数
print(df['rating'].groupby(by=df['movie title']).agg(['mean', 'count']).sort_values(by='mean', ascending=False))
我们发现,果然是有一些电影,评分数量过少,因此规定,评分次数大于50的才可以参与排名。
# 保存带有次数和平均值的DataFrame为df1
df1 = df['rating'].groupby(by=df['movie title']).agg(['mean', 'count'])
target = df1['count'] > 50
print(df1[target].sort_values(by='mean', ascending=False))
转载:https://blog.csdn.net/baidu_38591365/article/details/106736184