[CRF] 条件随机场 统计学习方法例11.3 代码实践

 
  
def viterbi_CRF(y, t, s):
    """
    统计学习方法例11.3
    :param y: 输出序列
    :param t: 转移特征 [序列*y标记矩阵*[yi-1,yi]]
    :param s: 状态特征 [序列*y标记]
    :return: 最优路径的状态索引、概率最大值矩阵、节点矩阵
    """
    y_lable = len(t[0])
    y_star = np.zeros([len(y)],dtype=np.int32) # 输出路径索引
    delta = np.zeros([len(y), y_lable],dtype=np.float64) #迭代矩阵
    psi = np.zeros([len(y), y_lable],dtype=np.int32)
    # 初始化
    delta[0][0] = s[0][0]
    delta[0][1] = s[0][1]
    for i in range(1,len(y)):
        for j in range(y_lable):
            tmp = [delta[i - 1][k] + s[i][j] + t[i][k][j] for k in range(y_lable)]
            psi[i][j] = np.argmax(tmp) # 记录位置
            delta[i][j] = tmp[psi[i][j]] # 记录最大概率

    y_star[2] = np.argmax(delta[len(y)-1]) # 获取最后deleta的最大值
    for i in range(len(y)-2,-1,-1): # 回溯
        y_star[i] = psi[i+1][y_star[i+1]]

    return y_star,delta,psi

def test_viterbi_CRF():
    y = np.array([1,2,2],dtype=np.int) # 给定输出序列
    mu = np.array([1,0.5,0.8,0.5]) # 状态权重
    # 状态特征 [序列*y标记]
    s = np.array([[mu[0],mu[1]],
        [mu[2],mu[1]],
        [mu[2],mu[3]]],dtype=np.float64)
    lamd = np.array([1,0.6,1,1,0.2]) # 转移权重
    #
    t = np.array([
        [[0,0],[0,0]],
        [[lamd[1],lamd[0]],[lamd[3],0]],
        [[0,lamd[0]],[lamd[2],lamd[4]]]],dtype=np.float64)
    y_star, delta, psi = viterbi_CRF(y,t,s)

    print '最优路径索引 y*:\n',y_star
    print '概率最大值矩阵 δ:\n',delta
    print '节点矩阵 ψ:\n',psi

if __name__ == '__main__':
    test_viterbi_CRF()


最终输出:
 
  
最优路径索引 y*:
[0 1 0]
概率最大值矩阵 δ:
[[1.  0.5]
 [2.4 2.5]
 [4.3 3.9]]
节点矩阵 ψ:
[[0 0]
 [0 0]
 [1 0]]


你可能感兴趣的:(机器学习)