hadoop2.5.2学习12-MR之PageRank

一、PageRank是什么

  PageRank的Page可是认为是网页,表示网页排名,也可以认为是Larry Page(google 产品经理),因为他是这个算法的发明者之一,还是google CEO(^_^)。PageRank算法计算每一个网页的PageRank值,然后根据这个值的大小对网页的重要性进行排序。它的思想是模拟一个悠闲的上网者,上网者首先随机选择一个网页打开,然后在这个网页上呆了几分钟后,跳转到该网页所指向的链接,这样无所事事、漫无目的地在网页上跳来跳去,PageRank就是估计这个悠闲的上网者分布在各个网页上的概率

二、PageRank原理

入链==投票

  PageRank让链接来进行”投票”, 到一个页面的超链接相当于对该页面投一票

入链的数量

  果一个页面节点接收到其他页面指向的入链越多,那么这个页面越重要

入链的质量

  指向A页面的入链质量不同,质量越高的页面指向A, 会传递更高的权重,如在董事会中, 核心董事成员可能一票相当于10票, 核心董事成员的一票肯定比普通董事成员一票更重要。
PageRank算法刚开始赋予每个网页相同的重要性得分,通过迭代递归计算来更新每个页面节点的PageRank得分,直到得分稳定为止

网络上的各个页面的链接图

这里写图片描述
PageRank的计算步骤:

  1)在初始阶段:网页通过链接关系构建起链接图,每个页面设置相同的PageRank值,通过若干轮的计算,会得到每个页面所获得的最终PageRank值。随着每一轮的计算进行,网页当前的PageRank值会不断得到更新。

  2)在一轮中更新页面PageRank得分的计算方法:在一轮更新页面PageRank得分的计算中,每个页面将其当前的PageRank值平均分配到本页面包含的出链上,这样每个链接即获得了相应的权值。而每个页面将所有指向本页面的入链所传入的权值求和,即可得到新的PageRank得分。当每个页面都获得了更新后的PageRank值,就完成了一轮PageRank计算。
这里写图片描述

PageRank的收敛

这里写图片描述

这里写图片描述

三、算法实现

原始数据为:

当前节点      出链节点1  出链节点2 
A   B   D

通过迭代计算每个节点的PR值

A   0.9    B      D

3.1、设置节点对象,

每个节点包含内容:

  • PR值
  • 出链的节点

所以创建一个节点类,具有的属性:

    //每个页面的出事pr值为1.0
    private double pageRank=1.0;
    //该节点的出链指向的节点
    private String[] adjacentNodeNames;

我们为了使用数据输出格式化, 创建一个分割符

    //各个节点的分隔符
    public static final char fieldSeparator = '\t';

重写头String(), 打印Node的节点信息, 输出成一个字符串
每个节点打印信息:PageRank值 出链节点1 出链节点2 …

    @Override
    public String toString() {//每个节点打印信息:PageRank值       出链节点1      出链节点2   ...
        StringBuilder sb = new StringBuilder();
        sb.append(pageRank);
        if (getAdjacentNodeNames() != null) {
            sb.append(fieldSeparator)
            .append(StringUtils
                    .join(getAdjacentNodeNames(), fieldSeparator));
        }
        return sb.toString();
    }

同时提供一个方法,通过PR值,及出链节点,将字符串信息恢复成一个Node对象。
给定的字符串:PR值 出链节点1 出链节点


    /**
     * @param value  给定一个字符串  value =1.0    B   D 
     * @return      将这个字符串1封装成Node对象。
     */
    public static Node fromMR(String value) throws IOException {
        String[] parts = StringUtils.splitPreserveAllTokens(
                value, fieldSeparator);
        if (parts.length < 1) {
            throw new IOException(
                    "Expected 1 or more parts but received " + parts.length);
        }
        Node node = new Node()
        .setPageRank(Double.valueOf(parts[0]));
        if (parts.length > 1) {
            node.setAdjacentNodeNames(Arrays.copyOfRange(parts, 1,
                    parts.length));
        }
        return node;
    }

节点的完整类Node:

package com.chb.pagerank;
import java.io.IOException;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
public class Node {
    //每个页面的出事pr值为1.0
    private double pageRank=1.0;
    //该节点的出链指向的节点
    private String[] adjacentNodeNames;
    //各个节点的分隔符
    public static final char fieldSeparator = '\t';

    public double getPageRank() {
        return pageRank;
    }

    public Node setPageRank(double pageRank) {
        this.pageRank = pageRank;
        return this;
    }

    public String[] getAdjacentNodeNames() {
        return adjacentNodeNames;
    }

    public Node setAdjacentNodeNames(String[] adjacentNodeNames) {
        this.adjacentNodeNames = adjacentNodeNames;
        return this;
    }
    //判断是否有出链节点
    public boolean containsAdjacentNodes() {
        return adjacentNodeNames != null && adjacentNodeNames.length>0;
    }

    @Override
    public String toString() {//每个节点打印信息:PageRank值       出链节点1      出链节点2   ...
        StringBuilder sb = new StringBuilder();
        sb.append(pageRank);
        if (getAdjacentNodeNames() != null) {
            sb.append(fieldSeparator)
            .append(StringUtils
                    .join(getAdjacentNodeNames(), fieldSeparator));
        }
        return sb.toString();
    }

    /**
     * @param value  给定一个字符串  value =1.0    B   D 
     * @return      将这个字符串1封装成Node对象。
     */
    public static Node fromMR(String value) throws IOException {
        String[] parts = StringUtils.splitPreserveAllTokens(
                value, fieldSeparator);
        if (parts.length < 1) {
            throw new IOException(
                    "Expected 1 or more parts but received " + parts.length);
        }
        Node node = new Node()
        .setPageRank(Double.valueOf(parts[0]));
        if (parts.length > 1) {
            node.setAdjacentNodeNames(Arrays.copyOfRange(parts, 1,
                    parts.length));
        }
        return node;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值