大数跨境
0
0

【机器学习 课后习题 系列教程】第 10 章 习题解答

【机器学习 课后习题 系列教程】第 10 章 习题解答 简博士数据分析吧
2025-04-04
1



内容提要:

 * 习题 10.1 详解

 * 习题 10.2 详解

 * 习题 10.3 详解

 * 习题 10.4 详解

 * 习题 10.5 详解

点击蓝字 |关注我们



习题 10.1 详解

「习题 10.1」 给定盒子和球组成的隐马尔可夫模型  ,其中

设  ,试用后向算法计算 

「解」

【十分钟 机器学习 系列课程】讲义(74)中已详细列出应用后向算法计算   的过程。这里,我们以 Ptyhon 代码实现,并列出所有后向概率,代码如下。

import numpy as np

# 定义隐马尔可夫模型的参数
A = np.array([[0.50.20.3],
              [0.30.50.2],
              [0.20.30.5]])  # 状态转移概率矩阵

B = np.array([[0.50.5],
              [0.40.6],
              [0.70.3]])  # 观测概率矩阵

pi = np.array([0.20.40.4])  # 初始状态概率向量

# 定义观测序列
O = ['Red''White''Red''White']  # 观测序列
T = len(O)  # 观测序列长度
N = A.shape[0]  # 状态数

# 将观测值映射为索引(红 -> 0, 白 -> 1)
obs_map = {'Red'0'White'1}
O_idx = [obs_map[o] for o in O]  # 转换为索引形式

# 后向算法
def backward_algorithm(A, B, pi, O_idx):
    T = len(O_idx)  # 观测序列长度
    N = A.shape[0]  # 状态数

    # 初始化后向概率
    beta = np.zeros((T, N))
    beta[-1, :] = 1# 时刻 T 的后向概率为 1

    # 递归计算后向概率
    for t in range(T - 2-1-1):  # 从 T-1 到 0
        for i in range(N):
            beta[t, i] = np.sum(A[i, :] * B[:, O_idx[t + 1]] * beta[t + 1, :])

    # 计算观测序列的概率
    P_O = np.sum(pi * B[:, O_idx[0]] * beta[0, :])
    return P_O, beta

# 计算观测序列的概率和后向概率
P_O, beta = backward_algorithm(A, B, pi, O_idx)

# 输出每个时刻的后向概率
print("Backward Probabilities")
for t in range(T):
    print(f"Time {t+1} backward probabilities : {beta[t, :]}")

# 输出观测序列的概率
print(f"\n Probability of the observation sequence:  P(O|λ) = {P_O:.6f}")

运行代码,得到结果如下。

Backward Probabilities
Time 1 backward probabilities: [0.1124620.1217370.104881]
Time 2 backward probabilities: [0.24610.23120.2577]
Time 3 backward probabilities: [0.460.510.43]
Time 4 backward probabilities: [1.1.1.]

Probability of the observation sequence:  P(O|λ) = 0.060091

所以,观测序列的概率为 

习题 10.2 详解

「习题 10.2」  考虑盒子和球组成的隐马尔可夫模型  ,其中

设  ,用前向后向算法计算 

「解」

编写前向算法、后向算法和状态条件概率计算的函数,输出所有的前向概率和后向概率、  和 

import numpy as np

# 定义隐马尔可夫模型(HMM)的参数
A = np.array([[0.50.10.4],
              [0.30.50.2],
              [0.20.20.6]])  # 状态转移矩阵

B = np.array([[0.50.5],
              [0.40.6],
              [0.70.3]])  # 观测概率矩阵

pi = np.array([0.20.30.5])  # 初始状态分布

# 定义观测序列
O = ['Red''White''Red''Red''White''Red''White''White']  # 观测序列
T = len(O)  # 观测序列的长度
N = A.shape[0]  # 状态数

# 将观测值映射为索引(红 -> 0, 白 -> 1)
obs_map = {'Red'0'White'1}
O_idx = [obs_map[o] for o in O]  # 将观测序列转换为索引形式

# 前向算法
def forward_algorithm(A, B, pi, O_idx):
    T = len(O_idx)  # 观测序列长度
    N = A.shape[0]  # 状态数

    # 初始化前向概率 alpha
    alpha = np.zeros((T, N))
    alpha[0, :] = pi * B[:, O_idx[0]]  # 初始时刻的前向概率

    # 递归计算前向概率
    for t in range(1, T):
        for i in range(N):
            alpha[t, i] = np.sum(alpha[t - 1, :] * A[:, i]) * B[i, O_idx[t]]

    # 计算观测序列的概率 P(O|λ)
    P_O = np.sum(alpha[-1, :])
    return P_O, alpha

