一、说明
推荐系统,通常称为推荐引擎或简称为“推荐”,是一种算法,旨在根据用户过去的行为、偏好和互动来预测和推荐用户可能感兴趣的项目。它们已成为在线购物体验不可或缺的一部分,影响着我们的购买决策并推动了企业的销售。
在本文中,我们将深入探讨推荐系统的迷人世界,并探讨如何使用 Python 构建一个推荐系统。我们将揭示这些系统的内部工作原理,从数据收集和预处理到算法选择和实现。
在此旅程结束时,您将拥有创建有效推荐系统的知识和工具,以满足您的电子商务平台的独特需求,最终推动增长和客户满意度。
二、加载数据集
我们将从 Kaggke 获取一个数据集来探索该主题,您可以在此处找到该数据集:Book Recommendation Dataset | Kaggle
- 首先要做的是使用 Pandas 加载数据
import pandas as pd
ratings = pd.read_csv(r'Data/ratings.csv')
三、筛选数据
- 我们的数据集太大了,我们将过滤掉评分很少的书籍,至少有 6 个评分,我们将为用户做同样的事情。
- 我们还将删除 0 的评分,假设人们没有投票。
- 然后我们将所有内容存储在一个新的
#Books
min_book_ratings = 5
filter_books = ratings['ISBN'].value_counts() > min_book_ratings
filter_books = filter_books[filter_books].index.tolist()
#Users
min_user_ratings = 5
filter_users = ratings['User-ID'].value_counts() > min_user_ratings
filter_users = filter_users[filter_users].index.tolist()
ratings_filtered = ratings[(ratings['ISBN'].isin(filter_books)) & (ratings['User-ID'].isin(filter_users))]
ratings_filtered = ratings[ratings['Book-Rating'] > 0]
四、构建模型
我们将使用“Surprise”,一个 Python scikit,用于构建和分析处理显式评级数据的推荐系统。
我们需要定义 Reader 并根据 “Surprise” 注解来格式化数据集:
- Surprise 中的 Reader 类用于分析包含评级的文件或 DataFrame。读取器的主要用途是定义数据集中评级的比例。这很重要,因为它有助于算法了解如何以数字方式解释评级。
- 数据是指您用于推荐系统的数据集,通常以用户与项目交互的形式(例如用户对书籍、电影等的评分)
from surprise import Reader, Dataset
reader = Reader(rating_scale=(0, 10))
data = Dataset.load_from_df(ratings_filtered[['User-ID', 'ISBN', 'Book-Rating']], reader)
经典:将数据拆分为训练集和测试集,避免过度拟合
from surprise.model_selection import train_test_split
trainset, testset = train_test_split(data, test_size=0.25)
对于模型选择,您可以从 Surprise 中包含的不同模型中进行选择,我将使用 SVD(奇异值分解)并使用网格搜索 CV 来查找最佳参数。
有关 SVD 👉🏼 Welcome to Surprise’ documentation! — Surprise 1 documentation 的更多信息。
超参数怎么样
- n_factors :表示从用户-项矩阵派生的潜在因子(或特征)的数量。虽然数据集主要由用户 ID、ISBN 和图书评级组成,但它本质上隐藏着关于不同用户如何评估不同书籍的属性或趋势。这些隐藏的属性被称为潜在因素。
- n_epochs :这表示整个训练数据集的迭代次数。在每个纪元期间,算法都会更新参数(用户和项目特征)以最大程度地减少预测误差。
- lr_all(学习率):学习率决定了训练过程中基于预测误差的模型调整程度。更高的学习率意味着更快的学习速度,模型在每次迭代中都会显着更新其参数。但是,这可能会导致诸如超过最佳解决方案或围绕它振荡等问题!
- reg_all (正则化术语) : 正则化通过对较大的模型参数施加惩罚来防止过度拟合,起着至关重要的作用。
我们将输入各种参数,并根据最低RMSE(均方根误差)结果显示最佳参数。请注意,RMSE 表示预测值与实际值之间的平均平方差。
from surprise import SVD
from surprise.model_selection import GridSearchCV
param_grid = {
'n_factors': [1,3,5,10,15],
'n_epochs': [20,30,40],
'lr_all': [0.005, 0.01],
'reg_all': [0.02, 0.1]
}
gs = GridSearchCV(SVD, param_grid, measures=['rmse'], cv=3)
gs.fit(data)
print("Best RMSE: ", gs.best_score['rmse'])
print("Best parameters: ", gs.best_params['rmse'])
过了一会儿。图片来源 : https://www.pinterest.com/pin/a-few-moments-later--677088125250940487/
我们得到的结果:
- 最高 RMSE:1.63;虽然该值可能看起来相对较高,但考虑到我们使用的规模,它仍然在可接受的范围内。
- 最佳参数: {'n_factors': 1, 'n_epochs': 30, 'lr_all': 0.005, 'reg_all': 0.1}
现在👇🏼让我们训练我们的模型
model = SVD(n_factors=1, n_epochs=30, lr_all=0.005, reg_all=0.1)
model.fit(trainset)
五、 构建函数以获得推荐
我们将开发一个函数来提取不同 ISBN 的列表,识别用户过去评分的项目,并为用户尚未评分的所有 ISBN 生成预测。
最终,我们将相应地安排这些预测。请记住,变量“n”表示我们在此上下文中要考虑的项目数量。
def get_recommendations(user_id, model, data, n=3):
unique_isbns = data.df['ISBN'].unique()
rated_isbns = data.df.loc[data.df['User-ID'] == user_id, 'ISBN']
predictions = [model.predict(user_id, isbn) for isbn in unique_isbns if isbn not in rated_isbns]
top_predictions = sorted(predictions, key=lambda x: x.est, reverse=True)[:n]
return top_predictions
- 让我们以用户 ID “276725” 为例
user_id_example = 276725
top_predictions = get_recommendations(user_id_example, model, data, n=3)
for pred in top_predictions:
print(f'ISBN: {pred.iid}, Predicted Rating: {pred.est}')
但是,我们也想显示书名!为此,我们需要引用 Kaggle 数据集中名为“Books”的补充表,其中包含每个 ISBN 的相应书名。
首先,让我们阅读数据,将注意力缩小到两列:['ISBN', 'Book-Title']。
books = pd.read_csv(r'Data/Books.csv', usecols=['ISBN', 'Book-Title'])
现在让我们构建函数:
- 提取每个预测对象的 ISBN 和预测评级。
- 使用提取的数据创建 DataFrame。
- 将 DataFrame 与书籍数据集合并以添加标题。
- 从 DataFrame 中检索书名和预测评级。
def map_isbn_to_titles(top_predictions, books):
isbn_ratings = [(pred.iid, pred.est) for pred in top_predictions]
top_preds_df = pd.DataFrame(isbn_ratings, columns=['ISBN', 'Predicted_Rating'])
recommendations = top_preds_df.merge(books[['ISBN', 'Book-Title']], on='ISBN', how='inner')
return recommendations[['Book-Title', 'Predicted_Rating']]
让我们用我们之前使用上述函数的预测示例来说明这一点,这是我们的结果!
top_recommendations_with_titles = map_isbn_to_titles(top_predictions, books)
for _, row in top_recommendations_with_titles.iterrows():
print(f"Title: {row['Book-Title']}, Predicted Rating: {row['Predicted_Rating']:.2f}")
总之,使用机器学习构建推荐系统为增强用户体验和推动电子商务领域的业务成功开辟了令人兴奋的可能性。
凭借从此旅程中获得的知识和工具,您已经做好了充分的准备,可以开始自己的推荐系统项目,并根据您的平台和受众的独特需求进行定制。祝您推荐愉快!