使用Apache Hadoop计算PageRanks

目前,我正在接受Coursera的培训“ 挖掘海量数据集 ”。 我对MapReduce和Apache Hadoop感兴趣已有一段时间了,通过本课程,我希望对何时以及如何MapReduce可以帮助解决一些现实世界中的业务问题有更多的了解(我在这里介绍了另一种解决方法)。 该Coursera课程主要侧重于使用算法的理论,而较少涉及编码本身。 第一周是关于PageRanking以及Google如何使用它来对页面进行排名。 幸运的是,与Hadoop结合可以找到很多关于该主题的信息。 我到这里结束并决定仔细看一下这段代码。

我所做的就是获取这段代码 (将其分叉)并重新编写了一下。 我创建的映射器单元测试和减速器跟我描述这里 。 作为测试用例,我使用了课程中的示例。 我们有三个相互链接和/或彼此链接的网页:

页面流

此链接方案应解析为以下页面排名:

  • Y 7/33
  • 5/33
  • M 21/33

由于MapReduce示例代码期望输入“ Wiki页面” XML ,因此我创建了以下测试集:

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en"><page><title>A</title><id>121173</id><revision>...<text xml:space="preserve" bytes="6523">[[Y]] [[M]]</text></revision></page><page><title>Y</title><id>121173</id><revision>...<text xml:space="preserve" bytes="6523">[[A]] [[Y]]</text></revision></page><page><title>M</title><id>121173</id><revision>...<text xml:space="preserve" bytes="6523">[[M]]</text></revision></page>
</mediawiki>

原始页面本身已经很好地解释了它的全局工作方式。 我将仅描述我创建的单元测试。 有了原始的解释和我的单元测试,您应该能够解决问题并了解发生了什么。

如上所述,整个工作分为三个部分:

  1. 解析
  2. 计算
  3. 订购

解析部分中,将原始XML提取,拆分成多个页面并进行映射,以便我们将页面作为键和它具有传出链接的页面的值作为输出获得。 因此,单元测试的输入将是三个“ Wiki”页面XML,如上所示。 预期带有链接页面的页面的“标题”。 单元测试如下所示:

package net.pascalalma.hadoop.job1;...public class WikiPageLinksMapperTest {MapDriver<LongWritable, Text, Text, Text> mapDriver;String testPageA = " <page>\n" +"    <title>A</title>\n" +"   ..." +"      <text xml:space=\"preserve\" bytes=\"6523\">[[Y]] [[M]]</text>\n" +"    </revision>";String testPageY = " <page>\n" +"    <title>Y</title>\n" +"    ..." +"      <text xml:space=\"preserve\" bytes=\"6523\">[[A]] [[Y]]</text>\n" +"    </revision>\n" +"  </page>";String testPageM = " <page>\n" +"    <title>M</title>\n" +"    ..." +"      <text xml:space=\"preserve\" bytes=\"6523\">[[M]]</text>\n" +"    </revision>\n" +"  </page>";@Beforepublic void setUp() {WikiPageLinksMapper mapper = new WikiPageLinksMapper();mapDriver = MapDriver.newMapDriver(mapper);}@Testpublic void testMapper() throws IOException {mapDriver.withInput(new LongWritable(1), new Text(testPageA));mapDriver.withInput(new LongWritable(2), new Text(testPageM));mapDriver.withInput(new LongWritable(3), new Text(testPageY));mapDriver.withOutput(new Text("A"), new Text("Y"));mapDriver.withOutput(new Text("A"), new Text("M"));mapDriver.withOutput(new Text("Y"), new Text("A"));mapDriver.withOutput(new Text("Y"), new Text("Y"));mapDriver.withOutput(new Text("M"), new Text("M"));mapDriver.runTest(false);}
}

映射器的输出将成为我们的reducer的输入。 那个的单元测试如下:

package net.pascalalma.hadoop.job1;
...
public class WikiLinksReducerTest {ReduceDriver<Text, Text, Text, Text> reduceDriver;@Beforepublic void setUp() {WikiLinksReducer reducer = new WikiLinksReducer();reduceDriver = ReduceDriver.newReduceDriver(reducer);}@Testpublic void testReducer() throws IOException {List<Text> valuesA = new ArrayList<Text>();valuesA.add(new Text("M"));valuesA.add(new Text("Y"));reduceDriver.withInput(new Text("A"), valuesA);reduceDriver.withOutput(new Text("A"), new Text("1.0\tM,Y"));reduceDriver.runTest();}
}

