机器学习:推荐系统(四. 创建推荐系统框架)

Building the Framework for Our Recommendation System

目录

  1. 浏览推荐系统数据集
  2. 以矩阵显示产品评价
    3.通过预测缺少的用户评级推荐
    4.预测缺失用户评分的简单方法

1. 浏览推荐系统数据集

我们项目的用户评论数据在一个名为movie_ratings_data_set.csv的文件中。我们也有movies.csv中的电影标题列表。这两个文件都是简单的逗号分隔数据,您可以在任何电子表格程序(如Microsoft Excel)中打开这些数据。但是数据集通常太大而无法直接打开,所以我们将使用Python来预览数据。我们来看看view_data.py.

import pandas
import webbrowser
import os

# Read the dataset into a data table using Pandas
data_table = pandas.read_csv("movie_ratings_data_set.csv")

# Create a web page view of the data for easy viewing
html = data_table[0:100].to_html()

# Save the html to a temporary file
with open("data.html", "w") as f:
    f.write(html)

# Open the web page in our web browser
full_filename = os.path.abspath("data.html")
webbrowser.open("file://{}".format(full_filename))

首先,我们使用pandas.read_csv命令将数据集加载到数据表中。数据表类似于电子表格。它与电子表格一样具有列和行,您可以使用电子表格对数据执行许多相同的操作。

接下来,我们将抓取前100行的数据,然后我们将使用pandas的html功能将数据转换为网页。pandas提供了很多这样的辅助功能,以方便查看您的数据。接下来,我们将html数据写出到一个文件中,然后我们将使用Python的内置Web浏览器模块在我们的Web浏览器中打开它。这使我们很方便的查看数据。让我们来看看前100行。右键单击,选择运行。此数据集中的每一行都是由一个用户输入的一个电影评级。

第一列是进行评分的用户的ID。第二列是用户评分的电影ID。第三列是用户给电影的评价。每个评分是从一到五,一是最差的,五是最好的。我们还有第二个数据文件,在movies.csv中列出了每个电影的名称。让我们来看看view_movie_list.py中的代码。

import pandas
import webbrowser
import os

# Read the dataset into a data table using Pandas
data_table = pandas.read_csv("movies.csv", index_col="movie_id")

# Create a web page view of the data for easy viewing
html = data_table.to_html()

# Save the html to a temporary file
with open("movie_list.html", "w") as f:
    f.write(html)

# Open the web page in our web browser
full_filename = os.path.abspath("movie_list.html")
webbrowser.open("file://{}".format(full_filename))

这个代码几乎和我们刚刚看到的代码一样。唯一的区别是我们将索引调用参数传递给pandas 的read csv函数。这告诉pandas使用已经在数据中的字段movie_id作为索引,而不是添加它自己的索引列。
让我们运行脚本,看看电影列表。


这是所有电影及其数据集的列表。每部电影都有一个ID和一个标题。另外,我们还为每部电影列出了流派。我们实际上不会在建议中使用流派信息,但是看到这些信息可以更好地了解推荐系统推荐的电影种类。当你开始一个新的推荐项目时,最好是直观地看一下数据,确保你明白你需要使用哪些数据

2. 以矩阵显示产品评价

我们的电影评论数据集包含每个评级的一行。这是通常收集审查数据的格式,但是为了通过这些数据构建推荐系统,我们希望创建一个矩阵或二维数组,以显示哪些用户已经对哪些电影进行了评级。该矩阵将以每个用户为一行,每个电影为一列。我们来看看create_review_matrix.py中的代码。

import pandas as pd
import numpy as np
import os
import webbrowser

# Read the dataset into a data table using Pandas
df = pd.read_csv("movie_ratings_data_set.csv")

# Convert the running list of user ratings into a matrix using the 'pivot table' function
ratings_df = pd.pivot_table(df, index='user_id', columns='movie_id', aggfunc=np.max)

# Create a web page view of the data for easy viewing
html = ratings_df.to_html(na_rep="")

# Save the html to a temporary file
with open("review_matrix.html", "w") as f:
    f.write(html)

# Open the web page in our web browser
full_filename = os.path.abspath("review_matrix.html")
webbrowser.open("file://{}".format(full_filename))

首先,我们将使用Pandas的read_csv函数来加载movie_ratings_data_set.csv文件。该评级对于每个单独的电影评论都有一行。为了将其转化为汇总所有电影中的所有评论的矩阵,我们需要使用Pandas数据透视表功能(pivot_table)。
数据透视表采用数据列表,并对每个唯一用户和我们数据集中唯一的影片用一行一列进行汇总。如果您在电子表格软件(如Microsoft Excel)中使用了数据透视表,则其工作原理与此处完全相同。首先我们传入包含我们想要总结的数据的数据框(data frame)。然后,我们需要告诉Pandas在数据透视表中为行或索引使用用户ID字段,而电影ID是表中的列。
使用数据透视表汇总数据时,可能会出现重复的情况。
如果同一个用户看过同一部电影两次,就会发生这种情况,但给了它两个不同的评级。所以我们必须通过告诉Pandas使用哪个函数来聚合重复的数据来决定如何解决重复的问题。我们将传入名为aggfunc = np.max的参数。这告诉Pandas使用NumPy的取最大功能来处理重复。取最大的功能将返回最高的数字,所以如果一个用户对同一部电影进行两次评级,我们将采取较高的评级。如果您想要用户的平均评分,则可以传入np.mean。最后,我们将把这个表格转换成HTML并在我们的浏览器中打开它。

让我们运行代码。

此表是所有电影中所有评论的摘要。用户列在左边,电影在上面。例如,我们可以看到,空白区域是尚未被用户评级的电影。如果我们滚动整个数据集,我们可以看到没有一个用户对每一部电影进行评级,实际上大部分数组都是空白的。我们只有相对少量的良好数据可供使用。这被称为稀疏数据集。
推荐系统的稀疏数据集是正常的。大多数用户只会查看少量的产品,所以总是会有大量的空白数据,但这些信息足以让我们开工。

3.通过预测缺少的用户评级来推荐

让我们来看看create_review_matrix_as_csv.py。

import pandas as pd
import numpy as np

# Read the dataset into a data table using Pandas
df = pd.read_csv("movie_ratings_data_set.csv")

# Convert the running list of user ratings into a matrix using the 'pivot table' function
ratings_df = pd.pivot_table(df, index='user_id', columns='movie_id', aggfunc=np.max)

# Create a csv file of the data for easy viewing
ratings_df.to_csv("review_matrix.csv", na_rep="")

此代码将生成csv文件。首先我们使用pandas的read_csv函数加载数据。然后我们使用熊猫的pivot_table函数来创建审阅矩阵。最后,我们将使用pandas的to_csv函数将结果保存为csv文件。

每个用户为一行,每个电影为一列。每个数字代表用户输入的评论。空白表示还没有被用户看过的电影。试想一下,如果我们能够根据我们所知道的数字找出填补所有空白空间的方法。例如,让我们看看用户3。我们可以看到,用户3对电影1和电影2给了四颗星,对电影3给了5颗星。如果我们可以利用我们所知道的评分和其他用户的评分来填写这个用户最可能评价电影4的数据呢?一旦我们知道用户将给予电影的评级,就知道我们是否应该推荐该电影。
如果我们认为这个用户会给电影4号来个五星评级,这是一个我们一定要推荐给这个用户的电影。所以为了建立一个推荐系统,我们真正需要的是一个算法,帮助我们根据我们已经知道的数字来完成矩阵中所有缺失的空白。如果我们可以填充矩阵中的每一个空白,用户就会给出这部电影的评分,那么我们就会知道每一个用户需要知道的一切。

4.预测缺失用户评分的简单方法

如果我们可以填写用户评论矩阵中的所有空白,我们将知道每个用户如何评价每部电影。那么,我们可以使用这些信息来推荐高度评价的电影。

