pagerank算法_马尔科夫链, PageRank算法, 与代数图论

马尔科夫链是一种时间离散的随机过程。因为时间是离散的,所以我们可以用整数

来表示时间指标。在每一个时刻
,马尔科夫链都可以用一个状态向量
来表示。随着时间的推移,状态向量也在演化。我们可以用一个矩阵将时刻
到时刻
状态向量联系起来:

这个矩阵

叫做马尔科夫矩阵。因为它表示不同时刻状态间的转移,所以又叫做转移矩阵。该矩阵应该满足一系列的性质,这些性质将会在下面举例说明。

马尔科夫链的一个特征是无记忆性,也就是马尔科夫链的演化只依赖于当前状态,而不依赖于过去的历史。现实世界中很多过程都可以简化为一个马尔科夫链。一个例子就是一维的随机游走。假设有一个被限制在一维空间的粒子,这个粒子每次以概率

向左移动一步,以概率
向右移动一步,并且每次粒子移动都不依赖于过去的历史,那么这个粒子的运动就是一个马尔科夫过程。进一步假设粒子的运动步长是固定的,也就是粒子的位置取值只能是离散的,那么这又是一个马尔科夫链。

第一节:一个简单的马尔科夫链

我们很有可能在高中时就已经接触到马尔科夫链了。这里有一道高中数学问题:

某城市有两个超市,分别记作A和B. 每次去A超市的人有20%下次仍然去A超市,其余的80%去B超市;每次去B超市的人有40%下次仍然去B超市,其余的60%去A超市。请问,经过足够长的时间后,去这A超市的人口和去B超市的人数比例会不会趋近于一个常数?如果会,请问这个常数为多少?

我们可以记第

次去A超市的人数为
,去B超市的人数为
. 于是,我们可以得到一个递归关系:

用矩阵表示为

这里得到了一个转移矩阵

.

使用递归,很容易得到

这是一个简单的马尔科夫链。对于每一个

,马尔科夫链的状态都可以用两个数字
完全表示出来。
时刻的状态可以用
时刻的状态唯一地表示出来,而不依赖于此前的历史,这正是马尔科夫链的性质。很容易证明,去A超市的人数与去B超市的人数的和是一个常数,因为:

这里已经涉及到了马尔科夫矩阵的一个重要性质,就是该矩阵的每一列的元素求和都是1. 因此,马尔科夫矩阵满足这个条件:

其中,

是元素全都是1的长度等于马尔科夫矩阵列数的列向量。很容易证明,
也满足这个条件。进一步可以证明,
的任意次正数幂都满足这个条件。将这条件两边取转置,得到

于是我们得到了矩阵

的一个特征值为1,它所对应的特征向量为
. 因为
有相同的特征值(特征向量未必一样),所以我们知道1也是马尔科夫矩阵的特征值。根据 Gershgorin circle theorem,我们知道马尔科夫矩阵的特征值不可能大于1. 因为该矩阵的每一个元素都大于0, 根据Perron-Frobenius theorem, 我们知道该矩阵除了一个等于1的特征值之外,其余所有的特征值的绝对值都小于1. 对于矩阵
,我们可以将它对角化得到

其中

.

马尔科夫矩阵的

次幂为

当幂为无穷大的时候,我们得到

所以经过足够长的时间后,去A超市的人数趋近于

,去B超市的人数趋近于
. 我们称状态向量
为马尔科夫链的稳态,经过归一化,我们知道稳态向量不依赖于初始条件。最后去A超市的人数与B超市的人数的比例为3:4.

第二节:马尔科夫矩阵

上一节已经引入了马尔科夫矩阵,并用这个矩阵求解了一个简单的马尔科夫链问题。这一节里,我要将上一节的内容系统化。因为马尔科夫矩阵表示了状态间的转移概率,所以马尔科夫矩阵的每一个元素都应该是非负的。记马尔科夫矩阵元素为

. 该元素表示系统从状态
转移到状态
的概率。例如,上一节中马尔科夫矩阵为
.
为系统从状态1(A超市)转移到状态1(A超市)的概率,
表示系统从状态2(B超市)转移到状态1(A超市)的概率,等等。因为我们的状态空间是完备的,也就是系统只能从一个状态转移到另外一个状态,所以马尔科夫矩阵的每一列求和都为1, 也就是
. 用矩阵表示为

这个性质决定了马尔科夫矩阵一定有一个值为1的特征值。而且可以根据 Gershgorin circle theorem 得到马尔科夫矩阵的任意一个特征值的绝对值都不可能大于一。为了得到马尔科夫矩阵的稳态解,我们需要计算马尔科夫矩阵的幂。当幂次为无穷大时,如果得到的矩阵是收敛的话,我们就把得到的矩阵称作是马尔科夫链的稳态矩阵。如果马尔科夫矩阵只有一个绝对值等于1的特征值,那么得到的幂矩阵一定是收敛的。相反,如果马尔科夫矩阵还有其它绝对值等于1的特征值,那么这个马尔科夫链就没有稳态解。通过幂矩阵的方法计算马尔科夫链稳态解的方法叫做power iteration method. Power iteration - Wikipedia 这个方法其实就是在计算马尔科夫矩阵特征值为1所对应的特征向量,该特征向量又叫做 Perron-Frobenius 向量。记

时刻马尔科夫链的状态向量为
,我们有状态向量的递归关系:

假设

存在,对两边同时求极限,得到

所以稳态向量

为马尔科夫矩阵对应着特征值为1的特征向量,该向量又可以看做是映射
的不动点。因此,只要我们知道了特征值为1的特征向量,我们就可以得到马尔科夫链的稳态解(如果这个稳态解存在的话)。下面我将要简单介绍一下power iteration method.

Power iteration method 为,对于一个可对角化的矩阵

,为了计算它绝对值为最大的那个特征值所对应的特征向量,我们可以使用这个递归公式:

实际用这个算法计算特征向量的时候,我们需要先选取一个任意非零的初始向量

,然后代入上面的式子做迭代,直到连续两次的迭代结果差异在误差范围内。用Python实现如下:
import numpy as np

def power_iteration(A):
    (row, col) = A.shape
    assert(row == col)
    dimension = row
    v = np.random.rand(dimension)
    counter = 0
    iteration_max = 1000
    eps = 1.0e-15
    while(counter < iteration_max):
        counter += 1
        v_updated = A.dot(v)
        v_updated = v_updated/np.linalg.norm(v_updated)
        error = min(np.linalg.norm(v - v_updated), np.linalg.norm(v + v_updated))
        print "counter = " + str(counter) + ", error = " + str(error)
        if (error < eps):
            break
        v = v_updated
    eigenvalue = v_updated.dot(A).dot(v_updated)/v_updated.dot(v_updated)
    return (eigenvalue, v_updated)

经过测试,该算法可以给出正确的最大特征值和它所对应的特征向量。测试代码如下:

import numpy as np
def generate_matrix(dimension):
    assert(dimension >= 2)
    A = np.zeros((dimension, dimension))
    for i in range(dimension):
        for j in range(dimension):
            A[i, j] = np.random.uniform()
    return A

def find_leading_eig(A):
    (eigenvalues, eigenvectors) = np.linalg.eig(A)
    leading_eigenvalue = abs(eigenvalues[0])
    leading_index = 0
    for i in range(1, len(eigenvalues)):
        if (leading_eigenvalue < abs(eigenvalues[i])):
            leading_index = i
            leading_eigenvalue = abs(eigenvalues[i])
    return (eigenvalues[leading_index], eigenvectors[:, leading_index])

def is_proportional(a, b):
    assert(len(a) == len(b))
    eps = 1.0e-15
    norm_a = np.linalg.norm(a, 1)
    norm_b = np.linalg.norm(b, 1)
    if (norm_a < eps and norm_b < eps):
        return True
    if (norm_a * norm_b < eps):
        return False
    a_normalized = a/norm_a
    b_normalized = b/norm_b
    #print ", ".join(map(str, a_normalized))
    #print ", ".join(map(str, b_normalized))
    error = min(np.linalg.norm(a_normalized - b_normalized), np.linalg.norm(a_normalized + b_normalized))
    print "Difference of two leading eigenvectors = " + str(error)
    if error < eps:
        return True
    return False

def main():
    import sys
    if (len(sys.argv) != 2):
        print "dimension = sys.argv[1]. "
        return -1
    dimension = int(sys.argv[1])
    A = generate_matrix(dimension)
    (eigenvalue, eigenvector) = power_iteration(A)
    print "leading eigenvalue = " + str(eigenvalue)
    print "leading eigenvector = "
    print eigenvector
    (leading_eigenvalue, leading_eigenvector) = find_leading_eig(A)
    print leading_eigenvalue
    print leading_eigenvector
    print "eigenvalue error = " + str(abs(eigenvalue - leading_eigenvalue))
    print "consistent leading eigenvector? " + str(is_proportional(eigenvector, leading_eigenvector))
    return 0

if __name__ == "__main__":
    import sys
    sys.exit(main())

使用这个算法计算矩阵的最大特征值有它的局限性。为了知道它的局限性,我们首先需要知道这个算法为什么成立。对于一个可对角化的

矩阵
,它有
个线性无关的特征向量,这
个特征向量可以张满整个
维欧氏空间。也就是任意一个
维向量都可以唯一地表示为这
个特征向量的线性组合:

其中

