pagerank是将众多网页看成一个有向图,每个页面就是有向图中的节点。计算每个节点的出度和入度。如果一个网站被大量其他的网页引用,那么他就会有更高的pr分数。

原理

对于所有与节点i相连的节点,用他们的pr值除以他们的出度(一个节点可以给多个节点投票,但是投票的权重会被平摊)

计算转移矩阵。第一列表示A的所有出度 (A->A, A->B, A->C, A->D) ,第一行表示A的所有入度 (A->A, B->A, C->A, D->A)

\[M=\left[\begin{array}{llll}
0 & 0 & \frac{1}{2} & 1 \\
\frac{1}{2} & 0 & 0 & 0 \\
\frac{1}{2} & 1 & 0 & 0 \\
0 & 0 & \frac{1}{2} & 0
\end{array}\right]
\]

用矩阵计算来更新pr值:

\[PR_{i}=\sum_{j \in B_{i}} \frac{PR_{j}}{L_{j}}
\]
\[PR(a)=M * P
\]
\[P_{1}=M \cdot P_{0}=\left[\begin{array}{cccc}
0 & 0 & \frac{1}{2} & 1 \\
\frac{1}{2} & 0 & 0 & 0 \\
\frac{1}{2} & 1 & 0 & 0 \\
0 & 0 & \frac{1}{2} & 0
\end{array}\right] \cdot\left[\begin{array}{c}
\frac{1}{4} \\
\frac{1}{4} \\
\frac{1}{4} \\
\frac{1}{4}
\end{array}\right]=\left[\begin{array}{c}
\frac{3}{8} \\
\frac{1}{8} \\
\frac{3}{8} \\
\frac{1}{4}
\end{array}\right]
\]

\(P\)是它们的pr得分, \(L\)是节点的出度。计算下一层pr的方法就是,把相连的节点的pr都拿过来,但是要同时除以他们的出度。pr的默认值就是\(\frac{1}{n}\)

\(0 * \frac{1}{4} + 0 * \frac{1}{4} + \frac{1}{2} * \frac{1}{4} + 1 * \frac{1}{4} = \frac{3}{8}\)

DeadEnds

当一个节点只有入度没有出度,那么他就是DeadEnds。这个节点会导致整个网页的pagerank值趋于0。



他的转移矩阵M如下,由于他的某一列全为0,导致所有结果都会变成0

\[M=\left[\begin{array}{cccc}
0 & 0 & 0 \\
0 & 0 & 0 \\
1 & 1 & 0 \\
\end{array}\right]
\]

可以看到两轮后就为0了

for i in range(3):
item = a.dot(item)
print(item) # [0. 0. 0.66666667]
# [0. 0. 0.]
# [0. 0. 0.]

修正的方法就是在全为0的那一列加上一个平均值。他的含义就是如果一个页面不链接到任何其他网页,他们他就有可能转换到任何页面。

\[M+a^{T}\left(\frac{e}{n}\right)
\]
  • M 是转移矩阵
  • a 是 n * n 的向量,如果第i个节点的出度为0,那么a的第i列就全为1,否则就全为0.
  • e 是全1的 n * 1 的向量
  • 点乘操作(而不是矩阵运算)

其实就是在对应一列加上一个平均值

\[M=\left[\begin{array}{cccc}
0 & 0 & \frac{1}{3} \\
0 & 0 & \frac{1}{3} \\
1 & 1 & \frac{1}{3} \\
\end{array}\right]
\]

SpiderTraps

一个节点只有指向自己的链接,这种节点的权重在迭代的过程中会变成1,而其他的节点会趋于0.

这种节点的转移矩阵如下:

\[M=\left[\begin{array}{cccc}
1 & \frac{1}{2} & \frac{1}{2} \\
0 & 0 & \frac{1}{2} \\
0 & \frac{1}{2} & 0 \\
\end{array}\right]
\]

由于这个节点的对角线元素是1,所以他的pagerank值会不断增加。他的解决方法就是引入一个概率\(\beta\),用户会有\(\beta\)的概率停留在这个节点,有\(1-\beta\)的概率跳转到其他任何网页。

\[M=\beta M+(1-\beta) \frac{e e^T}{n}
\]
  • \(\beta\)是用户留在网页的概率
  • e是全一的 n * 1 向量,\(ee^T\)就是全一的 n * n矩阵

这样的话,完整的公式如下所示:

\[PR(a)=\left[\beta\left(M+a^{T}\left(\frac{e}{n}\right)\right)+(1-\beta) \frac{ee^T}{n}\right] * PR
\]

networkx实现

import networkx as nx
import matplotlib.pyplot as plt
import random graph = nx.DiGraph()
graph.add_nodes_from(range(0, 100))
for i in range(200):
m = random.randint(0, 100)
n = random.randint(0, 100)
graph.add_edge(m,n) nx.draw(graph, with_labels=True)
plt.show() pr = nx.pagerank(graph, max_iter=100, alpha=0.01)
print(pr)

PageRank原理分析的更多相关文章

  1. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  2. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  3. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  4. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  5. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  6. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  7. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  8. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

  9. (转)Android 系统 root 破解原理分析

    现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的 原理吗?root破解的本质是什么呢?难道是利用了Lin ...

随机推荐

  1. Excel 统计函数(一):SUMIF 和 SUMIFS

    SUMIF [语法]SUMIF(range, criteria, [sum_range]). [参数] range :求和范围 criteria :筛选的条件 sum_range :可选参数,实际的求 ...

  2. 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 官方扩展集锦(Microsoft.Extensions on Nuget)

    什么是Microsoft.Extensions .NET Platform Extensions是一套.Net官方的API集合,提供了一些常用的编程模式和实用工具,例如依赖项注入.日志记录.缓存.Ho ...

  3. tqdm和zip组合使用时无法显示进度条-解决办法

    问题 单独对于可迭代对象iterator使用tqdm时,结合循环就可以在终端显示进度条, 以直观展示程序进度,如下: from tqdm import tqdm textlist = [] for i ...

  4. 教程 - 深度探讨在 Vue3 中引入 CesiumJS 的最佳方式

    目录 1. 你应该先知道的基础知识 1.1. CesiumJS 的库构成 1.2. 选择 Vite3 和 pnpm 的理由 1.3. 使用 External 模式引入静态库 - 不打包静态库 1.4. ...

  5. VS Code 之KoroFileHeader插件

    设置 在vscode左下角点击设置按钮,选择"设置",然后输入"fileheader", 文件头部注释:Fileheader:custom Made 函数注释: ...

  6. 源码(chan,map,GMP,mutex,context)

    目录 1.chan原理 1.1 chan底层数据结构 1.2 创建channel原理 1.3 写入channel原理 1.4 读channel原理 1.5 关闭channel原理 1.6 总结 2.m ...

  7. 让Python更优雅更易读(第二集)

    友情链接 让Python更优雅更易读(第一集) 1.装饰器 1.1装饰器特别适合用来实现以下功能 运行时校验:在执行阶段进行特定校验,当校验通不过时终止执行. 适合原因:装饰器可以方便地在函数执行前介 ...

  8. Java---Stream入门

    由于本文需要有一定的Lambda基础,所以如果不懂什么是Lambda的同学请移步:Java---Lambda 学习Stream的目的 函数式编程渐渐变成主流,而Stream是函数式编程的重点. 相对于 ...

  9. 跟羽夏学 Ghidra ——数据

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...

  10. CI/CD集成

    文章转载自:https://kuboard.cn/guide/cicd/ 下图展示了当前比较典型的持续构建集成的一种做法. 在是否自动将最新版本部署到 Kubernetes 环境这个问题上,可能会有多 ...