1、背景
最近在工作中遇到一个问题,需要过滤上千万的文章,判断每篇文章中都包含哪些敏感词。
解决方案有以下几种:
1、直接字符串匹配
2、首先对文章进行分词,然后判断分词中是否包含敏感词
3、ac自动机
前两种方式弊端都很明显
第一种效率太低,需要针对每个敏感词遍历整个文本串,时间复杂度为O(n*m)
第二种准确性不高,很大程度依赖于词典的质量,另外效率上也没有优势
2、ac自动机介绍
AC自动机是一种多模式匹配算法,用于在一个文本串中查找多个模式串的出现位置,是KMP算法的扩展和升级。
AC自动机的核心思想是将所有的模式串构建成一棵自动机,使得在文本串中匹配所有模式串的过程可以在这个自动机上完成。这个自动机是一个基于trie树的数据结构,每个节点代表一个前缀,从根节点开始,通过边上的字符转移,可以在树上向下遍历。当遍历到某个节点时,如果该节点代表一个模式串的结尾,就说明在文本串中匹配到了这个模式串。
AC自动机的构建过程包括两个步骤:Trie树的构建和自动机的构建。首先,将所有模式串插入到一个Trie树中,每个节点代表一个前缀。然后,对这个Trie树进行广度优先搜索,构建自动机的转移表和失效指针。
AC自动机的时间复杂度为O(n+m),其中n是文本串的长度,m是所有模式串的总长度
这段文字在理解起来比较有难度,我在b站上找到了一个非常优秀的视频,对ac自动机的构建,以及敏感词匹配过程讲解的非常透彻,可以根据视频消化消化
3、代码示例(以Python为例)
import ahocorasick
def build_ac():
sentiment_keywords = ['梦想', '正义']
A = ahocorasick.Automaton()
for index, keyword in enumerate(sentiment_keywords):
A.add_word(keyword, (index, keyword))
A.make_automaton()
return A
text = '路飞是一个勇敢、激情、有正义感的海贼,永远不会放弃自己的梦想和伙伴。'
for end_index, (index, keyword) in build_ac().iter(text):
print('{}一词出现在{}的位置'.format(keyword, end_index))
执行结果如下:
针对以上问题的解决方案,如有更好的解决方案,欢迎大家补充,一起沟通学习!!!!