1 資料集簡介
MovieLens資料集是一個關于電影評分的資料集,裡面包含了從IMDB, The Movie DataBase上面得到的使用者對電影的評分資訊,詳細請看下面的介紹。
1 links.csv
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CO4MWY2QWMyMjNiVWYlZjYtETMzIDO3YTMfRzN5MTO3AjMzcTN1EzX1UzN4gDM18CX4ATNwkTMwIzLcNXZslmZvwVbvNmLyVGZvN2dv5mLzVGbpZGZh9GbwV3Lc9CX6MHc0RHaiojIsJye.png)
檔案裡面的内容是幫助你如何通過網站id在對應網站上找到對應的電影連結的。
1.1 資料格式
movieId, imdbId, tmdbId
1.1.1 movieId
表示這部電影在movielens上的id,可以通過連結
https://movielens.org/movies/(movieId)來得到。
- https://movielens.org/movies/1
利用 Python 分析 MovieLens 1M 資料集1 資料集簡介3 ratings.csv4 tags.csv摘要引文檔案的内容和使用2 Python 資料處理3 再處理
1.1.2 imdbId
表示這部電影在imdb上的id,可以通過連結
http://www.imdb.com/title/(imdbId)/- tmdbId:表示這部電影在themoviedb上的id,可以通過連結 http://www.imdb.com/title/(tmdbId)/
2 movies.csv
movieId, title, genres
檔案裡包含了一部電影的id和标題,以及該電影的類别
2.1 資料格式
movieId, title, genres
2.1.1 movieId
每部電影的id
2.1.2 title
電影的标題
2.1.3 genres
電影的類别(詳細分類見readme.txt)
3 ratings.csv
檔案裡面的内容包含了每一個使用者對于每一部電影的評分。
3.1 資料格式
- userId: 每個使用者的id
- movieId: 每部電影的id
- rating: 使用者評分,是5星制,按半顆星的規模遞增(0.5 stars - 5 stars)
- timestamp: 自1970年1月1日零點後到使用者送出評價的時間的秒數
資料排序的順序按照userId,movieId排列的。
4 tags.csv
檔案裡面的内容包含了每一個使用者對于每一個電影的分類
4.1 資料格式
- tag: 使用者對電影的标簽化評價
摘要
=======
該資料集(ml-latest-small)描述了電影推薦服務[MovieLens](
http://movielens.org)的5星評級和自由文本标記活動。它包含9742部電影的100836個評級和3683個标簽應用程式。這些資料由610位使用者在1996年3月29日到2018年9月24日之間建立。該資料集于2018年9月26日生成。
随機選擇使用者以包含在内。所有標明的使用者評分至少20部電影。不包括人口統計資訊。每個使用者都由一個id表示,并且不提供其他資訊。
資料包含在
links.csv
,
movies.csv
ratings.csv
和
tags.csv
檔案中。有關所有這些檔案的内容和用法的更多詳細資訊如下。
這是一個發展的資料集。是以,它可能會随着時間的推移而發生變化,并不是共享研究結果的适當資料集。
引文
========
要确認在出版物中使用資料集,請引用以下檔案:
F. Maxwell Harper和Joseph A. Konstan。 2015.MovieLens資料集:曆史和背景。 ACM互動式智能系統交易(TiiS)5,4:19:1-19:19。 https://doi.org/10.1145/2827872
檔案的内容和使用
========================
格式化和編碼
資料集檔案以[逗号分隔值]檔案寫入,并帶有單個标題行。包含逗号(
,
)的列使用雙引号(
`
)進行轉義。這些檔案編碼為UTF-8。如果電影标題或标簽值中的重音字元(例如Misérables,Les(1995))顯示不正确,確定讀取資料的任何程式(如文本編輯器,終端或腳本)都配置為UTF-8。
使用者ID
MovieLens使用者随機選擇包含。他們的ID已經匿名化了。使用者ID在
ratings.csv
tags.csv
之間是一緻的(即,相同的id指的是兩個檔案中的同一使用者)。
電影Ids
資料集中僅包含至少具有一個評級或标記的電影。這些電影ID與MovieLens網站上使用的電影ID一緻(例如,id
1
對應于URL
)。電影ID在
ratings.csv
tags.csv
movies.csv
links.csv
之間是一緻的.
2 Python 資料處理
2.1 轉化DataFrame對象
通過[pandas.read_csv]将各表轉化為pandas 的DataFrame對象
# 使用者資訊
unames = ['user_id', 'gender', 'age', 'occupation', 'zip']
users = pd.read_csv('/Volumes/doc/PyCharmProjects/MovieLenData/users.dat',
sep=',', header=None, names=unames, engine='python')
# 評分
rnames = ['user_id', 'movieId', 'rating', 'timestamp']
ratings = pd.read_csv('/Volumes/doc/PyCharmProjects/MovieLenData/ratings.csv',
sep=',', header=None, names=rnames, engine='python')
# 電影資訊
mnames = ['movie_id', 'title', 'genres']
movies = pd.read_csv('/Volumes/doc/PyCharmProjects/MovieLenData/movies.csv',
sep=',', header=None, names=mnames, engine='python')
# 連結資訊
lnames = ['movieId', 'imdbId', 'tmdbId']
links = pd.read_csv('/Volumes/doc/PyCharmProjects/MovieLenData/links.csv',
sep=',', header=None, names=mnames, engine='python')
# 标簽資訊
tnames = ['userId', 'movieId', 'tag', 'timestamp']
tags = pd.read_csv('/Volumes/doc/PyCharmProjects/MovieLenData/tags.csv',
sep=',', header=None, names=mnames, engine='python')
其中用到的參數為分隔符sep、頭檔案header、列名定義names、解析器引擎engine
這裡和書上相比多用了engine參數,engine參數有C和Python,C引擎速度更快,而Python引擎目前功能更完整。
- 利用python的切片檢視每個DataFrame
## 2.2 檢查資料的輸出
print(users[:5])
print("===================================================================")
print(ratings[:5])
print("===================================================================")
print(movies[:5])
print("===================================================================")
print(links[:5])
print("===================================================================")
print(tags[:5])
print("===================================================================")
- 檢視dataframe的summary
users.info()
print("-----------------------------------")
ratings.info()
print("-----------------------------------")
movies.info()
print("-----------------------------------")
links.info()
print("-----------------------------------")
tags.info()
2.3 根據性别和年齡計算某部電影的平均得分
可用pandas.merge 将所有資料都合并到一個表中。merge有四種連接配接方式(預設為inner),分别為
- 内連接配接(inner),取交集;
- 外連接配接(outer),取并集,并用NaN填充;
- 左連接配接(left),左側DataFrame取全部,右側DataFrame取部分;
- 右連接配接(right),右側DataFrame取全部,左側DataFrame取部分;
data = pd.merge(pd.merge(ratings, users), movies)
data.info()
通過索引器檢視第一行資料,使用基于标簽的索引.loc或基于位置的索引.iloc
2.4 按性别計算每部電影的平均得分
可通過資料透視表(
pivot_table)實作
該操作産生了另一個DataFrame,輸出内容為rating列的資料,行标index為電影名稱,列标為性别,aggfunc參數為函數或函數清單(預設為numpy.mean),其中“columns”提供了一種額外的方法來分割資料。
2.5 過濾評分資料不夠250條的電影
- 通過groupby()對title進行分組
- 利用size()得到一個含有各電影分組大小的Series對象
print("過濾評分資料不夠250條的電影")
ratings_by_title = data.groupby('title').size()
print(ratings_by_title[:10])
- 最後通過index索引篩選出評分資料大于250條的電影名稱
print("通過index索引篩選出評分資料大于250條的電影名稱")
active_titles = ratings_by_title.index[ratings_by_title >= 250]
print(active_titles)
- 使用mean_ratings選取所需的行
mean_ratings = mean_ratings.loc[active_titles]
mean_ratings.info()
print(mean_ratings[:5])
2.6 了解女性觀衆最喜歡的電影
- 通過 sort_index 進行降序
top_female_ratings = mean_ratings.sort_index(by='F', ascending=False)
print(top_female_ratings[:10])
by參數的作用是針對特定的列進行排序(不能對行使用),ascending的作用是确定排序方式,預設為升序
2.7 計算評分分歧
增加一列存放平均得分之差,并對其排序,得到分歧最大且女性觀衆更喜歡的電影
mean_ratings['diff'] = mean_ratings['M'] - mean_ratings['F']
sorted_by_diff = mean_ratings.sort_index(by='diff')
print(sorted_by_diff[:10])
- 對排序結果反序可得男性觀衆更喜歡的電影
利用 Python 分析 MovieLens 1M 資料集1 資料集簡介3 ratings.csv4 tags.csv摘要引文檔案的内容和使用2 Python 資料處理3 再處理
3 再處理
3.1 資料集整合
movie_ratings = pd.merge(movies, ratings)
lens = pd.merge(movie_ratings, users)
3.2 列出被評價過次數最多的20部電影
按照電影标題将資料集分為不同的groups,并且用size( )函數得到每部電影的個數(即每部電影被評論的次數),按照從大到小排序,取最大的前20部電影列出如下
most_rated = lens.groupby('title').size().sort_values(ascending=False)[:20]
print(most_rated)
3.3 評分最高的十部電影
按照電影名稱分組,用agg函數通過一個字典{‘rating’: [np.size, np.mean]}來按照key即rating這一列聚合,檢視每一部電影被評論過的次數和被打的平均分。取出至少被評論過100次的電影按照平均評分從大到小排序,取最大的10部電影。
movie_stats = lens.groupby('title').agg({'rating': [np.size, np.mean]})
atleast_100 = movie_stats['rating']['size'] >= 100
print(movie_stats[atleast_100].sort_values([('rating', 'mean')], ascending=False)[:10])
3.4 檢視不同年齡見争議最大的電影
- 檢視使用者的年齡分布:
users.age.plot.hist(bins=30)
plt.title("Distribution of users' ages")
plt.ylabel('count of users')
plt.xlabel('age');
- 用pandas.cut函數将使用者年齡分組
labels = ['0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79']
lens['age_group'] = pd.cut(lens.age, range(0, 81, 10), right=False, labels=labels)
lens[['age', 'age_group']].drop_duplicates()[:10]
- 每個年齡段使用者評分人數和打分偏好,看起來年輕人更挑剔一點點
lens.groupby('age_group').agg({'rating': [np.size, np.mean]})
- 檢視被評價過最多次的50部電影在不同年齡段之間的打分差異。并且用unstack函數将資料轉換為一個表格,每一行為電影名稱,每一列為年齡組,值為該年齡組的使用者對該電影的平均評分。
3.5 不同性别間争議最大的電影
lens.reset_index(inplace=True)
pivoted = lens.pivot_table(index=['movieId', 'title'],
columns=['gender'],
values='rating',
fill_value=0)
pivoted['diff'] = pivoted.M - pivoted.F
print(pivoted.head())
pivoted.reset_index('movieId', inplace=True)
disagreements = pivoted[pivoted.movieId.isin(most_50.index)]['diff']
disagreements.sort_values().plot(kind='barh', figsize=[9, 15])
plt.title('Male vs. Female Avg. Ratings\n(Difference > 0 = Favored by Men)')
plt.ylabel('Title')
plt.xlabel('Average Rating Difference')
plt.show()