推荐算法学习记录2.2——kaggle数据集的动漫电影数据集推荐算法实践——基于内容的推荐算法、协同过滤推荐

1、基于内容的推荐

这种方法根据项的相关信息(如描述信息、标签等)和用户对项的操作行为(如评论、收藏、点赞等)来构建推荐算法模型。它可以直接利用物品的内容特征进行推荐,适用于内容较为丰富的场景。‌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#1. 基于内容的推荐算法

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel
import pandas as pd


anime = pd.read_csv('./data/archive_2/anime.csv')

# 使用TF-IDF向量化
tfidf = TfidfVectorizer(stop_words='english')
tfidf_matrix = tfidf.fit_transform(anime['Genres'].fillna(''))

# 计算每个动漫之间的余弦相似度
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)

# 创建一个动漫名字到索引的映射
indices = pd.Series(anime.index, index=anime['Name']).drop_duplicates()

# 推荐函数
def content_based_recommendations(title, cosine_sim=cosine_sim):
idx = indices[title]
sim_scores = list(enumerate(cosine_sim[idx]))
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
sim_scores = sim_scores[1:11]
anime_indices = [i[0] for i in sim_scores]
return anime['Name'].iloc[anime_indices]

# 示例:推荐与"Cowboy Bebop"相似的动漫
print(content_based_recommendations('Cowboy Bebop'))

结果如下:

2、协同过滤推荐

这种方法通过分析用户的历史行为和偏好,找出具有相似兴趣的用户群体,然后推荐他们喜欢的物品或内容。协同过滤是一种常见的推荐系统技术,它基于用户的历史行为(例如评分、点击、购买等)来预测用户可能感兴趣的物品。协同过滤主要有两种类型:基于用户的协同过滤和基于物品的协同过滤。

基于用户的协同过滤推荐通过寻找具有相似兴趣的用户来推荐,

基于物品的协同过滤推荐通过寻找具有相似特征的物品来推荐。‌

基于用户的协同过滤

  1. 计算用户相似度

    • 找出与目标用户相似的用户。
    • 常用的相似度度量方法包括余弦相似度、皮尔逊相关系数等。
    • 余弦相似度公式:
    • 其中 u 和 v 是两个用户的评分向量。
  2. 推荐物品:

    • 找出相似用户喜欢但目标用户未评分的物品。
    • 根据相似用户的评分来预测目标用户对这些物品的评分。
    • 推荐评分最高的物品给目标用户.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
from scipy.sparse import csr_matrix
import numpy as np


batch_size = 10000 # 由于内存不够,一次处理10000条信息
num_recommendations = 10 # 推荐10个电影


def process_batch(batch_df, user_item_matrix):
# 将当前批的数据合并到全局用户-项目矩阵
batch_pivot = batch_df.pivot(index='user_id', columns='anime_id', values='rating').fillna(0)
# 合并到全局矩阵
user_item_matrix = user_item_matrix.add(batch_pivot, fill_value=0)
return user_item_matrix

# 计算用户之间的相似度
def calculate_similarity(user_item_matrix):
# 转换为稀疏矩阵
sparse_user_item_matrix = csr_matrix(user_item_matrix)
# 计算相似度
user_similarity = cosine_similarity(sparse_user_item_matrix)
user_similarity_df = pd.DataFrame(user_similarity, index=user_item_matrix.index, columns=user_item_matrix.index)
return user_similarity_df

# 生成推荐
def user_based_recommendations(user_id, user_item_matrix, user_similarity_df, anime_df, num_recommendations=10):
if user_id not in user_item_matrix.index:
raise ValueError(f"用户ID {user_id} 不在数据中")

# 获取相似用户
similar_users = user_similarity_df[user_id].sort_values(ascending=False).index[1:]

if len(similar_users) == 0:
return []

# 获取相似用户的评分数据
similar_users_ratings = user_item_matrix.loc[similar_users]

# 计算推荐得分
scores = similar_users_ratings.mean(axis=0).sort_values(ascending=False)

# 获取当前用户已经评分的动漫
user_watched_animes = user_item_matrix.loc[user_id]
user_watched_animes = user_watched_animes[user_watched_animes > 0].index

# 排除当前用户已经看过的动漫
recommendations = scores.drop(user_watched_animes, errors='ignore')

# 获取前num_recommendations个推荐
top_recommendations = recommendations.head(num_recommendations).index

# 确保推荐的动漫在anime数据集中
top_recommendations = top_recommendations[top_recommendations.isin(anime_df['MAL_ID'])]

# 获取推荐的动漫名称
recommended_animes = anime_df[anime_df['MAL_ID'].isin(top_recommendations)]['Name'].values

return recommended_animes


def main():

anime_df = pd.read_csv('./data/archive_2/anime.csv')
user_item_matrix = pd.DataFrame()
for chunk in pd.read_csv('./data/archive_2/rating_complete.csv', chunksize=batch_size):
user_item_matrix = process_batch(chunk, user_item_matrix)

# 计算用户之间的相似度
user_similarity_df = calculate_similarity(user_item_matrix)

# 为用户0推荐动漫
recommended_animes = user_based_recommendations(0, user_item_matrix, user_similarity_df, anime_df, num_recommendations)
print("推荐动漫:", recommended_animes)

if __name__ == "__main__":
main()

基于物品的协同过滤

  1. 计算物品相似度

    • 找出与目标物品相似的物品。
    • 常用的相似度度量方法同样包括余弦相似度、皮尔逊相关系数等。
    • 余弦相似度公式:
    • 其中 i 和 j 是两个物品的评分向量。
  2. 推荐物品

    • 根据用户对相似物品的评分来预测用户对目标物品的评分。
    • 推荐评分最高的物品给用户。

协同过滤算法的优缺点

优点
  1. 无需领域知识
    :协同过滤仅依赖于用户的历史行为数据,不需要对物品本身有深入的了解。
  2. 个性化推荐
    :能够根据用户的兴趣和行为进行个性化推荐,效果较好。
  3. 简单直观
    :算法相对简单,易于实现和解释。
缺点
  1. 数据稀疏性
    :在实际应用中,用户对大多数物品没有评分,这会导致评分矩阵非常稀疏,影响推荐效果。
  2. 冷启动问题
    :对于新用户或新物品,由于缺乏历史数据,协同过滤很难做出准确的推荐。
  3. 扩展性差
    :当用户和物品数量增加时,计算相似度的开销会显著增加,影响系统性能。

冷启动问题

冷启动问题是指在推荐系统中,无法为新用户或新物品提供高质量的推荐。这是协同过滤算法面临的主要挑战之一。解决冷启动问题的方法包括:

  1. 新用户冷启动

    • 问卷调查
      :在用户注册时,通过问卷调查获取用户的兴趣偏好。
    • 使用社交网络数据
      :利用用户的社交网络数据,推测用户的兴趣。
    • 混合推荐
      :结合内容过滤或基于知识的推荐方法,使用用户的属性和特征进行推荐。
  2. 新物品冷启动

    • 内容过滤
      :利用物品的内容信息(如标签、描述等)进行推荐。
    • 使用上下文数据
      :利用物品的上下文数据,如发布日期、类型等,进行推荐。
    • 混合推荐
      :结合协同过滤与内容过滤,通过物品的内容特征和已有的少量用户反馈进行推荐。