用于自然语言处理的词频算法

时间:2008-09-18 06:49:27

标签: algorithm nlp word-frequency

如果没有获得信息检索的学位,我想知道是否存在任何用于计算单词在给定文本体中出现的频率的算法。目标是让人们对一组文本评论所说的内容有“普遍的感觉”。沿着Wordle

我想要的是什么:

  • 忽略文章,代词等('a','an','the','他','他们'等)
  • 保留专有名词
  • 忽略连字符,除了软类

到达星星,这些将是桃子的:

  • 处理词干&复数(例如喜欢,喜欢,喜欢,喜欢匹配相同的结果)
  • 将形容词(副词等)与其主题分组(“伟大的服务”而不是“伟大的”,“服务”)

我尝试了一些使用Wordnet的基本内容,但我只是盲目地调整内容并希望它适用于我的特定数据。更通用的东西会很棒。

8 个答案:

答案 0 :(得分:70)

你不需要一个,而是几个不错的算法,沿着以下几行。

  • 忽略代词是通过stoplist完成的。
  • 保留专有名词?你的意思是,检测命名实体,如 Hoover Dam 并说“它是一个单词”或复合名词,如编程 语言?我会给你一个提示:那个很难,但是两者都有库。寻找NER(命名的权利识别)和词汇分块。 OpenNLP是一个兼容两者的Java-Toolkit。
  • 忽略连字符?你的意思是,就像在线下休息一样?使用正则表达式并通过字典查找验证生成的单词。
  • 处理复数/词干:你可以查看Snowball stemmer。它很好地解决了这个问题。
  • 将形容词与其名词“分组”通常是shallow parsing的任务。但如果您正在寻找定性形容词(好的,坏的,蹩脚的,令人惊奇的......),您可能会对sentiment analysis感兴趣。 LingPipe做到这一点,还有更多。

对不起,我知道你说你想要吻,但不幸的是,你的要求并不容易。然而,存在所有这些的工具,你应该能够将它们绑在一起而不必自己执行任何任务,如果你不想这样做的话。如果你想自己完成一项任务,我建议你看一下干预,这是最简单的。

如果使用Java,请将LuceneOpenNLP工具包结合使用。你会得到非常好的结果,因为Lucene已经有一个内置的词干分析器和很多教程。另一方面,OpenNLP工具包的文档记录很少,但您不需要太多。您可能也对使用Python编写的NLTK感兴趣。

我会说你放弃了你的最后一个要求,因为它涉及浅层解析,并且肯定不会影响你的结果。

啊,顺便问一下。你正在寻找的那个文件 - 术语 - 频率 - 事物的确切术语称为tf-idf。这几乎是查找术语文档频率的最佳方式。为了正确地做到这一点,你不会使用多维矢量矩阵。

...是的,我知道。在参加IR研讨会后,我对Google的尊重更大。在做了IR的一些事情后,我对他们的尊重也同样快。但是。

答案 1 :(得分:16)

欢迎来到NLP世界^ _ ^

您只需要一点基础知识和一些工具。

已有工具可以告诉您句子中的单词是名词,形容词还是动词。它们被称为part-of-speech taggers。通常,他们将明文英语作为输入,并输出单词,基本形式和词性。以下是帖子第一句中流行的UNIX词性标注器的输出:

$ echo "Without getting a degree in information retrieval, I'd like to know if there exists any algorithms for counting the frequency that words occur in a given body of text." | tree-tagger-english 
# Word  POS     surface form
Without IN  without
getting VVG get
a   DT  a
degree  NN  degree
in  IN  in
information NN  information
retrieval   NN  retrieval
,   ,   ,
I   PP  I
'd  MD  will
like    VV  like
to  TO  to
know    VV  know
if  IN  if
there   EX  there
exists  VVZ exist
any DT  any
algorithms  NNS algorithm
for IN  for
counting    VVG count
the DT  the
frequency   NN  frequency
that    IN/that that
words   NNS word
occur   VVP occur
in  IN  in
a   DT  a
given   VVN give
body    NN  body
of  IN  of
text    NN  text
.   SENT    .

如您所见,它将“算法”识别为“算法”的复数形式(NNS),将“存在”识别为“存在”的共轭(VBZ)。它还将“a”和“the”标识为“确定者(DT)” - 文章的另一个词。如您所见,POS标记器还标记了标点符号。

除了列表中的最后一点之外,您只需要通过POS标记器运行文本,过滤掉您不感兴趣的类别(确定者,代词等)并计算频率。基本形式的单词。

以下是一些流行的POS标记:

TreeTagger(仅限二进制文件:Linux,Solaris,OS-X)
GENIA Tagger(C ++:编译你自己)
Stanford POS Tagger(Java)