为表示系数,
为矩阵
的特征向量。这些特征向量线性独立,但是未必彼此正交。将
作用到这个向量上,得到

其中

. 记绝对值最大的矩阵特征值为
. 将上面的式子两边同时除以
,得到

对于任意的特征值,我们都有

. 进一步假设除了
之外,矩阵所有其他的特征值的绝对值都小于
. 那么当
时,我们有

这里,

为特征值
所对应的特征向量。因为我们只关心特征向量的方向,所以特征向量乘以任意一个非零系数后得到的结果仍然是特征向量。实际使用该算法时,我们很有可能不知道
的值,所以我们不能通过计算
来得到矩阵的特征向量,而是每计算一次
都把它归一化一次,这样我们就可以在不知道最大特征值的前提下就可以得到矩阵的最大特征向量。知道了最大特征向量后,我们就可以根据定义得到最大特征值为:

在推导这个算法的时候,我们做了两个假设.

  • 假设一:矩阵
    是可对角化的。
  • 假设二:矩阵
    的绝对值为最大的特征值是唯一的。

这两个假设未必成立。有的矩阵是不可对角化的。不可对角化的矩阵称作是defective matrix. 对于不可对角化的

矩阵,它没有
个线性无关的特征向量。这种矩阵的特征多项式一定存在重根。记特征多项式为
. 如果
是该特征多项式的一个重根,那么特征多项式必定满足这个条件:

其中

是特征值
的代数重数,方程组
的非零解的个数称作是该特征值的几何重数。几何重数不可能大于代数重数。如果矩阵所有特征值的几何重数都等于它的代数重数,那么这个矩阵就是可对角化的,否则这个矩阵是不可对角化的,这时它只能通过相似变换变到若尔当标准型,而不能变到对角型矩阵。如果一个矩阵是不可对角化的,那么它的特征向量就不能张满整个欧氏空间,于是我们的基本假设
就失效了。为了使用这个算法,首先我们假设马尔科夫矩阵是可对角化的。数值上这个假设并没有给我们的问题加上一个特别强的限制,因为我们知道可对角化的矩阵是稠密的,因此我们可以假设在机器精度范围内,所有的矩阵都是可对角化的。在使用power iteration method的时候,我们需要进一步假设绝对值为最大的特征值是唯一的,这个条件给我们的算法加了一个比较强的限制。之所以需要这个条件,是因为我们使用这个算法的时候,需要假设
对任意的
都成立。如果这个条件不成立,那么这个算法只能给出所有特征值的绝对值等于
的特征向量的线性组合,而不能得到这些独立的特征向量。另外,该算法的收敛速度取决于
的值,其中
为绝对值为第二大的特征值。因为第二大的特征值决定了power iteration method的收敛速度,所以有很多专门的文章研究这个第二大的特征值。

对于马尔科夫矩阵,我们已经知道它最大的特征值为1,其余的特征值的绝对值要么小于1,要么等于1. 如果我们假设马尔科夫矩阵绝对值等于1的特征值的只有一个,那么我们就可以用power iteration method去计算它的特征向量。因为我们知道

,所以我们可以直接计算
得到最大特征向量,而不需要每次都对得到的向量做归一化操作。这就等价于我们只需要计算
就可以得到特征值
所对应的特征向量,其中
是任意的初始非零向量。当马尔科夫矩阵的只有一个绝对值为1的特征值时,该马尔科夫链的稳态解唯一,并且不依赖于初始向量,我们称这样的马尔科夫链为各态遍历的(ergodic)。如果马尔科夫矩阵有超过一个绝对值等于1的特征值,那么这个马尔科夫链就没有稳态解。一个简单的例子是
. 如果仍然用两个超市的顾客人数为例,这个矩阵表示每次去A超市的顾客下次会全部去B超市,而每次去B超市的顾客每次都全部去A超市。这是一个振荡的过程,这个马尔科夫链没有稳态解,也就是去A超市和B超市的人数比例不会趋近于一个常数。对应到矩阵
,它有两个特征值,一个是 1, 另一个是
. 因为它有两个绝对值为1的特征值,所以power iteration method不能给出稳态解,这时也没有稳态解。

一种特殊的马尔科夫矩阵是对称马尔科夫矩阵。对称马尔科夫矩阵的所有列的和与所有行的和都是1,因此

是该矩阵对应特征值为1的特征向量,也是该矩阵的稳态解(如果这个矩阵存在稳态解的话)。因此,如果一个马尔科夫链的转移矩阵是对称矩阵,并且存在稳态解,那么经过足够长的时间后,每个状态都会被等概率地访问到。

第三节:PageRank算法

