电影数据集介绍
用户信息
#u.user #列名称 'user_id','age','gender','occupation','zip_code' #数据 1|24|M|technician|85711 2|53|F|other|94043 3|23|M|writer|32067 4|24|M|technician|43537 5|33|F|other|15213
评分表
# u.data #列名称 'user_id','movie_id','rating','unix_timestamp' 196 242 3 881250949 186 302 3 891717742 22 377 1 878887116 244 51 2 880606923 166 346 1 886397596 298 474 4 884182806 115 265 2 881171488 253 465 5 891628467 305 451 3 886324817
电影表
#u.item #列名称 'movie_id','movie_title','release_date','video_release_date','imdb_url' 1|Toy Story (1995)|01-Jan1995||http://us.imdb.com/M/title-exact? Toy%20Story%20(1995)|0|0|0|1|1|1|0|0|0|0|0|0|0|0|0 2|GoldenEye (1995)|01-Jan1995||http://us.imdb.com/M/title-exact? GoldenEye%20(1995)|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0 3|Four Rooms (1995)|01-Jan1995||http://us.imdb.com/M/title-exact? Four%20Rooms%20(1995)|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0 4|Get Shorty (1995)|01-Jan1995||http://us.imdb.com/M/title-exact? Get%20Shorty%20(1995)|0|1|0|0|0|1|0|0|1|0|0|0|0|0|0|0 5|Copycat (1995)|01-Jan1995||http://us.imdb.com/M/title-exact? Copycat%20(1995)|0|0|0|0|0|0|1|0|1|0|0|0|0|0|0|0|1
加载数据
import numpy as np import pandas as pd import matplotlib.pyplot as plt #支持中文显示 plt.rcParams['font.family']='Kaiti' # 使用非unicode的负号,当使用中文时候要设置 plt.rcParams['axes.unicode_minus']=False # 加载用户信息 user id | age | gender | occupation | zip code user_cols=['user_id','age','gender','occupation','zip_code'] users = pd.read_csv('ml100k/u.user',sep='|',names=user_cols,encoding='latin-1') # 加载电影信息 movie id | movie title |release date | video release date | IMDb URL movie_cols=['movie_id','movie_title','release_date','video_release_date','imdb_url'] movies=pd.read_csv('ml100k/u.item',sep='|',names=movie_cols,usecols=range(5),encoding='latin-1')x` # 加载评分信息 user id | item id | rating |timestamp rating_cols=['user_id','movie_id','rating','unix_timestamp'] ratings = pd.read_csv('ml100k/u.data',sep='\t',names=rating_cols,encoding='latin-1') # 为了后续分组统计数据方便,将3个DataFrame进行合并 # 和并用户 评分 user_ratings = pd.merge(users,ratings) data = pd.merge(user_ratings,movies)
数据探索和清洗
基本信息描述
data.describe() #对评分男性和女性人数统计 data['gender'].value_counts()
缺值处理
data.shape() #每列缺值情况 data.info() data.isnull().sum() #删除video_release_date列 data.dropna(axis=1,how='all',inplace=True)
重复值查看
# 重复值查看 data.duplicated().any()
评分最多的电影
# 按照电影标题分组,统计分组中数据个数,即得到评分次数 g = data.groupby('movie_title') data.groupby('movie_title').size().sort_values(ascending=False).head(20) #或者data.groupby('movie_title')['movie_title'].count() #或者data['movie_title'].value_counts().head(20).plot(kind='bar')
评分最高的电影
# 根据电影标题分组,对分组中评分求均值,均值越高,评分也就越高 data.groupby('movie_title') ['rating'].mean().sort_values(ascending=False).head(10) #使用agg()函数 data.groupby('movie_title').agg({'rating':'mean'}) ['rating'].sort_values(ascending=False).head(10) #统计评分人数和评分的均值 data.groupby('movie_title') ['rating'].agg(['size','mean']).sort_values(by=['mean','size'],ascending=False).head(10) # movie_scores # 过滤,评分人数必须大于等于100 data_group = data.groupby('movie_title') ['rating'].agg(['count','mean']) most_100 =data_group[data_group['count']>100] top10 = most_100.sort_values(by=['mean','count'],ascending=False).head(10) top10['mean'].plot(kind='bar',title='评分最高的电影')
评分与年龄的关系
# 简单看下年龄分布 data['age'].describe() data['age'].plot(kind='hist',bins=30,figsize=(12,6)) # 自定义年龄区间,分布不同年龄组对电影评分总体状况 # 0-9 10-19 20-29 ...70-79 labels = ['0-9','10-19','20-29','30-39','40-49','50-59','60-69','70-79'] data['age_group'] =pd.cut(data['age'],np.arange(0,81,10),right=False,labels=labels) data.groupby('age_group').agg({'rating':['size','mean']}) #年龄越大的区间,对电影打分越高
不同年龄段对某部电影的评分
# 因为电影数据比较多,现在只分析评分次数排在前100的电影--》如何得到评分次数在前100的电影 # 得到评分次排在前100的电影的id信息,同时将数据movie_id列设置为行索引,利用索引数组来获得评分次数排在前100的电影的数据 # 得到评分次数在前100的电影 # 得到评分次排在前100的电影的id信息 most_100=data['movie_id'].value_counts().head(100) # most_100 # 数据movie_id列设置为行索引 data.set_index('movie_id',inplace=True) by_age_group =data.loc[most_100.index].groupby(['movie_title','age_group']) by_age_group['rating'].mean().unstack(1).fillna(0).head(10)