您的位置:首页 > 其它

敏感词过滤

2015-09-11 21:42 323 查看
最近需要实现对聊天里的敏感词过滤,要求比较简单,只需要对字库中存在的关键字进行匹配,所以不需要非常复杂的实现,但是需要能够快速地对一个关键字集合进行匹配。

搜了一下相关的资料,比较简单的一个算法是使用Aho-Corasick算法,以下简称AC算法。该算法的基本思想中包含了KMP算法,即利用模式串中已匹配的子串的最长后缀(同时是前缀)来跳过一些不可能的匹配位置,进而达到快速匹配的目的。

不过AC算法在匹配一个关键字集合时,比KMP要快。因为如果使用KMP在一个输入查找关键字集合中的元素,若关键字集合大小为m,那么我们需要进行m次匹配,而AC算法仅需对输入串遍历一次即可搜索出所有匹配的关键字,也就是说,算法的复杂度与关键字集合大小关系不大。

在实现了简单的AC算法后,简单的测试后发现较naive算法效率提高不少,从原来的50ms到1ms。

当然这里的过滤,只是最基本的过滤,只是根据字库进行过滤,而敏感词变化较多,要达到较高的过滤,需要比较复杂的实现。可以想到的问题是:

对于一个关键字,如果其中包含了空格等其他字符,对于我们来说,可能还是应该被过滤,但是由于不在字库中,所以不会进行过滤。可以考虑使用正则表达式,但是如果简单使用正则表达式,那么跟naive算法就一样了,有方法是将正则表达式转换为自动机,不过为了简单,可能只是实现正则表达式的一个子集。

关键字为输入字符串的一个子串,这个时候如果不做处理,可能就会误判。在上面那个简单实现中,我只是判断一下字符边界(只对英文字符起作用)来防止匹配子串的情况。

stackexchange上的一个回答提到了使用Phonic Algorithm来做过滤,不过似乎不能应用于中文。

由于AC的数据结构是Trie,所以可以考虑使用Double-Array Trie来提高查找的效率。

我是根据AC的paper实现的,里面有详细的伪代码以及算法的说明。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: