我有大约100兆字节的文本,没有任何标记,分为大约10,000个条目。我想自动生成一个'标签'列表。问题是有些词组(即短语)只有在组合在一起时才有意义。
如果我只计算单词,我会得到大量非常常见的单词(是,for,for,in,am等)。我已经计算了它之前和之后的其他单词的数量和数量,但现在我真的无法弄清楚下一步该做什么有关2和3个单词短语的信息存在,但我该如何提取这些数据呢?
答案 0 :(得分:34)
在此之前,尝试保留输入文字中“边界”的信息。
(如果这些信息不容易丢失,你的问题意味着可能已经完成了令牌化)
在标记化(单词解析,在这种情况下)过程中,寻找可以定义表达边界的模式(例如标点符号,特别是句点,以及多个LF / CR分离,使用这些。还有像“the”通常可以用作边界。这样的表达边界通常是“负面的”,在某种意义上它们将两个令牌实例分开,这些实例肯定不包含在同一个表达式中。正边界是引号,特别是双引号。这种类型的信息可能有助于过滤掉一些n-gram(参见下一段)。还有一些单词序列,例如“例如”或“代替”或“需要” to“也可以用作表达边界(但是使用这些信息就是使用”priors“,我将在后面讨论)。
不使用外部数据(输入文本除外),您可以通过运行文本的digrams和trigrams (序列2)来获得相对成功和连续3个字)。然后[大多数]具有重要(*)个实例的序列可能是您正在寻找的“表达/短语”的类型。
这种稍微粗糙的方法会产生一些误报,但总的来说可能是可行的。已经过滤了第一段中暗示的已知跨越“边界”的n-gram,可能有很大帮助,因为在自然语言中,句子结尾和句子开始倾向于从消息空间的有限子集中提取并因此产生可能的令牌组合。似乎在统计上表现得很好,但通常与语义无关。
更好的方法(可能更昂贵,处理方面,以及设计/投资方面),将使用与输入的域和/或国家语言相关的额外“先验”文本。
[抱歉,现在就去吧(加上想从你的具体目标中获得更多细节等)。我稍后会尝试提供更多细节和指示]
[顺便说一下,我想在这篇文章中插入 Jonathan Feinberg和Dervin Thunk的回复,因为它们提供了很好的指针,就手头任务的方法和工具而言。特别是, NTLK 和 Python-at-large 为实验提供了一个很好的框架]
答案 1 :(得分:11)
我将从Peter Norvig开始,在O'Reilly的书中Beautiful Data开始。他提供了您需要的ngram数据,以及漂亮的Python代码(可以解决您的问题,或者进行一些修改)on his personal web site。
答案 2 :(得分:8)
听起来你正在寻找collocation extraction。 Manning and Schütze将chapter用于该主题,解释和评估我链接到的维基百科文章中提到的“提议的公式”。
我不能把整章都纳入这个回应;希望their links中的一些人会有所帮助。 (NSP听起来特别适合。)nltk也有collocations module,Manning和Schütze没有提及,因为他们的书早于它。
到目前为止发布的其他回复涉及统计语言处理和更一般的n-gram;搭配是一个特定的子主题。
答案 3 :(得分:0)
做一个单词矩阵。然后,如果有两个连续的单词,则将一个单词添加到该单元。
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']++;
答案 4 :(得分:0)
一种方法是建立自己的自动机。很可能是非确定性有限自动机(NFA)。 NFA
另一种更简单的方法是创建一个文件,其中包含您要忽略,查找,比较等的单词和/或单词组,并在程序启动时将它们存储在内存中,然后您可以比较使用文件中包含的单词/单词组解析文件。