ahocorapy-纯python ahocorasick实现
ahocorap的Python项目详细描述
ahocorapy-在纯python中快速搜索多个关键字
ahocorapy是aho-corasick算法的纯python实现。 给定关键字列表,可以在线性时间内检查给定文本中是否存在至少一个关键字。
比较:
为什么还要执行另一个aho corasick?
我们从2016年初开始着手。我们的需求包括结合了python2.7的unicode支持。那个 使用基于c扩展的库(如pyahocorasick)是不可能的。纯净的 由于内存爆炸,python库非常慢或无法使用。此后又发布了一个纯python库 py-aho-corasick。存储库还包含一些关于 实现。 也有acora,但它包含注释('当前的构造算法不是 适用于非常大的关键字集),这是我上次测试时的情况,因为RAM很快就用完了。
差异
与pyahocorasick相比,我们的库在python 2.7中支持unicode,就像py-aho-corasick。 我们不使用任何C扩展,因此库不依赖于平台。
在标准的aho corasick最长后缀搜索之上,我们最后还执行了一个快捷方式例程,因此 我们的查找速度很快,而设置时间较长。在设置过程中,我们将遍历状态并直接添加 由最长的后缀或其最长的后缀“提供”。这将导致更快的查找时间,因为最终我们只需要 遵循简单的转换,不必执行任何额外的后缀查找。它还会导致更大的内存占用, 因为转换的数量更高,因为它们都是显式包含的,而不是由后缀指针隐式隐藏的。
我们添加了一个小工具,可以帮助您可视化生成的图形。如果你愿意的话,这可能有助于理解算法。见下文。
完全可腌制(pythons内置de-/serialization)。ahocorapy使用一个非递归的自定义实现来进行de-/serialization,这样即使是巨大的关键字树也可以被pickle。
性能
我把上面提到的两个库与ahocorapy进行了比较。我们使用了50000个关键字长列表和34199个字符的输入文本。 文本中只包含列表中的一个关键字。 每个库运行一次安装过程,搜索过程运行100次。以下结果以秒为单位(不是查找的平均值)。
您可以使用python tests/ahocorapy_performance_test.py
自己执行此测试。(除了pyahocarasick的结果。这些是通过进口
纯python版本的pyahocorasick代码。无法通过pypi获得
如代码中所述。)
我还使用run with pypy为纯python库添加了度量。
结果如下:
Library (Variant) | Setup (1x) | Search (100x) |
---|---|---|
ahocorapy | 1.2s | 1.76s |
ahocorapy (run with pypy) | 0.9s | 0.09s |
pyahocorasick | 0.1s | 0.06s |
pyahocorasick (pure python variant in github repo) | 0.5s | 1.68s |
py_aho_corasick | 1.9s | 13.2s |
py_aho_corasick (run with pypy) | 1.3s | 3.71s |
正如所料,c扩展破坏了纯python实现。即使在 我们不可能达到皮亚霍科拉希克设定的目标。阿霍科拉皮的查找速度比帕霍科拉希克快。 当使用pypy[pypy 5.1.2和gcc5.3.1 20160413]ahocorapy几乎和pyahocorasick一样快,至少在 搜索。由于使用了后缀快捷方式机制,安装开销更高。
基本用法:
安装
pip install ahocorapy
创建搜索树
fromahocorapy.keywordtreeimportKeywordTreekwtree=KeywordTree(case_insensitive=True)kwtree.add('malaga')kwtree.add('lacrosse')kwtree.add('mallorca')kwtree.add('mallorca bella')kwtree.add('orca')kwtree.finalize()
搜索
result=kwtree.search('My favorite islands are malaga and sylt.')print(result)
打印:
('malaga',24)
search_all方法返回找到的所有关键字的生成器,如果没有关键字,则返回none。
results=kwtree.search_all('malheur on mallorca bellacrosse')forresultinresults:print(result)
打印:
('mallorca',11)('orca',15)('mallorca bella',11)('lacrosse',23)
绘制图形
您可以使用Visualizer类打印底层图形。 此功能需要安装一个工作的pygraphviz库。
fromahocorapy_visualizer.visualizerimportVisualizervisualizer=Visualizer()visualizer.draw('readme_example.png',kwtree)
图形的结果.png如下: