【问题标题】:Replace Words on the basis of Bigram Frequency,Python基于二元组频率替换单词,Python
【发布时间】:2014-02-19 01:05:16
【问题描述】:

我有一个系列类型对象,我必须应用一个函数,该函数使用二元组来纠正单词,以防它与另一个单词一起出现。我创建了一个 bigrams list ,根据频率对其进行排序(最高优先)并将其命名为 fdist 。

bigrams = [b for l in text2 for b in zip(l.split(" ")[:-1], l.split(" ")[1:])]
freq = nltk.FreqDist(bigrams) #computes freq of occurrence
fdist = freq.keys() # sorted according to freq

接下来,我创建了一个函数,它接受每一行(“或句子”、“列表的对象”)并使用二元组来决定是否进一步纠正它。

def bigram_corr(line): #function with input line(sentence)
    words = line.split() #split line into words
    for word1, word2 in zip(words[:-1], words[1:]): #generate 2 words at a time words 1,2 followed by 2,3 3,4 and so on
        for i,j in fdist: #iterate over bigrams
            if (word2==j) and (jf.levenshtein_distance(word1,i) < 3): #if 2nd words of both match, and 1st word is at an edit distance of 2 or 1, replace word with highest occurring bigram
               word1=i #replace
               return word1 #return word

问题是整个句子只返回一个单词,例如:
“Lts go twards the east is” 替换为 Lets 。看起来进一步的迭代不起作用。
word1, word2 的 for 循环是这样工作的: 第一次迭代中的“lts go”,最终将被“lets”取代,因为“go”出现的频率更高

在第二次迭代中“走向”。

在第 3 次迭代中“朝向”……以此类推。

有一个小错误,我无法弄清楚,请帮忙。

【问题讨论】:

  • 请澄清。 bigram_corr("Lets go towards the east is") 的预期结果是什么?
  • 已编辑,请检查。我需要返回整个句子。
  • 你过早地回来了。
  • 读者可能对导致创建此帖子的聊天讨论感兴趣。那里可能还有其他线索。 chat.stackoverflow.com/transcript/message/14784810#14784810

标签: python return-value levenshtein-distance function n-gram


【解决方案1】:

听起来你在做word1 = i 并期望这会修改words 的内容。但这不会发生。如果你想修改words,你必须直接这样做。使用enumerate 跟踪word1 的索引。

正如 2rs2ts 指出的那样,您早早回来了。如果您希望在找到第一个好的替代品后终止内部循环,请break 而不是返回。然后在函数结束时返回。

def bigram_corr(line): #function with input line(sentence)
    words = line.split() #split line into words
    for idx, (word1, word2) in enumerate(zip(words[:-1], words[1:])):
        for i,j in fdist: #iterate over bigrams
            if (word2==j) and (jf.levenshtein_distance(word1,i) < 3): #if 2nd words of both match, and 1st word is at an edit distance of 2 or 1, replace word with highest occurring bigram
                words[idx] = i
                break
    return " ".join(words)

【讨论】:

  • 是的,我认为这可能比我提供的更接近 OP 试图实现的目标,基于word1=i。
【解决方案2】:

return 语句完全停止函数。我想你想要的是:

def bigram_corr(line):
    words = line.split()
    words_to_return = []
    for word1, word2 in zip(words[:-1], words[1:]):
        for i,j in fdist:
            if (word2==j) and (jf.levenshtein_distance(word1,i) < 3):
               words_to_return.append(i)
    return ' '.join(words_to_return)

这会将您处理过的每个单词放入一个列表中,然后用空格重新连接它们并返回整个字符串,因为您说过要返回“整个句子”。

我不确定您的代码的语义是否正确,因为我没有 jf 库或您正在使用的任何库,因此我无法测试此代码,所以这可能或可能无法完全解决您的问题。但这会有所帮助。

【讨论】:

  • words_to_return = [] 应该在第一个 for 循环之后,对吧?因为它会随着多个句子变得越来越大..
  • @Sword 你期望以line 传递什么?我认为这将是一个以换行符结尾的文本字符串 ('\n')。但是不,这是放置words_to_return 的正确位置。
  • 是真的..我在循环后初始化它并得到一个错误。我现在执行它..让我们看看..
  • 它没有用,但你教会了我一个新的逻辑......谢谢兄弟:)
  • @Sword 对。看到凯文的回答后,我想你正在尝试做一些我给你看的东西。但我很高兴你从中学到了一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 2011-04-24
  • 2018-09-02
  • 2020-09-03
  • 2011-08-18
  • 1970-01-01
相关资源
最近更新 更多