在开始之前,请注意我使用的是linux shell (通过Python中的using subprocess.call() ),并且我使用的是openFST。
我一直在筛选关于openFST的文档和问题,但我似乎找不到这个问题的答案:如何真正为openFST提供输入-定义、编译和合成的FST?输出到哪里?我只是简单地执行'fstproject‘吗?如果是这样的话,我该如何,比如说,给它一个字符串来进行转换,并在达到最终状态时打印各种转换?
如果这个问题看起来很明显,我很抱歉。到目前为止,我还不是很熟悉openFST。
发布于 2012-03-10 15:30:45
一种方法是创建执行转换的机器。一个非常简单的例子就是字符串的大写。
M.wfst
0 0 a A
0 0 b B
0 0 c C
0附带的符号文件为字母表中的每个符号包含一行。注0是为空(epsilon)转换保留的,在许多操作中具有特殊含义。
M.syms
<epsilon> 0
a 1
b 2
c 3
A 4
B 5
C 6然后编译机器
fstcompile --isymbols=M.syms --osymbols=M.syms M.wfst > M.ofst对于输入字符串"abc“,创建一个线性链自动机,这是一个从左到右的链,每个字符都有一条弧线。这是一个接受器,所以我们只需要输入符号的一列。
I.wfst
0 1 a
1 2 b
2 3 c
3 作为接受者进行编译
fstcompile --isymbols=M.syms --acceptor I.wfst > I.ofst然后组装机器并打印出来
fstcompose I.ofst M.ofst | fstprint --isymbols=M.syms --osymbols=M.syms 这将给出输出
0 1 a A
1 2 b B
2 3 c C
3fstcompose的输出是输入字符串的所有换能器的点阵。(在本例中只有一个)。如果fstprint比较复杂,可以使用-- M.ofst -nshortest=n标志来提取n个字符串。这个输出也是一个转换器,您可以丢弃fstprint的输出,或者使用C++代码和OpenFst库运行深度优先搜索来提取字符串。
插入fstproject --project_output将把输出转换为只包含输出标签的接受器。
fstcompose I.ofst M.ofst | fstproject --project_output | fstprint --isymbols=M.syms --osymbols=M.syms 给出了以下内容
0 1 A A
1 2 B B
2 3 C C
3这是一个接受者,因为输入和输出标签是相同的,所以可以使用--接受者选项生成更简洁的输出。
fstcompose I.ofst M.ofst | fstproject --project_output | fstprint --isymbols=M.syms --acceptor发布于 2019-01-07 09:13:30
保罗·迪克森的例子很棒。由于OP使用Python,我想我应该添加一个简单的示例来说明如何使用Open FST's Python wrapper“运行”转换器。遗憾的是,你不能用Open FST创建“线性链自动机”,但它很容易自动化,如下所示:
def linear_fst(elements, automata_op, keep_isymbols=True, **kwargs):
"""Produce a linear automata."""
compiler = fst.Compiler(isymbols=automata_op.input_symbols().copy(),
acceptor=keep_isymbols,
keep_isymbols=keep_isymbols,
**kwargs)
for i, el in enumerate(elements):
print >> compiler, "{} {} {}".format(i, i+1, el)
print >> compiler, str(i+1)
return compiler.compile()
def apply_fst(elements, automata_op, is_project=True, **kwargs):
"""Compose a linear automata generated from `elements` with `automata_op`.
Args:
elements (list): ordered list of edge symbols for a linear automata.
automata_op (Fst): automata that will be applied.
is_project (bool, optional): whether to keep only the output labels.
kwargs:
Additional arguments to the compiler of the linear automata .
"""
linear_automata = linear_fst(elements, automata_op, **kwargs)
out = fst.compose(linear_automata, automata_op)
if is_project:
out.project(project_output=True)
return out让我们定义一个大写字母“a”的简单Transducer:
f_ST = fst.SymbolTable()
f_ST.add_symbol("<eps>", 0)
f_ST.add_symbol("A", 1)
f_ST.add_symbol("a", 2)
f_ST.add_symbol("b", 3)
compiler = fst.Compiler(isymbols=f_ST, osymbols=f_ST, keep_isymbols=True, keep_osymbols=True)
print >> compiler, "0 0 a A"
print >> compiler, "0 0 b b"
print >> compiler, "0"
caps_A = compiler.compile()
caps_A

现在,我们可以使用以下命令简单地应用传感器:
apply_fst(list("abab"), caps_A)输出:

要了解如何将其用于接受者,请查看我的other answer
发布于 2021-04-28 01:37:39
将Yann Dubois的答案更新为python3:
import pywrapfst as fst
print("")
f_ST: fst.SymbolTable
def linear_fst(elements, automata_op, keep_isymbols=True, **kwargs):
"""Produce a linear automata."""
compiler = fst.Compiler(
isymbols=f_ST, # There should be some way to get this from automata_op
acceptor=keep_isymbols,
keep_isymbols=keep_isymbols,
**kwargs
)
for i, el in enumerate(elements):
print("{} {} {}".format(i, i + 1, el), end="", file=compiler)
print(str(i + 1), end="", file=compiler)
lf = compiler.compile()
return lf
def apply_fst(elements, automata_op, print_la=True, is_project=False, **kwargs):
"""Compose a linear automata generated from `elements` with `automata_op`.
Args:
elements (list): ordered list of edge symbols for a linear automata.
automata_op (Fst): automata that will be applied.
print_la (bool, optional): print linear automata as text representation
is_project (str, optional): whether to keep only the "input" or "output" labels.
kwargs: Additional arguments to the compiler of the linear automata .
"""
linear_automata = linear_fst(elements, automata_op, **kwargs)
if print_la:
print("Linear Automata:\n", linear_automata)
out = fst.compose(linear_automata, automata_op)
if is_project:
out.project("output")
return out
f_ST = fst.SymbolTable()
f_ST.add_symbol("<eps>", 0)
f_ST.add_symbol("A", 1)
f_ST.add_symbol("a", 2)
f_ST.add_symbol("b", 3)
compiler = fst.Compiler(
isymbols=f_ST, osymbols=f_ST, keep_isymbols=True, keep_osymbols=True
)
print("0 0 a A", end="", file=compiler)
print("0 0 b b", end="", file=compiler)
print("0", end="", file=compiler)
caps_A = compiler.compile()
print("Uppercase Transducer with", caps_A.num_states(), "states:\n", caps_A)
caps_I = apply_fst(list("abab"), caps_A)
print("Output:\n", caps_I)这将打印:
Uppercase Transducer with 1 states:
0 0 a A
0 0 b b
0
Linear Automata:
0 1 a 2
1 2 b 3
2 3 a 2
3 4 b 3
4
Output:
0 1 a A
1 2 b b
2 3 a A
3 4 b b
4https://stackoverflow.com/questions/9390536
复制相似问题