PageRank算法最早被Google用来做网页排序。这个算法在很多领域都有着广泛的应用。我们可以将网页看作是一个有向图,图的节点是网页,如果网页A有一个链接指向网页B,那么在节点A和节点B之间我们就可以建立一条有向边。Google最开始试图发明一种算法,该算法可以给所有的网页按照重要度排序。直觉上,我们可以认为如果一个网页被很多网页链接,那么这个网页应该比较重要。如果一个网页被另一个重要的网页链接了,那么这个被链接的网页也应该比较重要。PageRank算法通过分析网页之间的关联来给网页排序。这个算法仅仅分析网页之间的关联,而不考虑网页的内容,因此也有一定的局限性。接下来,我要简单的介绍一下这个算法。我们很容易发现,这个算法本质上就是马尔科夫链的应用。

假设我们有如下的几个网页:

56e37d011fa076f538f38643a05ce20d.png
图片来源:http://www.ams.org/publicoutreach/feature-column/fcarc-pagerank

这些网页彼此之间有关联。例如网页1有链接指向网页2, 3,而网页1本身又被网页7指向。图中一共有8个节点,代表8个网页,我们的目标是通过分析网页之间的关联,来给每一个网页赋予一个重要度。记这个重要度为向量

. 这是一个长度为8的列向量,向量中的每一个元素都是一个非负数。数字本身的大小没有意义,有意义的是它们的相对大小。一个网页越重要,那么它所对应的向量元素值就越大。PageRank算法试图通过模拟一个用户浏览网页的过程来给网页做重要度排序。假设一个用户在网页1,该网页有两个指向外部的链接,这两个链接分别指向网页2和网页3. PageRank算法该用户有相等的概率去点击这些指向外部的链接,于是下一步这个用户就有1/2的概率走到网页2,也有1/2的概率走到网页3. 通过这些指向外部的链接,网页1将它的重要度传递给了网页2和网页3. 与此同时,网页1被网页7指向,于是网页7将它的一部分重要度传给了网页1. 网页7一共有三个指向外部的链接,因此它将1/3的重要度传给了网页1. 这明显是一个迭代过程,也就是我们为了计算每一个网页的重要度,就需要先知道其他网页的重要度。如果我们一开始假设网页的重要度可以用一个长度为8的向量
表示,那么经过一次迭代,我们得到了新的向量
,该向量可以用
表示为

其中

为网页重要度的转移矩阵:

该矩阵元素

表示网页
将它的重要度传给网页
的比例。如果
,表示网页
之间没有关联。根据定义,只要网页
有指向外部的链接,我们就有
. 但是如果网页
没有指向外部的链接,那么对于每一个
,我们都有
. 也就是转移矩阵的每一列的和要么是
,要么是
. 如果假设每一个网页都有指向外部的链接, 也就是转移矩阵的每一列的和都为
, 那么得到的转移矩阵是马尔科夫矩阵,PageRank算法模拟的其实是一个马尔科夫链。对于上面的网页图,我们的转移矩阵是一个马尔科夫矩阵,因此,我们可以得到这样一个递归关系:

如果转移矩阵只有一个绝对值为1的特征值,那么这个马尔科夫链有稳态解,并且该稳态解是马尔科夫矩阵等于1的特征值所对应的特征向量:

数值上,稳态解可以通过递归关系

得到,其中我们需要一个任意的初始向量
, 我们对这个向量唯一的要求是它的每一个元素都是非负数。如果马尔科夫矩阵有稳态解,那么它最终的稳态解不应该依赖于这个初始向量。我们可以用这个特性来判断我们的程序是否正确:我们选择任意两个不同的初始向量,由此可以得到两个不同的稳态解;如果这两个稳态解在机器误差范围内,那么我们的程序就是正确的,否则我们的程序可能有问题。我将这个算法用Scala实现,然后运行,经过100次迭代,我得到稳态解为(可以精确到
)

由此得到网页8的重要度最高,这与我们的直觉相一致。

这里我们假设了每一个网页都有指向其他网页的外部链接,但是实际上可能存在某些网页没有外部链接,这时得到的转移矩阵就不再是马尔科夫矩阵, 因为该转移矩阵存在某些和等于

的列。为了处理这种情况,我们需要引入一个任意的跳转概率,这样我们仍然可以用power iteration算法得到稳态解,但是这时的转移矩阵最大的特征值就未必是
了。这些内容在这篇文章中有详细的叙述:
American Mathematical Society​www.ams.org
fe45aab36111c11c167f33d68fad5022.png

第四节:代数图论

代数图论使用代数的方法研究图论。上一节的PageRank算法就是代数图论的一个具体应用。代数图论研究的内容远不限于上一节所示的有向图,也不限于仅仅是给节点的重要度排序。这里,我要系统地总结一下代数图论,并且将代数图论应用到更广泛的场景中。有空再写。也可以另外开辟一个专题讲这些内容。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值