代码之家  ›  专栏  ›  技术社区  ›  Kimvais

从文本中检测短语和关键字的算法

  •  42
  • Kimvais  · 技术社区  · 16 年前

    我有大约100兆字节的文本,没有任何标记,分为大约10000个条目。我想自动生成一个“标签”列表。问题是,有些单词组(即短语)只有在组合在一起时才有意义。

    如果我只计算单词,我会得到大量真正常见的单词(is、the、for、in、am等)。我已经计算了它之前和之后的单词和其他单词的数量,但是现在我真的不知道接下来要做什么,2和3个单词短语的相关信息已经存在,但是我该如何提取这些数据呢?

    5 回复  |  直到 16 年前
        1
  •  34
  •   mjv    16 年前

    在任何事情发生之前, 尝试保留输入文本中的“边界”信息。
    (如果这些信息不容易丢失,您的问题意味着标记化技术可能已经很容易完成)
    在标记化技术(在本例中是单词解析)过程中,寻找可以定义 表达式边界 (例如标点符号,尤其是句点,以及多个LF/CR分隔符,请使用这些符号。像“the”这样的词也可以经常用作边界。这样的表达式边界通常是“负的”,从某种意义上说,它们将两个令牌实例分开,而这两个令牌实例必须 包含在同一表达式中。一些积极的边界是引号,特别是双引号。这种类型的信息可能有助于过滤掉一些n-gram(见下一段)。此外,诸如“例如”或“代替”或“需要”等词的连词也可以用作表达式边界(但使用此类信息正逐渐使用“优先顺序”,我稍后将讨论)。

    不使用外部数据 (输入文本除外),通过在 文本的有向图和三角图 (2和3个连续单词的顺序)。然后[大多数]具有大量实例的序列很可能是您要查找的“表达式/短语”类型。
    这种有点粗糙的方法会产生一些假阳性,但总的来说可能是可行的。过滤了第一段中提到的已知跨越“边界”的n-gram后,可能会有很大帮助,因为在自然语言中,句尾和句首趋向于从消息空间的有限子集中提取,从而产生标记组合,这些标记似乎在统计上表现得很好,但它们是典型的语义上不相关。

    较好的方法 (可能更昂贵、处理方面和设计/投资方面),将使用与输入文本的域和/或国家语言相关的额外“优先级”。

    • POS (Part-Of-Speech) tagging 在很多方面都非常有用(提供了额外的、更客观的表达式边界,以及“噪音”单词类,例如所有文章,即使在实体的上下文中使用,在标记云中通常很少,因此OP希望生成。
    • 词典、词典 类似的也很有用。特别是,这些识别“实体”(即 WordNet 以及它们的替代形式。实体对于标签云非常重要(尽管它们不是其中唯一的一类单词),通过识别它们,也可以使它们正常化(许多不同的表达方式,可以用来说“参议员T.Kennedy”),从而消除重复,但也增加了潜在实体的频率。
    • 如果语料库结构为文档集合,那么使用与tf(term frequency)和idf(inverse document frequency)相关的各种技巧可能会很有用。

    [抱歉,现在必须走了(另外还想从你的具体目标等方面了解更多细节)。稍后我将尝试提供更多细节和提示]

    [顺便说一句,我想插在这里 Jonathan Feinberg和Dervin Thunk回应 从这篇文章,因为他们提供了优秀的指针,在方法和工具方面的那种手头的任务。特别地, NTLK 巨蟒 提供一个优秀的实验框架]

        2
  •  11
  •   Jonathan Feinberg    16 年前

    我将从一个精彩的章节开始, Peter Norvig 在O'Reilly的书中 Beautiful Data . 他提供了您需要的NGRAM数据,以及漂亮的python代码(可以按原样解决您的问题,或者进行一些修改)。 on his personal web site .

        3
  •  8
  •   Darius Bacon    16 年前

    听起来你在找 collocation extraction . Manning and Schütze 奉献一个 chapter 关于这个话题,解释和评估维基百科文章中提到的“建议的公式”。

    我不能把整章都写进这个回答中;希望 their links 会有帮助的。( NSP 听起来特别贴切。)NLTK有一个 collocations module 同样,曼宁和sch_¼tze也没有提及,因为他们的书早于此。

    到目前为止,其他的回答都涉及到统计语言处理和n-gram,搭配是一个特定的副标题。

        4
  •  0
  •   Egon    16 年前

    为单词做一个矩阵。然后,如果有两个连续的单词,则在相应的单元格中添加一个。

    For example you have this sentence.
    
    mat['for']['example'] ++;
    mat['example']['you'] ++;
    mat['you']['have'] ++;
    mat['have']['this'] ++;
    mat['this']['sentence'] ++;
    

    这将为您提供两个连续单词的值。 这个词你也可以用三个词。注意这需要O(n^3)内存。

    还可以使用堆来存储数据,如:

    heap['for example']++;
    heap['example you']++;
    
        5
  •  0
  •   ChadNC    16 年前

    一种方法是把你自己打造成一个自动机器。最有可能的是非确定性有限自动机(NFA)。 NFA

    另一种更简单的方法是创建一个包含要忽略、查找、比较等单词和/或单词组的文件,并在程序启动时将它们存储在内存中,然后您可以将要分析的文件与文件中包含的单词/单词组进行比较。