我的页面排名总和收敛于0.9

时间:2014-07-18 16:30:11

标签: algorithm web-crawler pagerank

当我计算一组已爬网域的页面排名时,使用0.85的阻尼系数。正如许多页面排名论文中所提到的,页面冲突的总和应该收敛到1.但无论我做了多少迭代,它似乎都收敛于0.90xxx。如果我将阻尼系数降低到0.5,我显然会接近1。

页面排名总和收敛于0.90是不是很糟糕,这通常会牵连什么?

2 个答案:

答案 0 :(得分:7)

是的,这很糟糕,因为它表明您的实施中存在错误。 Pagerank给出一个概率空间,它必须总和为1作为基本的健全性检查。

猜测的问题是您没有处理'sinks' - 没有外向链接的节点。

处理接收器的常用方法是:

  1. 对于接收器vi,将所有节点(vi,vj)视为已存在,除了vi = vj
  2. 完全从图表中删除它们(并重复直到收敛)
  3. 将它们链接回链接到它们的所有节点(如果vi是接收器,对于所有边缘(vj,vi),也添加(vi,vj))。
  4. 考虑以下玩具示例:2页,A,B。 B,B的链接指向任何内容。得到的矩阵是:

    W=
        0      1
        0      0
    

    现在,使用d = 0.85,您可以得到以下等式:

    v = 0.85* W'v + 0.15*[1/2,1/2]
    v1 = 0.85* (0*v1+0*v2) + 0.15*1/2 = 0.15*1/2 = 0.075
    v2 = 0.85*(1*v1 + 0*v2) + 0.15/2 = 0.85v1 + 0.075 = 0.006375 + 0.075 = 0.13875 
    

    总和不是1.

    但是,如果你处理接收器,采用一种建议的方法(让我们检查方法(1)),你会得到:

    W =
       0     1
       1     0
    

    现在您将获得一组方程式:

    v = 0.85* W'v + 0.15*[1/2,1/2]
    v1 = 0.85* (0*v1+1*v2) + 0.15*1/2 = 0.85v2 + 0.075
    v2 = 0.85*(1*v1 + 0*v2) + 0.15/2 = 0.85v1 + 0.075  (/0.85)-> 1/0.85 * v2 = v1 + 0.075/0.85
    -> (add 2 equations)
    1/0.85*v2 + v1 = 0.85v2 + 0.075 + v1 + 0.075/0.85 
    -> (approximately)
    0.326*v2 = 0.163
    v2 = 0.5
    

    正如您所看到的,通过使用此方法,我们得到了一个概率空间,现在,正如预期的那样,所有节点的页面排名总和为1.

答案 1 :(得分:0)

这成了算法:

// data structures

private HashMap<String, Double> pageRanks;
private HashMap<String, Double> oldRanks;
private HashMap<String, Integer> numberOutlinks;
private HashMap<String, HashMap<String, Integer>> inlinks;
private HashSet<String> domainsWithNoOutlinks;
private double N;

// data parsing occluded

public void startAlgorithm() {
    int maxIterations = 20;
    int itr = 0;
    double d = 0.85;
    double dp = 0;
    double dpp = (1 - d) / N;

    // initialize pagerank
    for (String s : oldRanks.keySet()) {
        oldRanks.put(s, 1.0 / N);
    }

    System.out.println("Starting page rank iterations..");
    while (maxIterations >= itr) {
        System.out.println("Iteration: " + itr);
        dp = 0;
        // teleport probability
        for (String domain : domainsWithNoOutlinks) {
            dp = dp + d * oldRanks.get(domain) / N;
        }
        for (String domain : oldRanks.keySet()) {
            pageRanks.put(domain, dp + dpp);

            for (String inlink : inlinks.get(domain).keySet()) { // for every inlink of domain
                pageRanks.put(domain, pageRanks.get(domain) + inlinks.get(domain).get(inlink) * d * oldRanks.get(inlink) / numberOutlinks.get(inlink));
            }
        }
        // update pageranks with new values
        for (String domain : pageRanks.keySet()) {
            oldRanks.put(domain, pageRanks.get(domain));
        }

        itr++;
    }
}

这一行是重要的一行:

pageRanks.put(domain, pageRanks.get(domain) + inlinks.get(domain).get(inlink) * d * oldRanks.get(inlink) / numberOutlinks.get(inlink));

inlinks.get(domain).get(inlink)返回当前域的链接“喜欢/引用”多少,我们将它除以当前域有多少个链接。并且“inlinks.get(domain).get(inlink)”是我在算法中遗漏的因此为什么总和没有收敛于1。

了解详情:http://www.ccs.northeastern.edu/home/daikeshi/notes/PageRank.pdf