📅  最后修改于: 2023-12-03 15:19:02.979000             🧑  作者: Mango
本文将介绍如何用 Python 实现一个简单的电影推荐系统。电影推荐系统是一种基于用户历史行为以及个人兴趣偏好,为用户推荐更合适的电影的一种智能化系统。
在本文中,我们将使用 IMDB 的电影数据作为实例演示,来构建并训练一个基于协同过滤算法的推荐系统。协同过滤算法是推荐系统中应用最广泛的算法之一,经典的协同过滤算法包括基于用户的协同过滤和基于物品的协同过滤两种。
我们将通过以下步骤来构建我们的电影推荐系统:
作为我们实例的数据集,我们将使用 IMDP 的电影数据集。IMDB 数据集包括了数万部电影的元数据,包括电影名称、导演、演员、上映年份、用户评分等信息。我们将从 Kaggle 上下载这个数据集并使用 Pandas 库进行数据读取和预处理。
import pandas as pd
metadata = pd.read_csv('movies_metadata.csv', low_memory=False)
metadata = metadata.drop_duplicates(subset=['id']) # 删除重复项
metadata = metadata[metadata['vote_count'] > 10] # 过滤评分次数小于等于 10 的电影
为了训练协同过滤模型,我们需要将电影的特征表示成向量。在本文中,我们将使用电影的关键词(包括电影名称、导演、演员、电影类型等)作为电影的特征,使用 TfidfVectorizer 计算出每个电影的关键词权重,并使用 TruncatedSVD 将高维的权重向量降维到 50 维。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import TruncatedSVD
metadata['features'] = metadata[['title', 'genres', 'overview', 'director', 'cast']].apply(lambda x: ' '.join(x.dropna().astype(str)), axis=1)
vectorizer = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
x = vectorizer.fit_transform(metadata['features'])
svd = TruncatedSVD(n_components=50, random_state=0)
x = svd.fit_transform(x)
metadata['features_vec'] = list(x)
我们将使用基于用户的协同过滤算法来构建电影推荐系统。在基于用户的协同过滤算法中,我们通过计算用户之间的相似度,从而为指定用户推荐其他用户评分高的电影。
我们将首先计算每个用户对电影的评分矩阵,其中每行代表一个用户,每列代表一个电影,矩阵元素表示用户对电影的评分。然后,我们将计算每个用户之间的余弦相似度,并使用 pearson_baseline 相似度调整算法来消除不完全重叠的情况下的误差。
from surprise import Dataset, Reader, KNNWithMeans
reader = Reader(rating_scale=(0, 5))
data = Dataset.load_from_df(ratings, reader)
sim_options = {'name': 'pearson_baseline', 'user_based': True}
knn = KNNWithMeans(k=50, sim_options=sim_options, verbose=False)
knn.fit(data.build_full_trainset())
训练电影推荐模型需要两步:
from sklearn.metrics.pairwise import cosine_similarity
def get_similar_users(user_id):
user_index = ratings_matrix.index.get_loc(user_id)
similarities = cosine_similarity(ratings_matrix[user_index].reshape(1, -1), ratings_matrix)
similar_users_idx = similarities.argsort()[0][-11:-1][::-1]
return list(ratings_matrix.index[similar_users_idx])
def recommend_movies(user_id):
similar_users = get_similar_users(user_id)
candidate_movies = metadata[~metadata['title'].isin(ratings.loc[ratings['userId'] == user_id]['title'])]
candidate_movies = candidate_movies[candidate_movies['vote_count'] >= 50]
candidate_movies['score'] = candidate_movies['features_vec'].apply(lambda x: knn.predict(user_id, x).est)
candidate_movies = candidate_movies.sort_values(by='score', ascending=False)
return candidate_movies.head(10)['title'].tolist()
我们将为指定的用户推荐 10 个电影。在此之前,用户需要对一些电影进行评分,以此作为训练集。评分数据应满足如下格式(我们已经在数据预处理中读取了评分数据):
ratings.head()
userId movieId rating timestamp \
0 1 2.0 3.5 1112486027
1 1 29.0 3.5 1112484676
2 1 32.0 3.5 1112484819
3 1 47.0 3.5 1112484727
4 1 50.0 3.5 1112484580
title
0 Jumanji (1995)
1 City of Lost Children, The (Cité des enfants p...
2 Twelve Monkeys (a.k.a. 12 Monkeys) (1995)
3 Seven (a.k.a. Se7en) (1995)
4 Usual Suspects, The (1995)
user_id = 1
recommendations = recommend_movies(user_id)
recommendations
['Intouchables (2011)',
'Monsters, Inc. (2001)',
'Pulp Fiction (1994)',
'Shawshank Redemption, The (1994)',
'Forrest Gump (1994)',
'Fight Club (1999)',
'Inception (2010)',
'Godfather, The (1972)',
'Goodfellas (1990)',
'Dark Knight, The (2008)']
我们构建的电影推荐系统基于用户的协同过滤算法,使用 IMDb 的电影数据集,为指定用户推荐 10 部合适的电影。在实现过程中,我们使用了 TfidfVectorizer 和 TruncatedSVD 去处理电影的特征向量,使用 KNNWithMeans 模型进行训练,并使用 pearson_baseline 相似度调整算法来消除不完全重叠的情况下的误差。最后,我们为用户推荐了 10 部电影,得到了不错的结果。
{% raw %}
```{% endraw %}