关于nlp:自然语言处理的词频算法

关于nlp:自然语言处理的词频算法

Word frequency algorithm for natural language processing

在没有获得信息检索学位的情况下,我想知道是否存在用于计算单词在给定文本正文中出现频率的算法。目的是让人们对一组文本评论所说的内容具有"一般感觉"。沿着Wordle。

我想要的是:

  • 忽略文章,代词等(" a"," an"," the"," him"," them"等)
  • 保留专有名词
  • 忽略连字号,软类型除外

伸手摘星,这些将是桃红色的:

  • 处理词干和复数(例如,喜欢,喜欢,喜欢,喜欢匹配相同结果)
  • 形容词(副词等)及其主题的分组("优质服务",而不是"优质","服务")

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


按照以下内容,您将不需要一个,但是需要几个不错的算法。

  • 忽略代词是通过非连续列表完成的。
  • 保留专有名词?您是说要检测诸如胡佛水坝之类的命名实体并说"这是一个单词"或诸如编程语言之类的复合名词?我会给你一个提示:这很困难,但是两者都有库。寻找NER(命名实体识别)和词汇分块。 OpenNLP是同时执行这两种操作的Java工具包。
  • 忽略连字符?你的意思是,就像在换行符吗?使用正则表达式,并通过字典查找来验证生成的单词。
  • 处理复数/词干:您可以查看Snowball提取器。它的技巧很好。
  • 形容词和名词的"组合"通常是浅层解析的任务。但是,如果您专门寻找定性形容词(好的,坏的,卑鄙的,令人惊讶的...),您可能会对情感分析感兴趣。 LingPipe可以做到这一点,还有更多。

对不起,我知道您说过要KISS,但不幸的是,您的要求很难满足。但是,存在用于所有这些功能的工具,如果您不想这样做,则应该能够将它们捆绑在一起,而不必自己执行任何任务。如果您想自己执行任务,建议您研究一下词干,这是最简单的方法。

如果您使用Java,请将Lucene与OpenNLP工具箱结合使用。由于Lucene已经内置了词干提取器和大量教程,因此您将获得非常好的结果。另一方面,OpenNLP工具包的文档很少,但是您不需要太多。您可能也对用Python编写的NLTK感兴趣。

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

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

... 是的我知道。在参加IR研讨会之后,我对Google的敬意更高。不过,在IR中做了一些事情之后,我对它们的敬意就下降了。


欢迎来到NLP的世界^ _ ^

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

已经有工具可以告诉您句子中的单词是名词,形容词还是动词。它们被称为词性标记器。通常,他们以纯文本英语作为输入,然后输出单词,其基本形式和词性。这是帖子第一句中流行的UNIX词性标记器的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ 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标记器运行文本,过滤掉您不感兴趣的类别(决定因素,代词等),并计算基本形式的频率的话。

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

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

要执行列表中的最后一项操作,您不仅需要单词级别的信息。一个简单的开始方法是计算单词的顺序,而不只是单词本身。这些被称为n-gram。 UNIX for Poets是一个很好的起点。如果您愿意投资一本有关NLP的书,我将推荐统计自然语言处理基础。


这是一个示例,说明如何在Python中进行操作,这些概念在任何语言中都是相似的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> 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(表示一次出现。)对于您正在谈论的情况,您需要更加注意细节,例如使用大写为了仅在句子中间等处帮助识别专有名词,这很粗糙,但表达了这一概念。

为了深入研究词干和多元性的东西,进行实验,然后研究第三方的工作,我喜欢NLTK的一部分,这是一个学术性开源项目,也使用python。


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

如果使用前缀树,请确保要查找任何要转到O(N)的单词,其中N是数据集中单词的最大长度。在这种情况下,前缀树的优势在于,如果您想查找复数形式和词干,则可以在O(M + 1)中检入该词是否可行,其中M是没有词干或复数的词的长度(这是一个字吗?呵呵)。构建完前缀树后,我将重新分析其词干等,然后将其压缩下来,以使根词保留结果。

在搜索时,您可能有一些简单的规则来使匹配在出现根或茎或您有什么情况的情况下返回正数。

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

语义分析的另一种选择是将每个句子建模为主题,动词等关系的树(句子具有主题和动词,主题具有名词和形容词等)。一旦用这种方式将所有文本分解,似乎很容易遍历并快速了解发生的不同配对。

只是有些杂乱无章,我确定有更好的主意,但我喜欢考虑这些东西。


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

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


您刚刚描述的算法。一个开箱即用的程序,带有一个大按钮,上面写着" Do it"(执行)...我不知道。

但是,让我保持建设性。我向您推荐这本书《编程集体智慧》。第3章和第4章包含非常实用的示例(实际上,没有复杂的理论,仅是示例)。


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

  • 忽略一些单词-使用停用词
  • 提取主题-使用语音标记的一部分进行识别(开箱即用)。解析句子后,找到" ROOT"-句子的主要动词。通过浏览分析树,您将找到与此动词相关的名词。这将是主题。
  • 忽略连字符-在大多数情况下,它们的令牌生成器处理连字符。它可以轻松扩展以处理更多特殊情况。
  • 如果主题列表是预定的并且不是很大,则您甚至可以走得更远:构建一个可以预测主题的分类模型。
    假设您有10个科目。您收集示例句子或文本。您将它们加载到另一个产品:神童。使用出色的界面,您可以快速将主题分配给样本。最后,使用分类的样本,您可以训练spacy模型来预测文本或句子的主题。


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


    推荐阅读