尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

马尔可夫链:从醉汉漫步到PageRank与文本生成的数学建模

马尔可夫链:从醉汉漫步到PageRank与文本生成的数学建模 1. 从“无记忆”的随机漫步说起如果你玩过“大富翁”或者任何一款掷骰子决定步数的棋盘游戏那你其实已经接触过马尔可夫链最朴素的思想了。你下一步走到哪个格子只取决于你当前在哪个格子以及你掷出的骰子点数跟你之前是怎么走过来的——比如你是绕了地图三圈还是刚从监狱里出来——完全没有关系。这种“未来只取决于现在与过去无关”的特性就是马尔可夫链Markov chain最核心的“无记忆性”学术上称为马尔可夫性质。别被“链”这个字吓到它不是什么高深的物理或化学概念而是一种描述随机过程如何随时间演变的数学模型。想象一个醉汉在一条街上踉跄行走他下一步是向前、向后还是原地不动完全由他当前所在的位置和一股“醉意”概率决定他记不清十分钟前是从哪个酒吧出来的。这个醉汉的行走轨迹就可以用一个简单的马尔可夫链来模拟。为什么这个看似简单的模型如此重要以至于成为从自然语言处理到金融预测从网页排名到生物信息学的基石工具因为它用极其简洁的数学框架捕捉了大量现实系统中状态转移的本质。当我们说“天气”明天的晴雨大概率取决于今天的天气而不是上周的当我们分析用户行为他下一个点击的链接很大程度上受当前浏览页面的影响。这些场景里历史路径的细节被“遗忘”了当前状态包含了预测未来所需的所有信息。马尔可夫链正是将这种直觉形式化、可计算化的利器。本文将彻底拆解马尔可夫链不堆砌公式吓唬人而是聚焦于理解其为何有效、如何工作以及在实际项目中你会怎么用它。我们会从醉汉漫步的比喻开始一步步构建起状态、转移概率这些核心概念然后深入到平稳分布这个决定系统长期行为的关键。接着我们会看到它如何从理论走进现实驱动了像PageRank这样改变互联网的算法并成为当今生成式AI中语言模型的基础构件。最后我会分享在具体应用比如文本生成和简单预测模型中如何设计状态、估算概率以及那些容易踩坑的细节。无论你是想理解其原理还是打算亲手实现一个这篇文章都会给你一张清晰的路线图。2. 核心构件状态、转移与概率矩阵要搭建一个马尔可夫链你需要三个基本要素状态空间、转移概率和初始分布。理解了这三样你就掌握了它的全部家当。2.1 状态空间系统可能处于的所有“位置”状态State是马尔可夫链所描述系统在某个时刻的“快照”。它可以是任何离散的、可枚举的情况。离散天气模型状态空间 S {晴天 阴天 雨天}。网页浏览状态空间 S {首页 产品页A 产品页B 购物车 结账页}。棋盘游戏状态空间 S {格子1 格子2 ... 格子40}。文本中的字符状态空间 S {a, b, c, ..., z, 空格 标点}。状态的定义至关重要它直接决定了模型的表达能力和复杂度。一个粗糙的状态划分如“情绪”好/坏可能丢失信息而过于精细的划分如股票精确到分则会使模型参数爆炸难以计算。在实际项目中定义状态往往是第一步也是最需要结合业务知识进行权衡的一步。注意我们通常讨论离散时间、离散状态的马尔可夫链这也是最常用、最直观的形式。即时间t0,1,2,...状态是可数的。也存在连续时间和/或连续状态的马尔可夫过程如布朗运动但那是更进阶的话题。2.2 转移概率从“这里”到“那里”的可能性这是马尔可夫链的动力之源。转移概率Transition Probability定量描述了系统从当前状态 i 下一步转移到状态 j 的可能性记作 P(i - j) 或 P_{ij}。关键约束从任何一个状态出发转移到所有可能状态包括自身的概率之和必须为1。这很好理解因为下一步总要走到某个状态或留在原地。沿用天气例子假设我们观察到如果今天是晴天明天有70%概率仍是晴天20%概率转阴10%概率下雨。如果今天是阴天明天有30%概率转晴50%概率维持阴天20%概率下雨。如果今天是雨天明天有20%概率转晴30%概率转阴50%概率继续下雨。用数学表示就是 P(晴 - 晴) 0.7, P(晴 - 阴) 0.2, P(晴 - 雨) 0.1 P(阴 - 晴) 0.3, P(阴 - 阴) 0.5, P(阴 - 雨) 0.2 P(雨 - 晴) 0.2, P(雨 - 阴) 0.3, P(雨 - 雨) 0.5并且每一行加起来都等于1。2.3 概率转移矩阵把规则装进表格为了便于计算和表示我们把所有转移概率按行列排成一个矩阵这就是概率转移矩阵Transition Probability Matrix通常记作 P。对于我们的天气模型矩阵 P 如下当前状态 \ 下一状态晴阴雨晴0.70.20.1阴0.30.50.2雨0.20.30.5这个矩阵是马尔可夫链的“心脏”。它完整地刻画了系统演变的规则。矩阵的第 i 行第 j 列元素 P_{ij}就是从状态 i 转移到状态 j 的概率。矩阵的每一行都是一个概率分布和为1。2.4 初始分布故事从哪里开始初始分布Initial Distribution是一个向量描述了在时间 t0 时系统处于各个状态的概率。比如我们完全不知道第一天天气可以假设均匀分布π⁽⁰⁾ [1/3, 1/3, 1/3]。或者根据历史数据我们知道一年中第一天的气候设为 π⁽⁰⁾ [0.4, 0.4, 0.2]。有了初始分布 π⁽⁰⁾ 和转移矩阵 P我们就可以预测未来任意时刻的状态概率分布。t1时刻的分布 π⁽¹⁾ π⁽⁰⁾ P t2时刻的分布 π⁽²⁾ π⁽¹⁾ P π⁽⁰⁾ P² 以此类推。这里 Pⁿ 表示矩阵 P 的 n 次幂其 (i, j) 元素就是从状态 i 出发经过 n 步后处于状态 j 的概率。3. 长期行为与平稳分布系统最终会“安定”下来吗一个自然的问题是如果这个天气过程日复一日地进行下去长期来看晴天、阴天、雨天的比例会稳定在某个值上吗这个长期稳定的概率分布如果存在就称为平稳分布Stationary Distribution通常记作 π。数学上平稳分布 π 满足以下方程π P π且 π 的各分量之和为1。这意味着一旦系统达到了平稳分布 π那么下一步的状态分布仍然是 π系统在宏观上达到了动态平衡。平稳分布是转移矩阵 P 的左特征向量对应特征值为1归一化后的结果。对于我们假设的天气转移矩阵 P我们可以解出它的平稳分布。通过计算具体求解过程涉及解线性方程组可以使用Python的numpy.linalg.eig计算特征向量我们可以得到近似解 π ≈ [0.413, 0.261, 0.326]这个结果告诉我们无论第一天天气如何初始分布是什么在经过足够长的时间后晴天约占41.3%阴天约占26.1%雨天约占32.6%。这是一个非常深刻的结论系统的长期统计性质完全由转移矩阵 P 决定与起点无关。3.1 可达性与周期性平稳分布存在的条件并不是所有马尔可夫链都有唯一的平稳分布。这取决于链的结构性质。不可约性Irreducible从任何一个状态出发经过有限步都有正的概率到达任何其他状态。这意味着所有状态都是相通的整个链是一个整体。我们的天气模型看起来是不可约的因为三种天气状态最终都可以互相转换。非周期性Aperiodic系统返回某个状态的步数没有固定的周期。如果一个状态有周期d比如只能在第2,4,6,...步返回那么链就是周期的。这会影响长期行为的振荡。通常如果转移矩阵中所有状态的自转移概率 P_{ii} 0则该链是非周期的。如果一个有限状态的马尔可夫链是不可约且非周期的那么它就具有遍历性Ergodic并且存在唯一的平稳分布且从任意初始分布出发长期状态分布都会收敛到这个平稳分布。这是大多数应用中所期望的性质。3.2 吸收态与吸收链一旦进入永不离开与遍历链相对的是存在**吸收态Absorbing State**的链。吸收态是指一旦进入就永远无法离开的状态即 P_{ii} 1。例如在一个简单的“健康-生病-死亡”模型中“死亡”就是一个吸收态。包含吸收态的马尔可夫链其长期行为是最终以概率1进入某个吸收态或吸收态集合。研究这类链时我们更关心的是进入吸收态的平均时间、概率等。这在可靠性分析、赌徒破产问题中很常见。理解你的链属于哪种类型是进行正确分析和应用的前提。在文本生成中我们通常希望链是遍历的以产生丰富多样的输出在游戏或流程建模中吸收态可能代表“游戏结束”或“流程终止”。4. 从理论到实践PageRank与隐马尔可夫模型理解了基础我们来看看马尔可夫链如何解决真实世界的大问题。这两个例子极具代表性一个改变了互联网另一个成为了序列数据分析的经典工具。4.1 PageRank将互联网视为一个巨大的马尔可夫链谷歌早期的核心算法PageRank其本质就是一个基于马尔可夫链的网页重要性排序算法。它做了一个巧妙的类比状态每一个网页就是一个状态。转移概率一个“随机冲浪者”在当前网页上会随机点击页面上的一个链接跳转到下一个网页。如果当前页面有3个外链那么点击每个链接的概率就是1/3。这就定义了从当前网页到其链接网页的转移概率。平稳分布即重要性PageRank巧妙地将一个网页的“重要性”定义为在足够长的随机冲浪后这个随机冲浪者出现在该网页的概率。这个概率就是整个网络马尔可夫链的平稳分布 π。平稳分布值越高的网页被认为越重要。这里有两个技术细节处理悬挂节点如果一个网页没有外链出度为0随机冲浪者就会“无处可去”。PageRank的处理是让冲浪者以概率1“跳”到整个互联网的任何一個网页均匀随机。这通过在所有状态间添加一个很小的均匀转移概率来实现在数学上对应着对转移矩阵 P 进行了一个小小的修正使其成为不可约、非周期的从而保证唯一平稳分布的存在。阻尼因子实际上冲浪者并不总是跟着链接走。他以一定概率如15%阻尼因子 d0.15随机跳转到任意网页而以剩余概率85%按照链接行走。这个修正解决了网络中的“孤岛”问题并让算法更稳定。最终PageRank通过求解这个巨大马尔可夫链的平稳分布通常用幂迭代法因为矩阵太大无法直接求特征向量得到了每个网页的排名。这个例子完美展示了如何将一个抽象的链接网络转化为一个可计算的概率模型并利用平稳分布这一概念提取出全局结构信息。4.2 隐马尔可夫模型当状态不可见时在更多情况下我们无法直接观察到系统的真实状态。例如在语音识别中我们听到的是声音信号观测值背后对应的是发音的音素或单词隐藏状态。隐马尔可夫模型Hidden Markov Model, HMM就是用来处理这类问题的利器。HMM在马尔可夫链的基础上增加了一层隐藏的状态序列遵循一个马尔可夫链有状态转移矩阵A。观测序列每个隐藏状态会以一定的概率发射概率矩阵B产生一个可观测的符号。初始状态分布π。所以一个HMM由三元组 λ (A, B, π) 完全定义。HMM要解决三大经典问题评估问题给定模型λ和观测序列O计算P(O|λ)即这个观测序列由该模型产生的概率。用前向算法高效解决。解码问题给定模型λ和观测序列O找出最有可能产生该观测序列的隐藏状态序列。用维特比算法一种动态规划算法解决。这是语音识别、词性标注等任务的核心。学习问题给定观测序列O估计模型参数λ(A, B, π)。用鲍姆-韦尔奇算法一种期望最大化EM算法解决。HMM将马尔可夫链的应用范围从“完全可见”的系统拓展到了“通过可见输出来推测不可见内部机制”的广阔领域是连接时序数据与概率图模型的桥梁。5. 实战用Python构建一个文本生成器理论说得再多不如动手实现一个。我们将用马尔可夫链构建一个简单的文本生成器这是一个非常直观且有趣的应用。我们会基于一个英文文本语料库学习词与词之间的转移规律然后根据这个规律生成新的句子。5.1 设计状态与转移这里的关键决策是什么是状态常见的有两种选择字符级状态是单个字符包括字母、空格、标点。生成的是字符序列。词汇级状态是单词。生成的是单词序列。词汇级生成的文本通常更通顺因为我们捕获的是词语间的搭配习惯。我们选择词汇级模型。但这里又有一个问题一个单词的下一个词可能依赖于前面多个词。这就是N-gram模型的思路。一个一阶马尔可夫链假设下一个词只依赖于当前词Bigram模型。为了获得更丰富的上下文我们可以使用二阶链下一个词依赖于前两个词Trigram模型但状态空间会急剧膨胀。为了平衡效果和复杂度我们使用Bigram模型即状态当前词下一个状态下一个词。5.2 数据准备与概率计算假设我们有一个简单的语料库由以下三个句子组成经过简单的预处理如转为小写、添加句子起止标记s i love programming /s s i love python /s s python is great /s这里s和/s是特殊标记分别表示句子的开始和结束。我们的目标是构建转移矩阵。首先统计所有连续出现的词对Bigram的频率s-i: 出现2次s-python: 出现1次i-love: 出现2次love-programming: 出现1次love-python: 出现1次programming-/s: 出现1次python-is: 出现1次python-/s: 出现1次等等检查语料第二句是i love python /s所以python后面是/s。第三句是s python is great /s所以python后面是is。因此python-is: 出现1次python-/s: 出现1次is-great: 出现1次great-/s: 出现1次然后将频率转换为概率。例如状态i总共出现了2次每次都转移到love所以 P(love|i) 2/2 1.0。状态python出现了2次一次转到is一次转到/s所以 P(is|python) 0.5 P(/s|python) 0.5。5.3 生成文本的算法生成新句子的过程就是一个马尔可夫链的随机游走从初始状态s开始。根据当前状态单词的转移概率分布随机选择下一个单词作为新状态。将新状态作为当前状态重复步骤2。直到当前状态为/s生成结束。例如从s开始根据概率 P(i|s) 2/3, P(python|s) 1/3随机选择。假设选中i。当前状态为i它100%转移到love所以下一个词是love。当前状态为love P(programming|love) 1/2, P(python|love) 1/2。假设选中python。当前状态为python P(is|python) 0.5, P(/s|python) 0.5。假设选中/s。生成结束得到句子s i love python /s即 “I love python.”5.4 Python代码实现与平滑处理下面是一个简单的实现框架import random from collections import defaultdict, Counter class BigramMarkovGenerator: def __init__(self): self.transitions defaultdict(Counter) # 存储状态-下一个词的计数 self.states set() def train(self, sentences): 训练模型 sentences是列表每个元素是单词列表包含s和/s for sentence in sentences: for i in range(len(sentence)-1): current_word sentence[i] next_word sentence[i1] self.transitions[current_word][next_word] 1 self.states.add(current_word) self.states.add(next_word) def _get_next_word(self, current_word): 根据当前词按概率随机选择下一个词 # 获取当前词的所有可能下一个词及其计数 next_word_counter self.transitions[current_word] if not next_word_counter: return None # 没有转移可能是生僻词或句子结束符处理不当 words, counts zip(*next_word_counter.items()) # 根据计数构建概率分布这里简化未做归一化因为random.choices接受权重 return random.choices(words, weightscounts)[0] def generate(self, start_words, max_length20): 生成句子 current_word start_word sentence [current_word] while current_word ! /s and len(sentence) max_length: next_word self._get_next_word(current_word) if next_word is None: break sentence.append(next_word) current_word next_word # 过滤掉起止标记后返回 return .join([w for w in sentence if w not in (s, /s)]) # 使用示例 if __name__ __main__: # 准备训练数据实际中应从文件读取大量文本 corpus [ [s, i, love, programming, /s], [s, i, love, python, /s], [s, python, is, great, /s] ] generator BigramMarkovGenerator() generator.train(corpus) for _ in range(5): print(generator.generate())运行这段代码可能会生成如 “i love python”, “i love programming”, “python is great” 这样的句子也可能因为随机选择产生 “i love python is great” 这种看似通顺但训练集中没有的组合因为python后可以接is而love后可以接python链式组合产生了新句子。实操心得与平滑技巧数据稀疏与零概率问题在真实语料中绝大多数可能的词对Bigram从未出现其概率为0。但在生成时如果当前词转移到的所有可能下一个词的概率都为0即next_word_counter为空我们的简单实现会卡住。更糟的是一些低频但合理的组合会被忽略。这就需要**平滑Smoothing**技术如加一平滑Laplace Smoothing或更先进的Kneser-Ney平滑。简单来说加一平滑就是给所有可能的词对包括未出现的都加一个很小的计数如1然后重新计算概率确保没有零概率。状态空间爆炸对于词汇级模型词汇表可能很大数万甚至数十万导致转移矩阵极其稀疏存储和计算成本高。在实际应用中需要优化数据结构如使用稀疏矩阵存储或考虑使用字符级模型状态空间小但生成长文本效率可能较低。生成质量一阶Bigram模型生成的文本往往局部连贯但缺乏长期逻辑。使用更高阶的N-gram模型如Trigram或基于神经网络的语言模型本质上是极其高阶、参数化的马尔可夫链可以大幅提升生成质量。6. 在简单预测与模拟中的应用思路除了文本生成马尔可夫链在业务场景中常用于简单的状态预测和系统模拟。6.1 用户行为预测假设我们想预测一个电商App用户下一步会访问哪个页面。我们可以将页面首页、搜索页、商品详情页、购物车、支付页等定义为状态。通过分析大量用户的历史会话日志我们可以统计出从页面A跳转到页面B的频次从而估算出转移概率矩阵P。给定一个用户当前的页面状态我们就可以用矩阵P预测他下一步最可能去的页面。更进一步我们可以计算多步转移概率 Pⁿ来预测用户在未来n步后的页面分布。这对于个性化推荐、流量预判、异常检测如用户行为突然偏离常规模式都有参考价值。6.2 市场状态模拟在金融或市场分析中我们经常将市场简化为几种离散状态例如{牛市 震荡市 熊市}。通过对历史行情数据划分状态并统计状态间的转移频率可以构建一个市场状态转移的马尔可夫链模型。这个模型可以用来回答诸如“如果当前是牛市那么三个月后市场仍处于牛市的概率是多少”或者“从熊市恢复到牛市的平均时间是多少”等问题。虽然金融市场极其复杂远非一个简单的马尔可夫链所能精确描述但这种简化模型可以作为风险分析、资产配置的辅助工具提供一种概率视角的参考。6.3 游戏与随机过程设计很多棋盘游戏、卡牌游戏中的随机事件都可以用马尔可夫链来建模和分析。例如分析玩家在“大富翁”中到达某个关键格子的概率或者计算在某种卡牌组合下下个回合抽到关键牌的概率。通过建模游戏设计师可以平衡游戏机制确保随机性带来的趣味性不会破坏游戏的公平性或策略深度。7. 局限性与超越马尔可夫假设的打破尽管马尔可夫链强大而优雅但它的核心假设——“无记忆性”——在现实中常常被打破。系统的下一个状态往往不仅取决于当前状态还依赖于更久远的历史。自然语言句子“The cat sat on the ___”要填最后一个词你可能立刻想到“mat”。但如果你知道前文是“The dog chased the cat, and then the cat sat on the ___”那么“mat”依然合理但“fence”或“roof”也可能。如果历史信息更长选择会更复杂。这就是为什么Bigram模型效果有限而现代Transformer模型如GPT使用自注意力机制能够关注序列中所有历史位置的信息本质上是在用极其复杂的方式建模一个“超长记忆”的依赖关系。股票价格明天的股价真的只和今天有关吗显然趋势、交易量、市场情绪、宏观经济事件等历史信息都至关重要。因此单纯的马尔可夫链模型对金融时间序列的预测能力很弱更复杂的模型如ARIMA, LSTM, GARCH等被开发出来以捕捉长期依赖和波动聚集性。认识到马尔可夫链的局限性不是为了否定它而是为了更恰当地使用它。在许多场景中一阶或二阶的马尔可夫假设是一个非常好的计算与效果之间的权衡点。它用可管理的复杂度捕获了系统中最直接、最强烈的依赖关系。当需要更精细的建模时我们可以转向高阶马尔可夫链、隐马尔可夫模型或者更现代的循环神经网络RNN、长短期记忆网络LSTM和Transformer模型。这些高级模型可以看作是马尔可夫思想在参数化和记忆能力上的深度扩展。在我自己的项目中使用马尔可夫链通常是一个快速原型验证的起点。比如需要做一个简单的对话机器人或者文本补全功能我会先用Bigram或Trigram模型快速搭一个基线看看核心流程是否跑通生成的结果是否有一定的合理性。这个基线模型的实现简单训练速度快能立刻让我对问题的难度和数据的特性有一个直观感受。之后如果需要追求更好的效果再考虑引入更复杂的模型。这种“由简入繁”的策略往往能帮助我更高效地定位问题核心避免一开始就陷入复杂模型的调参泥潭。
返回列表