如单元测试所示,我们期望reducer将输入减少到“初始”页面等级1.0的值,该等级与(关键)页面具有传出链接的所有页面连接。 这是该阶段的输出,将用作“计算”阶段的输入。
计算部分中,将对传入的页面排名进行重新计算,以实现“ 幂迭代 ”方法。 将多次执行此步骤,以获得给定页面集的可接受页面排名。 如前所述,前一步的输出是该步骤的输入,正如我们在此映射器的单元测试中所看到的:

package net.pascalalma.hadoop.job2;
...
public class RankCalculateMapperTest {MapDriver<LongWritable, Text, Text, Text> mapDriver;@Beforepublic void setUp() {RankCalculateMapper mapper = new RankCalculateMapper();mapDriver = MapDriver.newMapDriver(mapper);}@Testpublic void testMapper() throws IOException {mapDriver.withInput(new LongWritable(1), new Text("A\t1.0\tM,Y"));mapDriver.withInput(new LongWritable(2), new Text("M\t1.0\tM"));mapDriver.withInput(new LongWritable(3), new Text("Y\t1.0\tY,A"));mapDriver.withOutput(new Text("M"), new Text("A\t1.0\t2"));mapDriver.withOutput(new Text("A"), new Text("Y\t1.0\t2"));mapDriver.withOutput(new Text("Y"), new Text("A\t1.0\t2"));mapDriver.withOutput(new Text("A"), new Text("|M,Y"));mapDriver.withOutput(new Text("M"), new Text("M\t1.0\t1"));mapDriver.withOutput(new Text("Y"), new Text("Y\t1.0\t2"));mapDriver.withOutput(new Text("A"), new Text("!"));mapDriver.withOutput(new Text("M"), new Text("|M"));mapDriver.withOutput(new Text("M"), new Text("!"));mapDriver.withOutput(new Text("Y"), new Text("|Y,A"));mapDriver.withOutput(new Text("Y"), new Text("!"));mapDriver.runTest(false);}
}

源页面中说明了此处的输出。 “额外”项目带有“!” 和'|' 在减少步骤中对于计算是必需的。 减速器的单元测试如下:

package net.pascalalma.hadoop.job2;
...
public class RankCalculateReduceTest {ReduceDriver<Text, Text, Text, Text> reduceDriver;@Beforepublic void setUp() {RankCalculateReduce reducer = new RankCalculateReduce();reduceDriver = ReduceDriver.newReduceDriver(reducer);}@Testpublic void testReducer() throws IOException {List<Text> valuesM = new ArrayList<Text>();valuesM.add(new Text("A\t1.0\t2"));valuesM.add(new Text("M\t1.0\t1"));valuesM.add(new Text("|M"));valuesM.add(new Text("!"));reduceDriver.withInput(new Text("M"), valuesM);List<Text> valuesA = new ArrayList<Text>();valuesA.add(new Text("Y\t1.0\t2"));valuesA.add(new Text("|M,Y"));valuesA.add(new Text("!"));reduceDriver.withInput(new Text("A"), valuesA);List<Text> valuesY = new ArrayList<Text>();valuesY.add(new Text("Y\t1.0\t2"));valuesY.add(new Text("|Y,A"));valuesY.add(new Text("!"));valuesY.add(new Text("A\t1.0\t2"));reduceDriver.withInput(new Text("Y"), valuesY);reduceDriver.withOutput(new Text("A"), new Text("0.6\tM,Y"));reduceDriver.withOutput(new Text("M"), new Text("1.4000001\tM"));reduceDriver.withOutput(new Text("Y"), new Text("1.0\tY,A"));reduceDriver.runTest(false);}
}

如图所示,映射器的输出被重新创建为输入,我们检查reducer的输出是否与页面等级计算的第一次迭代相匹配。 每次迭代将导致相同的输出格式,但可能具有不同的页面等级值。
最后一步是“订购”部分。 这非常简单,单元测试也是如此。 这部分仅包含一个映射器,该映射器获取上一步的输出并将其“重新格式化”为所需的格式:pagerank +按pagerank的页面顺序。 当将映射器结果提供给化简器步骤时,按键进行排序是由Hadoop框架完成的,因此该排序不会反映在Mapper单元测试中。 此单元测试的代码是:

