1. 程式人生 > >敏感詞過濾-AC自動機

敏感詞過濾-AC自動機

在很多內容系統中,都需要過濾一些敏感詞,比如說"fuck you shit up"就要發現裡面有"fuck"、"shit"這些髒詞。

首先,我們要先了解敏感詞過濾的一些特徵:

1. 敏感詞多,一般成千上萬

2. 單詞長度有限,一般不會超過10

3. 要過濾的句子長度有限,一般不過1000

通過上面特徵,我們粗略的算一下,如果採用暴力匹配方案的話,複雜度將會是1k*10*1k=10^7左右的運算量。

現在再考慮一下,該機制要用在什麼樣的系統中。如果是一個內容釋出平臺,每天呼叫次數有限,比如評論功能,不是特別頻繁的,暴力匹配或許是個還不錯的方案,因為簡單易實現難出錯:


是的,不要想太多,暴力匹配就好了。仔細想想,併發量不高,不會產生大量匹配過程,CPU不會太繁忙,暴力匹配也並不會對系統造成什麼影響。

但如果是用在IM(及時訊息)系統中呢?比如直播。

該類系統的特點是,在一段時間內,會同時有大量的請求。字串處理是很耗CPU的操作,用上面暴力匹配方式的話,大量併發的請求,會不會造成大量的訊息延時?

所以現在我們需要一種結構,可以儲存多個字串,並且快速匹配,最適合的莫過於Trie(字典樹)了,也就是網上常說的DFA(確定有限狀態機):


(不好意思,寫的有點緊湊了,螢幕大小有限。)這種辦法的好處很明顯了,把詞庫數量忽略了,計算量只剩10*1k=1w了。

上面字典樹的好處很明顯,但也會發現一個問題,就是每次都從根上走一遍,那有沒有辦法呢?有,就是用AC自動機,在每個節點上多記錄一個fail指標,但這種方法優化下來,最終的結果還是10*1k=1w。

這裡先推薦一個AC自動機的庫:https://github.com/eachain/aca,github上的一個AC自動機的庫,這個庫比較好玩的是Debug功能,可以把整棵樹打印出來,方便除錯及學習用。

好,言歸正傳,仔細觀察會發現,fail指標指向的節點多數還不是完整的單詞,這就造成了多數時候的跳轉是無用的。所以上面的庫優化了這一點,fail指標指向的就是一個完整的單詞,這樣就會把失配情況拋棄掉。但同樣的,這也只是無限逼近O(1k)。

我把一個7700大小的庫匯入試了一下,發現大多情況是這樣的:


發現了麼?只有及其少數的fail指標是有指向的,翻幾屏發現fail全是0的太常見了,當然這是優化過後的,如果是優化之前的,應該會多一些有指向的fail。

到現在為止,我們說的都是機械的掃描字串的辦法,會有很多誤判的時候,比如“江陰毛紡廠”,不能做分詞,就會誤判了。但那些方法已經超出本篇範圍,這裡就不說了。

最後,如果大家要做敏感詞過濾機制,而且可以有一定誤判的情況下,建議用優化後的AC自動機,99%的情況下,時間複雜度等於串長。

相關推薦

敏感過濾-AC自動機

在很多內容系統中,都需要過濾一些敏感詞,比如說"fuck you shit up"就要發現裡面有"fuck"、"shit"這些髒詞。 首先,我們要先了解敏感詞過濾的一些特徵: 1. 敏感詞多,一般成千

61 dfa 實現敏感過濾

引用 nbsp bsp 概念 pre clas logs code println 基本的概念 Class class=null 【只是在棧內存中有了指向,堆內存並沒有分配內存】 Class class=new Class()【棧內存中有了指向(引用),堆內存也分配了內存

PHP實現敏感過濾系統

trie樹 sel 重復 .html ole lang 最大 foreach header PHP實現敏感詞過濾系統 安裝說明 安裝PHP擴展 trie_filter,安裝教程 http://blog.41ms.com/post/39.html 安

Java 敏感過濾,Java 敏感替換,Java 敏感工具類

blog rds log code ima 方法 www enter iteye Java 敏感詞過濾,Java 敏感詞替換,Java 敏感詞工具類 =========================== ?Copyright 蕃薯耀 2017年9月25日 http:

5分鐘Serverless實踐 | 構建無服務器的敏感過濾後端系統

trab 平臺 ase lac mps creat base pen 服務器架構 前言 在上一篇“5分鐘Serverless實踐”系列文章中,我們介紹了什麽是Serverless,以及如何構建一個無服務器的圖片鑒黃Web應用,本文將延續這個話題,以敏感詞過濾為例,介紹如何構

