机器学习:推荐系统(六. 测试推荐系统)

目录

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的微小改进。

结语

下一章将介绍如何在现实生活中应用推荐系统 .

你的 关注-收藏-转发 是我继续分享的动力!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容