我正在分析一个大型公共数据集,其中包含大量冗长的人类可读字符串,这些字符串是由一些常规(在形式语言理论意义上)语法明确生成的。
要逐一查看这些字符串集来查看模式并不太难;不幸的是,大约有24,000个这些独特的字符串分为33个类别和1714个子类别,因此手动执行此操作会有点痛苦。
基本上,我正在寻找一个现有算法(最好使用现有参考实现)来获取任意字符串列表,并尝试来推断一些最小值(对于可用于生成它们的正则表达式的一组合理定义(即,从该语法生成的语言中推断出有限字符串集中的常规语法)。
我考虑过重复贪婪最长的常见子串消除,但这只是到目前为止,因为除了完全匹配之外它不会崩溃,所以不会检测到特定数字字符串的常见模式在语法中的位置。
强行执行任何不会脱离常见子串消除的事情是可能的,但可能在计算上不可行。 (此外,我已经考虑过它,并且可能存在子阶段消除的“阶段排序”和/或“局部最小”问题,因为您可能会进行贪婪的子字符串匹配,最终强制最终语法压缩较少/即使它最初看起来是最好的减少,也是最小的。)
答案 0 :(得分:19)
是的,事实证明这确实存在;所需要的是学术界所知的 DFA学习算法,其中的例子包括:
以上内容是libalf,一个C ++中的开源自动机学习算法框架;至少其中一些算法的描述可以在this textbook等中找到。对于MATLAB,gitoolbox还有语法推理算法(包括DFA学习)的实现。
由于this question has come up before并且过去没有得到满意的回答,我正在评估这些算法,并会更新有关它们有用的更多信息,除非在该领域拥有更多专业知识的人先做(这是优选的)。
注意:我现在接受自己的答案,但如果有人可以提供,我很乐意接受更好的答案。
进一步说明:我决定采用自定义代码的路线,因为使用通用算法对于我正在使用的数据来说有点矫枉过正。我在这里留下这个答案以防其他人需要它,如果我做了评估,我会更新。
答案 1 :(得分:0)
我唯一可以建议的是稍微使用Nltk(Python的自然语言工具包),看看它是否至少可以识别重复出现的模式。
您可以研究的另一件事是MALLET(基于Java的自然语言处理,文档分类,聚类,主题建模,信息提取等包。)
Perl有一个名为LinkParser的东西,但它似乎要求你提供一个实际语法的表示(另一方面,它带有一大堆不同的模型,所以也许它可以帮助你对样品进行分类)。
Gate可能允许您从语料库中的记录子集创建示例,并可能从这些记录中对语法进行反向工程。