# 后向算法
def backward_algorithm(A, B, pi, O_idx):
    T = len(O_idx)  # 观测序列长度
    N = A.shape[0]  # 状态数

    # 初始化后向概率
    beta = np.zeros((T, N))
    beta[-1, :] = 1# 时刻 T 的后向概率为 1

    # 递归计算后向概率
    for t in range(T - 2-1-1):  # 从 T-1 到 0
        for i in range(N):
            beta[t, i] = np.sum(A[i, :] * B[:, O_idx[t + 1]] * beta[t + 1, :])

    return beta

# 计算 gamma_t(i) = P(i_t = q_i | O, λ)
def compute_gamma(alpha, beta, P_O):
    gamma = (alpha * beta) / P_O
    return gamma

# 计算前向概率和后向概率
P_O, alpha = forward_algorithm(A, B, pi, O_idx)
beta = backward_algorithm(A, B, pi, O_idx)

# 输出前向概率
print("Forward Probabilities alpha_t(i):")
for t in range(T):
    print(f"Time {t + 1} forward probabilities: {alpha[t, :]}")

# 输出后向概率
print("\n Backward Probabilities beta_t(i):")
for t in range(T):
    print(f"Time {t + 1} backward probabilities: {beta[t, :]}")

# 输出观测序列的概率
print(f"\n Probability of the observation sequence P(O|λ) = {P_O:.6f}")

# 计算并输出 gamma_t(i)
gamma = compute_gamma(alpha, beta, P_O)
print("\n Conditional Probabilities gamma_t(i):")
for t in range(T):
    print(f"Time {t + 1} gamma_t(i): {gamma[t, :]}")

# 计算 P(i_4 = q_3 | O, \lambda)
P_i4_q3 = gamma[32]  # 时刻 4 处于状态 q_3 的概率
print(f"\n P(i_4 = q_3 | O, λ) = {P_i4_q3:.6f}")

运行代码,得到结果如下。

Forward Probabilities:
Time 1 forward probabilities: [0.10.120.35]
Time 2 forward probabilities: [0.0780.0840.0822]
Time 3 forward probabilities: [0.040320.0264960.068124]
Time 4 forward probabilities: [0.02086680.012361920.04361112]
Time 5 forward probabilities: [0.01143210.010193920.01109573]
Time 6 forward probabilities: [0.005496690.003383730.00928834]
Time 7 forward probabilities: [0.002810560.002459520.00253453]
Time 8 forward probabilities: [0.001325020.001210630.00094105]

Backward Probabilities:
Time 1 backward probabilities: [0.006325690.006847060.00577855]
Time 2 backward probabilities: [0.014829640.012272140.01568294]
Time 3 backward probabilities: [0.025564420.023434480.02678985]
Time 4 backward probabilities: [0.045865310.052809090.04280618]
Time 5 backward probabilities: [0.1055210.1008830.111934]
Time 6 backward probabilities: [0.18610.24150.1762]
Time 7 backward probabilities: [0.430.510.4 ]
Time 8 backward probabilities: [1.1.1.]

Probability of the observation sequence P(O|λ) = 0.003477

P(i_4 = q_3 | O, λ) = 0.536952

所以,观测序列的概率为 

习题 10.3 详解

「习题 10.3」 在习题 10.1 中,试用维特比算法求最优路径 

「解」

【十分钟 机器学习 系列课程】讲义(78)中已详细列出应用维特比算法计算最优路径的过程。这里,我们以 Ptyhon 代码实现,并输出所有的   和  ,代码如下。


import numpy as np

# 定义隐马尔可夫模型的参数
A = np.array([[0.50.20.3],
              [0.30.50.2],
              [0.20.30.5]])  # 状态转移矩阵

B = np.array([[0.50.5],
              [0.40.6],
              [0.70.3]])  # 观测概率矩阵

pi = np.array([0.20.40.4])  # 初始状态分布

# 定义观测序列
O = ['Red''White''Red''White']  # 观测序列
T = len(O)  # 观测序列长度
N = A.shape[0]  # 状态数

# 将观测值映射为索引(红 -> 0, 白 -> 1)
obs_map = {'Red'0'White'1}
O_idx = [obs_map[o] for o in O]  # 转换为索引形式

