PageRank 简单理解为网页排名,但是网页是根据什么排名的,接下来就简单介绍一下。

举例:

假设网页 A 的内容中有网页 B,C 和 D 的链接,并且 A 的 PageRank的值为0.25。

那接下里我们就可以计算在网页 A 中的其他网页的PageRank的值了。我们拿网页 B 来进行说明,

在网页 A 中的网页 B 的 PageRank 为 0.25 * (1/n) 其中n为网页 A 中网页链接数,结果则为 0.25*(1/3)。

可以简单理解为A的PageRank被B,C 和 D 平分了,B分到了0.25的三分之一。

然后将所有网页中的关于网页B的pagerank值求出来,就是网页B真实的pagerank了。

但是上面的例子没有考虑到如下的特殊情况:

1 网页A中只有指向自己的网页链接。

2 网页A中没有任何链接。

如果出现以上情况,会导致pagerank结果不准确。

所以出现了下面的公式:

result = sum * n + (1-n)/N

sum 为上面计算出来的,如网页B在所有网页中的pagerank值的总和。

n 可以理解为停留在当前网页继续进行网页跳转浏览的概率

1-n 可以理解为不访问当前网页的任何链接,从浏览器的地址栏输入,转去其他网页的概率。

N 为网页的数量

下面介绍通过MapReduce实现PageRank

简单的流程分析:

Map

取一行数据进行说明

A    B    C    D

网页A中有网页B,C,D的链接;

刚开始给网页A一个默认的pagerank值,然后根据这个值计算其他网页链接在网页A中的PageRank。处理后的数据如下:

A    0.25    B    C    D
B 0.25*(/)
C 0.25*(/)
D 0.25*(/)

Reduce

然后通过 Reduce 计算出各个网页在其他网页中的 PageRank 的总和 sum,然后代入公式计算实际的PageRank,并更新 A 0.25 B C D 中的数据,这里将0.25更新为计算出来真实的 PageRank。

重复计算各个网页的 PageRank 的值,直到 PageRank 的结果收敛,值趋于稳定。

A    0.25    B    C    D  =>A    ?    B    C    D

测试数据:

A    B       C       D
B A D
C C
D B C

测试代码:

RunJob.java

 import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException; /**
* Created by Edward on 2016/7/13.
*/
public class RunJob { public static enum ValueEnum{
CLOSURE_VALUE;
} public static void main(String[] args)
{ //access hdfs's user
System.setProperty("HADOOP_USER_NAME","root"); Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://node1:8020"); try {
int i = 0;
while(true) {
i++;
conf.setInt("count", i); FileSystem fs = FileSystem.get(conf);
Job job = Job.getInstance(conf);
job.setJarByClass(RunJob.class);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class); //需要指定 map out 的 key 和 value
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class); //设置输入类的
job.setInputFormatClass(KeyValueTextInputFormat.class);
if(i==1)
FileInputFormat.addInputPath(job, new Path("/test/pagerank/input"));
else
FileInputFormat.addInputPath(job, new Path("/test/pagerank/output/pr"+(i-1))); Path path = new Path("/test/pagerank/output/pr"+i);
if (fs.exists(path))//如果目录存在,则删除目录
{
fs.delete(path, true);
}
FileOutputFormat.setOutputPath(job, path); boolean b = job.waitForCompletion(true);
if (b) {
long closure =job.getCounters().findCounter(ValueEnum.CLOSURE_VALUE).getValue();
double avg= closure/4000.0;//计算收敛的平均值,浮动小于0.001则认为收敛
System.out.println("执行第"+i+"次, closure="+closure+",avg="+avg);
if(avg < 0.001){
System.out.println("总共执行了"+i+"次,之后收敛");
break;
}
}
} } catch (Exception e) {
e.printStackTrace();
}
} public static class MyMapper extends Mapper<Text, Text, Text, Text> {
@Override
protected void map(Text key, Text value, Context context) throws IOException, InterruptedException {
AdjacentNodes adjacentNodes = new AdjacentNodes();
int count = context.getConfiguration().getInt("count", 1); if(count == 1)
{
AdjacentNodes firstAdj = new AdjacentNodes();
firstAdj.setValue(1.0);
firstAdj.setNodes(value.toString().split("\t"));
adjacentNodes = firstAdj;
}
else
{
//格式化 value: 1.0 B C D
adjacentNodes.formatInfo(value.toString());
}
//A 1.0 B C D
context.write(key, new Text(adjacentNodes.toString())); double pagerank = adjacentNodes.getValue()/adjacentNodes.getNum();
for(int i=0; i<adjacentNodes.getNum(); i++)
{
String node = adjacentNodes.getNodes()[i];
//B 0.333
context.write(new Text(node), new Text(pagerank+""));
}
}
} public static class MyReducer extends Reducer<Text, Text, Text, Text> {
@Override
protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { AdjacentNodes adjacentNodes = new AdjacentNodes(); Double sum = 0.0;
for(Text adj : values)
{
String str = adj.toString();
if(str.split("\t").length>1)
{
adjacentNodes.formatInfo(str);
}
else{
sum += Double.parseDouble(str); //对节点的 pagerank 求和,
}
} //计算pagerank
double n = 0.80;
double pagerank = sum * n + (1-n)/4.0;// 计算pagerank 公式 sum * n + (1-n)/N //计算收敛的差值
int closure =(int)(Math.abs(pagerank - adjacentNodes.getValue()) * 1000);
//通过context.getCounter(ENUM)方法,每次执行reduce将closure的值进行累加,结果传递给主函数, context.getCounter(ValueEnum.CLOSURE_VALUE).increment(closure); adjacentNodes.setValue(pagerank);
context.write(key, new Text(adjacentNodes.toString()));
}
}
}

