如何从有效的连续字符串中提取文字的话吗? [重复](How to extract literal

2019-09-19 21:50发布

可能重复:
如何在没有空格为单词的列表拆分文本?

还有的是在由HTML解析人的评论文本信息质量,但目前还没有定界人物在其中。 例如: thumbgreenappleactiveassignmentweeklymetaphor 。 显然,有“经验”,“绿色”,“苹果”,等的字符串中。 我也有一个大的字典查询词是否合理。 那么,什么是提取这些话的最快方法?

Answer 1:

我真的不知道一个天真的算法将成为你的目的很好,由eumiro指出的,所以我将描述一个稍微复杂的一个。

这个想法

继续进行下去的最佳方式是输出的分销模式 。 一个良好的第一近似值是假设所有的词都独立分布。 然后,你只需要知道的所有单词的相对频率。 这是合理的假设,他们按照齐普夫定律,那就是在单词列表与等级n词有概率约为1 /(N日志N),其中N是字典中的单词的数量。

一旦你有固定的模式,你可以使用动态编程来推断空间的位置。 最有可能的一句话就是,最大限度地提高每个单词的概率的产品之一,它很容易与动态编程来计算它。 而不是直接使用概率,我们使用定义为概率的倒数的对数成本,以避免溢出。

编码

import math

# Build a cost dictionary, assuming Zipf's law and cost = -math.log(probability).
words = open("words-by-frequency.txt").read().split()
wordcost = dict((k,math.log((i+1)*math.log(len(words)))) for i,k in enumerate(words))
maxword = max(len(x) for x in words)

def infer_spaces(s):
    """Uses dynamic programming to infer the location of spaces in a string
    without spaces."""

    # Find the best match for the i first characters, assuming cost has
    # been built for the i-1 first characters.
    # Returns a pair (match_cost, match_length).
    def best_match(i):
        candidates = enumerate(reversed(cost[max(0, i-maxword):i]))
        return min((c + wordcost.get(s[i-k-1:i], 9e999), k+1) for k,c in candidates)

    # Build the cost array.
    cost = [0]
    for i in range(1,len(s)+1):
        c,k = best_match(i)
        cost.append(c)

    # Backtrack to recover the minimal-cost string.
    out = []
    i = len(s)
    while i>0:
        c,k = best_match(i)
        assert c == cost[i]
        out.append(s[i-k:i])
        i -= k

    return " ".join(reversed(out))

您可以与使用

s = 'thumbgreenappleactiveassignmentweeklymetaphor'
print(infer_spaces(s))

例子

我使用这个快速和肮脏的125K字字典我放在一起 ,从维基百科的一小部分。

之前:thumbgreenappleactiveassignmentweeklymetaphor。
后:拇指青苹果主动分配每周比喻。

之前:thereismassesoftextinformationofpeoplescommentswhichisparsedfromhtmlbuttherearen odelimitedcharactersinthemforexamplethumbgreenappleactiveassignmentweeklymetapho rapparentlytherearethumbgreenappleetcinthestringialsohavealargedictionarytoquery whetherthewordisreasonablesowhatsthefastestwayofextractionthxalot。

也有存在的是从HTML解析人民意见的文本信息,群众但是在他们没有分隔字符例如拇指青苹果主动分配每周比喻显然有字符串中的拇指青苹果等我大词典:后查询词是否合理,有何提取THX很多的最快方式。

之前:itwasadarkandstormynighttherainfellintorrentsexceptatoccasionalintervalswhenitwascheckedbyaviolentgustofwindwhichsweptupthestreetsforitisinlondonthatoursceneliesrattlingalongthehousetopsandfiercelyagitatingthescantyflameofthelampsthatstruggledagainstthedarkness。

后:这是一个夜黑风高的大雨如注,除了在当它是由风的猛烈阵风席卷了大街小巷,因为这是在伦敦,我们的现场位于沿房顶剑拔弩张检查偶有间隔激烈搅动那挣扎着对黑暗的灯寥寥无几火焰。

正如你可以看到它本质上是完美无瑕的。 最重要的部分是要确保你的单词列表被培养成类似于你会真正遇到语料库,否则结果会很糟糕。


优化

执行消耗的时间和存储器的线性量,因此它是相当有效的。 如果您需要进一步的加速,你可以从单词列表构建一个后缀树,以减少候选集的大小。

如果您需要处理一个非常大的连续字符串时,它可以合理地分割字符串,以避免过多的内存使用情况。 例如,你可以在处理10000个字块的文字加上两侧1000个字符的保证金,以避免边界效应。 这将让内存使用到最低限度,将几乎肯定对质量没有影响。



Answer 2:

“显然”是很好的人,不是计算机...

words = set(possible words)
s = 'thumbgreenappleactiveassignmentweeklymetaphor'
for i in xrange(len(s) - 1):
    for j in xrange(1, len(s) - i):
        if s[i:i+j] in words:
            print s[i:i+j]

在可能的词/usr/share/dict/wordsfor j in xrange(3, len(s) - i): (3最小字长度),它发现:

thumb
hum
green
nap
apple
plea
lea
act
active
ass
assign
assignment
sign
men
twee
wee
week
weekly
met
eta
tap


文章来源: How to extract literal words from a consecutive string efficiently? [duplicate]