机器学习经典算法之(十三) 隐马尔可夫模型

        一、隐马尔可夫模型简介:

        隐马尔可夫模型(Hidden MarkovModel,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。然后利用这些参数来作进一步的分析,例如模式识别。

        隐马尔可夫模型马尔可夫链的一种,它的状态不能直接观察到,但能通过观测向量序列观察到,每个观测向量都是通过某些概率密度分布表现为各种状态,每一个观测向量是由一个具有相应概率密度分布的状态序列产生。所以,隐马尔可夫模型是一个双重随机过程----具有一定状态数的隐马尔可夫链和显示随机函数集。自20世纪80年代以来,HMM被应用于语音识别,取得重大成功。到了90年代,HMM还被引入计算机文字识别和移动通信核心技术“多用户的检测”。HMM在生物信息科学、故障诊断等领域也开始得到应用

        隐马尔可夫模型(HMM)可以用五个元素来描述,包括2个状态集合和3个概率矩阵:

        1. 隐含状态S

        这些状态之间满足马尔可夫性质,是马尔可夫模型中实际所隐含的状态。这些状态通常无法通过直接观测而得到。(例如S1、S2、S3等等)

        2. 可观测状态O

        在模型中与隐含状态相关联,可通过直接观测而得到。(例如O1、O2、O3等等,可观测状态的数目不一定要和隐含状态的数目一致。)

        3. 初始状态概率矩阵π

        表示隐含状态在初始时刻t=1的概率矩阵,(例如t=1时,P(S1)=p1、P(S2)=P2、P(S3)=p3,则初始状态概率矩阵π=[ p1,p2, p3 ].

        4. 隐含状态转移概率矩阵 A

        描述了HMM模型中各个状态之间的转移概率。

        其中Aij = P( Sj | Si ),1≤i,j≤N.

        表示在 t 时刻、状态为 Si 的条件下,在 t+1时刻状态是 Sj 概率

        5. 观测状态转移概率矩阵 B或者有时称为:发射概率,某种隐含状态产生某种观测现象的概率。令N代表隐含状态数目,M代表可观测状态数目,则:

 
 

        Bij = P( Oi| Sj ), 1≤i≤M,1≤j≤N.

表示在 t 时刻、隐含状态是 Sj 条件下,观察状态为 Oi 的概率。

        总结:一般的,可以用λ=(A,B,π)三元组来简洁的表示一个隐马尔可夫模型。隐马尔可夫模型实际上是标准马尔可夫模型的扩展,添加了可观测状态集合和这些状态与隐含状态之间的概率关系。

        二、解决的三类基本问题:

        1. 评估问题。

        给定观测序列 O=O1O2O3…Ot和模型参数λ=(A,B,π),怎样有效计算某一观测序列的概率,进而可对该HMM做出相关评估。例如,已有一些模型参数各异的HMM,给定观测序列O=O1O2O3…Ot,我们想知道哪个HMM模型最可能生成该观测序列。通常我们利用forward算法分别计算每个HMM产生给定观测序列O的概率,然后从中选出最优的HMM模型。

        这类评估的问题的一个经典例子是语音识别。在描述语言识别的隐马尔科夫模型中,每个单词生成一个对应的HMM,每个观测序列由一个单词的语音构成,单词的识别是通过评估进而选出最有可能产生观测序列所代表的读音的HMM而实现的。

        2.解码问题

        给定观测序列 O=O1O2O3…Ot和模型参数λ=(A,B,π),怎样寻找某种意义上最优的隐状态序列。在这类问题中,我们感兴趣的是马尔科夫模型中隐含状态,这些状态不能直接观测但却更具有价值,通常利用Viterbi算法来寻找。

        这类问题的一个实际例子是中文分词,即把一个句子如何划分其构成才合适。例如,句子“发展中国家”是划分成“发展-中-国家”,还是“发展-中国-家”。这个问题可以用隐马尔科夫模型来解决。句子的分词方法可以看成是隐含状态,而句子则可以看成是给定的可观测状态,从而通过建HMM来寻找出最可能正确的分词方法。

        3. 学习问题。

        如果HMM的模型参数λ=(A,B,π)未知,如何调整这些参数以使观测序列O=O1O2O3…Ot的概率尽可能的大。通常使用Baum-Welch算法以及ReversedViterbi算法解决。

         三、HMM的语音识别应用举例。

import os
import numpy as np
from scipy.io import wavfile
from python_speech_features import mfcc
# import sys
# sys.path.append(r'C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\hmmlearn-0.2.0')  #加入路径,添加目录
import hmmlearn
from hmmlearn import *
# Class to handle all HMM related processing
class HMMTrainer(object):
    def __init__(self, model_name='GaussianHMM', n_components=4, cov_type='diag', n_iter=1000):
        self.model_name = model_name
        self.n_components = n_components
        self.cov_type = cov_type
        self.n_iter = n_iter
        self.models = []
        if self.model_name == 'GaussianHMM':
            self.model = hmm.GaussianHMM(n_components=self.n_components, 
                    covariance_type=self.cov_type, n_iter=self.n_iter)
        else:
            raise TypeError('Invalid model type')
    # X is a 2D numpy array where each row is 13D
    def train(self, X):
        np.seterr(all='ignore')
        self.models.append(self.model.fit(X))


    # Run the model on input data
    def get_score(self, input_data):
        return self.model.score(input_data)


if __name__=='__main__':
    input_folder = "d:\\learning\\speech-reconginzer"
    hmm_models = []
    # Parse the input directory
    for dirname in os.listdir(input_folder):
        # Get the name of the subfolder 
        subfolder = os.path.join(input_folder, dirname)
        if not os.path.isdir(subfolder): 
            continue
        # Extract the label
        label = subfolder[subfolder.rfind('/') + 1:]
        # Initialize variables
        X = np.array([])
        y_words = []
        # Iterate through the audio files (leaving 1 file for testing in each class)
        for filename in [x for x in os.listdir(subfolder) if x.endswith('.wav')][:-1]:
            # Read the input file
            filepath = os.path.join(subfolder, filename)
            sampling_freq, audio = wavfile.read(filepath)
            
            # Extract MFCC features
            mfcc_features = mfcc(audio, sampling_freq)
            # Append to the variable X
            if len(X) == 0:
                X = mfcc_features
            else:
                X = np.append(X, mfcc_features, axis=0)            
            # Append the label
            y_words.append(label)
        # print 'X.shape =', X.shape
        # Train and save HMM model
        hmm_trainer = HMMTrainer()
        hmm_trainer.train(X)
        hmm_models.append((hmm_trainer, label))
        hmm_trainer = None
    # Test files
    input_files = [
            'data/pineapple/pineapple15.wav',
            'data/orange/orange15.wav',
            'data/apple/apple15.wav',
            'data/kiwi/kiwi15.wav'
            ]
    # Classify input data
    for input_file in input_files:
        # Read input file
        sampling_freq, audio = wavfile.read(input_file)
        print("input_file",input_file)
        # Extract MFCC features
        mfcc_features = mfcc(audio, sampling_freq)
        # Define variables
        max_score = None
        output_label = None
        # Iterate through all HMM models and pick 
        # the one with the highest score
        for item in hmm_models:
            hmm_model, label = item
            score = hmm_model.get_score(mfcc_features)
            if score > max_score:
                max_score = score

                output_label = label

     部分内容摘自百度百科,大家加油!

猜你喜欢

转载自blog.csdn.net/weixin_42039090/article/details/80685276