NLTK FreqDist将两个单词统计为一个

时间:2017-08-06 11:23:11

标签: python nltk

我在使用NLTK的FreqDist时遇到了一些麻烦。让我先给你一些背景信息:

  • 我已经构建了一个网络抓取工具,可以抓取销售可穿戴产品(智能手表等)的公司的网页。
  • 我正在做一些语言分析,对于那个分析我也使用了一些NLTK函数 - 在这种情况下是FreqDist
  • nltk.FreqDist一般来说运作良好 - 它完成了工作并做得很好;我没有收到任何错误等。

我唯一的问题是"心率"经常出现,因为我正在生成最常用单词的列表,我会分别将heartrate分别调整为几百次。

现在当然rateheart都可以在不被用作"心率"但是我如何计算"心率"的发生率?而不是单独的两个单词,我的意思是准确的方式。我不想在我现在的计数器或其他类似的东西中减去另一个。

提前谢谢!

2 个答案:

答案 0 :(得分:1)

实现此目的的一种方法是在将文本传递给FreqDist之前对其进行预处理。这可以在您调用word_tokenize之前或之后完成(假设这是您管道中唯一的其他步骤,否则它取决于其他步骤正在做什么)。

您还必须决定是否要区分“心率”和“心率”的出现,或将它们视为相同的“单词”。如果你想区分它们(再次,如果它不会弄乱后面的步骤),你可以称之为heart_rate。这使它成为一个“单词”,但与“心灵”不同。

我将把它用作例句:

original = "A heart rate monitor measures your heartrate."

要在标记化之前执行此操作,您可以执行简单的replace

def preprocess(text):
    return text.replace("heart rate", "heart_rate")

txt = preprocess(original)
tokens = nltk.word_tokenize(txt)
nltk.FreqDist(tokens).tabulate()

这导致:

monitor       your          .   measures  heartrate heart_rate          A
      1          1          1          1          1          1          1

如果您想对它们进行相同的处理,您只需将其更改为text.replace("heart rate", "heartrate")即可。这将导致:

heartrate   monitor      your         .  measures         A
        2         1         1         1         1         1

如果你想在标记化之后进行处理,那么它会变得有点复杂,因为你现在有一个要循环的标记列表。这是一个例子:

def process_tokens(tokens):
    deleted = 0
    for i in range(len(tokens)):
        i = i - deleted
        if tokens[i] == "heart":
            if tokens[i+1] == "rate":
                tokens[i] = "heart_rate"
                del tokens[i+1]
                deleted += 1 # keep track so we don't get an IndexError later
    return tokens

当找到“心脏”标记时,它会检查下一个是否为“rate”,如果是,则将两者合并。同样,如果您愿意,可以将其从heart_rate更改为heartrate。此功能将使用如下:

tokens = nltk.word_tokenize(original)
nltk.FreqDist(process_tokens(tokens)).tabulate()

给出与第一个相同的结果。

答案 1 :(得分:0)

这是NLP中一个众所周知的问题,它通常被称为Tokenization。我可以考虑两种可能的解决方案:

  • 尝试使用不同的NLTK标记器(例如twitter标记器),这可能能够涵盖所有情况
  • 对您的句子运行名称实体识别(NER)。这允许您识别文本中存在的实体。这可能有效,因为它可以将心率识别为单个实体,因此可以作为单个标记。