Python:将复合词拆分为已知单词(来自字典)

时间:2015-11-17 01:11:36

标签: python

我需要一个非常有效的算法来执行以下操作:

我必须用任何语言分隔复合词。例如英语。

但是当一个单词由共享最后一个和第一个字母的两个单词组成时,会出现问题。

即。第一个单词以第二个单词开头的字母结束。

所以,我们有一个包含所有可能单词的字典,简而言之:

假设我们想用这个典型的词典来分割'lightshow'这个词:

d = {"light": "Noun, S, N",
    "lights": "Noun, P, N",
    "how": "Q",
    "show": "Noun, S, N",
    ...}

我的算法现在将单词分成两个列表:

left = []; right = []
for x in range(len(word)-1, 1, -1):
    ls = word[:x]; rs = word[x:]
    if ls.lower() in d: left.append(ls)
    if rs.lower() in d: right.append(rs)

然后我找到左边最长的单词和右边列表中最长的单词。

所以,我知道这个词包含哪些单词,以及它们在复合词中开始和结束的位置。

现在不要担心过多的情况,其中单词不在词典中,单词不匹配等等,我只是想向你提出这个想法,以及这个方法的最大问题。

在整个算法结束时使用这种方法,结果将是:

["lights", "how"]

而不是:

["light", "show"]

什么是,你可以想象不可接受。

哦,是的,我可以通过使用:

来检查dict中是否存在单词show
l = ["lights", "how"]
if l[0][-1]+l[1] in d: <repair the list>

但是它很实用,我的算法也递归地处理由超过2个单词组成的单词。

它还处理以大写等差异分隔的单词。

这就是为什么我没有发布它的原因,因为它很大并且经过优化,因此需要阅读很多不重要的代码。

哦,是的,我可以做一些改进,将最后一个词改为主要。或者比较选择哪一个等的长度等。

但并不总是能够正确地决定这些操作。例如,如何处理以多个字母相交的找到的最长单词?

我想在一个循环中完成所有操作。速度是必不可少的。

注意:我提供的字典是示例性的。我必须使用的数据集不包含任何有关单词类型的信息。只是它的发音,只有有用的信息可以是说话时单词是短/长。

希望在这里看到一些非常好的想法。请记住,代码必须非常高效。它由TTS实时用于发出不在字典中但实际上包含通常与发音匹配的单词的单词。 不需要为我提供代码,只需要付诸行动的想法。

2 个答案:

答案 0 :(得分:3)

在这些情况下,您可以使用连字算法或字典建议的单词中的音节中断。一个好的连字算法会告诉你light-showdata-set正确地分解了这个词。

我认为绝对不可能在所有情况下都做到这一点,但没有一个数据文件明确地将lightshow映射到light + showdataset到{{无论你想出什么算法,它总会在出错的地方出现例外情况。

Frank Liang的连字算法is available here for Python,并帮助你的两个例子之一:

data + set

您可以尝试测试>>> hyphenate_word("dataset") ['dataset'] >>> hyphenate_word("lightshow") ['light', 'show'] 返回的音节组合(这应该非常高效,因为它在TeX中使用),如果找不到任何内容,请尝试使用原始方法。

在这些方面做得很好:

hyphenate_word()

A handy list of compound words,还有一些triple compound words

答案 1 :(得分:2)

我立即想到了两个因素,但您可能希望首先使用数据集对其进行验证。

  1. 按字种重量。通常组成的单词将由名词组成,因此如果您可以在N + QN + N之间进行选择,则N + N可能是正确的解决方案。从我的头脑中,我想不出一个例子,你会更喜欢某个名词,但那是你应该检查的重点
  2. 单数,复数的重量。特别是对于&#34; s&#34;在中间通常是复数形式的情况,所以更喜欢S + X而不是P + X