要做清单上的最后一件事,您需要的不仅仅是单词级信息。一个简单的方法是计算序列 而不仅仅是单词本身。这些被称为n-grams。一个好的开始是UNIX for Poets。如果您愿意投资一本关于NLP的书,我建议Foundations of Statistical Natural Language Processing

答案 2 :(得分:4)

以下是如何在Python中执行此操作的示例,其概念在任何语言中都相似。

>>> import urllib2, string
>>> devilsdict = urllib2.urlopen('http://www.gutenberg.org/files/972/972.txt').read()
>>> workinglist = devilsdict.split()
>>> cleanlist = [item.strip(string.punctuation) for item in workinglist]
>>> results = {}
>>> skip = {'a':'', 'the':'', 'an':''}
>>> for item in cleanlist:
      if item not in skip:
        try:
          results[item] += 1
        except KeyError:
          results[item] = 1

>>> results
{'': 17, 'writings': 3, 'foul': 1, 'Sugar': 1, 'four': 8, 'Does': 1, "friend's": 1, 'hanging': 4, 'Until': 1, 'marching': 2 ...

第一行只是获取帮助解决部分问题的库,如第二行所示,其中urllib2下载了Ambrose Bierce的“Devil's Dictionary”副本。下一行列出了文本中的所有单词,没有标点。然后创建一个哈希表,在这种情况下就像一个与数字相关联的唯一单词列表。 for循环遍历Bierce书中的每个单词,如果表中已存在该单词的记录,则每个新出现在表中与该单词相关联的值中加1;如果单词尚未出现,则会将其添加到表中,值为1(表示一次出现。)对于您正在讨论的案例,您可能希望更加注重细节,例如使用大小写为了帮助识别只在句子等中间的专有名词,这是非常粗糙的,但表达了这个概念。

要进入词干和复数化的东西,进行实验,然后看看第三方的工作,我很喜欢NLTK的一部分,这是一个学术性的开源项目,也是在python中。

答案 3 :(得分:2)

我写了一个完整的程序来做这件事。我回家后可以上传一个演示版。

以下是代码(asp.net/c#):h ttp://naspinski.net/post/Findingcounting-Keywords-out-of-a-Text-Document.aspx

答案 4 :(得分:2)

你问题的第一部分听起来并不那么糟糕。您基本上需要做的就是从文件中读取每个单词(或者使用流w / e)并将其放入前缀树中,并且每次遇到已存在的单词时,都会增加与之关联的值。当然,你也会忽略你计算中遗漏的所有内容。

如果使用前缀树,则确保找到任何单词转到O(N),其中N是数据集中单词的最大长度。在这种情况下,前缀树的优点是,如果你想查找复数和词干,你可以检查O(M + 1),如果这个词甚至可能,那么M是没有词干或多个词的长度(这是一个字吗?呵呵)。一旦你构建了你的前缀树,我会重新分析它的词干等,并将其压缩,以便根词是保存结果的。

在搜索时,您可以制定一些简单的规则,以便在根或干或您拥有的情况下使匹配返回正数。

第二部分似乎极具挑战性。我天真的倾向是对形容词 - 主题分组保持单独的结果。使用与上述相同的原则,但只是将其分开。

语义分析的另一个选择是将每个句子建模为主语,动词等关系(句子有主​​语和动词,主语有名词和形容词等)。一旦你以这种方式破坏了所有文本,似乎可以相当容易地运行并快速计算发生的不同的适当配对。

只是一些ramblings,我确信有更好的想法,但我喜欢思考这些东西。

答案 5 :(得分:1)

您刚才描述的算法。一个开箱即用的程序,带有一个大按钮,上面写着“做它”......我不知道。

但让我具有建设性。我推荐你这本书Programming Collective Intelligence。第3章和第4章包含非常实用的例子(实际上,没有复杂的理论,只是例子)。

答案 6 :(得分:0)

你可以使用worldnet字典来获取问题关键词的基本信息,如其过去的语音,提取同义词,你也可以为你的文档做同样的创建索引。 然后,您可以轻松地将关键字与索引文件匹配并对文档进行排名。然后总结一下。

答案 7 :(得分:0)

spacy可以很好地处理您列出的所有内容。

  1. 忽略一些单词-使用停用词
  2. 提取主题-使用部分语音标签进行识别(开箱即用)。解析句子后,找到“ ROOT”-句子的主要动词。通过navigating the parse tree,您将找到与此动词相关的名词。这将是主题。
  3. 忽略连字符-在大多数情况下,其令牌生成器处理连字符。它可以轻松扩展以处理更多特殊情况。

如果主题列表是预先确定的并且不是很大,则您甚至可以走得更远:建立一个可以预测主题的分类模型。 假设您有10个科目。您收集示例句子或文本。您将它们加载到另一个产品中:prodigy。使用出色的界面,您可以快速将主题分配给样本。最后,使用分类的样本,您可以训练spacy模型来预测文本或句子的主题。