摘要 形式语言与自动机是计算机科学的理论基础,对于计算机科学与技术专业人才的计算思维能力培养极其重要。本文首先从Chomsky谱系出发,对形式语言的概念和类别进行了阐述,然后按照形式文法与自动机之间的对应关系,介绍了四种自动机。最后通过单词拼写检查例子展现了形式语言与自动机在自然语言处理中的应用。
引言
自动机和形式语言是计算机科学的理论基础,它在信息科学,生物学,管理学等众多学科领域中应用广泛。自动机和形式语言的研究起源于二十世纪人们对逻辑学的研究,1930年,图灵提出图灵机这一抽象计算模型,用以界定什么能够计算,什么不能够计算,图灵机也因此成为现代计算机的理论基础。其后,德国著名数学家Hilbert在研究证明理论时进一步推动了自动机和形式语言的研究。上世纪60年代,齐姆斯基借助形式化的方法描述语言,提出了Chomsky谱系,从而使形式语言理论成为一门独立的学科。
计算机科学与技术强调4方面的专业能力:计算思维能力、算法分析与设计能力、程序设计与实现能力、计算机系统的认知、分析、设计和应用能力。形式语言与自动机理论,在对计算机科学与技术学科人才进行计算思维能力培养中占有极其重要的地位。本文首先对形式语言和自动机的基本概念,研究内容进行讨论,然后结合目前自然语言处理的热点,展示了形式语言与自动机在自然语言处理中的应用。
形式语言
形式语言与形式文法
语言是交流和沟通的工具,分为自然语言和人工语言。自然语言是人类使用的语言,如汉语、英语等,这类语言由自然进化产生;人工语言是为特定应用而认为设计的语言,如化学家用的化学式,计算机编程语言等。不同的研究者对语言给出了不同的定义。《现代汉语词典》中对语言定义为:“人类所特有的用来表达意思,交流思想的共工具,是一种特殊的社会现象,由语音、词汇和语法构成一定的系统。”乔姆斯基将语言定义为:“按照一定规律构成的句子和符号串的有限或无限集合。”我国计算语言学家吴蔚天也给出了自己对语言的定义:“语言可以被看成一个抽象的数学系统。”这些定义描述虽然不同,但是都包含了语言是一个词汇表构成的符号系统的观念,因此可以采用数学的方法对语言的语法进行研究。在数学、逻辑和计算机科学中,将用来精确地描述语言(包括人工语言和自然语言)及其结构的手段称为形式语言,也称代数语言。1956年,乔姆斯基发表了用形式语言方法研究语言的第一篇文章,由此开启了形式语言的研究。
在形式语言学中,我们一般将语言形式化定义为:给定一组符号,称为字母表,以Σ表示,又以
Σ
∗
Σ^*
Σ∗表示由Σ中字母组成的所有字符串的集合,则
Σ
∗
Σ^*
Σ∗的每个子集都是Σ上的一个语言。对语言就行定义后,还需要对语言进行形式化描述,形式语言学中,采用形式文法对语言进行描述。形式文法被严格定义为四元组G=(N,Σ,P,S),其中,N是非终结符的有穷集合;Σ是终结符的有限集合,N∩Σ=∅;V=N∪Σ称总词汇表;P是一组重写规则的有限集合:P={α→β},其中,α,β是V中元素构成的串,但α中至少应含有一个非终结符号;S∈N,称为句子符或初始符。在形式文法的定义中,重写规则P={α→β}最为重要,重写规则P={α→β}表示字符串α可以被改写成β。一个初始字符串通过不断运用重写规则,就可以得到另一个字符串,通过选择不同的规则并以不同的顺序来运用这些规则,就可以得到不同的新字符串。
形式语言类别
文法是一种足够强大的语言描述工具,理论上可以描述语法规则非常复杂的语言,因此需要对其加以限制才能简单充分地描述常见的语言。针对重写规则P加以不同的约束,乔姆斯基将形式文法分为以下四类:
(1)0型文法,对重写规则P不施加任何限制,因此0型文法又称作无约束文法。由0型文法产生的语言记为
L
(
G
0
)
L(G_0)
L(G0)。
(2)1型文法,如果P中的规则满足如下形式:αAβ→αγβ,其中A∈N,α,β,
γ
∈
(
N
∪
Σ
)
∗
γ∈(N∪Σ)^*
γ∈(N∪Σ)∗,且γ至少包含一个字符,则称该文法为1型文法,观察重写规则P可以发现,字符串A只有在上下文分别是α和β的情况下才能被改写成γ,因此1型文法又称为上下文有关文法(context-sensitive grammar,CSG)。由1型文法产生的语言记为
L
(
G
1
)
L(G_1)
L(G1)。
(3)2型文法,如果P中的规则满足如下形式:A→α,其中A∈N,
α
∈
(
N
∪
Σ
)
∗
α∈(N∪Σ)^*
α∈(N∪Σ)∗,则称该文法为2型文法,因为对A改写成α的规则没有上下文约束,2型文法又称为上下文无关文法(context-free grammar,CFG)。由2型文法产生的语言记为
L
(
G
2
)
L(G_2)
L(G2)。
(4)3型文法,如果P中的规则满足如下形式:A→Bx,或A→x,其中A,B∈N,x∈Σ,则称该文法为正则文法或3型文法。由3型文法产生的语言记为
L
(
G
3
)
L(G_3)
L(G3)。
显然,每一个正则文法都是上下文无关文法,每一个上下文无关文法都是上下文有关文法,而每一个上下文有关文法都是0型文法,即
L
(
G
3
)
⊆
L
(
G
2
)
⊆
L
(
G
1
)
⊆
L
(
G
0
)
L(G_3)⊆L(G_2)⊆L(G_1)⊆L(G_0)
L(G3)⊆L(G2)⊆L(G1)⊆L(G0)。从0型文法到3型文法,限制越来越多,但性质也越来越好。如果一种语言能由几种文法所产生,则把这种语言称为在这几种文法中受限制最多的那种文法所产生的语言。在计算机科学中最常见的是上下文无关语言和正则语言,上下文无关语言根据其转换规则可以表示成树的形式,因而可以使用图论的方法进行搜索。
自动机
自动机概念
自动机是一种抽象的计算装置,给定输入符号,自动机将依据转移函数从当前状态跳转到下一状态,逐个读取输入中的符号,直到输入被耗尽,自动机也将停止下来。依据自动机停止时的状态,可以判定这个输入是被自动机“接受”还是“拒绝”。如果自动机停止于“接受状态”,则这个输入被自动机接受,反过来,如果自动机停止于“拒绝状态”,则这个输入被自动机“拒绝”。自动机接受的所有输入的集合称为这个自动机接受的语言。1951年到1956年间,克林(Kleene)在研究神经细胞中,从识别的角度,建立了识别语言的系统——有穷状态自动机。1959年,乔姆斯基发现文法和自动机分别从生成和识别的角度去表达语言,而且证明了文法与自动机的等价性,这一成果被认为是将形式语言置于了数学的光芒之下,使得形式语言真正诞生了。
自动机分类
基于乔姆斯基建立的形式文法与自动机之间的联系,我们也可以将自动机分成四种类型:有限自动机,下推自动机,线性有界自动机和图灵机,并与形式文法一一对应:若某一语言能用有限自动机识别,则它能用正则文法生成,反之亦然;若某一语言能用下推自动机识别,则它能用上下文无关文法生成,反之亦然;若某一语言能用线性有界自动机识别,则它能用上下文有关文法生成,反之亦然;若某一语言能用图灵机识别,则它能用0型文法生成,反之亦然;
有限自动机与正则文法
有限自动机M可以用五元组表示
M
=
<
Σ
,
Q
,
δ
,
q
o
,
F
>
M=<Σ,Q,δ,q_o,F>
M=<Σ,Q,δ,qo,F>:
Σ:输入符号的有穷集合;
Q:状态的有限集合;
q
o
∈
Q
q_o∈Q
qo∈Q是初始状态;
F:终止状态集合,F⊆Q;
δ是Q与Σ的值积Q×Σ到Q(下一个状态)的映射。它支配着有限状态控制的行为,有时也称状态转移函数。
有限自动机示意图如下:
处在状态q∈Q中的有限控制器从左到右依次从输入带上读入字符。开始时有限控制器处在状态
q
o
q_o
qo,并注视
Σ
∗
Σ^*
Σ∗中一个链的最左符号。映射
δ
(
q
,
a
)
=
q
′
(
q
,
q
′
∈
Q
,
a
∈
Σ
)
δ(q,a)=q' (q,q'∈Q,a∈Σ)
δ(q,a)=q′(q,q′∈Q,a∈Σ)表示在状态q时,若输入符号为a,则自动机进入状态
q
′
q'
q′,并且将输入头向右移动一个字符。
映射
δ
(
q
,
a
)
=
q
′
δ(q,a)=q'
δ(q,a)=q′可以由状态转换图描述。
为了明确起见,终止状态用双圈表示,起始状态用有“开始”标记的箭头表示。
有限自动机分为确定有限自动机(definite automata,DFA),不确定有限自动机(non-definite automata,NFA),NFA与DFA的唯一区别是:在NFA中
δ
(
q
,
a
)
δ(q,a)
δ(q,a)是一个状态集合,而在DFA中
δ
(
q
,
a
)
δ(q,a)
δ(q,a)是一个状态。如果L是一个被NFA所接受的句子的集合,则一定存在一个DFA,它能够接受L。若
G
=
<
V
N
,
V
T
,
P
,
S
>
G=<V_N,V_T,P,S>
G=<VN,VT,P,S>是一个正则文法,则存在一个有限自动机
M
=
(
Σ
,
Q
,
δ
,
q
0
,
F
)
M=(Σ,Q,δ,q_0,F)
M=(Σ,Q,δ,q0,F),使得:
T
(
M
)
=
L
(
G
)
T(M)=L(G)
T(M)=L(G)。反之亦然。由G构造M的一般步骤如下:
(1)令
Σ
=
V
T
Σ=V_T
Σ=VT,
Q
=
V
N
∪
T
Q=V_N∪{T}
Q=VN∪T,
q
0
=
S
q_0=S
q0=S,其中T是一个新增加的非终结符。
(2)如果在P中有产生式
S
→
ε
S→ε
S→ε,则
F
=
S
,
T
F={S,T}
F=S,T,否则
F
=
T
F={T}
F=T。
(3)如果在P中有产生式
B
→
a
B→a
B→a,
B
∈
V
N
B∈V_N
B∈VN,
a
∈
V
T
a∈V_T
a∈VT,则
T
∈
δ
(
B
,
a
)
T∈δ(B,a)
T∈δ(B,a)。
(4)如果在P中有产生式
B
→
a
C
B→aC
B→aC,
B
,
C
∈
V
N
B,C∈V_N
B,C∈VN,
a
∈
V
T
a∈V_T
a∈VT,则
C
∈
δ
(
B
,
a
)
C∈δ(B,a)
C∈δ(B,a)。
(5)对于每一个
a
∈
V
T
a∈V_T
a∈VT,有
δ
(
B
,
a
)
=
∅
δ(B,a)=∅
δ(B,a)=∅。
由M构造G的一般步骤如下:
(1)令
V
N
=
Q
V_N=Q
VN=Q,
V
T
=
Σ
V_T=Σ
VT=Σ,
S
=
q
0
S=q_0
S=q0;
(2)如果
C
∈
δ
(
B
,
a
)
C∈δ(B,a)
C∈δ(B,a),
B
,
C
∈
Q
B,C∈Q
B,C∈Q,
a
∈
Σ
a∈Σ
a∈Σ,则在P中有产生式
B
→
a
C
B→aC
B→aC;
(3)如果
C
∈
δ
(
B
,
a
)
C∈δ(B,a)
C∈δ(B,a),
C
∈
F
C∈F
C∈F,则在P中有产生式
B
→
a
B→a
B→a。
下推自动机与上下文无关文法
下推自动机(push-down automata,PDA)可以看成是一个带有附加的下推存储器的有限自动机,下推存储器是一个栈,如下图所示:
一个下推自动机可以表达成一个7元组:
M
=
(
Σ
,
Q
,
Γ
,
δ
,
q
0
,
Z
0
,
F
)
M=(Σ,Q,\Gamma,δ,q_0,Z_0,F)
M=(Σ,Q,Γ,δ,q0,Z0,F),其中:
Σ是输入符号的有穷集合;
Q是状态的有限集合;
Γ
\Gamma
Γ为下推存储器符号的有穷集合;
Z
0
∈
Γ
Z_0∈\Gamma
Z0∈Γ为最初出现在下推存储器顶端的符号;
q
0
∈
Q
q_0∈Q
q0∈Q是初始状态;
F是终止状态集合,F⊆Q;
δ
δ
δ是从
Q
×
(
Σ
∪
ε
)
×
Γ
Q×(Σ∪{ε})×\Gamma
Q×(Σ∪ε)×Γ到
Q
×
Γ
∗
Q×\Gamma^*
Q×Γ∗子集的映射,映射关系
δ
(
q
,
a
,
Z
)
=
{
(
q
1
,
γ
1
)
,
(
q
2
,
γ
2
)
,
⋯
,
(
q
m
,
γ
m
)
}
δ(q,a,Z)=\{(q_1,γ_1),(q_2,γ_2),⋯, (q_m,γ_m)\}
δ(q,a,Z)={(q1,γ1),(q2,γ2),⋯,(qm,γm)},其中,
q
1
,
q
2
,
⋯
q
m
∈
Q
q_1,q_2,⋯q_m∈Q
q1,q2,⋯qm∈Q,
a
∈
Σ
a∈Σ
a∈Σ,
Z
∈
Γ
Z∈\Gamma
Z∈Γ,
γ
1
,
γ
2
,
⋯
γ
m
∈
Γ
∗
γ_1,γ_2,⋯γ_m∈\Gamma^*
γ1,γ2,⋯γm∈Γ∗。该映射的意思是:当PDA处于状态q,面临输入符号a时,自动机进入
q
i
,
i
=
1
,
2
,
⋯
m
q_i,i=1,2,⋯m
qi,i=1,2,⋯m状态,并以
γ
i
γ_i
γi来代替下推存储器顶端符号Z,同时将输入头指向下一个字符。当Z被
γ
i
γ_i
γi取代时,
γ
i
γ_i
γi的符号按照从左到右的顺序依次从下向上推入到存储器。
假设下推自动机
M
=
(
Σ
,
Q
,
Γ
,
δ
,
q
0
,
Z
0
,
F
)
M=(Σ,Q,\Gamma,δ,q_0,Z_0,F)
M=(Σ,Q,Γ,δ,q0,Z0,F)接受语言
L
=
w
c
w
R
∣
w
∈
a
,
b
∗
L={wcw^R |w∈{a,b}^*}
L=wcwR∣w∈a,b∗,其中,
Q
=
0
,
1
Q={0,1}
Q=0,1,
Σ
=
a
,
b
,
c
Σ={a,b,c}
Σ=a,b,c,
Γ
=
A
,
B
\Gamma={A,B}
Γ=A,B,
q
0
=
0
q_0=0
q0=0,
Z
0
=
#
Z_0=\#
Z0=#,
F
=
{
1
}
F=\{1\}
F={1},
δ
δ
δ定义如下:
(1)
δ
(
0
,
a
,
ε
)
⊢
{
(
0
,
A
)
}
δ(0,a,ε)\vdash\{(0,A)\}
δ(0,a,ε)⊢{(0,A)}
\quad
(2)
δ
(
0
,
b
,
A
)
⊢
{
(
0
,
A
B
)
}
δ(0,b,A)\vdash\{(0,AB)\}
δ(0,b,A)⊢{(0,AB)}
\quad
(3)
δ
(
0
,
b
,
B
)
⊢
{
(
0
,
B
B
)
}
δ(0,b,B)\vdash\{(0,BB)\}
δ(0,b,B)⊢{(0,BB)}
(4)
δ
(
0
,
c
,
B
)
⊢
{
(
1
,
B
)
}
δ(0,c,B)\vdash\{(1, B)\}
δ(0,c,B)⊢{(1,B)}
\quad
(5)
δ
(
1
,
b
,
B
)
⊢
{
(
1
,
ε
)
}
δ(1,b,B)\vdash\{(1,ε)\}
δ(1,b,B)⊢{(1,ε)}
\quad
(6)
δ
(
1
,
a
,
A
)
⊢
{
(
1
,
ε
)
}
δ(1,a,A)\vdash\{(1,ε)\}
δ(1,a,A)⊢{(1,ε)}
下表展示了对于输入abbcbba下推自动机M的处理步骤:
状态 | 输入 | 栈 | 运用的规则 |
---|---|---|---|
0 | abbcbba | # | |
0 | bbcbba | A# | δ ( 0 , a , ε ) ⊢ { ( 0 , A ) } \delta(0,a,\varepsilon)\vdash\{(0,A)\} δ(0,a,ε)⊢{(0,A)} |
0 | bcbba | BA# | δ ( 0 , b , A ) ⊢ { ( 0 , A B ) } \delta(0,b,A)\vdash\{(0,AB)\} δ(0,b,A)⊢{(0,AB)} |
0 | cbba | BBA# | δ ( 0 , b , B ) ⊢ { ( 0 , B B ) } \delta(0,b,B)\vdash\{(0,BB)\} δ(0,b,B)⊢{(0,BB)} |
1 | bba | BBA# | δ ( 0 , c , B ) ⊢ { ( 1 , B ) } \delta(0,c,B)\vdash\{(1, B)\} δ(0,c,B)⊢{(1,B)} |
1 | ba | BA# | δ ( 1 , b , B ) ⊢ { ( 1 , ε ) } \delta(1,b,B)\vdash\{(1,\varepsilon)\} δ(1,b,B)⊢{(1,ε)} |
1 | a | A# | δ ( 1 , b , B ) ⊢ { ( 1 , ε ) } \delta(1,b,B)\vdash\{(1,\varepsilon)\} δ(1,b,B)⊢{(1,ε)} |
1 | ε \varepsilon ε | # | δ ( 1 , a , A ) ⊢ { ( 1 , ε ) } \delta(1,a,A)\vdash\{(1,\varepsilon)\} δ(1,a,A)⊢{(1,ε)} |
图灵机与0型文法
图灵机是英国数学家图灵于1936年提出的一种抽象计算模型。图灵的基本思想是用机器模拟人们用纸笔进行数学运算的过程,他把这样的过程看作下列两种简单的动作:
(1)在纸上写上或擦除某个符号;
(2)把注意力从纸的一个位置转移到另一个位置。
而在每一阶段,人在决定下一步的动作时,依赖于(a)此人当前所关注的纸上某个位置的符号和(b)此人当前思维状态。为了模拟人的这种运算过程,图灵构造出一台假象的机器,图灵机的示意图如下图所示:
该机器由以下几部分组成:
(1)一条无限长的纸带,纸带被划分为一个接一个的小格子,纸带上的格子从左到右依次被编号为0,1,2,⋯,纸带的右端可以无限伸展。
(2)一个读写头,该读写头可以在纸带上左右移动,它能读出当前所指的格子上的符号,并能改变当前格子上的符号。
(3)一套控制规则,它根据当前机器所处的状态以及当前读写头所指的格子上的符号来确定读写头下一步的动作,并改变状态寄存器的值,令机器进入一个新的状态,按照以下顺序告知图灵机命令:1、写入(替换)或擦除当前符号;2、移动读写头向左向右或不移动;3、保持当前状态或者转移到另一状态。
(4)一个状态寄存器,它用来保存图灵机当前所处的状态。图灵机的所有可能状态的数目是有限的,并且有一个特殊的状态,称为停机状态。
线性有界自动机与上下文有关文法
线性有界自动机(Linear Bounded Automata,LBA)是一种确定的单带图灵机,其读写头不能超越原输入带上字符串的初始和终止位置,即线性有界自动机的存储空间被输入符号串的长度所限制。其意义是给定一个字符串,只准修改,不准添加删除,但是修改可以随意修改。
各类自动机的主要区别是它们能够使用的信息存储空间的差异:有限状态自动机只能用状态来存储信息;下推自动机除了可以用状态以外,还可以用下推存储器;线性有界自动机可以利用状态和输入/输出带本身,因为输入/输出带没有“先进后出”的限制,因此,其功能大于栈;而图灵机的存储空间没有任何限制。
英语单词拼写检查
单词拼写检查是一个非常常见的应用,在很多场景都有用到,如word,输入法和搜索引擎中。单词拼写检查近乎是实时完成的,所以利用简单的词典匹配肯定是不可行的,因此可以考虑采用有限状态自动机实现。在单词拼写检查中最重要一个概念就是编辑距离,本章将从编辑距离开始讲解用有限自动机实现单词拼写检查。
编辑距离
编辑距离(Edit Distance)用来度量两个字符串之间的差距,设X是拼写错误的字符串,其长度为m,Y是X对应的正确单词,其长度为n。则X和Y的编辑距离ed(X[m],Y[n])定义为:从字符串X转换到Y需要的插入、删除、替换和交换两个相邻字符的最小个数,如:ed(recoginze,recognize)=1,ed(sailn,failing)=3。编辑距离的计算可以通过递归方法计算,分为三种情况:
(1)如果
x
(
i
+
1
)
=
y
(
j
+
1
)
x_{(i+1)}=y_{(j+1)}
x(i+1)=y(j+1),即两个串的最后一个字符系统,则
e
d
(
X
[
i
+
1
]
,
Y
[
j
+
1
]
)
=
e
d
(
X
[
i
]
,
Y
[
j
]
)
ed(X[i+1],Y[j+1])=ed(X[i],Y[j])
ed(X[i+1],Y[j+1])=ed(X[i],Y[j])
(2)如果 x i = y ( j + 1 ) x_i=y_{(j+1)} xi=y(j+1),并且 x ( i + 1 ) = y j x_{(i+1)}=y_j x(i+1)=yj,即最后两个字符需要交换位置,则 e d ( X [ i + 1 ] , Y [ j + 1 ] ) = 1 + m i n e d ( X [ i − 1 ] , Y [ i − 1 ] ) , e d ( X [ i ] , Y [ j + 1 ] ) , e d ( X [ i + 1 ] , Y [ j ] ) ed(X[i+1],Y[j+1])=1+min{ed(X[i-1],Y[i-1]),ed(X[i],Y[j+1]),ed(X[i+1],Y[j])} ed(X[i+1],Y[j+1])=1+mined(X[i−1],Y[i−1]),ed(X[i],Y[j+1]),ed(X[i+1],Y[j])
(3)其他情况,即
x
(
i
+
1
)
≠
y
(
j
+
1
)
且
(
x
(
i
+
1
)
≠
y
j
或
x
i
≠
y
(
j
+
1
)
)
x_{(i+1)}\ne y_{(j+1)}且(x_{(i+1)}\ne y_j 或x_i\ne y_{(j+1)})
x(i+1)=y(j+1)且(x(i+1)=yj或xi=y(j+1)),此时
e
d
(
X
[
i
+
1
]
,
Y
[
j
+
1
]
)
=
1
+
m
i
n
e
d
(
X
[
i
]
,
Y
[
j
]
)
,
e
d
(
X
[
i
]
,
Y
[
j
+
1
]
)
,
e
d
(
X
[
i
+
1
]
,
Y
[
j
]
)
ed(X[i+1],Y[j+1])=1+min{ed(X[i],Y[j]),ed(X[i],Y[j+1]),ed(X[i+1],Y[j])}
ed(X[i+1],Y[j+1])=1+mined(X[i],Y[j]),ed(X[i],Y[j+1]),ed(X[i+1],Y[j])
其中约定:
e
d
(
X
[
0
]
,
Y
[
j
]
)
=
j
(
0
≤
j
≤
n
)
e
d
(
X
[
i
]
,
Y
[
0
]
)
=
i
(
0
≤
i
≤
m
)
e
d
(
X
[
−
1
]
,
Y
[
j
]
)
=
e
d
(
X
[
i
]
,
Y
[
−
1
]
)
=
m
a
x
{
m
,
n
}
ed(X[0],Y[j])=j \quad(0≤j≤n)\\ ed(X[i],Y[0])=i \quad(0≤i≤m)\\ ed(X[-1],Y[j])=ed(X[i],Y[-1])=max\{m,n\}
ed(X[0],Y[j])=j(0≤j≤n)ed(X[i],Y[0])=i(0≤i≤m)ed(X[−1],Y[j])=ed(X[i],Y[−1])=max{m,n}
因此,我们可以构造一个确定的有限状态自动机
R
=
(
Q
,
A
,
δ
,
q
0
,
F
)
R=(Q,A,δ,q_0,F)
R=(Q,A,δ,q0,F),其中,Q表示状态集,A表示输入字符集,即26个字母,
δ
:
Q
×
A
→
Q
δ:Q×A→Q
δ:Q×A→Q是状态转移函数,
q
0
q_0
q0表示初始状态,F⊆Q表示终止状态。如果
L
⊆
A
∗
L⊆A^*
L⊆A∗表示有限状态机R接受的语言,字母构成的所有合法单词都是有限状态机中的一条路径,给定一个输入串,对其进行检查的过程就是在给定阈值(t>0)的情况下,寻找那些与输入串的编辑距离小于t的路径。那么,一个错误字符串X[m]能够被R识别的条件是存在非空集合:
C
=
{
Y
[
n
]
∣
Y
[
n
]
∈
L
a
n
d
e
d
(
X
[
m
]
,
Y
[
n
]
)
≤
t
}
C=\{Y[n]|Y[n]∈L\quad and\quad ed(X[m],Y[n])≤t\}
C={Y[n]∣Y[n]∈Landed(X[m],Y[n])≤t}
有限状态自动机能够用有向图表示,因此单词拼写检查可以表示为下图:
cut-off编辑距离
单词拼写检查想要具有实用价值,必须搜索速度非常的快,这意味着必须进行检查操作,排除那些不可能的路径,以减少搜索空间。因此,1996年kemal oflazer在经典编辑距离的基础上提出了cutoff距离,非常适合自然语言处理领域。
cut-off编辑距离度量错误字符串的一系列子串与候选正确字符串之间的最小编辑距离。设Y[n]是长度为n的候选正确字符串,X[m]是长度为m的拼写错误字符串。定义
l
=
m
a
x
(
1
,
n
−
t
)
l=max(1,n-t)
l=max(1,n−t),
u
=
m
i
n
(
m
,
n
+
t
)
u=min(m,n+t)
u=min(m,n+t),cut-off编辑距离定义如下:
c
u
t
e
d
(
X
[
m
]
,
Y
[
n
]
)
=
min
(
l
≤
i
≤
u
)
e
d
(
X
[
i
]
,
Y
[
n
]
)
cuted(X[m],Y[n])=\min \limits_{(l≤i≤u)}ed(X[i],Y[n])
cuted(X[m],Y[n])=(l≤i≤u)mined(X[i],Y[n])
例如,令t=2,
X
[
m
]
=
r
e
p
o
r
t
e
r
X[m]=reporter
X[m]=reporter,
Y
[
n
]
=
r
e
p
o
Y[n]=repo
Y[n]=repo,则:
c
u
t
e
d
(
r
e
p
r
t
e
r
,
r
e
p
o
)
=
m
i
n
{
e
d
i
t
(
r
e
,
r
e
p
o
)
=
2
,
e
d
i
t
(
r
e
p
,
r
e
p
o
)
=
1
,
e
d
i
t
(
r
e
p
r
,
r
e
p
o
)
=
1
,
e
d
i
t
(
r
e
p
r
t
,
r
e
p
o
)
=
2
,
e
d
i
t
(
r
e
p
r
t
e
,
r
e
p
o
)
=
3
}
=
1
cuted(reprter,repo)=min \{edit(re,repo)=2,\\ \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad edit(rep,repo)=1,\\ \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad edit(repr,repo)=1,\\ \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad edit(reprt,repo)=2,\\ \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad \quad\quad edit(reprte,repo)=3\}=1
cuted(reprter,repo)=min{edit(re,repo)=2,edit(rep,repo)=1,edit(repr,repo)=1,edit(reprt,repo)=2,edit(reprte,repo)=3}=1
寻找正确字符串
给定拼写错误的字符串X,自动机从起始状态开始,搜寻所有可能的转换,从而生成部分候选字符串Y。 每当我们继续搜寻,扩展Y时,我们检查X和Y的cut-off编辑距离是否在由阈值t指定的范围内。如果cut-off编辑距离超过阈值,则最后一个转换将退回到源节点,同时缩短Y,并尝试其他一些转换。当搜索不能从该状态继续时,递归地应用回溯。如果在构造Y的过程中达到了终止状态,并且没有违反cut-off编辑距离约束,即edit(X[m],Y[n])<t,那么Y是拼写错误字符串的一个有效正确形式。该过程可以采用深度优先搜索算法完成,算法伪代码如下所示:
push(ε,q_0); /*将一个空的字符串和初始节点压栈*/
while stack≠NULL {
pop(Y',q_i); /*从栈顶弹出一个部分字符串Y'和节点状态*/
for all q_j,a: δ(q_i,a)=q_j {
Y=concat(Y',a); /*扩展候选串,把字符a连接到Y'上*/
if cuted(X,Y)≤t: /*保证剪除距离在限定的范围*/
push(Y,q_j);
if edit(X,Y) ≤t and q_j∈F:
output(Y) /*输出Y*/
}
}
参考文献
本文主要参考了宗成庆老师《统计自然语言处理》第三章的PPT
[1] 宗成庆. 统计自然语言处理[M]. 清华大学出版社, 2013.
[2] Oflazer K. Error-tolerant finite-state recognition with applications to morphological analysis and spelling correction[J]. Computational Linguistics, 1996, 22(1): 73-89.