我在使用NLTK的FreqDist时遇到了一些麻烦。让我先给你一些背景信息:
FreqDist
。nltk.FreqDist
一般来说运作良好 - 它完成了工作并做得很好;我没有收到任何错误等。我唯一的问题是"心率"经常出现,因为我正在生成最常用单词的列表,我会分别将heart
和rate
分别调整为几百次。
现在当然rate
和heart
都可以在不被用作"心率"但是我如何计算"心率"的发生率?而不是单独的两个单词,我的意思是准确的方式。我不想在我现在的计数器或其他类似的东西中减去另一个。
提前谢谢!
答案 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。我可以考虑两种可能的解决方案: