【发布时间】:2010-03-28 00:46:05
【问题描述】:
我知道 SOUNDEX 和 (double) Metaphone,但这些不能让我测试整个单词的相似性 - 例如,“Hi”听起来与“Bye”非常相似,但这两种方法会将它们标记为完全不同。
Ruby 中是否有任何库或您知道的任何方法能够确定两个单词之间的相似性? (布尔值是/不相似,或数字 40% 相似)
编辑:如果有一种简单的方法可以“插入”不同的方言或语言,则可以获得额外的奖励积分!
【问题讨论】:
我知道 SOUNDEX 和 (double) Metaphone,但这些不能让我测试整个单词的相似性 - 例如,“Hi”听起来与“Bye”非常相似,但这两种方法会将它们标记为完全不同。
Ruby 中是否有任何库或您知道的任何方法能够确定两个单词之间的相似性? (布尔值是/不相似,或数字 40% 相似)
编辑:如果有一种简单的方法可以“插入”不同的方言或语言,则可以获得额外的奖励积分!
【问题讨论】:
我认为您在描述 levenshtein 距离。是的,有宝石。如果您喜欢纯 Ruby,请选择 text gem。
$ gem install text
The docs 有更多细节,但关键在于:
Text::Levenshtein.distance('test', 'test') # => 0
Text::Levenshtein.distance('test', 'tent') # => 1
如果您对本机扩展没问题...
$ gem install levenshtein
It's usage is similar。它的性能非常好。 (它在我的系统上每分钟处理约 1000 次拼写更正。)
如果您需要知道两个词的相似程度,请使用距离而不是词长。
如果你想要一个简单的相似性测试,考虑这样的事情:
未经测试,但直截了当:
String.module_eval do
def similar?(other, threshold=2)
distance = Text::Levenshtein.distance(self, other)
distance <= threshold
end
end
【讨论】:
smile -> snail => smaɪl -> sneɪl 将具有较小的 Levenshtein 距离,其中 gait -> late => /geɪt/ -> /leɪt/ 将具有相同的距离,但由于g 和@987654331 之间的语音差异,蜗牛和微笑听起来比步态和迟到更相似@ 和n 和m 之间的相似性(想象一下像“fan”和“fang”这样的词)。假设我可以为各种声音之间的转换成本创建一个准确的数字地图,这可以导入到 ruby Leveinshtein 中吗?
你需要的是一本发音词典。最好的免费邮箱是CMU Pronouncing Dictionary。
将字符串映射到它们的发音,然后进行一些预处理(例如,您可能想要删除 cmudict 用来表示压力的数字),然后您可以使用其他人建议的技术之一,例如作为 levenshtein 距离,在发音字符串而不是输入字符串上。
有关类似内容的示例,请参阅Rhyme Ninja 中的 dict/dict.rb。
【讨论】:
您可能首先使用同义词库数据库对单词进行预处理,该数据库会将具有相似含义的单词转换为同一个单词。那里有各种各样的词库数据库,不幸的是我找不到一个像样的免费英语词库(http://www.gutenberg.org/etext/3202 是我找到的那个,但这并没有显示特定单词的关系(如相似;相反;替代含义) ; 等等),所以同一行上的所有单词都有 some 关系,但你不会知道那个关系是什么)
但是例如对于匈牙利语,有一个很好的免费词库数据库,但是您没有用于匈牙利语文本的 soundex/metaphone...
如果你有数据库编写一个预处理文本的程序并不太难(最终它是一个简单的搜索替换,但你可能也想使用单工或甲基音素来预处理同义词库数据库)
【讨论】: