敏感詞過濾演算法實現

2021-09-01 01:28:48 字數 2759 閱讀 2129

說到敏感詞過濾,我也覺得這裡沒有必要寫這個文章,因為前人已經前前後後有過很多種演算法解決該問題。這裡我之所以寫這個文章,是因為我自己自創了一種演算法(真的是自創哦,因為我在寫這個演算法的時候,完全是自己想出來的方式,沒有借鑑任何**!靈感來自於一篇文章中的一句話「如果能掃瞄一遍文字就能將所有的詞找出來,那速度就是最快的」)。想法不周到或想得不周到,請大家磚頭輕拍

在網路日益發達的現在,也伴隨著有益資訊與造成不穩定因素的資訊也隨之日益氾濫,為了網民的思想健康,也為了社會的和諧,在許多對外公共場合下,有些內容是要經過審查才能顯示的。在網路審查初期,都是通過人工審核,這種審核方式雖然準確且智慧型,但與網路文字產生的速度相比,其效率就顯示微不足道了!因此,自動化的系統處理方式的需求越來越強烈……

有需求就有市場,因此自動化處理的方式自然而然隨之如雨後春筍般地迅速產生了一大批!其處理方式都是基於一點:敏感詞庫!然後基於該詞庫對目標文字進行敏感詞提取操作,因此各自動化處理方式的唯一差別就在於敏感詞提取演算法的不同,因為演算法不同,效率不同、結果也可能不同。而對於敏感詞過濾演算法來說,要掌握兩個關鍵點:效率和準確率!效率就是對於大批量敏感詞和長段的目標文字處理時要能在很短時間內響應;準確率就是對於乙個敏感詞要盡量區分語境,不能誤將非敏感詞判斷為敏感詞而過濾掉(如我們敏感詞庫的精確匹配與模糊匹配的定義)!

就我所知,目前較為流行且成熟的演算法有:

這種方式是最簡單的,就是迴圈把每個敏感詞在目標文字中從頭到尾搜尋一遍,如果有文字高亮或替換的話,那就找到乙個就處理乙個。這種方式的優缺點如下:

優點:演算法簡單。對於開發人員來說,簡單的演算法會使**實現上簡單,開發難度最小! 缺點:

效率太低。因為迴圈每個敏感詞,所以當敏感詞很多、目標文字很長時,其效率可以說是該演算法的致命問題!

匹配準備率太低。比如,有乙個敏感詞為as,那它邊hash、class等中的as都會被匹配甚至被處理。

所以這個演算法絕對不能使用!

優點:效率高於上面的演算法;

缺點:理論演算法太過複雜,開發成本很大,而且網上沒有該演算法的原始碼或相應的包!而且該演算法匹配率也比較低。再者就是該演算法鉅耗記憶體,而且啟動很慢。

其演算法主要原理為:

1、首先掃瞄文章裡面的每乙個字元,只有當某乙個字元是髒字表中任意乙個髒詞的第乙個字元(稱為「起始符」),我們才試圖看看接下來是否是髒字(觸發檢索)。

2、但是我們也不是毫無頭緒的就開始迴圈髒字表的每乙個詞條:

2.1、我們往後檢索乙個字元,先看一下這個字元是否是髒字表裡面的任意乙個字元,如果不是,就表明不可能是髒字表中的任何乙個條目,就可以退出了。

2.2、如果是,我們就取從第乙個被檢出字元到目前掃瞄到的字元之間的字串,求雜湊值,看看能否從雜湊表中檢出乙個髒詞。

如果檢出了,那就大功告成,否則繼續檢索後面乙個字元(重複2.1、2.2),直至找不到,或者超出髒字表條目最大的長度。

2.3、如果都找不到,或者超長,那麼接下來就回到剛才的那個「起始符」後乙個字元繼續掃瞄(重複1、2),直至整個文章結束。

詳細的演算法說明參考:

其它查到的演算法還有:kmp演算法是單模匹配演算法,bm據說也是單模式的演算法,wm演算法是多模匹配……好吧,我承認,到最後的時候,我沒有耐心再看下去了,因為這些演算法都說自己很厲害,可是卻都沒有放出具體完整的可用的演算法程式出來!開發難度還是存在的,這些方法都不是我的菜