# 维特比算法
def viterbi_algorithm(A, B, pi, O_idx):
    T = len(O_idx)  # 观测序列长度
    N = A.shape[0]  # 状态数

    # 初始化 delta 和 Phi
    delta = np.zeros((T, N))  # delta_t(i) 存储时刻 t 处于状态 i 的最大概率
    Phi = np.zeros((T, N), dtype=int)  # Phi_t(i) 存储时刻 t 处于状态 i 的最优前驱状态

    # (1) 初始化
    delta[0, :] = pi * B[:, O_idx[0]]  # 初始时刻的 delta
    Phi[0, :] = 0# 初始时刻没有前驱状态,设为 0

    # (2) 递推
    for t in range(1, T):
        for i in range(N):
            # 计算 delta_t(i)
            delta[t, i] = np.max(delta[t - 1, :] * A[:, i]) * B[i, O_idx[t]]
            # 记录最优前驱状态
            Phi[t, i] = np.argmax(delta[t - 1, :] * A[:, i])

    # (3) 终止
    P_star = np.max(delta[-1, :])  # 最优路径的概率
    i_T_star = np.argmax(delta[-1, :])  # 最优路径的最终状态

    # (4) 最优路径回溯
    I_star = np.zeros(T, dtype=int)  # 存储最优路径
    I_star[-1] = i_T_star  # 最终状态
    for t in range(T - 2-1-1):
        I_star[t] = Phi[t + 1, I_star[t + 1]]  # 根据 phi 回溯前驱状态

    return delta, Phi, I_star, P_star

# 运行维特比算法
delta, Phi, I_star, P_star = viterbi_algorithm(A, B, pi, O_idx)

# 输出 delta_t(i)
print(" Delta values delta_t(i):")
for t in range(T):
    print(f"Time {t + 1} delta_{t + 1}(i): {delta[t, :]}")

# 输出 Phi_t(i)
print("\n Phi values Phi_t(i):")
for t in range(T):
    print(f"Time {t + 1} Phi_{t + 1}(i): {Phi[t, :]}")

# 输出最优路径
print("\n Optimal path I_star:")
print(I_star + 1

# 输出最优路径的概率
print(f"\n Probability of the optimal path P_star: {P_star:.6f}")

运行代码,得到结果如下。

Delta values delta_t(i):
Time 1 delta_1(i): [0.10.160.28]
Time 2 delta_2(i): [0.0280.05040.042 ]
Time 3 delta_3(i): [0.007560.010080.0147 ]
Time 4 delta_4(i): [0.001890.0030240.002205]

Phi values Phi_t(i):
Time 1 Phi_1(i): [000]
Time 2 Phi_2(i): [222]
Time 3 Phi_3(i): [112]
Time 4 Phi_4(i): [012]

Optimal path I_star:
[3222]

Probability of the optimal path: 0.003024

所以,最优路径为 

习题 10.4 详解

「习题 10.4」试用前向概率和后向概率推导

「解」

根据全概率公式,可以将   分解

这意味着,任取一个时刻  ,都可以根据前向概率、后向概率、状态转移概率矩阵和观测概率矩阵计算观测序列的概率。

习题 10.5 详解

「习题 10.5」 比较维特比算法中变量   的计算和前向算法中变量   的计算的主要区别。

「解」 我们主要从定义以及运算出发进行比较。

(1) 定义公式和所代表的含义不同:

  • 维特比算法中的   定义为

递推公式为

  • 前向算法中的   定义为

递推公式为

虽然两者在初始时刻的值是相同的,但是两者的定义和递推公式明显不同。  表示在时刻   处于状   的所有可能路径中,概率最大的路径的概率值。  表示在时刻   处于状态  ,并且观测序列为   的概率。

(2) 运算符号不同:

  • 因为维特比算法的目的是找到最优路径,所以    的计算采用   运算符,选择概率最大值。

  • 前向算法的目的是计算观测序列的概率,所以   的计算采用   运算符,将所有路径的概率累加求和。




欢迎大家关注简博士的B站和公众号,在公众号后台发送“入群”,就可以与小伙伴们一起讨论问题哦。


【声明】内容源于网络
0
0
简博士数据分析吧
信息时代最不缺的是什么?数据!最缺的是什么?数据分析的思维!在这里,你将获取神秘的力量,推开数据之门!
内容 181
粉丝 0
简博士数据分析吧 信息时代最不缺的是什么?数据!最缺的是什么?数据分析的思维!在这里,你将获取神秘的力量,推开数据之门!
总阅读66
粉丝0
内容181