快速将一连串的单词分解成单个单词的方法

时间:2016-12-20 11:24:16

标签: python string nlp

说我有这个字符串:

hellohowareyou

有没有快速的方法将其分成单个单词,最终结果是hello how are you?我可以想到几种方法,但它们会非常慢(首先我需要根据字典识别每个字母,看哪些字母组成一个单词,并且可能有多种组合,然后我需要决定最可能的组合等。)

3 个答案:

答案 0 :(得分:2)

这是一些执行递归暴力搜索的代码。它将单词列表放入一个集合中,因此查找速度非常快:下面的示例在我的旧2 GHz机器上运行不到1秒,内存为2GB。然而,分裂比我使用的例子更长的序列肯定需要更长的时间,主要是因为有太多可能的组合。要清除无意义的结果,您需要手动完成,或者使用可以进行自然语言处理的软件。

#!/usr/bin/env python3

''' Separate words

    Use dictionary lookups to recursively split a string into separate words

    See http://stackoverflow.com/q/41241216/4014959

    Written by PM 2Ring 2016.12.21
'''

# Sowpods wordlist from http://www.3zsoftware.com/download/

fname = 'scrabble_wordlist_sowpods.txt'
allwords = set('AI')
with open(fname) as f:
    for w in f:
        allwords.add(w.strip())

def parse(data, result=None):
    if result is None:
        result = []
    if data in allwords:
        result.append(data)
        yield result[::-1]
    else:
        for i in range(1, len(data)):
            first, last = data[:i], data[i:]
            if last in allwords:
                yield from parse(first, result + [last])

# Test

data = (
    'HELLOHOWAREYOU',
    'THISEXAMPLEWORKSWELL',
    'ISTHEREAFASTWAY',
    'ONE',
    'TWOWORDS',
)

for s in data:
    print(s)
    for u in parse(s):
        print(u)
    print('')    

<强>输出

HELLOHOWAREYOU
['HELL', 'OHO', 'WARE', 'YOU']
['HELLO', 'HO', 'WARE', 'YOU']
['HELLO', 'HOW', 'ARE', 'YOU']
['HELL', 'OH', 'OW', 'ARE', 'YOU']
['HELLO', 'HOW', 'A', 'RE', 'YOU']
['HELL', 'OH', 'OW', 'A', 'RE', 'YOU']

THISEXAMPLEWORKSWELL
['THIS', 'EXAMPLE', 'WORK', 'SWELL']
['THIS', 'EX', 'AMPLE', 'WORK', 'SWELL']
['THIS', 'EXAMPLE', 'WORKS', 'WELL']
['THIS', 'EX', 'AMPLE', 'WORKS', 'WELL']

ISTHEREAFASTWAY
['I', 'ST', 'HER', 'EA', 'FAS', 'TWAY']
['IS', 'THERE', 'A', 'FAS', 'TWAY']
['I', 'ST', 'HERE', 'A', 'FAS', 'TWAY']
['IS', 'THE', 'RE', 'A', 'FAS', 'TWAY']
['I', 'ST', 'HE', 'RE', 'A', 'FAS', 'TWAY']
['I', 'ST', 'HER', 'EA', 'FAST', 'WAY']
['IS', 'THERE', 'A', 'FAST', 'WAY']
['I', 'ST', 'HERE', 'A', 'FAST', 'WAY']
['IS', 'THE', 'RE', 'A', 'FAST', 'WAY']
['I', 'ST', 'HE', 'RE', 'A', 'FAST', 'WAY']
['I', 'ST', 'HER', 'EA', 'FA', 'ST', 'WAY']
['IS', 'THERE', 'A', 'FA', 'ST', 'WAY']
['I', 'ST', 'HERE', 'A', 'FA', 'ST', 'WAY']
['IS', 'THE', 'RE', 'A', 'FA', 'ST', 'WAY']
['I', 'ST', 'HE', 'RE', 'A', 'FA', 'ST', 'WAY']

ONE
['ONE']

TWOWORDS
['TWO', 'WORDS']

此代码是为Python 3编写的,但您可以通过更改

使其在Python 2上运行
yield from parse(first, result + [last])

for seq in parse(first, result + [last]):
    yield seq

顺便说一句,我们可以按长度对输出列表进行排序,即每个列表中的单词数。这往往会使更明智的结果接近顶部。

for s in data:
    print(s)
    for u in sorted(parse(s), key=len):
        print(u)
    print('')

答案 1 :(得分:0)

思想:

接受句子:

Isthereafastwaytosetratethisininividualwordssotheendresulthehellohowhowyyoucantofinkofheveralways butthethewtrbebetrTrmymheloweneedideideytleletragantadtolitsthewitsletterscompawawords ...

一个人能够很好地把它分成一个有意义的句子。因此,机器应该能够做同样的事情。

服用:

  

isthereafastwaytoseparate

reafastwaytoseparate ...”应该是“那里快速分开” 请注意,无论在reafast之后拍摄了多少封信......他们都不会说一句话。

因此,一种可能的,正确的方法是通过句子找到最短的可能单词,直到后面的单词不是单词。这可以通过在加长原始单词之前取15个字母来近似。

在极少数情况下,您可能需要返回前两个单词,或者在极少数情况下,返回2或3个单词。此外,对于较长的单词,15个字母可能太少。

最后,如果有其他语言的专有名词或单词,它们会出现在字典中。因此,在找不到单词后,下一个单词可以是新的起始点,并且该单词可以被标记或忽略。在学习模型和本案例中,应将其添加到语料库或单词中。

将单词拆分为词性(动词,名词等)可以加快处理速度,因为形容词通常后跟名词。但这可能不值得努力,因为另一个形容词可以遵循。在任何情况下,必须对语料库中的所有单词进行测试,因为这不是为了检查语法而构建的。

答案 2 :(得分:0)

这是一个“难”的问题,因为你需要使用一些启发式方法,而不仅仅是一个字典背后的字典。您可以将字典转换为树,以便从单词的假定开头逐字逐句地进行有效搜索,但是当您遇到不在字典中的字母串时,您会去哪里。像“ABS”(塑料)或“invac”(银行员工可能是“投资账户”的简写)或“ncie”(“好”的拼写错误)之类的东西。

哦,还有一些内在的含糊之处,缺少的空间会对后面的内容产生很大的影响。考虑“治疗师”......你需要成为一个人(或几乎)来分析以下背景,以确定是否需要在“the”之后的空间。