有限状态机
什么是有限状态机
DFA-确定性有限自动机
DFA M
是一个五元组:
其中,
是输入事件的有穷集合;Q是状态的有限集合;
是初始状态;
是终止状态集合;
是Q与
的笛卡儿积到Q(下一个状态)的映射,它支配着有限状态控制的行为,有时也称为状态转移函数。
在NLP中,事件通常是输入一个字符或者字符串。
DFA
M
是一个五元组:
其中, 是输入事件的有穷集合;Q是状态的有限集合; 是初始状态; 是终止状态集合; 是Q与 的笛卡儿积到Q(下一个状态)的映射,它支配着有限状态控制的行为,有时也称为状态转移函数。
在NLP中,事件通常是输入一个字符或者字符串。
NFA-不确定性有限自动机
如果将DFA中的替换成笛卡儿积到幂集的映射,DFA就变成了NFA了。
NFA和DFA最大的区别就是映射函数, 在DFA中,当前事件和输入确定后,下一个状态也是确定的,在NFA中,当前事件和状态确定后,下一个状态可以选择一个状态集合中的任何一个状态作为下一个状态。
来点干货来说明确定性有限自动机和不确定性有限自动机的区别,比如说
- 有一个男孩,单身(状态)
- 遇到了一个心怡的女孩子(事件),展开了追求(状态)
- 女孩答应了男孩的追求(事件),男孩和女孩进入甜蜜的二人世界(状态)
- 两人一生一世,然后直到死了(结束状态)
- 相处一段事件两人觉得不合适分手(事件),男孩重新又变成了单身狗(状态)
- 女孩没有答应男孩的追求(事件),男孩仍然是单身狗(状态)
- 一直遇不到心怡的女孩(事件),单身一辈子(状态),然后悄悄的走了(结束状态)
但是呢,还有一个电视里的男孩,他的人生轨迹是这样的
- 有一个男孩
- 如果单身(状态)
- 遇到一个心怡的女孩(事件),他可能选择追她、追她的闺蜜、羞辱她获得她的关注……(状态集合)
- 已经有女朋友了(状态)
- 遇到了一个新的女孩(事件),他可能选择保持忠诚、出轨后跪舔女友、劈腿后换新女友……(状态集合)
- 没有遇到新的女孩(事件),他可能选择聊骚、追求女友的闺蜜、做二十四孝老公……(状态集合)
- ……
第一个男孩就是确定性男友机,第二个男孩就是不确定性男友机,哦,不,是确定性有限自动机和不确定性有限自动机。
DFA和NFA合称有限自动机(FA),也称有限状态机(FSM)。
如果将DFA中的替换成笛卡儿积到幂集的映射,DFA就变成了NFA了。
NFA和DFA最大的区别就是映射函数, 在DFA中,当前事件和输入确定后,下一个状态也是确定的,在NFA中,当前事件和状态确定后,下一个状态可以选择一个状态集合中的任何一个状态作为下一个状态。
来点干货来说明确定性有限自动机和不确定性有限自动机的区别,比如说
- 有一个男孩,单身(状态)
- 遇到了一个心怡的女孩子(事件),展开了追求(状态)
- 女孩答应了男孩的追求(事件),男孩和女孩进入甜蜜的二人世界(状态)
- 两人一生一世,然后直到死了(结束状态)
- 相处一段事件两人觉得不合适分手(事件),男孩重新又变成了单身狗(状态)
- 女孩答应了男孩的追求(事件),男孩和女孩进入甜蜜的二人世界(状态)
- 女孩没有答应男孩的追求(事件),男孩仍然是单身狗(状态)
- 一直遇不到心怡的女孩(事件),单身一辈子(状态),然后悄悄的走了(结束状态)
- 遇到了一个心怡的女孩子(事件),展开了追求(状态)
但是呢,还有一个电视里的男孩,他的人生轨迹是这样的
- 有一个男孩
- 如果单身(状态)
- 遇到一个心怡的女孩(事件),他可能选择追她、追她的闺蜜、羞辱她获得她的关注……(状态集合)
- 已经有女朋友了(状态)
- 遇到了一个新的女孩(事件),他可能选择保持忠诚、出轨后跪舔女友、劈腿后换新女友……(状态集合)
- 没有遇到新的女孩(事件),他可能选择聊骚、追求女友的闺蜜、做二十四孝老公……(状态集合)
- ……
- 如果单身(状态)
第一个男孩就是确定性男友机,第二个男孩就是不确定性男友机,哦,不,是确定性有限自动机和不确定性有限自动机。
DFA和NFA合称有限自动机(FA),也称有限状态机(FSM)。
FST-有限状态转换机
如果FA在完成状态转移的同时产生一个输出,那么就被称作有限状态转换机。
如果FA在完成状态转移的同时产生一个输出,那么就被称作有限状态转换机。
说人话
上面的定义让人头疼不已,现在开始说人话,有限状态机其实非常建档,用一句话概括就是
current state + event = next state
从当前状态+事件=下一个状态,这个状态转移的过程就是通过状态转移函数实现,由于状态和事件都是有限的,所以被称作有限状态机。
上面的定义让人头疼不已,现在开始说人话,有限状态机其实非常建档,用一句话概括就是
current state + event = next state
从当前状态+事件=下一个状态,这个状态转移的过程就是通过状态转移函数实现,由于状态和事件都是有限的,所以被称作有限状态机。
最长正向匹配分词
有限状态机可以被用来实现最长匹配分词,
事件集合()={所有可能输入的字符},
状态集合(Q)={词典中所有词的前缀(包括词本身),单个字符,以及空字符串}
初始状态()=空字符串
状态转移函数()={如果当前状态对应的字符+输入字符在状态集合中,则状态转移到当前状态对应的字符和输入字符,否则,状态转移到输入字符,并把前一个状态对应的字符串最为一个词输出}
有限状态机可以被用来实现最长匹配分词,
事件集合()={所有可能输入的字符},
状态集合(Q)={词典中所有词的前缀(包括词本身),单个字符,以及空字符串}
初始状态()=空字符串
状态转移函数()={如果当前状态对应的字符+输入字符在状态集合中,则状态转移到当前状态对应的字符和输入字符,否则,状态转移到输入字符,并把前一个状态对应的字符串最为一个词输出}
算法
我们通过词典把状态转移函数保存成一个HashMap
(字典
),以方便后面的状态转移使用,我们把这个字典称作前缀状态字典。
我们通过词典把状态转移函数保存成一个HashMap
(字典
),以方便后面的状态转移使用,我们把这个字典称作前缀状态字典。
Build pdict (构造前缀追她字典)
Input: dicts={word1, word2, ..., wordn)$
Output: 前缀状态字典pdict
pdict <- 空字典
for word in dicts:
pdict[word] = 1
word_len = word的长度
for j in {word_len, ..., 1}:
subword = word[:j]
if subword not in pdict:
pdict[subword] = 1
Input: dicts={word1, word2, ..., wordn)$
Output: 前缀状态字典pdict
pdict <- 空字典
for word in dicts:
pdict[word] = 1
word_len = word的长度
for j in {word_len, ..., 1}:
subword = word[:j]
if subword not in pdict:
pdict[subword] = 1
正向最大匹配(状态转移和输出)
Input: pdict, sentence={c1c2...cN}
Output: 正向最大匹配的分词结果words=[word1, word2, ..., wordn]
N = sentence的长度
words = []
subword = ""
for i in {0, 1, ..., N-1}:
subword += sentence[i]
if subword not in pdict:
if len(subword) == 1:
words.append(subword[:-1])
subword = sentence[i]
else:
words.append(subword)
subword = ""
if len(subword) > 0:
words.append(subword)
# words即所需的分词
以上即最大正向匹配分词的全部算法,源代码因为版权问题,就不贴了。
Input: pdict, sentence={c1c2...cN}
Output: 正向最大匹配的分词结果words=[word1, word2, ..., wordn]
N = sentence的长度
words = []
subword = ""
for i in {0, 1, ..., N-1}:
subword += sentence[i]
if subword not in pdict:
if len(subword) == 1:
words.append(subword[:-1])
subword = sentence[i]
else:
words.append(subword)
subword = ""
if len(subword) > 0:
words.append(subword)
# words即所需的分词
以上即最大正向匹配分词的全部算法,源代码因为版权问题,就不贴了。
进一步思考
如何在最大匹配的算法基础上,利用有限状态机实现全切分词呢?
如何在最大匹配的算法基础上,利用有限状态机实现全切分词呢?
欢迎关注我的微信公众号
直觉与逻辑-二维码
微信公众号:
直觉与逻辑
微信号: roy-qu
扫描上述二维码即可关注我的微信公众号

扫描上述二维码即可关注我的微信公众号