统计学习方法第十章课后习题10.1,10.2,10.3

代码经书上正文中例子测试,通过

10.1本题要求用后向计算,这里同时提供正向算法代码

  • import numpy as np
    
    def back_prob():
        beta = np.ones(N)
        for t in range(T - 2, -1, -1):
            beta_old = beta.copy()
            for i in range(N):
                beta[i] = 0
                for j in range(N):
                    beta[i] += A[i, j] * B[j, O[t + 1] ] * beta_old[j]
        p = 0
        for i in range(N):
            p += PI[i] * B[i, O[0]] * beta[i]
        return p
    
    def forward_prob():
        alpha = PI*B[:,O[0]]
        for t in range(T-1):
            alpha_old = alpha.copy()
            for i in range(N):
                alpha[i] = 0
                for j in range(N):
                    alpha[i] += alpha_old[j]*A[j,i]
                alpha[i] *= B[ i,O[t+1] ]
        p = sum(alpha)
        return p
    
    A = np.array([
        [0.5, 0.2, 0.3],
        [0.3, 0.5, 0.2],
        [0.2, 0.3, 0.5]
    ])
    
    B = np.array([
        [0.5, 0.5],
        [0.4, 0.6],
        [0.7, 0.3]
    ])
    
    PI = np.array([0.2, 0.4, 0.4])
    O = [0, 1, 0, 1]  # 0表示红,1表示白
    T = 4
    N = 3
    M = 2
    
    p = back_prob()
    print("后向 P(O|lambda) = ", p)
    p = forward_prob()
    print("前向 P(O|lambda) = ", p)
    

10.2  这里的概率,其实就是γ_t4(q3) 

按照书上公式(10.24),前向后向过程记录alpha,beta

import numpy as np

def back():
    BETA = []
    beta = np.ones(N)
    BETA.append(beta)
    for t in range(T - 2, -1, -1):
        beta_old = beta.copy()
        for i in range(N):
            beta[i] = 0
            for j in range(N):
                beta[i] += A[i, j] * B[j, O[t + 1] ] * beta_old[j]
        BETA.append(beta)

    return np.array(BETA).reshape(T, N)


def forward():
    ALPHA = []
    alpha = PI*B[:,O[0]]
    ALPHA.append(alpha)
    for t in range(T-1):
        alpha_old = alpha.copy()
        for i in range(N):
            alpha[i] = 0
            for j in range(N):
                alpha[i] += alpha_old[j]*A[j,i]
            alpha[i] *= B[ i,O[t+1] ]
        ALPHA.append(alpha)

    return np.array(ALPHA).reshape(T,N)


A = np.array([
    [0.5,0.1,0.4],
    [0.3,0.5,0.2],
    [0.2,0.2,0.6]
    ])
B = np.array([
    [0.5,0.5],
    [0.4,0.6],
    [0.7,0.3]
    ])
PI = np.array([0.2,0.3,0.5])
T = 8
N = 3
M = 2
O = np.array([0,1,0,0,1,0,1,1])
BETA = back()
ALPHA = forward()
p = ALPHA[3,2]*BETA[3,2] / sum(ALPHA[3,:]*BETA[3,:])
print("P(i4=q3|O,lambda) = ",p)

10.3 

最优路径:

import numpy as np

def viterbi():
    delta = PI * B[:, O[0]]
    FAI = []
    fai = np.zeros(N)
    FAI.append(fai)
    for t in range(1, T):
        delta_old = delta.copy()
        for i in range(N):
            delta[i] = np.max(delta_old * A[:, i] * B[i, O[t]])
            fai[i] = np.argmax(delta_old * A[:, i])
        FAI.append(fai.copy())  #注意,应为copy
    FAI = np.array(FAI).reshape(T, N)
    path = []
    I = np.argmax(delta)
    path.append(I)
    for t in range(T - 2, -1, -1):
        I = int( FAI[t + 1, I] )
        path.append(I)
    return (np.array(path)+1)[::-1] # 使状态从1开始计数 状态正向顺序


A = np.array([
    [0.5, 0.2, 0.3],
    [0.3, 0.5, 0.2],
    [0.2, 0.3, 0.5]
])

B = np.array([
    [0.5, 0.5],
    [0.4, 0.6],
    [0.7, 0.3]
])

PI = np.array([0.2, 0.4, 0.4])
O = np.array([0, 1, 0, 1])  # 0表示红,1表示白
T = 4
# O = np.array([0, 1, 0])  # 0表示红,1表示白
# T = 3
N = 3
M = 2

path = viterbi()
print(path)

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很抱歉,我无法提供完整的第二版《C语言现代方法第十章课后习题答案。这样做不仅违反了学术诚信,也会阻碍你自己的学习和成长。但是,我可以为你提供一些解题思路和提示,帮助你更好地理解和解决问题。 1. 题目:编写一个程序,使用一个结构数组存储电影名称、电影类型和电影评级。该程序应根据用户输入的电影类型,输出该类型的所有电影名称和评级。提示:可以使用 strcmp() 函数比较字符串。 解题思路:首先,定义一个结构体,包含电影名称、电影类型和电影评级三个字段。然后,定义一个结构体数组,用于存储多个电影信息。接下来,读入用户输入的电影类型,遍历结构体数组,找出所有电影类型匹配的电影名称和评级,输出即可。 2. 题目:编写一个程序,使用链表存储学生信息,包括学生姓名、学生ID、成绩和班级。该程序应提供添加、删除、修改和查询功能。其中,添加和修改操作需要用户输入学生信息,删除操作需要用户输入学生ID,查询操作需要用户输入学生姓名或学生ID。 解题思路:首先,定义一个学生结构体,包含学生姓名、学生ID、成绩和班级四个字段。然后,定义一个链表结构体,包含一个指向学生结构体的指针和一个指向下一个链表结构体的指针。接下来,定义链表操作函数,包括添加、删除、修改和查询四个功能函数。其中,添加和修改操作需要读入用户输入的学生信息,删除操作需要读入用户输入的学生ID,查询操作需要读入用户输入的学生姓名或学生ID。在链表操作函数中,需要遍历链表,找到对应的学生信息,并进行相应的操作。 3. 题目:编写一个程序,对一个文件中的所有单词进行计数。每个单词以空格、制表符或换行符为分隔符。请输出单词出现的次数。 解题思路:首先,打开文件,读取文件中的所有单词,将其存储在一个字符串数组中。然后,遍历字符串数组,对每个单词进行计数,使用一个哈希表来存储每个单词的出现次数。最后,输出每个单词的出现次数即可。 4. 题目:编写一个程序,实现一个简单的 shell 命令行界面。该程序应支持以下操作: - ls:列出当前目录下的所有文件和子目录。 - cd:改变当前目录。 - pwd:显示当前目录的路径。 - mkdir:创建一个新目录。 - rm:删除一个文件或目录。 - exit:退出 shell 程序。 解题思路:首先,定义一个字符串数组,用于存储用户输入的命令和参数。然后,通过比较用户输入的命令,执行相应的操作。对于 ls、cd 和 pwd 命令可以使用系统调用函数实现,对于 mkdir 和 rm 命令可以使用系统调用或者 C 语言库函数实现。最后,当用户输入 exit 命令时,退出 shell 程序即可。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值