从文本中检测短语和关键字的算法
Posted
技术标签:
【中文标题】从文本中检测短语和关键字的算法【英文标题】:Algorithms to detect phrases and keywords from text 【发布时间】:2010-12-11 05:54:09 【问题描述】:我有大约 100 兆字节的文本,没有任何标记,分为大约 10,000 个条目。我想自动生成一个“标签”列表。问题是有些词组(即短语)只有在组合在一起时才有意义。
如果我只计算单词,我会得到大量非常常见的单词(is、the、for、in、am 等)。我已经计算了它之前和之后的单词和其他单词的数量,但现在我真的不知道下一步该怎么做 存在与 2 和 3 单词短语相关的信息,但我如何提取这些数据?
【问题讨论】:
您可能希望首先通过使用停用词列表删除常见的“噪音”词来清理输入数据。 @teabot,是的,处理干扰词很重要,但在这些词用于其他目的之前不应该这样做。例如,如果您打算对输入文本进行 POS 标记,则需要干扰词。即使没有 POS 标记,更简单的技术也可以利用这些噪声词来推断表达式边界等。 @Kimvais,请提供有关大“标签列表”目的的更多背景信息。是否只是对文本进行索引,是否提供了一种创建标签云的方法,是否是对基础文档进行分类的一步等等?有了这些额外的信息,SO 贡献者将能够更好地响应这个相对广泛的任务。可能只是你需要的只是如 heferav 所暗示的 Swish-e,或者你可能需要更多关于如何定制各种 NLP 实践以满足特定需求的建议和想法(不一定“重新发明***”)。 @mjv - 数据是与工单相关的通信,目的是检测通常冗长通信的关键字,以便我们可以有一个自动的“标签云”和看起来相关的工单列表/相关或处理相同的功能等。 named entity recognition 有多种算法,尽管这可能是一个稍微不同的问题。 【参考方案1】:为单词做一个矩阵。然后,如果有两个连续的单词,则在相应的单元格中添加一个。
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']++;
【讨论】:
【参考方案2】:我将从 Peter Norvig 的精彩章节开始,在 O'Reilly 的书 Beautiful Data 中。他提供了你需要的 ngram 数据,以及漂亮的 Python 代码(可以按原样解决你的问题,或者进行一些修改)on his personal web site。
【讨论】:
这是一个很棒的章节,完全值得一读——我应该知道,因为我在致谢中。 :-) 但它并没有直接解决发布的问题。 (我认为我的答案是。)它是关于您可以使用文本语料库中的 n-gram 统计数据做的种类,以及如何使用拼写更正、解决密码和分段等示例单词拼凑在一起,没有空格。 是的,但是使用链接到的 ngram 数据,他可以快速浏览他的数据集并提取有意义的 ngram。 听起来 Kimvais 已经从他们自己的数据集中计算了 n-gram 数据,并且正在询问如何使用这些数据来区分出现频率明显高于偶然出现的单词序列。 这就是我所说的“有意义”:) 好的。这就是我的答案所要解决的问题,而 Norvig 的代码却没有。我同意这一章值得一读,因为它可以很好地介绍 n-gram一般,尽管很多人可以在没有它的情况下遵循搭配参考。【参考方案3】:首先,尝试保留输入文本中有关“边界”的信息。 (如果此类信息不容易丢失,则您的问题意味着标记化可能已经完成) 在标记化(在本例中为单词解析)过程中,寻找可以定义表达式边界的模式(例如标点符号,特别是句点,以及多个 LF/CR 分隔,使用这些。还有像“the”,通常可以用作边界。这样的表达式边界通常是“负的”,从某种意义上说,它们分隔了两个肯定不包含在同一个表达式中的标记实例。一些正边界是引号,尤其是双引号。这种类型的信息可能有助于过滤掉一些 n-gram(见下一段)。还有单词序列,例如“例如”或“代替”或“需要” to" 也可以用作表达式边界(但使用此类信息正在使用我稍后讨论的“先验”)。
不使用外部数据(输入文本除外),您可以通过对文本的二字和三字(2和 3 个连续的单词)。那么 [大多数] 具有大量 (*) 实例的序列可能是您正在寻找的“表达/短语”的类型。 这种有点粗略的方法会产生一些误报,但总的来说可能是可行的。如第一段所述,过滤已知跨越“边界”的 n-gram 可能会有很大帮助,因为在自然语言中,句子结尾和句子开头倾向于从消息空间的有限子集中提取,因此产生的标记组合可能似乎在统计上很好地表示,但通常在语义上不相关。
更好的方法(可能更昂贵、处理方面和设计/投资方面),将使用与输入的域和/或国家语言相关的额外“先验”文本。
POS (Part-Of-Speech) tagging 在几个方面非常有用(提供额外的、更客观的表达边界,以及“噪音”词类,例如所有文章,即使在实体上下文中使用时,标签云中通常很少,因此OP 想要制作。 字典、词典等也很有用。特别是,这些标识“实体”(又名WordNet lingo 中的实例)及其替代形式。实体对于标签云非常重要(尽管它们不是在其中发现的唯一一类词),并且通过识别它们,也可以对它们进行规范化(可以使用许多不同的表达方式,例如,“Senator T. Kennedy"),因此消除了重复,但也增加了基础实体的频率。 如果语料库被构造为文档集合,则使用与 TF(词频)和 IDF(逆文档频率)相关的各种技巧可能会很有用[抱歉,我得走了,现在(另外想从你的具体目标等方面获得更多细节)。稍后我会尝试提供更多细节和要点]
[顺便说一句,我想在此处插入 Jonathan Feinberg 和 Dervin Thunk 对此帖子的回复,因为他们在手头任务的方法和工具方面提供了出色的指导。特别是,NTLK 和 Python-at-large 为实验提供了出色的框架]
【讨论】:
【参考方案4】:一种方法是为自己构建一个自动机。很可能是非确定性有限自动机(NFA)。 NFA
另一种更简单的方法是创建一个文件,其中包含您要忽略、查找、比较等的单词和/或单词组,并在程序启动时将它们存储在内存中,然后您可以比较您正在使用文件中包含的单词/单词组解析的文件。
【讨论】:
【参考方案5】:听起来您正在寻找collocation extraction。 Manning and Schütze 将chapter 用于该主题,解释和评估我链接到的***文章中提到的“提议的公式”。
我无法将整个章节都放入这个回复中;希望their links 中的一些会有所帮助。 (NSP 听起来特别合适。)nltk 也有一个 collocations module,Manning 和 Schütze 没有提到,因为他们的书早于它。
到目前为止发布的其他回复更广泛地涉及统计语言处理和 n-gram;搭配是一个特定的子主题。
【讨论】:
以上是关于从文本中检测短语和关键字的算法的主要内容,如果未能解决你的问题,请参考以下文章