package net.pascalalma.hadoop.job3;
...
public class RankingMapperTest {MapDriver<LongWritable, Text, FloatWritable, Text> mapDriver;@Beforepublic void setUp() {RankingMapper mapper = new RankingMapper();mapDriver = MapDriver.newMapDriver(mapper);}@Testpublic void testMapper() throws IOException {mapDriver.withInput(new LongWritable(1), new Text("A\t0.454545\tM,Y"));mapDriver.withInput(new LongWritable(2), new Text("M\t1.90\tM"));mapDriver.withInput(new LongWritable(3), new Text("Y\t0.68898\tY,A"));//Please note that we cannot check for ordering here because that is done by Hadoop after the Map phasemapDriver.withOutput(new FloatWritable(0.454545f), new Text("A"));mapDriver.withOutput(new FloatWritable(1.9f), new Text("M"));mapDriver.withOutput(new FloatWritable(0.68898f), new Text("Y"));mapDriver.runTest(false);}
}

因此,在这里,我们只检查映射器是否接受输入并正确格式化输出。

总结了单元测试的所有示例。 通过这个项目,您应该能够自己对其进行测试,并且对原始代码的工作方式有更深入的了解。 它肯定有助于我理解它!

  • 包括单元测试在内的完整代码版本可以在这里找到。

翻译自: https://www.javacodegeeks.com/2015/02/calculate-pageranks-apache-hadoop.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享一篇关于奇异值分解的文章[Eng]

原文地址&#xff1a;http://www.igvita.com/2007/01/15/svd-recommendation-system-in-ruby/ One day, a bunch of friends, who happened to be big Family Guy fans, decided to put together a site to rank and share their thoughts on the show. Soon thereafter they h…

为雅安祈福

四川是个多灾多难的省份&#xff0c;更是个多地震的省份&#xff0c;十年之内发生了两次大地震。我们能做的就是为雅安的人们祈福。 淘宝给互联网带头了&#xff1a; 天猫也跟着祈福了&#xff0c;因为他们都属于阿里巴巴&#xff0c;这里就不上图了。 百度作为国内互联网企业的…

在运行时打开GC日志记录

总是有下一个JVM表现不佳。 而且&#xff0c;您内心深知&#xff0c;如果您只有少数启动选项可以公开一些有关正在发生的事情的信息&#xff0c;那么您可能就有机会真正修复该死的东西。 但是不&#xff0c;您需要的标志&#xff08; -XX&#xff1a; HeapDumpOnOutOfMemoryErr…

jpannel设置位置xy_实用的摄影技巧!10种常见摄影场景的单反相机设置技巧!

相机是爱拍一族必不可少的东西&#xff0c;对于摄影爱好者对于一些相机设置技巧可能也不是太了解&#xff0c;在摄影过程中&#xff0c;有很多的场景需要不同的设置&#xff0c;根据光线变化和周围环境&#xff0c;一般来说都会特定的摄影技巧&#xff0c;今天红视觉和大家一起…

Only digits (0-9) can be put inside [] in the path string: formData.XXX

使用uniapp开发时微信小程序中爆出的问题&#xff0c;问题在于form表单组件中绑定表单值,去除报错值则正常。 解决办法如下&#xff1a; 修改注释行内容&#xff0c; 转载连接

外包以小时计算金额的费用_2020年初级会计各大税种的计算公式,请收藏!

一、各种税的计算方式增值税1、一般纳税人应纳税额销项税额—进项税销项税额销售额税率组成计税价格成本(1成本利润率)组成计税价格成本(1成本利润率)(1-消费税税率)2、进口货物应纳税额组成计税价格税率组成计税价格关税完税价格关税(消费税)3、小规模纳税人应纳税额销售额征收…

VSCode设置ESLint语法检查

转载 "eslint.validate": ["javascript","javascriptreact","vue-html",{"language": "vue","autoFix": true}],"eslint.run": "onSave","eslint.autoFixOnSave": true…

次要GC,主要GC与完整GC

在使用Plumbr中的GC暂停检测功能时&#xff0c;我被迫通过大量有关该主题的文章&#xff0c;书籍和演示工作。 在整个旅程中&#xff0c;我多次对次要&#xff0c;主要和完全GC事件的使用&#xff08;误用&#xff09;感到困惑。 这导致了这篇博客文章&#xff0c;我希望我设法…

怎么改字段名称_精装房这么改!换门框,封阳台,效果出来比毛坯房还好

最近有朋友后台留言&#xff0c;称自己原本想一步到位购买精装房&#xff0c;但收房验收时才发现根本不合心意&#xff0c;空间利用率太低配色也老气&#xff0c;已经打算重新改装了。所谓精装房就是开发商将地板、门、厨房、卫生间、少量天花和部分柜子进行安装,业主只要添加些…

ZF2系列 – Zend Framework 2 MVC實作 (Part 3)

我之所以這麼喜歡Zend Framework的關係&#xff0c;其中一項就是它可以幫你很簡單的實現MVC的架構&#xff0c;所以今天的任務就是要建立一個以MVC為架構的基本網頁。 首先當然要先建立一個測試用的資料庫&#xff0c;因此我簡單的建立了一個名為Employee的資料表來進行展示&am…

方向盘左右能摇动_学车这么久了,你还不会打方向盘呢?

刚刚学车的朋友肯定有过这样的问题&#xff1a;教练说&#xff1a;往左打两圈&#xff0c;往右打一圈&#xff0c;往左打半圈……你乖乖听话照做&#xff0c;然后教练说&#xff1a;回正吧。是不是一下就蒙住了&#xff1f;&#xff1f;我刚才打几圈来着&#xff1f;&#xff1…

Asp.Net基础 - 9.Web开发原则

目录&#xff1a; 9.1.Web开发的一些基本原则 9.2 原则一 9.2.1 C#代码是运行在服务器端的&#xff0c;JS代码是运行在浏览器客户端的 9.2.2 在服务器端“弹出消息窗口” 9.2.3 案例说明&#xff08;客户端与服务端互不影响&#xff09; 9.3 原则二 9.4 原则三 9.4.1 客户端…

重置手机_【轻松办税】ITS客户端申报密码重置不会操作?看过来,3分钟包你会!...

ITS扣缴客户端实名办税功能已经上线了&#xff0c;并且在2020年1月1日后将不再支持以CA方式进行登录&#xff0c;可是公司申报密码是很久前去大厅办理的&#xff0c;早就忘记了&#xff0c;这可咋好&#xff1f;别急&#xff0c;快来关注“上海税务”&#xff0c;包你3分钟学会…

Drools 6.2.0.Final发布

我们很高兴宣布最新&#xff0c;最出色的Drools 6.2.0.Final版本。 特别是此发行版更加注重改进的可用性和功能&#xff0c;这些功能使项目更易于使用&#xff08;和采用&#xff09;。 新功能包括对工作台UI的大量改进&#xff0c;对社交活动和插件管理的支持以及规则的全新E…

对OIM Web(UI)层进行压力测试

Oracle IDM中的默认配置保留20个专用于服务前端&#xff08;UI&#xff09;请求的线程 。 从根本上讲&#xff0c;这意味着应用程序服务器具有20个线程池&#xff0c;可用于为通过Web控制台&#xff08;/ identity或/ sysadmin&#xff09;访问OIM的用户提供服务。 对于Weblog…

java 拼接html_程序员用1.5小时写出的Java代码,让同事瞠目结舌!直呼优秀

1.曾经不止一次在生产中见过类似这样的代码&#xff1a;这有很多变种&#xff0c;例如用 Integer.valueOf(1)、 (Integer)1 之类的&#xff0c;那些细节都不重要。重要的是&#xff1a;凭空用一个 Integer 对象作为锁对象。2.AbstractComponentBuilderTemplateFactory3.HelloWo…

本地项目antd 修改.less文件导致内存溢出

项目场景&#xff1a; antd 项目&#xff0c;修改less文件会导致内存溢出 问题描述 本地环境antd 项目&#xff0c;修改less文件会导致内存溢出&#xff1b;如下 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory原因分析&#xff1a; 这…

序列化代理模式

在上一篇文章中 &#xff0c;我谈到了一般的序列化。 这是更加集中的内容&#xff0c;并提供了一个细节&#xff1a; 序列化代理模式 。 这是处理序列化许多问题的一种好方法&#xff0c;通常是最好的方法。 如果开发人员只想了解有关该主题的一件事&#xff0c;我会告诉他。 …

函数分组学通MongoDB——第三天 细说高级操作

改章节个人在广东喝咖啡的时候突然想到的...明天就有想写几篇关于函数分组的文章&#xff0c;所以回家到后之就奋笔疾书的写出来发布了 明天跟大家分享一下mongodb中比拟好玩的识知&#xff0c;要主括包&#xff1a;聚合&#xff0c;标游。 一&#xff1a; 聚合 见常的聚合作操…

eps如何建立立体白模_服装立体裁剪教程 结构都是“立裁”出来的 才智服装

核心提示&#xff1a;基础立裁服装立体裁剪是指用白坯布为常用替代物&#xff0c;在人台上直接塑造服装样式&#xff0c;并进行样板制作的技术。由于立体裁剪是设计师主要依靠视觉进行的直观操作的过程&#xff0c;所以它具有激发和展开新的设计思维的功能。一、基础立裁服装立…