目录
1.浏览我们系统的推荐
2.使用正则
3.评估推荐准确率
1.浏览我们系统的推荐
现在我们有一个可用的产品推荐系统,让我们看看我们为不同的用户拿到了什么结果。我们来看看Chapter 6/make_recommendations.py。
# Load user ratings
raw_dataset_df = pd.read_csv('movie_ratings_data_set.csv')
# Load movie titles
movies_df = pd.read_csv('movies.csv', index_col='movie_id')
# Convert the running list of user ratings into a matrix
ratings_df = pd.pivot_table(raw_dataset_df, index='user_id',
columns='movie_id',
aggfunc=np.max)
# Apply matrix factorization to find the latent features
U, M = matrix_factorization_utilities.low_rank_matrix_factorization(ratings_df.as_matrix(),
num_features=15,
regularization_amount=0.1)
首先,我们将使用pandas的read csv命令读取数据集。我们还将使用read csv加载电影列表,所以我们也可以访问电影标题。然后,我们将使用pandas的pivot_table函数来创建审查矩阵,然后我们将审查矩阵分解以获得U和M矩阵。然后我们将乘以U和M来为每个用户创建预测评级。现在我们已经有了预测评分,我们可以做出预测。
# Find all predicted ratings by multiplying U and M matrices
predicted_ratings = np.matmul(U, M)
print("Enter a user_id to get recommendations (Between 1 and 100):")
user_id_to_search = int(input())
print("Movies previously reviewed by user_id {}:".format(user_id_to_search))
reviewed_movies_df = raw_dataset_df[raw_dataset_df['user_id'] == user_id_to_search]
reviewed_movies_df = reviewed_movies_df.join(movies_df, on='movie_id')
print(reviewed_movies_df[['title', 'genre', 'value']])
在这里,我们将提示输入用户ID,用户可以键入任何用户ID来查看针对不同用户的推荐。
在我们打印用户推荐的电影之前,让我们打印用户已经评价过的电影。
我们可以在原始数据集df数据框中查找它们。我们用pandas将列表筛选到用户ID与刚输入的用户相同的条目中。接下来,让我们将这个评论列表与电影df数据join起来,以便我们可以显示每个电影的详细信息。我们可以用pandas的join功能来做到这一点。现在我们将打印带有标题,流派,价值或用户给电影评分的评论电影列表。
现在我们来看看我们要推荐给这个用户的电影列表。
user_ratings = predicted_ratings[user_id_to_search - 1]
movies_df['rating'] = user_ratings
首先,让我们从预测评级列表中提取此特定用户的预测评级。我们需要在这里减去一个,因为这个数组是零索引,但用户ID从一开始。现在我们可以将每部电影的预测评级保存到电影列表中,以便于打印。在这一点上,我们有一个电影列表,每个电影的分数取决于用户的喜好程度,但我们不想显示用户已经评分过的电影。所以我们需要从列表中排除那些电影。
already_reviewed = reviewed_movies_df['movie_id']
recommended_df = movies_df[movies_df.index.isin(already_reviewed) == False]
recommended_df = recommended_df.sort_values(by=['rating'], ascending=False)
print(recommended_df[['title', 'genre', 'rating']].head(5))
我们可以获得用户已经看过的电影ID列表,并将其保存到一个名为“already_reviewed”的变量中。然后,我们将看看不在该列表中的电影。这行代码有点复杂。首先,我们使用is函数来查找列表中的电影,然后我们将该列表与false进行比较,以将其反转并找到不在该列表中的电影。然后,我们可以使用排序值对列表进行排序,以便评级最高的电影是第一个。最后,我们可以使用pandas的head功能打印列表中的前五个电影。
让我们来运行代码。
让我们输入用户2,然后回车。这是用户ID 2已经评分的电影。我们可以看到用户给科幻,神秘,惊悚和戏剧电影五颗星。注意,这个用户给了大城市法官1和警长1五颗星。现在让我们按回车,看看我们的系统有什么推荐。
好的,这五部电影看起来很不错。这些建议中有三个甚至是用户评价很高的电影续集。
它看起来像一切工作得很好。您可以尝试使用不同的用户ID系统,看看你得到什么样的结果。
2.使用正则
在我们的推荐系统中,我们采用评论数据,并从中提取用户属性和电影属性作为模型。使用这个模型,我们可以提出建议。构建像这样的模型时可能发生的常见问题称为过度拟合。过度拟合是指模型没有学习数据的整体模式,而是在取了太多的特定数据点。我们来举个例子来解释一下。
想象一下,我们有两部电影。第一部电影是恐怖喜剧。第二个是严肃的血腥恐怖片,根本没有喜剧。两部电影都有恐怖元素,但一些观众可能更喜欢有趣的电影,而其他观众可能更喜欢这部严肃的电影。
一个好的推荐系统将能把这两部电影分开,看看这两部电影有着相似的元素,但却是截然不同的电影,吸引了不同的观众。一个糟糕的推荐系统会过度配合,完全将注意力放在恐怖的属性上,而忽视其他的一切。那个系统会提出更糟糕的建议,因为它会把电影推荐给任何喜欢恐怖的人。它会忽略使这两部电影独一无二的其他属性。为了防止这种情况,我们使用正则化。正则化限制了用矩阵分解查找用户或电影属性时,我们将设置在单个属性上的权重。
我们设置的正则化量越高,我们将放在任何单个属性上的权重就越小。这有助于我们识别出恐怖喜剧中恐怖和喜剧两种元素。
到目前为止,我们在代码中使用了0.1的正则化数量。这适用于较小的数据集,就像我们在这里少于100个产品一样。但是,对于具有数千个产品的更大的数据集,您应该使用更大的值。当您使用自己的数据集建立推荐系统时,您需要尝试使用不同的正则化值来了解它是如何影响推荐的质量的。
在下一节中,我们将学习如何衡量模型的性能。当试验不同的正则化设置时,这将会有非常大的帮助。
3.评估推荐准确率
我们如何知道我们用推荐系统预测的电影评分是正确的?为了衡量我们的预测的准确性,我们将使用称为均方根误差或RMSE(Root-Mean-Square-Error)的标准统计量度。 RMSE是衡量用户的真实电影评级与我们为同一部电影预测的评级之间的差异。 RMSE越低,模型越精确。 RMSE为零意味着我们的模型完美地猜测用户评分。RMSE等于1,意味着当预测用户评级时,我们平均只有一颗星。
在衡量我们的推荐系统的准确性时,我们需要确保我们用来验证系统的数据是系统从未见过的数据。否则,这不是一个公平的测试。所以,我们将我们的电影评级数据随机分成两组,前70%的数据将成为我们的训练数据集。我们将使用训练数据集来进行矩阵分解,并创建U和M矩阵。另外30%的数据将作为测试数据集保留下来。我们将使用测试数据集来检查系统如何对数据进行预测,这是以前从未见过的数据。
我们来看一下measure_accuracy.py
# Load user ratings
raw_training_dataset_df = pd.read_csv('movie_ratings_data_set_training.csv')
raw_testing_dataset_df = pd.read_csv('movie_ratings_data_set_testing.csv')
# Convert the running list of user ratings into a matrix
ratings_training_df = pd.pivot_table(raw_training_dataset_df, index='user_id', columns='movie_id', aggfunc=np.max)
ratings_testing_df = pd.pivot_table(raw_testing_dataset_df, index='user_id', columns='movie_id', aggfunc=np.max)
# Apply matrix factorization to find the latent features
U, M = matrix_factorization_utilities.low_rank_matrix_factorization(ratings_training_df.as_matrix(),
num_features=11,
regularization_amount=1.1)
我已经把数据集分成了两个不同的文件,movie_ratings_data_set_training.csv有70%的评论,而movie_ratings_data_set_testing.csv有另外的30%。我们将使用pandas的read_CSV功能将两个文件加载到单独的数据框中。接下来,我们将使用Panda的pivot_table函数为训练数据和测试数据创建单独的评分矩阵。然后,我们将只对训练数据进行矩阵分解。
然后,我们将乘以U和M来获得预测评级。
现在,我们可以使用RMSE函数和矩阵分解工具来计算错误率。要使用这个函数,我们只需要传入我们想要比较的两个数组。
# Apply matrix factorization to find the latent features
U, M = matrix_factorization_utilities.low_rank_matrix_factorization(ratings_training_df.as_matrix(),
num_features=11,
regularization_amount=1.1)
# Find all predicted ratings by multiplying U and M
predicted_ratings = np.matmul(U, M)
# Measure RMSE
rmse_training = matrix_factorization_utilities.RMSE(ratings_training_df.as_matrix(),
predicted_ratings)
rmse_testing = matrix_factorization_utilities.RMSE(ratings_testing_df.as_matrix(),
predicted_ratings)
print("Training RMSE: {}".format(rmse_training))
print("Testing RMSE: {}".format(rmse_testing))
首先,我们将训练数据与预测评分进行比较,我们在训练数据框架上调用as_matrix,所以它作为num.py矩阵数据类型被传入。然后,我们还将测试数据与预测评分进行比较,最后我们可以打印出两个数字。让我们运行代码,看看我们得到了什么样的结果。
好吧,我们得到了0.24的training-RMSE和约1.2的testing-RMSE。低的training-RMSE表明我们的基本算法正在工作,testing-RMSE是更重要的数字,因为它告诉我们预测到底如何。得分为1.2意味着我们的系统在预测用户的评分时得分很少。我们可以做的一件事就是调整正则化量参数。然而,这是一个折衷,正规化将提高训练分数,但可能会降低测试分数。
我们在这个例子中有一个局限性,就是我们只有几百个电影评论可供使用,在这种情况下我们可以做的最好的事情就是获得更多的用户评论。更多的电影评论会给我们的系统提供更多的信息,所以它可以做得更好。在构建自己的建议系统时,RMSE是查看系统运行状况的有用工具,但RMSE不是最后的评定。推荐系统的终极测试是用户喜欢他们得到的建议。因此,如果实际上并没有改善用户体验,那么不要担心RMSE的微小改进。
结语
下一章将介绍如何在现实生活中应用推荐系统 .
你的 关注-收藏-转发 是我继续分享的动力!
网友评论