AdjacentNodes.java
/**
* Created by Edward on 2016/7/14.
*/
public class AdjacentNodes { double value = 0.0;
int num = 0;
String[] nodes = null; public void formatInfo(String str)
{
String[] val = str.split("\t");
this.setValue(Double.parseDouble(val[0]));
this.setNum(val.length-1); if(this.num != 0)
this.nodes = new String[this.num]; for(int i=1; i<val.length; i++)
{
this.nodes[i-1] = val[i];
}
} public boolean isEmpty()
{
if(this.num == 0)
return true;
else
return false;
} public void setNodes(String[] nodes) {
this.nodes = nodes;
this.num = nodes.length;
} public void setNum(int num) {
this.num = num;
} public void setValue(double value) {
this.value = value;
} public double getValue() {
return value;
} public int getNum() {
return num;
} public String[] getNodes() {
return nodes;
} @Override
public String toString() { StringBuffer stringBuffer = new StringBuffer(this.value+""); for(int i=0; i<this.num; i++)
{
stringBuffer.append("\t"+this.nodes[i]);
} return stringBuffer.toString();
}
}

结果数据:

A       0.10135294176208584     B       C       D
B 0.12838069628609527 A D
C 0.6560527651143326 C
D 0.12838069628609527 B C

总共执行了24次,之后收敛;

PageRank值越高,越值得推荐。