JavaScript 版敏感過濾

    考慮到太多的違禁詞彙,所以縮小化顯示,縮小到讓你看不清楚。如果想看清楚一點,還是去演示地址裡面看吧。消滅敏感詞是每個公民義不容辭的責任!你不站崗我不站崗,誰保衛咱祖國誰來保衛家!讀者們你們要是敢舉報,看我不砍死你! 安裝方法 # 安裝到當前專案 np

敏感過濾演算法:字首樹演算法

背景 平時我們在逛貼吧、牛客網的時候,我們經常可以看到一些形如 “***”的符號,通過上下文,我們也可以很容易猜到這些詞原來是罵人的話,只是被系統和諧了。那麼這是如何實現的呢?作為普通人,我們最先想到的一種辦法就是把所有敏感串存入一個列表中,然後使用者每發一條內容後臺就把該內容與敏感串列表

敏感過濾工具

SensitivewordEngine.java 敏感詞過濾工具類 package keyFilter; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.uti

php 實現敏感過濾 - PHP擴充套件trie_filter

實現方法1 使用PHP擴充套件trie_filter  安裝:libiconv  wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz tar zxvf libiconv-1.14.tar.gz cd libicon

java HashMap實現中文分器 應用:敏感過濾實現

今天下午部門內部技術分享是分詞器演算法。這次的主講是大名鼎鼎的Ansj分詞器的作者-孫健。 作者簡介: Ansj分詞器作者 elasticsearch-sql(elasticsearch的sql外掛)作者,支援sql查詢 nlp-lang自然語言工具包發起人 NLPCN(自然語言處理

【python 走進NLP】英文敏感過濾演算法改進版本

中文DFA演算法過濾敏感詞改進版本 # 中文DFA演算法過濾敏感詞改進版本 class Chinese_DFAFilter(): def __init__(self): self.keyword_chains = {} s

敏感過濾golang

 用golang寫了敏感詞過濾的工具,主要用來檢測使用者暱稱中是否存在敏感詞,同時提供剔除轉移字元的功能。 可以先將敏感詞庫存放在一個map中,敏感詞可以參考這裡:https://github.com/fwwdn/sensitive-stop-words 將map和暱稱傳入,程

C#敏感過濾演算法實現

1.DFA演算法簡介DFA全稱為:Deterministic Finite Automaton,即確定有窮自動機。其特徵為:有一個有限狀態集合和一些從一個狀態通向另一個狀態的邊,每條邊上標記有一個符號,其中一個狀態是初態,某些狀態是終態。但不同於不確定的有限自動機,DFA中不

Spring MVC的使用技巧(APP驗證 加密/解密Json 敏感過濾

APP服務端的Token驗證 通過攔截器對使用了 @Authorization 註解的方法進行請求攔截,從http header中取出token資訊,驗證其是否合法。非法直接返回401錯誤,合法將token對應的user key存入request中後繼續執行。具體實現程

正則表示式的實際應用(採集器,敏感過濾,UBB翻譯器)

正則表示式在.Net就是用字串表示,這個字串格式比較特殊,無論多麼特殊,在C#語言看來都是普通的字串,具體什麼含義由Regex類內部進行語法分析。 正則表示式可以進行字串的匹配、字串的提取、字串的替換。C#中分別對應正則表示式的三個重要方法。 1) IsMatch() 

DFA敏感過濾演算法

運用DFA演算法加密。首先我先對敏感詞庫初始化,若我的敏感詞庫為冰毒白粉大麻大壞蛋初始化之後得到的是下面這樣。:{冰={毒={isEnd=1}, isEnd=0}, 白={粉={isEnd=1}, isEnd=0}, 大={麻={isEnd=1}, isEnd=0, 壞={蛋

DFA演算法實現Java敏感過濾

      敏感詞、文字過濾是一個網站必不可少的功能,如何設計一個好的、高效的過濾演算法是非常有必要的。前段時間我一個朋友(馬上畢業,接觸程式設計不久)要我幫他看一個文字過濾的東西,它說檢索效率非常慢。我把它程式拿過來一看,整個過程如下:讀取敏感詞庫、如果Ha

Java Web敏感過濾演算法

1.DFA演算法DFA演算法的原理可以參考 這裡 ,簡單來說就是通過Map構造出一顆敏感詞樹,樹的每一條由根節點到葉子節點的路徑構成一個敏感詞,例如下圖:程式碼簡單實現如下:public class TextFilterUtil { //日誌 private stat

JAVA 敏感過濾

package me.mymilkbottles; import org.apache.commons.lang.CharUtils; import java.io.File; import java.util.HashMap; import java.ut

高效能的敏感過濾演算法 可以忽略大小寫、全半形、簡繁體、特殊符號干擾 (二)

/// <summary> /// 敏感詞過濾 已忽略大小寫 全半形 簡繁體差異 特殊符號 html標籤 干擾 /// </summary> public static class FilterKeyWords { priv