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. eclipse java web项目经常自动调试进入debug模式

    今天在运行Javaweb项目时,程序运行运行着就自动调试进入ThreadpoolExecutor,看着非常影响心情.最后在网上搜解决方法最后找到原因,解决方法如下. Window——>Prefe ...

  2. CSS中的三种常用定位

    一.相对定位(position:relative) 如果想让一个元素在本来的位置进行一个位移,可以将该元素的定位设置为relative,同时指定相对位移(利用top,bottom,left,right ...

  3. js多线程(worker)

    浏览器端js是单线程执行,所以当js执行高负载运算时,UI渲染就会阻塞,页面就会出现卡顿,用户体验就不是很好 js为此也提供了异步操作,例如: 定时器(setTimeout 和 setInterval ...

  4. Flutter:修改TextField的高度,以及无边框圆角

    修改TextField的高度可以通过decoration: InputDecoration的contentPadding进行修改,代码如下 new TextField( decoration: Inp ...

  5. springboot 学习之路 18(webflux详细介绍(2))

    webflux的详细介绍 引言:上一节已经简单介绍webflux的一些基本概念,本章继续学习webflux的原理和实战方面的东西: Spring WebFlux架构: note:注意理解上面这张图.下 ...

  6. LeetCode题解之Univalued Binary Tree

    1.题目描述 2.问题分析 遍历一遍树,然后将所有节点的数值放入到一个set中,最后检查set中元素的个数是否为1. 3.代码 bool isUnivalTree(TreeNode* root) { ...

  7. LeetCode题解之Longest Increasing Subsequence

    1.题目描述 2.题目分析 使用动态规划,在计算以每个字符结尾的最长子序列. 3.代码 int lengthOfLIS(vector<int>& nums) { ){ ; } ve ...

  8. 蓝魔i7s刷机

    ,电脑管家,豌豆荚之类的PC工具 5. 安装MFT6.0.43.exe, 注意:MFT6.0.43需要对应的ISOC和USB驱动,不可使用其它版本 6. 将CUSTOM_CONFIG..INI文件复制 ...

  9. wordpress使用七牛云加速

    一.准备工作. wordpress搭建的网站 七牛云账号 二.简要步骤 1.wordpress安装七牛云插件. WordPress七牛镜像存储插件已经被WordPress官方收录,可以直接在wordp ...

  10. jbosscache

    JBossCache 讲解说明 是什么? 一个树形结构.支持集群.支持事务的缓存技术. 有什么作用? JBoss Cache是针对Java应用的企业级集群解决方案,其目的是通过缓存需要频繁访问的Jav ...