Mapreduce -- PageRank的更多相关文章

  1. Hadoop实战训练————MapReduce实现PageRank算法

    经过一段时间的学习,对于Hadoop有了一些了解,于是决定用MapReduce实现PageRank算法,以下简称PR 先简单介绍一下PR算法(摘自百度百科:https://baike.baidu.co ...

  2. PageRank算法简介及Map-Reduce实现

    PageRank对网页排名的算法,曾是Google发家致富的法宝.以前虽然有实验过,但理解还是不透彻,这几天又看了一下,这里总结一下PageRank算法的基本原理. 一.什么是pagerank Pag ...

  3. mapReduce编程之google pageRank

    1 pagerank算法介绍 1.1 pagerank的假设 数量假设:每个网页都会给它的链接网页投票,假设这个网页有n个链接,则该网页给每个链接平分投1/n票. 质量假设:一个网页的pagerank ...

  4. mapreduce 实现pagerank

    输入格式: A 1 B,C,D B 1 C,Dmap: B A 1/3 C A 1/3 D A 1/3 A |B,C,D C B 1/2 D B 1/2 B |C,Dreduce: B (1-0.85 ...

  5. PageRank算法MapReduce实现

    如果你现在需要计算网页的排名只有4一:数据如下面的: baidu 10.00 google,sina,nefu google 10.00 baidu sina 10.00 google nefu 10 ...

  6. MapReduce实现PageRank算法(邻接矩阵法)

    前言 之前写过稀疏图的实现方法,这次写用矩阵存储数据的算法实现,只要会矩阵相乘的话,实现这个就很简单了.如果有不懂的可以先看一下下面两篇随笔. MapReduce实现PageRank算法(稀疏图法) ...

  7. MapReduce实现PageRank算法(稀疏图法)

    前言 本文用Python编写代码,并通过hadoop streaming框架运行. 算法思想 下图是一个网络: 考虑转移矩阵是一个很多的稀疏矩阵,我们可以用稀疏矩阵的形式表示,我们把web图中的每一个 ...

  8. 【Hadoop学习之十一】MapReduce案例分析三-PageRank

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 什么是pagerank?算法原理- ...

  9. Google的PageRank及其Map-reduce应用(日志五)

    上一篇:Hadoop的安装(日志四) 1,算法的原理解释: 如下图所示,G就是传说中的谷歌矩阵,这个矩阵是n*n型号的,n表示共计有n个网页. 如矩阵中所示: 11位置处的元素,是表示第一个网页指向的 ...

随机推荐

  1. HTTP协议学习随笔

    一 HTTP概述 HTTP简单说其实就是一套语言交流规则!Http使用的是可靠的数据传输协议,因此即使数据来自地球的另一端,也能够确保数据在传输过程中不会被损坏或产生混乱. B/S结构 用户在浏览器, ...

  2. .net中反射与IOC容器实现

    反射还是很有用的,比如IOC容器基本上都是通过反射实现的. IOC是什么 IOC:Inversion of Control 控制反转是一种是面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度 ...

  3. 【第三组】心·迹 Alpha版本 成果汇报

    GITHUB地址 https://github.com/shirley-wu/HeartTrace 目录 项目简介 成果概要 详细展示(多图预警) 代码结构及技术难点 问题与规划 1. 项目简介 心· ...

  4. 风险指针(Hazard Pointer) 内存空间共享模型

    WiredTiger是一种高性能的开源存储引擎,现已在MongoDB中作为内模式应用.WiredTiger支持行存储.列存储两种存储模式,采用LSM Tree方式进行索引记录 WiredTiger支持 ...

  5. AWS CSAA -- 04 AWS Object Storage and CDN - S3 Glacier and CloudFront(四)

    026 S3 Summary

  6. 【SPL标准库专题(2)】 Iterator

    Iterator界面 本段内容来自阮一峰老师再加自己的部分注解 SPL规定,所有部署了Iterator界面的class,都可以用在foreach Loop中.Iterator界面中包含5个必须部署的方 ...

  7. 解决:Determining IP Information for eth0...问题

    环境:Centos 6.2     VMWare Workstation 7.1.2  故障现象: 在虚拟机中启动Centos,在启动页面中停留在Determining IP Information ...

  8. 转:在ASP.NET MVC中通过URL路由实现对多语言的支持

    对于一个需要支持多语言的Web应用,一个很常见的使用方式就是通过请求地址来控制界面呈现所基于的语言文化,比如我们在表示请求地址的URL中将上语言文化代码(比如en或者en-US)来指导服务器应该采用怎 ...

  9. 在Ubuntu17.04中遇到无法清空回收站解决方法

    在Ubuntu17.04下,遇到清空回收站文件时报错,提示”Failed to delete the item from the trash”,无法清空回收站. 回收站其实就是一个文件夹,存放着被删掉 ...

  10. 脱壳_00_压缩壳_ASPACK

    写在前面的话: Aspack是最常见的一种压缩壳,具有较好的兼容性.压缩率和稳定性,今天我们就来一起分析一下这个壳: 零.分析压缩壳: 0.在开始动态调试前,用PEID和LoadPE查看一些信息,做到 ...