1. 安德雷·马尔可夫的诗歌研究:一个数学分支的诞生
1906年,俄罗斯数学家安德雷·马尔可夫正在研究一个看似与数学无关的问题:俄语诗歌中元音和辅音的排列规律。他分析了普希金的史诗《叶甫盖尼·奥涅金》的前2万个字母,发现了一个有趣的现象:字母的排列并非完全随机,而是存在某种"记忆有限"的模式——下一个字母的类型往往只取决于当前字母的类型,而与更早的历史无关。
这个发现催生了马尔可夫链的概念,马尔可夫在1913年发表的论文中首次严格定义了这种特殊的随机过程。他用数学语言描述道:
P(Xt+1=x∣Xt=xt,Xt−1=xt−1,...,X0=x0)=P(Xt+1=x∣Xt=xt)
这个看似简单的性质——无记忆性(马尔可夫性),却成为了现代概率论中最重要的概念之一。有趣的是,马尔可夫最初研究这个理论是为了反驳当时流行的"独立事件论",却意外地开创了一个全新的数学分支。
2. 马尔可夫链的数学之美:转移矩阵与平稳分布
马尔可夫链的核心是转移概率矩阵P,其中Pij表示从状态i转移到状态j的概率。这个矩阵具有几个迷人特性:
- 每个行向量和为1:∑jPij=1
- 多步转移:k步转移矩阵是Pk
- 平稳分布:存在π满足πP=π
让我们用Python探索这些性质:
import numpy as np
from numpy.linalg import matrix_power
# 定义天气模型转移矩阵:晴、阴、雨
P = np.array([
[0.8, 0.15, 0.05], # 晴天后的天气
[0.4, 0.5, 0.1], # 阴天后的天气
[0.1, 0.3, 0.6] # 雨天后的天气
])
# 计算3天后的转移矩阵
P_3 = matrix_power(P, 3)
print("3天后的转移概率矩阵:\n", P_3)
# 计算平稳分布
eigenvalues, eigenvectors = np.linalg.eig(P.T)
pi = eigenvectors[:, np.isclose(eigenvalues, 1)].real.flatten()
pi = pi / pi.sum()
print("\n平稳分布:", pi)
# 验证平稳性
print("\n验证πP = π:", np.allclose(pi @ P, pi))
这段代码展示了马尔可夫链的两个关键特性:
- 多步转移:通过矩阵幂运算,我们可以计算未来任意多步的状态概率
- 平稳分布:无论从何种天气开始,长期来看天气分布会趋于稳定(这里大约是63%晴天,27%阴天,10%雨天)
3. 文本预测的魔法:n-gram模型的实现
马尔可夫链最直观的应用就是文本预测。当我们使用手机键盘时,那些看似"智能"的下一词推荐,很多都基于马尔可夫原理。让我们实现一个三元模型(trigram):
from collections import defaultdict
import random
class TrigramTextGenerator:
def __init__(self):
self.counts = defaultdict(lambda: defaultdict(int))
self.start_counts = defaultdict(int)
self.context_counts = defaultdict(int)
def train(self, corpus):
"""训练模型:统计所有三元组出现频率"""
for text in corpus:
words = ['<start>', '<start>'] + text.split() + ['<end>']
# 记录起始词
self.start_counts[words[2]] += 1
for i in range(2, len(words)-1):
context = (words[i-1], words[i])
next_word = words[i+1]
self.counts[context][next_word] += 1
def generate_text(self, seed_words, max_length=20):
"""生成文本"""
if len(seed_words) < 2:
# 如果没有足够的种子词,随机选择常见起始词
seed_words = random.choices(
list(self.start_counts.keys()),
weights=list(self.start_counts.values()),
k=2
)
output = list(seed_words)
for _ in range(max_length):
context = tuple(output[-2:])
if context not in self.counts or not self.counts[context]:
break
# 根据频率选择下一个词
next_words, weights = zip(*self.counts[context].items())
next_word = random.choices(next_words, weights=weights)[0]
if next_word == '<end>':
break
output.append(next_word)
return ' '.join(output)
# 示例:训练一个简单的诗歌生成器
corpus = [
"the quick brown fox jumps over the lazy dog",
"a quick brown fox jumps over the lazy cat",
"the lazy dog is quick to jump over the brown fox",
"quick and brown fox jumps high over the lazy dog",
"the quick lazy dog never jumps over the brown fox"
]
generator = TrigramTextGenerator()
generator.train(corpus)
print("生成的文本示例:")
for _ in range(5):
print("-", generator.generate_text(["the", "quick"], 10))
这个简单的模型已经能够生成看似合理的文本序列。现代语言模型如GPT虽然更加复杂,但核心思想仍然包含马尔可夫链的原理。
4. PageRank:马尔可夫链如何塑造互联网
1996年,斯坦福大学的两位博士生拉里·佩奇和谢尔盖·布林面临一个难题:如何衡量网页的重要性? 当时的搜索引擎主要根据关键词匹配度排序,导致结果质量低下。
他们的突破性想法是将互联网视为一个巨大的马尔可夫链:
- 每个网页是一个状态
- 链接是状态转移(用户点击链接相当于状态转换)
- 重要网页就是那些在长期浏览中被访问概率高的网页
PageRank的数学公式实际上是马尔可夫链平稳分布的计算:
πi=N1−d+dj∈Bi∑L(j)πj
其中:
- πi:网页i的PageRank值
- d:阻尼系数(通常0.85),表示用户继续点击链接的概率
- Bi:链接到i的网页集合
- L(j):网页j的出链数量
让我们实现一个简化版的PageRank:
import numpy as np
def pagerank(links, d=0.85, max_iter=100, tol=1e-6):
"""
links: 网页链接关系的字典 {page: [linked_pages]}
d: 阻尼因子
"""
pages = list(links.keys())
n = len(pages)
page_to_idx = {p:i for i,p in enumerate(pages)}
# 构建转移矩阵
P = np.zeros((n, n))
for i, page in enumerate(pages):
linked_pages = links[page]
out_links = len(linked_pages)
if out_links == 0:
# 处理悬挂节点(没有出链的页面)
P[:,i] = 1/n
else:
for linked_page in linked_pages:
j = page_to_idx[linked_page]
P[j,i] = 1/out_links
# 加入阻尼因子
P = d * P + (1-d)/n * np.ones((n,n))
# 幂迭代法计算平稳分布
rank = np.ones(n)/n
for _ in range(max_iter):
new_rank = P @ rank
if np.linalg.norm(new_rank - rank) < tol:
break
rank = new_rank
return {page: rank[i] for i, page in enumerate(pages)}
# 示例:小型网页网络
web = {
'A': ['B', 'C'],
'B': ['C'],
'C': ['A'],
'D': ['C'],
'E': ['A', 'D'],
'F': ['B', 'E']
}
ranks = pagerank(web)
print("PageRank结果:")
for page, rank in sorted(ranks.items(), key=lambda x: -x[1]):
print(f"{page}: {rank:.4f}")
这个算法最终成为了谷歌搜索引擎的基础,也展示了马尔可夫链在实际工程中的强大威力。
5. 马尔可夫链蒙特卡洛(MCMC):贝叶斯统计的革命
在统计学中,我们常常需要从复杂分布中采样。马尔可夫链蒙特卡洛(MCMC)方法通过构造一个特殊的马尔可夫链,使其平稳分布等于目标分布,从而解决这个难题。
5.1 Metropolis-Hastings算法
这是最经典的MCMC算法,由物理学家Nicholas Metropolis等人于1953年提出:
import numpy as np
import matplotlib.pyplot as plt
def metropolis_hastings(target_density, proposal, initial, iterations=10000):
"""
target_density: 目标分布(非归一化)
proposal: 建议分布函数 q(x'|x)
"""
samples = [initial]
current = initial
for _ in range(iterations):
# 生成候选样本
candidate = proposal(current)
# 计算接受概率
acceptance = min(1, target_density(candidate)/target_density(current) *
proposal(current, candidate)/proposal(candidate, current))
# 决定是否接受
if np.random.random() < acceptance:
current = candidate
samples.append(current)
return samples
# 示例:采样双峰分布
def target_density(x):
"""混合高斯分布"""
return 0.3*np.exp(-0.2*(x-3)**2) + 0.7*np.exp(-0.2*(x+3)**2)
def proposal(x, sigma=2):
"""对称建议分布:正态分布"""
return x + np.random.normal(0, sigma)
# 运行采样
samples = metropolis_hastings(target_density, proposal, 0, 10000)
# 可视化
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plt.plot(samples)
plt.title('MCMC采样路径')
plt.subplot(1,2,2)
plt.hist(samples[500:], bins=50, density=True, alpha=0.6)
x = np.linspace(-6, 6, 100)
plt.plot(x, target_density(x)/np.trapz(target_density(x),x), 'r')
plt.title('采样分布 vs 真实分布')
plt.show()
5.2 Gibbs抽样:高维分布的采样利器
对于高维分布,Gibbs抽样通过轮流更新每个维度来采样:
def gibbs_sampling(cond_dists, initial, iterations=10000):
"""
cond_dists: 各变量的条件分布函数列表
"""
samples = [initial.copy()]
current = initial.copy()
dim = len(initial)
for _ in range(iterations):
for i in range(dim):
# 根据其他变量的当前值更新第i个变量
current[i] = cond_dists[i](current)
samples.append(current.copy())
return samples
# 示例:二元正态分布
def cond_x1(x):
"""给定x2,x1的条件分布"""
return np.random.normal(0.5*x[1], np.sqrt(0.75))
def cond_x2(x):
"""给定x1,x2的条件分布"""
return np.random.normal(0.5*x[0], np.sqrt(0.75))
# 运行Gibbs抽样
samples = gibbs_sampling([cond_x1, cond_x2], [0,0], 10000)
samples = np.array(samples)
# 可视化
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plt.scatter(samples[1000:,0], samples[1000:,1], alpha=0.5)
plt.title('采样点分布')
plt.subplot(1,2,2)
plt.plot(samples[:,0], label='x1')
plt.plot(samples[:,1], label='x2')
plt.title('采样轨迹')
plt.legend()
plt.show()
6. 结语:无处不在的马尔可夫链
从普希金的诗歌到谷歌的搜索引擎,从文本预测到贝叶斯统计,马尔可夫链展示了数学概念如何穿越时空,在不同领域绽放异彩。安德雷·马尔可夫当年研究字母序列时,恐怕不会想到他的理论会在一个世纪后支撑起价值万亿美元的互联网产业。
"数学之美在于,"正如著名数学家Persi Diaconis所言,"最抽象的理论往往在最实际的地方找到意想不到的应用。马尔可夫链就是这样一个完美的例子——它既深刻又实用,既优雅又强大。"
马尔可夫链在多领域的神奇应用
6181

被折叠的 条评论
为什么被折叠?



