32

在没有获得信息检索学位的情况下,我想知道是否存在任何算法来计算单词在给定文本中出现的频率。目标是获得人们对一组文本评论的“总体感觉”。沿着Wordle的路线。

我想要什么:

  • 忽略冠词、代词等('a'、'an'、'the'、'him'、'them'等)
  • 保留专有名词
  • 忽略连字符,除了软种类

伸手去拿星星,这些将是桃色的:

  • 处理词干和复数(例如喜欢、喜欢、喜欢、喜欢匹配相同的结果)
  • 形容词(副词等)与其主语(“伟大的服务”相对于“伟大的”、“服务”)的分组

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

4

8 回答 8

69

您不需要一个,而是几个不错的算法,如下所示。

  • 忽略代词是通过stoplist完成的。
  • 保留专有名词?你的意思是,检测命名实体,比如胡佛 水坝,然后说“这是一个词”或复合名词,比如编程 语言?我会给你一个提示:这很难,但两者都有库。寻找 NER(命名实体识别)和词法分块。OpenNLP是一个兼具两者的 Java 工具包。
  • 忽略连字符?你是说,比如换行?使用正则表达式并通过字典查找验证生成的单词。
  • 处理复数/词干:您可以查看Snowball stemmer。它做得很好。
  • 将形容词与其名词“分组”通常是浅层解析的任务。但是,如果您专门寻找定性形容词(好、坏、糟糕、惊人……),您可能会对情绪分析感兴趣。LingPipe可以做到这一点,还有更多。

对不起,我知道你说你想KISS,但不幸的是,你的要求并不容易满足。尽管如此,所有这些都存在工具,如果您不想这样做,您应该能够将它们捆绑在一起而不必自己执行任何任务。如果您想自己执行一项任务,我建议您查看词干提取,这是最简单的。

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

我想说你放弃你的最后一个要求,因为它涉及浅层解析,并且绝对不会改善你的结果。

啊,顺便说一句。您要查找的文档术语频率事物的确切术语称为tf-idf。这几乎是查找术语的文档频率的最佳方式。为了正确地做到这一点,您将无法使用多维向量矩阵。

... 是的,我知道。参加了 IR 研讨会后,我对 Google 的敬意更加深了。不过,在 IR 中做了一些事情之后,我对他们的尊重也很快下降了。

于 2008-09-18T08:04:19.263 回答
16

欢迎来到自然语言处理的世界^_^

您所需要的只是一些基本知识和一些工具。

已经有一些工具可以告诉您句子中的单词是名词、形容词还是动词。它们被称为词性标注器。通常,他们将纯文本英语作为输入,并输出单词、其基本形式和词性。这是您帖子第一句话中流行的 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”标识为“determiners (DT)”——文章的另一个词。如您所见,词性标注器还标记了标点符号。

要完成列表中最后一点以外的所有操作,您只需通过 POS 标记器运行文本,过滤掉您不感兴趣的类别(限定词、代词等)并计算基本形式的频率的话。

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

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

要完成列表中的最后一件事,您需要的不仅仅是单词级别的信息。一个简单的开始方法是计算单词序列 而不仅仅是单词本身。这些被称为n-gram。一个好的起点是UNIX for Poets。如果你愿意投资一本关于 NLP 的书,我会推荐Foundations of Statistical Natural Language Processing

于 2008-09-18T08:17:37.873 回答
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 的“恶魔词典”的副本。下一行列出了文本中的所有单词,没有标点符号。然后创建一个哈希表,在这种情况下,它就像一个与数字相关联的唯一单词列表。for 循环遍历 Bierce 书中的每个单词,如果表中已经存在该单词的记录,则每次新出现的值都会在表中与该单词关联的值上加一;如果该词尚未出现,则将其添加到表中,值为 1(表示出现一次。)对于您正在谈论的情况,您可能希望更加关注细节,例如使用大写帮助识别仅在句子中间的专有名词,

为了进入词干化和复数化的东西,实验,然后研究第 3 方的工作,我喜欢 NLTK 的部分内容,这是一个学术开源项目,也是在 python 中的。

于 2008-09-18T08:26:36.293 回答
2

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

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

于 2008-09-18T07:48:39.550 回答
2

你问题的第一部分听起来还不错。您基本上需要做的就是从文件(或 w/e 流)中读取每个单词并将其放入前缀树中,每次遇到已经存在的单词时,您都会增加与其关联的值。当然,您也会有一个忽略列表,其中包含您希望从计算中排除的所有内容。

如果您使用前缀树,您可以确保找到任何单词都需要 O(N),其中 N 是数据集中单词的最大长度。在这种情况下,前缀树的优点是,如果你想查找复数和词干,你可以检查 O(M+1) 如果这个词甚至可能的话,其中 M 是没有词干或复数的词的长度(这是一个词吗?呵呵)。一旦你建立了你的前缀树,我会重新分析它的词干等并将它浓缩下来,这样根词就是保存结果的东西。

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

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

语义分析的另一个选项可以将每个句子建模为主语、动词等关系的树(句子有主​​语和动词,主语有名词和形容词等)。一旦您以这种方式分解了所有文本,似乎很容易通过并快速计算发生的不同适当配对。

只是一些漫无边际的东西,我相信有更好的想法,但我喜欢思考这些东西。

于 2008-09-18T08:07:19.613 回答
1

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

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

于 2008-09-18T07:00:35.860 回答
0

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

于 2009-09-01T06:03:19.577 回答
0

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

  1. 忽略一些词 - 使用停用词
  2. 提取主题 - 使用词性标记来识别它(开箱即用)。解析一个句子后,找到“ROOT”——句子的主要动词。通过导航分析树,您将找到与该动词相关的名词。这将是主题。
  3. 忽略连字符 - 他们的分词器在大多数情况下处理连字符。它可以很容易地扩展以处理更多的特殊情况。

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

于 2019-01-13T08:22:27.240 回答