下面让我们学习如何手动完成这个矩阵,假设我们有每个用户和每部电影的额外信息。这将教会我们用来计算每个用户对每部电影的兴趣的基本思想。要了解如何预测用户的评分,让我们先来思考一下某人如何决定给予电影什么评级。每个人都是独一无二的可能没有办法完全理解某个评级的思维过程。因此,让我们假设一个用户的评级是一个特定电影对该用户独特兴趣集的吸引力的反映。

这给了我们一个计算用户评分的方法。首先,我们将创建一个关于电影指数的模型。然后,我们将制作一个用户特定兴趣的模型。最后,我们可以根据用户的兴趣与电影的匹配程度来计算用户的评分。让我们从电影类型建模开始。
我们可以用什么来描述不同类型的电影?让我们从这五个开始,一个动作指数评级,一个剧情指数评级,一个浪漫指数评级,一个文艺指数评级,和一个大众指数评级。
现在我们有一个属性列表,我们可以浏览我们的数据库中的电影,并给每个电影在这些指数上从-5到5的评级。让我们从一个名为[地球大战](Attack on Earth)片子开始吧。我们假设这是一个动作和科幻冒险片,一个典型的夏天大片,所以我们给它的评级:

动作指数:5
剧情指数:-2
浪漫指数:-2
文艺指数:-5
大众指数:4

第二部电影是关于一个慢节奏剧情的片子[my complicated family],所以我们给它评级是:

动作指数:5
剧情指数:5
浪漫指数:1
文艺指数:4
大众指数:5

这些评级是主观的,但我们会尽最大努力在不同的电影中尽可能一致地分级。现在我们有电影的分数,我们需要模拟用户的兴趣。我们使用相同的类别为每个用户建模。我们将根据每个用户的兴趣在这些类别中的强度分配给每个用户一个分数。为了得到这些分数,我们可以给每个用户做个个性测验。我们将使用个性测验的结果来捕捉用户喜欢在电影中出现的每个特征。例如,如果我们问用户,“你有多喜欢爆炸场面?他们回答说:“非常喜欢”,我们可能会给他们5分在动作片上。
这个测验将帮助我们想出一个用户的偏好将如何映射到这些属性的想法。让我们假设在给出个性测验后,我们得到了这些结果:

动作指数:5
剧情指数:-2
浪漫指数:1
文艺指数:5
大众指数:5

让我们看看哪个电影是这个用户的最佳匹配。

对于第一部电影,我们将每个用户的评分乘以电影评分。这会给我们每个属性的分数。然后我们将这些分数加起来,得到总分74分。现在,让我们为第二部电影做同样的事情。

这次,当我们把这些属性分数加在一起,总共得到-79分。这是最后的结果。用户的兴趣与74分的得分相匹配。第二部电影的得分是-79,所以根据我们简单的属性评分系统,相比第二部电影用户更喜欢第一部电影,因为它更接近他们的偏好。如果我们为每个电影中的每个用户重复这个过程,我们可以计算出如何估计我们评论矩阵中的每个评分.

如果你熟悉线性代数,你可能会意识到我们如何将这个问题表示为矩阵乘法。如果你毕业的时候都把所学的线代知识还给老师了, 也没关系,跟着我一起来。在线性代数术语中,我们定义了一个名为U的用户矩阵,其中包含用户属性,这里是5,-2,1,-5和5。

然后,我们还定义了一个电影属性矩阵M,其中每列包含一个电影的评级。如果我们对这两个矩阵进行矩阵乘法,它会给我们每部电影的总评分。下面是结果,


74,-79.
数学运算没啥变化,但现在我们可以使用numpy来计算这一行代码,因为这是一个标准的矩阵乘法运算。Numpy是经过优化的, 可以并行计算这些矩阵。

结语

在本章,我们学会了如何估计用户喜欢电影的程度,如果我们知道用户的兴趣以及电影对这些兴趣的吸引程度。问题是很难以同样的方式为更多的电影和用户分配属性评级。在下一章中,我们将学习如何自动提取兴趣属性,而不必手动分配它们.

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

推荐阅读更多精彩内容