彼得诺维格著名的spellchecker(java 8版本here)能够纠正单个单词,如果在训练数据中出现与该单词相近的内容。但我如何才能适应它来处理整个短语。例如,如果我有一个文件,其中每个短语都用新行分隔:
Plastic box
Pencils and sketch
Romeo and Juliet
.
.
.
如果我告诉算法更正
'Platic'
,它应该返回'Plastic box'
。同样,如果我告诉它更正'Pencils'
,它应该返回'Pencils and sketch'
。我试图更改以上代码的以下行(Java版本):
Stream.of(new String(Files.readAllBytes( dictionaryFile )).toLowerCase().replaceAll("[^a-z ]","").split(" ")).forEach( (word) ->{
dict.compute( word, (k,v) -> v == null ? 1 : v + 1 );
});
到
Stream.of(new String(Files.readAllBytes( dictionaryFile )).toLowerCase().split("\n")).forEach( (word) ->{
dict.compute( word, (k,v) -> v == null ? 1 : v + 1 );
});
但似乎没用。
最佳答案
如果你仔细阅读norvig的spellchecker
,你会发现,由于error model
,他使用了拼写错误的单词中的edit distance
1和2处的单词。因此,如果您想使用文件Platic
作为字典来更正big.text
,它可以找到编辑距离2处的单词Elastic
作为候选的正确单词。
现在,使用修改后的代码,短语Plastic box
甚至与单词Platic
的编辑距离都不在2以内,甚至在错误模型中都不会被视为候选,这就是它不起作用的原因。
例如,它们之间的编辑距离是5,然后必须实现函数edit3
、edit4
和edit5
才能使其工作,这将需要考虑数百万字,而且效率很低。
相反,我认为您可以考虑bigram
language model
并且尽管返回了一个可能的拼写错误单词的候选单词,但是您仍然可以返回最有可能的bigram phrase
,这取决于字典中的probability of occurrence
,其中language model
P(Plastic box
)=P(Plastic
)*P(box
)和候选短语的概率a P(Plastic
)*P(Platic塑料盒)Plastic box
Bayeswith
错误模型(或者你有数据可以学习)。