大家好,我是微学AI,今天给大家介绍一下机器学习实战15-推荐算法-协同过滤在电影推荐中的应用实践。 随着互联网的发展,信息过载问题日益严重,推荐系统应运而生。本文将详细介绍推荐算法在电影推荐领域的应用实践,以及其背后的数学原理。本博客我将介绍推荐系统的背景与应用场景,然后详细阐述推荐算法的数学原理,然后通过一个电影推荐的实例来展示推荐算法的实际应用,利用python代码实现一个案例。
推荐系统是一种信息过滤系统,旨在解决信息过载问题。在电影推荐领域,推荐系统能够根据用户的兴趣和历史行为,为用户推荐可能感兴趣的电影。例如,当用户在电影平台上浏览电影时,推荐系统可以根据用户的观看历史、评分、搜索记录等信息,为用户推荐相似或相关的电影。
推荐算法主要分为协同过滤和基于内容的推荐两种方法。下面我们将分别介绍这两种方法的数学原理。
协同过滤(Collaborative Filtering, CF)是一种基于用户历史行为数据的推荐方法。其基本思想是:如果两个用户在过去的某些项目上表现出相似的兴趣,那么他们在未来的项目上也可能表现出相似的兴趣。协同过滤主要包括用户基于的协同过滤(User-based CF)和物品基于的协同过滤(Item-based CF)两种方法。
用户基于的协同过滤通过计算用户之间的相似度,找到与目标用户相似的用户群体,然后根据这些相似用户的兴趣推荐项目。用户之间的相似度可以通过余弦相似度、皮尔逊相关系数等方法计算。假设我们有一个用户-物品评分矩阵
R
∈
R
m
×
n
R \in \mathbb{R}^{m \times n}
R∈Rm×n,其中
m
m
m表示用户数,
n
n
n表示物品数,
R
i
j
R_{ij}
Rij?表示用户
i
i
i对物品
j
j
j的评分。用户
i
i
i和用户
j
j
j之间的余弦相似度可以表示为:
sim
(
i
,
j
)
=
∑
k
=
1
n
R
i
k
?
R
j
k
∑
k
=
1
n
R
i
k
2
?
∑
k
=
1
n
R
j
k
2
\text{sim}(i, j) = \frac{\sum_{k=1}^{n} R_{ik} \cdot R_{jk}}{\sqrt{\sum_{k=1}^{n} R_{ik}^2} \cdot \sqrt{\sum_{k=1}^{n} R_{jk}^2}}
sim(i,j)=∑k=1n?Rik2???∑k=1n?Rjk2??∑k=1n?Rik??Rjk??
物品基于的协同过滤通过计算物品之间的相似度,找到与目标物品相似的物品群体,然后根据用户对这些相似物品的评分预测用户对目标物品的评分。物品之间的相似度可以通过余弦相似度、调整余弦相似度等方法计算。假设我们有一个物品-用户评分矩阵
R
∈
R
n
×
m
R \in \mathbb{R}^{n \times m}
R∈Rn×m,物品
i
i
i和物品
j
j
j之间的余弦相似度可以表示为:
sim
(
i
,
j
)
=
∑
k
=
1
m
R
k
i
?
R
k
j
∑
k
=
1
m
R
k
i
2
?
∑
k
=
1
m
R
k
j
2
\text{sim}(i, j) = \frac{\sum_{k=1}^{m} R_{ki} \cdot R_{kj}}{\sqrt{\sum_{k=1}^{m} R_{ki}^2} \cdot \sqrt{\sum_{k=1}^{m} R_{kj}^2}}
sim(i,j)=∑k=1m?Rki2???∑k=1m?Rkj2??∑k=1m?Rki??Rkj??
基于内容的推荐(Content-based Filtering)是一种基于项目特征的推荐方法。其基本思想是:如果用户喜欢某个项目,那么具有相似特征的其他项目也可能受到用户的喜爱。基于内容的推荐主要包括项目特征提取、用户兴趣建模和推荐生成三个步骤。
以电影推荐为例,我们可以将电影的特征分为导演、演员、类型、年代等。假设我们有一个电影-特征矩阵
F
∈
R
n
×
p
F \in \mathbb{R}^{n \times p}
F∈Rn×p,其中
p
p
p表示特征数,
F
i
j
F_{ij}
Fij?表示电影
i
i
i在第
j
j
j个特征上的取值。根据用户的历史行为,我们可以得到一个用户-特征偏好矩阵
P
∈
R
m
×
p
P \in \mathbb{R}^{m \times p}
P∈Rm×p,其中
P
i
j
P_{ij}
Pij?表示用户
i
i
i对特征
j
j
j的偏好程度。那么,用户
i
i
i对电影
j
j
j的兴趣可以表示为:
兴趣
(
i
,
j
)
=
∑
k
=
1
p
F
j
k
?
P
i
k
\text{兴趣}(i, j) = \sum_{k=1}^{p} F_{jk} \cdot P_{ik}
兴趣(i,j)=k=1∑p?Fjk??Pik?
根据计算得到的兴趣值,我们可以为用户推荐兴趣值最高的电影。
数据csv样例:movie_data2.csv
user_id,movie_id,rating,title,genre,release_year
1,1,5,"The Shawshank Redemption","Drama",1994
1,2,4,"The Godfather","Crime",1972
1,3,3,"Pulp Fiction","Crime",1994
1,4,2,"Forrest Gump","Drama",1994
2,1,4,"The Shawshank Redemption","Drama",1994
2,2,5,"The Godfather","Crime",1972
2,3,2,"Pulp Fiction","Crime",1994
2,5,4,"The Dark Knight","Action",2008
3,1,5,"The Shawshank Redemption","Drama",1994
3,6,4,"Inception","Sci-Fi",2010
3,7,3,"The Matrix","Sci-Fi",1999
4,2,4,"The Godfather","Crime",1972
4,4,5,"Forrest Gump","Drama",1994
4,5,3,"The Dark Knight","Action",2008
4,6,4,"Inception","Sci-Fi",2010
5,3,3,"Pulp Fiction","Crime",1994
5,7,4,"The Matrix","Sci-Fi",1999
5,8,5,"Fight Club","Drama",1999
实现代码如下:
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
# 假设df是已经读取的CSV数据,直接运行
df = pd.DataFrame({
'user_id': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3],
'movie_id': [1, 2, 3, 4, 1, 2, 3, 5, 1, 6, 7],
'rating': [5, 4, 3, 2, 4, 5, 2, 4, 5, 4, 3],
'title': ["The Shawshank Redemption", "The Godfather", "Pulp Fiction", "Forrest Gump",
"The Shawshank Redemption", "The Godfather", "Pulp Fiction", "The Dark Knight",
"The Shawshank Redemption", "Inception", "The Matrix"],
'genre': ["Drama", "Crime", "Crime", "Drama", "Drama", "Crime", "Crime", "Action", "Drama", "Sci-Fi", "Sci-Fi"],
'release_year': [1994, 1972, 1994, 1994, 1994, 1972, 1994, 2008, 1994, 2010, 1999]
})
print(df )
# 如果是读取movie_data.csv,可以根据以上数据构建出movie_data.csv
# data = pd.read_csv('movie_data.csv')
# df = data
# print(df )
# 构建一个用户-电影评分矩阵
user_movie_matrix = df.pivot_table(index='user_id', columns='movie_id', values='rating')
# 填充缺失值为0
user_movie_matrix = user_movie_matrix.fillna(0)
# 计算余弦相似度
user_similarity = cosine_similarity(user_movie_matrix)
# 转换为DataFrame以便查看
user_similarity_df = pd.DataFrame(user_similarity, index=user_movie_matrix.index, columns=user_movie_matrix.index)
# 找到与用户1最相似的用户
most_similar_users = user_similarity_df.loc[1].sort_values(ascending=False).index[1:] # 排除用户自己
# 找出这些用户评价较高的电影
recommended_movies = df[(df['user_id'].isin(most_similar_users)) &
~(df['movie_id'].isin(df[df['user_id'] == 1]['movie_id']))].groupby('movie_id').mean().sort_values(by='rating', ascending=False)
print(recommended_movies)
运行结果:
movie_id
5 2.0 4.0 2008.0
6 3.0 4.0 2010.0
7 3.0 3.0 1999.0