在無盡的苦海探尋的過程中,我的大學數學知識不斷滴從的我意識深處湧了出來!我突然想起乙個可能可行的辦法:因為網路上有許多效能很不錯的分詞工具(jar包形式的也大有存在),而且大學時有一種向量演算法可以計算兩個向量間的相似度的能力,於是就想到是否可以使用向量演算法來解決該問題。該演算法的主體思想為:將所有敏感詞構建為乙個向量,再將目標文字用分詞工具分成若干個詞並構建成另乙個向量,然後將這兩個向量進行相似值計算,得出哪些向量元素相同,並最終得知該目標文字中存在哪些敏感詞!

呃……看來我還是對不起祖國對不起黨!我已經不記得相應的向量演算法了,而且也沒有找到乙個計算兩個向量元素之間相同的演算法(因為向量的高階演算法太多、太複雜了)!看來從我意識深處湧出來的只是一些影子~

所以,這只是乙個設想,而非真正實現方案!

該演算法基於dfa並結合許多演算法並進行相應的簡化,最終其演算法基本原理為:將所有敏感詞庫按模組聚合構建成乙個詞樹(所謂聚合,就是將相同字開頭的部分進行聚合,以減少對詞的查詢範圍,相當於建立敏感詞索引,如:他奶奶的、他媽的、他娘的,這三個詞,聚合構建成詞樹時,「他」字就是這三個詞的索引,同時每個詞的結尾都有乙個結束標誌和該詞的一些描述,如敏感級別等),然後從頭到尾掃瞄一遍目標文字,當遇到以敏感詞樹中的索引的字時,檢視後面的文字是否構成敏感詞(如果這裡有以這個敏感詞開頭的更長的敏感詞時,以更長的為匹配結果,並判斷該詞在文字中前後是否有分隔符來區別其匹配方式),如果是則記錄,一遍掃瞄完之後所有敏感詞即被掃瞄出來了!

我的這個演算法不一定是最好的,但相比較上面幾種演算法,從成本、效果等整體上來說是很合適的!另外網上還有許多一些未公開演算法的過濾方式,這些演算法因為無法獲知其演算法,而無法為我所借鑑,因此平添幾許遺憾!另外還有著名的演算法有:kmp演算法是單模匹配演算法,bm據說也是單模式的演算法,wm演算法是多模匹配(wm演算法詳細描述:的等等。

該方法還有許多可優化的空間,如可增加多執行緒、可優化判斷已記錄的詞直接跳過不匹配等方式。

演算法的效率要注意盡量滿足兩點:盡量少的掃瞄目標文字(包括盡量少的回掃目標文字),盡快能從敏感詞庫中找到指定的詞!不斷做到這兩點,則效率就越高!

目前只是單執行緒的一種操作,而且演算法實現的**上可能還有一些小小的改進餘地,如變數定義與資料結構的定義等方面的實現。

運用的場景很多,如高亮指定的詞、分詞(可以指定以最長或最短模式匹配)、拼音與漢字間的轉換等等字串匹配功能!

注:附件中有兩個檔案,乙個ppt,用於演示該演算法的過程(用office2007開啟效果最佳);乙個是源**;請大家自己瀏覽,謝謝!

敏感詞過濾演算法實現

filterhelper類 region 非法關鍵字過濾 bate 1.1 public class filterhelper public filterhelper string dictionarypath private string dictionarypath string empty 詞...

Java Web 敏感詞過濾演算法

1.dfa演算法 dfa演算法的原理可以參考這裡,簡單來說就是通過map構造出一顆敏感詞樹,樹的每一條由根節點到葉子節點的路徑構成乙個敏感詞,例如下圖 簡單實現如下 public class textfilterutil 構建敏感詞庫 param keyword private static voi...

Java Web敏感詞過濾演算法

1.dfa演算法 dfa演算法的原理可以參考 這裡 簡單來說就是通過map構造出一顆敏感詞樹,樹的每一條由根節點到葉子節點的路徑構成乙個敏感詞,例如下圖 簡單實現如下 public class textfilterutil 構建敏感詞庫 param keyword private static vo...