提交 71928801 编写于 作者: W wizardforcel

2021-02-22 21:41:51

上级 81d7ec1d
......@@ -2,7 +2,7 @@
让我们谈谈我个人的专业领域-推荐系统,这样的系统可以根据其他人的建议向人们推荐东西。 我们将看一些这样的示例以及几种实现方法。 具体来说,两种技术称为基于用户的协作过滤和基于项目的协作过滤。 所以,让我们深入。
我的职业生涯大部分时间都在[这个页面](http://amazon.com)[imdb.com](http://imdb.com)度过,在那儿我做的很多事情都是开发推荐系统。 像*的人也买了**为您推荐的东西*,以及为人们推荐电影的东西。 因此,这是我个人非常了解的一些事情,希望与您分享一些知识。 我们将逐步介绍以下主题:
我的职业生涯大部分时间都在[这个页面](http://amazon.com)[imdb.com](http://imdb.com)度过,在那儿我做的很多事情都是开发推荐系统。 像*购买此商品的人也买了**为您推荐的东西*,以及为人们推荐电影的东西。 因此,这是我个人非常了解的一些事情,希望与您分享一些知识。 我们将逐步介绍以下主题:
* 什么是推荐系统?
* 基于用户的协同过滤
......@@ -17,9 +17,9 @@
![](img/e3f5a477-dc07-4d71-91b0-2e162b81c327.png)
推荐系统可能包括您已评分或购买的内容以及其他数据。 我无法透露细节,因为它们会追捕我,而且您知道,对我做坏事。 但是,这很酷。 您还可以想到购买了*的人,同时也在亚马逊上购买了*功能作为推荐系统。
推荐系统可能包括您已评分或购买的内容以及其他数据。 我无法透露细节,因为它们会追捕我,而且您知道,对我做坏事。 但是,这很酷。 您还可以想到*购买了该商品的人,同时也在亚马逊上购买了*功能作为推荐系统。
所不同的是,您在亚马逊推荐页面上看到的推荐是基于您过去的所有行为,而购买此商品的*人也购买了**人也查看了* ,诸如此类的事情,只是基于您当前正在查看的内容,并向您显示您可能也感兴趣的类似内容。事实证明,您现在正在做的是 无论如何,这可能是您最感兴趣的信号。
所不同的是,您在亚马逊推荐页面上看到的推荐是基于您过去的所有行为,而*购买此商品的人也购买了**也查看了*,诸如此类的事情,只是基于您当前正在查看的内容,并向您显示您可能也感兴趣的类似内容。事实证明,您现在正在做的是 无论如何,这可能是您最感兴趣的信号。
另一个示例来自 Netflix,如下图所示(下图是 Netflix 的屏幕截图):
......@@ -59,7 +59,7 @@
* 另一个问题是,系统中的人数通常比系统中的人数要多。因此,全世界有 70 亿,而且还在继续增长,全世界可能没有 70 亿部电影,或者您可能不推荐 70 亿部电影 您的目录。 查找系统中所有用户之间的所有相似性的计算问题可能比查找系统中项目之间的相似性的问题要大得多。 因此,通过将系统聚焦于用户,您将使计算问题变得比原本要困难得多,因为您有很多用户,至少希望您为一家成功的公司工作。
* 最终的问题是人们做坏事。 有一种非常真实的经济动机来确保您的产品或电影或任何推荐的产品被推荐给人们,并且有些人试图通过游戏系统来实现他们的新电影,新产品或新产品的实现。 新书或其他内容。
通过创建新用户并让他们进行一系列喜欢很多受欢迎的物品然后又喜欢您的物品的事件,在系统中制造假角色很容易。 这就是所谓的**先攻击**,我们理想情况下希望拥有一个可以应对这种情况的系统。
通过创建新用户并让他们进行一系列喜欢很多受欢迎的物品然后又喜欢您的物品的事件,在系统中制造假角色很容易。 这就是所谓的**先攻击**,我们理想情况下希望拥有一个可以应对这种情况的系统。
关于如何在基于用户的协同过滤中检测和避免这些先发攻击的研究很多,但是一个更好的方法是使用完全不同的方法,这种方法不太容易受到系统游戏的影响。
......@@ -87,7 +87,7 @@
所以,假设我有一对电影,好吗? 也许是《星球大战》和《帝国反击》。 我找到了所有看过这两部电影的人的名单,然后将它们的收视率进行了比较,如果它们相似,那么我可以说这两部电影是相似的,因为看过这两部电影的人对它们的评分相似 。 这是这里的总体思路。 那是做到这一点的一种方式,而不仅仅是做到这一点的方式!
然后,我可以按影片对所有内容进行排序,然后按与所有相似影片的相似度进行排序,结果是*的人也喜欢**的人 高度评价为*等等,依此类推。 就像我说的那样,这只是其中一种方式。
然后,我可以按影片对所有内容进行排序,然后按与所有相似影片的相似度进行排序,结果是*喜欢该影片的人也喜欢**高度评价*等等,依此类推。 就像我说的那样,这只是其中一种方式。
这是基于项目的协作筛选的第一步,首先,我根据观看每对给定电影对的人的关系来确定电影之间的关系。 当我们看下面的例子时,它将更有意义:
......@@ -111,9 +111,9 @@
好吧,让我们开始吧! 我们有一些将使用 Pandas 的 Python 代码以及我们可以使用的所有其他工具来创建电影推荐,而这些代码的数量却很少。
我们要做的第一件事是向您展示基于项目的协作过滤。 因此,我们将建立*观看者,同时基本上也观看*,您知道,*的人对事物的评价也很高*,因此建立了电影与电影的关系。 因此,我们将基于从 MovieLens 项目获得的真实数据。 因此,如果您访问 MovieLens.org,实际上那里有一个开放的电影推荐系统,人们可以在其中对电影进行评分并获得有关新电影的推荐。
我们要做的第一件事是向您展示基于项目的协作过滤。 因此,我们将建立*观看者同时基本上也观看*,您知道,*对它评价很高的人对它评价也很高*,因此建立了电影与电影的关系。 因此,我们将基于从 MovieLens 项目获得的真实数据。 因此,如果您访问 MovieLens.org,实际上那里有一个开放的电影推荐系统,人们可以在其中对电影进行评分并获得有关新电影的推荐。
而且,它们将所有基础数​​据公开提供给像我们这样的研究人员。 因此,我们将使用一些真实的电影收视率数据-有点过时了,大约有 10 年的历史了,因此请记住这一点,但最终要在这里使用的是真实的行为数据 。 并且,我们将使用它来计算电影之间的相似度。 而且,这些数据本身很有用。 您可以使用该数据说*的人也喜欢*的人。 因此,假设我正在看电影的网页。 然后,系统会说:*如果您喜欢这部电影,并且考虑到正在观看它,则可能对它感兴趣,那么您可能也喜欢这些电影*。 这就是推荐系统的一种形式,尽管我们甚至都不知道您是谁。
而且,它们将所有基础数​​据公开提供给像我们这样的研究人员。 因此,我们将使用一些真实的电影收视率数据-有点过时了,大约有 10 年的历史了,因此请记住这一点,但最终要在这里使用的是真实的行为数据 。 并且,我们将使用它来计算电影之间的相似度。 而且,这些数据本身很有用。 您可以使用该数据说*喜欢它的人也喜欢*。 因此,假设我正在看电影的网页。 然后,系统会说:*如果您喜欢这部电影,并且考虑到正在观看它,则可能对它感兴趣,那么您可能也喜欢这些电影*。 这就是推荐系统的一种形式,尽管我们甚至都不知道您是谁。
现在,它是真实数据,因此我们将遇到一些真实问题。 我们最初的结果看起来不会很好,所以我们将花费一些额外的时间来找出原因,这是您花费大量时间作为数据科学家纠正的原因 问题,然后返回并再次运行它,直到获得有意义的结果。
......@@ -189,9 +189,9 @@ movieRatings.head()
![](img/2be0e510-8351-4be3-93c1-210bf6a1edef.jpg)
怎么能将所有这些整合在一起对我们来说真是太神奇了。 现在,您将看到一些`NaN`值,它们代表**而不是数字**,以及Pandas如何指示缺失值。 因此,这种解释的方式是,例如`user_id`数字`1`没看电影`1-900 (1994)`,但是`user_id`数字`1`却看了`101 Dalmatians (1996)`并将它评为`2`星。 `user_id`数字`1`也观看了`12 Angry Men (1957)`并将其评为`5`星,但没有观看电影`2 Days in the Valley (1996)`,例如,好吗? 因此,我们最终得到的基本上是一个稀疏矩阵,其中包含每个用户和每个电影,并且在用户对电影进行评分的每个路口处都有一个评分值。
怎么能将所有这些整合在一起对我们来说真是太神奇了。 现在,您将看到一些`NaN`值,它们代表**数字**,以及Pandas如何指示缺失值。 因此,这种解释的方式是,例如`user_id`数字`1`没看电影`1-900 (1994)`,但是`user_id`数字`1`却看了`101 Dalmatians (1996)`并将它评为`2`星。 `user_id`数字`1`也观看了`12 Angry Men (1957)`并将其评为`5`星,但没有观看电影`2 Days in the Valley (1996)`,例如,好吗? 因此,我们最终得到的基本上是一个稀疏矩阵,其中包含每个用户和每个电影,并且在用户对电影进行评分的每个路口处都有一个评分值。
因此,现在您可以看到,我们可以很容易地提取用户观看的每部电影的矢量,我们还可以提取对给定电影评分的每个用户的矢量,这正是我们想要的。 因此,这对于基于用户和基于项目的协作过滤都很有用,对吗? 如果要查找用户之间的关系,可以查看这些用户行之间的相关性,但是如果要查找电影之间的相关性,则对于基于项目的协作过滤,可以根据用户行为查看列之间的相关性。 因此,这就是真正的*翻转用户和基于项目的相似性*的地方。
因此,现在您可以看到,我们可以很容易地提取用户观看的每部电影的矢量,我们还可以提取对给定电影评分的每个用户的矢量,这正是我们想要的。 因此,这对于基于用户和基于项目的协作过滤都很有用,对吗? 如果要查找用户之间的关系,可以查看这些用户行之间的相关性,但是如果要查找电影之间的相关性,则对于基于项目的协作过滤,可以根据用户行为查看列之间的相关性。 因此,这就是真正的*反转用户与项目之间的相似性*的地方。
现在,我们要进行基于项目的协作过滤,因此我们想提取列,为此,我们运行以下代码:
......
......@@ -27,7 +27,7 @@ KNN 听起来很花哨,但实际上它是其中最简单的技术之一! 假
在这里,我们可以根据散点图中任意两点之间的等级和受欢迎程度来计算某种距离。 假设有一个新观点出现,一部我们不知道其类型的新电影。 我们可以做的是将`K`设置为`3`,然后将`3`最近的邻居设为散点图上的该点; 然后他们都可以对新的点/电影的分类进行投票。
您可以看到是否带了三个最近的邻居( *K = 3* ),我有 2 部戏剧电影和 1 部科幻电影。 然后,我让他们全部投票,然后我们将基于最近的 3 个邻居为该新点选择戏剧的分类。 现在,如果我将这个圈子扩大到包括 5 个最近的邻居,即 *K = 5* ,我得到一个不同的答案。 因此,在这种情况下,我选择了 3 部科幻小说和 2 部戏剧电影。 如果让他们全部投票,我最终将得到一部关于新电影的科幻小说分类。
您可以看到是否带了三个最近的邻居(`K = 3`),我有 2 部戏剧电影和 1 部科幻电影。 然后,我让他们全部投票,然后我们将基于最近的 3 个邻居为该新点选择戏剧的分类。 现在,如果我将这个圈子扩大到包括 5 个最近的邻居,即·K = 5,我得到一个不同的答案。 因此,在这种情况下,我选择了 3 部科幻小说和 2 部戏剧电影。 如果让他们全部投票,我最终将得到一部关于新电影的科幻小说分类。
我们对 K 的选择可能非常重要。 您想确保它足够小,以至于您不会走得太远并开始拾取不相关的邻居,但是它必须足够大以包含足够的数据点以获得有意义的样本。 因此,通常必须使用训练/测试或类似技术来实际确定给定数据集的`K`正确值。 但是,归根结底,您必须从直觉开始,然后从那里开始工作。
......@@ -37,7 +37,7 @@ KNN 听起来很花哨,但实际上它是其中最简单的技术之一! 假
![](img/22a520fc-4ebf-43d3-9427-5974ced51f65.jpg)
从理论上讲,我们可以仅使用 k 近邻来重新创建类似于*的客户,这些客户同时也观看了*(上图是亚马逊的屏幕截图)。 而且,我可以采取进一步的措施:一旦我根据 k 最近邻算法确定了与给定电影相似的电影,就可以让他们全部对该电影的预测收视率进行投票。
从理论上讲,我们可以仅使用 k 近邻来重新创建类似于*观看了的用户,同时也观看了*(上图是亚马逊的屏幕截图)。 而且,我可以采取进一步的措施:一旦我根据 k 最近邻算法确定了与给定电影相似的电影,就可以让他们全部对该电影的预测收视率进行投票。
这就是我们在下一个示例中要做的。 因此,您现在有了 KNN(k 最近邻)的概念。 让我们继续将其应用于实际查找彼此相似的电影,并使用最近的邻近电影来预测我们之前从未看过的另一部电影的评级的示例。
......@@ -445,7 +445,7 @@ ETL 是一种古老的做法,您需要先脱机转换一堆数据,然后再
我们可以看看他可以采取的行动:他实际上根本不能向左移动,但是他可以向上,向下或向右移动,我们可以为所有这些动作分配一个值。 向上或向右走,实际上什么也没有发生,没有药丸或点药可消耗。 但是,如果他走了,那绝对是一个负值。 可以说,对于吃豆人所处的当前状况所给出的状态,下移将是一个非常糟糕的选择。 为此,应该有一个负的`Q`值。 根本无法向左移动。 向上或向右移动或保持中性,对于给定状态的那些动作选择,`Q`值将保持为 0。
现在,您还可以稍作展望,以打造一个更加智能的代理。 所以,我实际上距离这里获得药丸只有两步之遥。 因此,当吃豆人探索这个状态时,如果我想在下一个状态下吃该药的情况,我实际上可以将其计入上一个状态的`Q`值中。 如果您只是某种折扣因素,则根据您的时间间隔,距离的步数,您可以将所有因素综合考虑在内。 因此,这实际上是在系统中构建一点内存的一种方式。 您可以在计算 Q 时使用折扣因子“向前看”多个步骤(此处`s`是先前状态, *s'*是当前状态):
现在,您还可以稍作展望,以打造一个更加智能的代理。 所以,我实际上距离这里获得药丸只有两步之遥。 因此,当吃豆人探索这个状态时,如果我想在下一个状态下吃该药的情况,我实际上可以将其计入上一个状态的`Q`值中。 如果您只是某种折扣因素,则根据您的时间间隔,距离的步数,您可以将所有因素综合考虑在内。 因此,这实际上是在系统中构建一点内存的一种方式。 您可以在计算 Q 时使用折扣因子“向前看”多个步骤(此处`s`是先前状态, `s'`是当前状态):
*Q(s,a) += discount * (reward(s,a) + max(Q(s')) - Q(s,a))*
......@@ -479,13 +479,13 @@ ETL 是一种古老的做法,您需要先脱机转换一堆数据,然后再
* **决策**:在给定状态下,如果给定一组可能性,我们将采取什么行动?
* **在结果部分为随机的情况下**:嗯,有点像我们在那里的随机探索。
* **部分受决策者**的控制:决策者是我们计算出的`Q`值。
* **部分受决策者的控制**:决策者是我们计算出的`Q`值。
因此,MDP,马尔可夫决策过程是描述我们刚刚为强化学习而描述的探索算法的一种理想方式。 表示法甚至相似,状态仍然描述为 s,而 s'是我们遇到的下一个状态。 对于给定的 s 和 s'状态,我们具有定义为 *P <sub class="calibre50">a</sub>* 的状态转换函数。 我们有`Q`值,它们基本上表示为奖励函数,对于给定的 s 和 s', *R <sub class="calibre50">和</sub>* 值。 因此,从一种状态转移到另一种状态具有与之相关的给定奖励,并且从一种状态转移到另一种状态由状态转换函数定义:
因此,MDP,马尔可夫决策过程是描述我们刚刚为强化学习而描述的探索算法的一种理想方式。 表示法甚至相似,状态仍然描述为 s,而 s'是我们遇到的下一个状态。 对于给定的 s 和 s'状态,我们具有定义为`P[a]`的状态转换函数。 我们有`Q`值,它们基本上表示为奖励函数,对于给定的 s 和 s', `R[a]`值。 因此,从一种状态转移到另一种状态具有与之相关的给定奖励,并且从一种状态转移到另一种状态由状态转换函数定义:
* 状态仍然描述为`s` *s''*
* 状态转换函数描述为 *Pa(s,s')*
* 我们的`Q`值描述为奖励函数 *Ra(s,s')*
* 状态仍然描述为`s``s'`
* 状态转换函数描述为`P[a](s, s')`
* 我们的`Q`值描述为奖励函数`R[a](s, s')`
因此,再次描述马尔科夫决策过程,只是描述我们所做的事情,只有一种数学符号和一个听起来更奇特的单词。 而且,如果您想听起来更聪明,也可以使用另一个名称来调用马尔可夫决策过程:离散时间随机控制过程。 听起来很聪明! 但是概念本身就是我们刚刚描述的东西。
......@@ -509,7 +509,7 @@ ETL 是一种古老的做法,您需要先脱机转换一堆数据,然后再
然后,我们存储最终与每个状态相关联的`Q`值,并可以使用它来告知其将来的选择。 因此,我们可以进入一个全新的迷宫,并拥有一个真正聪明的吃豆人,可以独自避开鬼魂并有效地将它们吃掉。 这是一个非常简单的概念,但是功能非常强大。 您也可以说您了解很多花哨的术语,因为它们全称为同一件事。 Q 学习,强化学习,马尔可夫决策过程,动态规划:所有这些都捆绑在同一个概念中。
我不知道,我认为通过这样一种简单的方法实际上可以制造出一种人工智能的吃豆人真是太酷了,它确实有效! 如果您想更详细地研究它,请参考以下示例,这些示例具有一个实际的源代码,您可以查看并可以使用 [**Python Markov Decision Process Toolbox**](http://pymdptoolbox.readthedocs.org/en/latest/api/mdp.html)
我不知道,我认为通过这样一种简单的方法实际上可以制造出一种人工智能的吃豆人真是太酷了,它确实有效! 如果您想更详细地研究它,请参考以下示例,这些示例具有一个实际的源代码,您可以查看并可以使用 [**Python 马尔可夫决策过程工具箱**](http://pymdptoolbox.readthedocs.org/en/latest/api/mdp.html)
有一个 Python Markov 决策过程工具箱,将其包装在我们所讨论的所有术语中。 您可以查看一个示例,一个类似于猫和老鼠游戏的示例。 而且,实际上还有一个“吃豆人”示例,您也可以在网上查看,该示例与我们所讨论的内容更直接相关。 随意探索这些链接,并进一步了解它。
......
......@@ -184,11 +184,11 @@ print scores.mean()
您需要注意许多不同类型的问题和数据:
* **离群值**:因此,也许您的人员在数据中表现得有些奇怪,而当您对它们进行挖掘时,它们却是您不应该首先关注的数据。 一个很好的例子是,如果您正在查看 Web 日志数据,并且看到一个会话 ID 不断地反复出现,并且它以人们永远无法完成的高速度执行某项操作。 您可能会看到一个机器人,该脚本正在某个地方运行以实际抓取您的网站。 甚至可能是某种恶意攻击。 但是无论如何,您都不希望这些行为数据通知您的模型,这些数据只能用来预测使用您的网站的真实人类的行为。 因此,监视异常值是识别在构建模型时可能希望从模型中删除的数据类型的一种方法。
* **缺数据**:当数据不存在时您会怎么做? 回到网络日志的示例,您可能在该行中有一个引荐来源网址,也可能没有。 如果不存在该怎么办? 是否为丢失或未指定的内容创建新分类? 还是您将那条线全部淘汰? 您必须考虑正确的做法。
* **缺数据**:当数据不存在时您会怎么做? 回到网络日志的示例,您可能在该行中有一个引荐来源网址,也可能没有。 如果不存在该怎么办? 是否为丢失或未指定的内容创建新分类? 还是您将那条线全部淘汰? 您必须考虑正确的做法。
* **恶意数据**:可能有人在尝试玩您的系统,有人可能在试图欺骗系统,而您不希望那些人逃避它。 假设您正在建立一个推荐系统。 可能有人在外面捏造行为数据以推广他们的新产品,对吗? 因此,您需要警惕此类情况,并确保对输入数据识别先令攻击或其他类型的攻击,并从结果中过滤掉它们,不要让它们获胜。 。
* **错误数据**:如果某些系统中某处出现软件错误,而该错误仅在某些情况下会写出错误的值? 这有可能发生。 不幸的是,您没有很好的方法来了解这一点。 但是,如果您看到的数据看起来有些混乱,或者结果对您而言没有意义,那么深入研究有时可能会发现潜在的错误,这些错误首先导致写入错误的数据。 也许某些时候事情没有被正确地组合在一起。 可能不是整个会议期间都举行会议。 例如,人们在访问网站时可能会丢弃其会话 ID 并获取新的会话 ID。
* **不相关数据**:此处非常简单。 也许您只对纽约市人的数据感兴趣,或出于某种原因。 在这种情况下,来自世界各地的人们的所有数据都与您要查找的内容无关。 您要做的第一件事就是丢弃所有数据并限制数据,将其缩减为您真正关心的数据。
* **数据不一致**:这是一个很大的问题。 例如,在地址中,人们可以用许多不同的方式编写相同的地址:他们可能会缩写街道,或者可能不会缩写街道,他们可能根本不会将街道放在街道名称的末尾。 他们可能以不同的方式将行组合在一起,可能会拼写不同的东西,可能在美国使用邮政编码,或者在美国使用邮政编码加 4 码,他们可能有一个国家,他们可能没有一个国家。 您需要以某种方式找出您看到的变化以及如何将它们全部归一化。
* **不一致数据**:这是一个很大的问题。 例如,在地址中,人们可以用许多不同的方式编写相同的地址:他们可能会缩写街道,或者可能不会缩写街道,他们可能根本不会将街道放在街道名称的末尾。 他们可能以不同的方式将行组合在一起,可能会拼写不同的东西,可能在美国使用邮政编码,或者在美国使用邮政编码加 4 码,他们可能有一个国家,他们可能没有一个国家。 您需要以某种方式找出您看到的变化以及如何将它们全部归一化。
* 也许我正在看有关电影的数据。 电影在不同国家/地区可能具有不同的名称,或者一本书在不同国家/地区可能具有不同的名称,但它们的含义相同。 因此,您需要在需要规范化数据,可以用许多不同方式表示相同数据的地方,并需要将它们组合在一起以获得正确的结果。
* **格式化**:这也可能是一个问题; 事物的格式可能不一致。 以日期为例:在美国,我们总是执行月,日,年(MM / DD / YY),但是在其他国家,他们可能会执行日,月,年(DD / MM / YY),谁知道呢。 您需要了解这些格式差异。 电话号码可能在区号周围带有括号,也许没有。 也许数字的每个部分之间都有破折号,也许没有。 也许社会保险号有破折号,也许没有。 这些都是您需要注意的事情,并且您需要确保在处理过程中不会将格式的变化视为不同的实体或不同的分类。
......@@ -636,4 +636,4 @@ plt.show()
# 概括
在本章中,我们讨论了在偏差和方差之间保持平衡并最小化误差的重要性。 接下来,我们看到了 k 折交叉验证的概念以及如何在 Python 中实现它以防止过度拟合。 我们了解了在处理数据之前清理数据并对其进行标准化的重要性。 然后,我们看到了一个确定网站受欢迎页面的示例。 在第 9 章和 *Apache Spark-大数据机器学习*中,我们将使用 Apache Spark 学习大数据机器学习。
\ No newline at end of file
在本章中,我们讨论了在偏差和方差之间保持平衡并最小化误差的重要性。 接下来,我们看到了 k 折交叉验证的概念以及如何在 Python 中实现它以防止过度拟合。 我们了解了在处理数据之前清理数据并对其进行标准化的重要性。 然后,我们看到了一个确定网站受欢迎页面的示例。 在第 9 章和“Apache Spark-大数据机器学习”中,我们将使用 Apache Spark 学习大数据机器学习。
\ No newline at end of file
......@@ -23,10 +23,10 @@
1. **安装 JDK**:您需要首先安装 JDK,这是 Java 开发工具包。 您可以直接访问 Sun 的网站并下载并安装(如果需要)。 我们需要 JDK,因为即使在本课程中我们将使用 Python 进行开发,也需要将其转换为 Scala 代码,这是 Spark 本身开发的。 而且,Scala 反过来又在 Java 解释器上运行。 因此,为了运行 Python 代码,您需要一个 Scala 系统,该系统将作为 Spark 的一部分默认安装。 另外,我们需要 Java 或更具体地说是 Java 的解释器来实际运行 Scala 代码。 就像技术层蛋糕。
2. **安装 Python**:显然,您将需要 Python,但是如果您到此为止,则应该已经建立了 Python 环境,并希望使用 Enthought Canopy。 因此,我们可以跳过此步骤。
3. **安装适用于 Hadoop 的 Spark 的预构建版本**:幸运的是,Apache 网站提供了可用的 Spark 的预构建版本,这些预构建版本可以立即使用为最新 Hadoop 版本进行预编译的版本。 您无需构建任何东西,只需将其下载到计算机上,然后将其放置在正确的位置即可,大部分时间都很好。
4. **创建 conf / log4j.properties 文件**:我们需要处理一些配置事项。 我们要做的一件事就是调整警告级别,这样我们在工作时就不会收到很多警告垃圾邮件。 我们将逐步介绍如何做到这一点。 基本上,您需要重命名其中一个属性文件,然后在其中调整错误设置。
5. **添加一个 SPARK_HOME 环境变量**:接下来,我们需要设置一些环境变量,以确保您可以实际从任何路径运行 Spark。 我们将添加一个指向您安装 Spark 的位置的 SPARK_HOME 环境变量,然后将`%SPARK_HOME%\bin`添加到您的系统路径中,以便在您运行 Spark Submit,PySpark 或所需的任何 Spark 命令时,Windows 会知道 在哪里找到它。
6. **设置一个 HADOOP_HOME 变量**:在 Windows 上,我们还需要做一件事,我们还需要设置一个`HADOOP_HOME`变量,因为它将期望找到一点点 Hadoop,即使您 不要在独立系统上使用 Hadoop。
7. **安装 winutils.exe**:最后,我们需要安装一个名为`winutils.exe`的文件。 本书的资源中有指向`winutils.exe`的链接,因此您可以在那里找到它。
4. **创建`conf/log4j.properties`文件**:我们需要处理一些配置事项。 我们要做的一件事就是调整警告级别,这样我们在工作时就不会收到很多警告垃圾邮件。 我们将逐步介绍如何做到这一点。 基本上,您需要重命名其中一个属性文件,然后在其中调整错误设置。
5. **添加一个`SPARK_HOME`环境变量**:接下来,我们需要设置一些环境变量,以确保您可以实际从任何路径运行 Spark。 我们将添加一个指向您安装 Spark 的位置的 SPARK_HOME 环境变量,然后将`%SPARK_HOME%\bin`添加到您的系统路径中,以便在您运行 Spark Submit,PySpark 或所需的任何 Spark 命令时,Windows 会知道 在哪里找到它。
6. **设置一个`HADOOP_HOME`变量**:在 Windows 上,我们还需要做一件事,我们还需要设置一个`HADOOP_HOME`变量,因为它将期望找到一点点 Hadoop,即使您 不要在独立系统上使用 Hadoop。
7. **安装`winutils.exe`**:最后,我们需要安装一个名为`winutils.exe`的文件。 本书的资源中有指向`winutils.exe`的链接,因此您可以在那里找到它。
如果您想详细了解这些步骤,可以参考后面的章节。
......@@ -94,7 +94,7 @@
![](img/417d9e6f-4b8c-4a51-bb1c-694e1cf23530.png)
您显然不想将其保留在`Downloads`文件夹中,所以让我们继续在此处打开一个新的文件浏览器窗口。 我转到`C`驱动器并创建一个新文件夹,让我们将其命名为`spark`。 因此,我的 Spark 安装将在`C:\spark`中运行。 同样,很容易记住。 打开该文件夹。 现在,我回到下载的`spark`文件夹,并使用 *Ctrl* +`A`选择 Spark 发行版中的所有内容,`Ctrl + C`复制它,然后返回`C:\spark`,我要放置在其中,然后 *Ctrl* +`V`粘贴到:
您显然不想将其保留在`Downloads`文件夹中,所以让我们继续在此处打开一个新的文件浏览器窗口。 我转到`C`驱动器并创建一个新文件夹,让我们将其命名为`spark`。 因此,我的 Spark 安装将在`C:\spark`中运行。 同样,很容易记住。 打开该文件夹。 现在,我回到下载的`spark`文件夹,并使用`Ctrl + A`选择 Spark 发行版中的所有内容,`Ctrl + C`复制它,然后返回`C:\spark`,我要放置在其中,然后`Ctrl + V`粘贴到:
![](img/e5a2e48a-10c4-4849-9ef2-11833945eaa8.png)
......@@ -333,14 +333,14 @@ hiveCtx = HiveContext(sc) rows = hiveCtx.sql("SELECT name, age FROM users")
让我们先谈谈转换。 转换正是它们的本质。 这是一种采用 RDD 并将 RDD 中的每一行转换为基于您提供的函数的新值的方法。 让我们看一下其中的一些功能:
* **map()和 flatmap()**`map``flatmap`是您最常看到的功能。 两者都将具有您可以梦想的任何功能,将 RDD 的一行作为输入,并且将输出转换后的行。 例如,您可能会从 CSV 文件中获取原始输入,并且您的`map`操作可能会将该输入获取并基于逗号分隔符将其分解为各个字段,然后返回 Python 列表,该列表以更结构化的方式包含该数据 您可以对其进行进一步处理的格式。 您可以将映射操作链接在一起,因此一个`map`的输出可能最终会创建一个新的 RDD,然后对其进行另一次转换,依此类推。 再次,关键是,Spark 可以将这些转换分布在整个群集中,因此它可能会包含 RDD 的一部分并在一台机器上进行转换,而 RDD 的另一部分又会在另一台计算机上进行转换。
* `map()``flatmap()``map``flatmap`是您最常看到的功能。 两者都将具有您可以梦想的任何功能,将 RDD 的一行作为输入,并且将输出转换后的行。 例如,您可能会从 CSV 文件中获取原始输入,并且您的`map`操作可能会将该输入获取并基于逗号分隔符将其分解为各个字段,然后返回 Python 列表,该列表以更结构化的方式包含该数据 您可以对其进行进一步处理的格式。 您可以将映射操作链接在一起,因此一个`map`的输出可能最终会创建一个新的 RDD,然后对其进行另一次转换,依此类推。 再次,关键是,Spark 可以将这些转换分布在整个群集中,因此它可能会包含 RDD 的一部分并在一台机器上进行转换,而 RDD 的另一部分又会在另一台计算机上进行转换。
就像我说的,`map``flatmap`是您将看到的最常见的转换。 唯一的区别是`map`仅允许您为每一行输出一个值,而`flatmap`则允许您实际为给定行输出多个新行。 因此,实际上您可以创建比使用`flatmap.`时更大的 RDD 或更小的 RDD。
* **filter()**`filter`可用于以下情况:仅创建一个布尔函数,该布尔函数表示“是否应保留此行?是或否”。
* **different()**`distinct`是一种不太常用的转换,仅会返回 RDD 中的不同值。
* **sample()**:此函数可让您从 RDD 中抽取随机样本
* **union(),intersection(),subtract()和 Cartesian()**:您可以执行诸如 union,intersection,subtract 甚至生成 RDD 中存在的每个笛卡尔组合的交集操作。
* `filter()``filter`可用于以下情况:仅创建一个布尔函数,该布尔函数表示“是否应保留此行?是或否”。
* `different()``distinct`是一种不太常用的转换,仅会返回 RDD 中的不同值。
* `sample()`:此函数可让您从 RDD 中抽取随机样本
* `union()``intersection()``subtract()``cartesian()`:您可以执行诸如 union,intersection,subtract 甚至生成 RDD 中存在的每个笛卡尔组合的交集操作。
# 使用 map()
......@@ -855,7 +855,7 @@ spark-submit SparkKMeans.py
TF-IDF 代表术语频率和文档逆向频率,这基本上是两个指标,它们在进行搜索和弄清楚给定单词与文档的相关性(给定大量文档)时紧密相关。 因此,例如,对于 Wikipedia 上的每篇文章,可能都会有一个术语频率与之相关,对于该文档中出现的每个单词,Internet 上的每个页面都可能会与术语频率相关联。 听起来很花哨,但是,正如您将看到的,这是一个非常简单的概念。
* **所有术语频率**表示给定文档中给定单词出现的频率。 那么,在一个网页内,在一篇 Wikipedia 文章内,在任何内容内,给定单词在该文档中的普遍程度如何? 您知道,该单词在该文档中所有单词中的出现率是多少? 而已。 这就是所有术语的频率。
* **所有词频**表示给定文档中给定单词出现的频率。 那么,在一个网页内,在一篇 Wikipedia 文章内,在任何内容内,给定单词在该文档中的普遍程度如何? 您知道,该单词在该文档中所有单词中的出现率是多少? 而已。 这就是所有术语的频率。
* **文档频率**是相同的想法,但是这次是该单词在整个文档库中的频率。 因此,这个词多久出现在我拥有的所有文档,所有网页,维基百科上的所有文章中,无论如何。 例如,“ a”或“ the”之类的常用词的文档出现频率很高,我希望它们的术语出现频率也很高,但这并不一定意味着它们与给定文档相关 。
您可以看到我们将如何发展。 因此,假设给定单词的词频很高,而文档词频很低。 这两件事的比例可以使我对该词与文档的相关性有所了解。 因此,如果我看到某个单词在给定文档中经常出现,但在文档的整体空间中却很少出现,那么我知道这个单词可能对该特定文档传达了一些特殊含义。 它可能传达了本文档的实际含义。
......@@ -998,7 +998,7 @@ tfidf = idf.transform(tf)
# 使用 Wikipedia 搜索引擎算法
让我们尝试使用该算法。 让我们尝试为 **Gettysburg** 一词查找最佳文章。 如果您不熟悉美国历史,那是亚伯拉罕·林肯发表著名演讲的地方。 因此,我们可以使用以下代码将“葛底斯堡”一词转换为其哈希值:
让我们尝试使用该算法。 让我们尝试为`Gettysburg`一词查找最佳文章。 如果您不熟悉美国历史,那是亚伯拉罕·林肯发表著名演讲的地方。 因此,我们可以使用以下代码将“葛底斯堡”一词转换为其哈希值:
```py
gettysburgTF = hashingTF.transform(["Gettysburg"])
......
......@@ -22,7 +22,7 @@
什么是 A / B 测试? 好吧,这是一个通常在网站上运行的受控实验,它也可以应用于其他环境,但是通常我们谈论的是网站,并且我们将测试该网站的某些更改的效果, 与以前相比。
基本上,您有一个*控件*组查看旧网站的人,以及一个*测试*组查看该网站更改的人,其目的是衡量行为差异 在这两组之间进行比较,并使用该数据来实际确定此更改是否有益。
基本上,您有一个*对照*组查看旧网站的人,以及一个*测试*组查看该网站更改的人,其目的是衡量行为差异 在这两组之间进行比较,并使用该数据来实际确定此更改是否有益。
例如,我拥有一家拥有网站的公司,我们向人们授权软件,现在我有一个漂亮,友好的橙色按钮,人们在想购买许可证时可以单击该按钮,如下图左图所示 。 但是,如果将按钮的颜色更改为蓝色(如右图所示),会发生什么?
......@@ -38,7 +38,7 @@ A / B 测试会将人们分成看到橙色按钮的人们和看到蓝色按钮
* **设计更改**:这些可以是按钮颜色,按钮位置或页面布局的更改。
* **UI 流程**:因此,也许您实际上是在改变购买渠道的工作方式以及人们在您的网站上结帐的方式,并且您实际上可以衡量其效果。
* **算法更改**:让我们考虑在第 6 章和*推荐系统*中讨论过的电影推荐示例。 也许我想测试一种算法与另一种算法。 我真正关心的不是去依靠错误指标和我进行火车测试的能力,而是要去驱动购买或租赁,或者本网站上的任何内容。
* **算法更改**:让我们考虑在第 6 章和“推荐系统”中讨论过的电影推荐示例。 也许我想测试一种算法与另一种算法。 我真正关心的不是去依靠错误指标和我进行火车测试的能力,而是要去驱动购买或租赁,或者本网站上的任何内容。
* A / B 测试可以让我直接测量该算法对我真正关心的最终结果的影响,而不仅仅是我预测别人已经看过的电影的能力。
* 您还可以梦想得到的任何其他东西,实际上,影响用户与您的网站交互方式的任何更改都值得测试。 也许甚至可以使网站更快,或者可以是任何东西。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册