最全NLP反作弊攻略,從馬蜂窩注水事件說起

大資料文摘發表於2018-11-22

最全NLP反作弊攻略,從馬蜂窩注水事件說起

大資料文摘出品

作者:龍心塵、July

在開始正文之前,我們先回顧一下事件背景。

10月21日,朋友圈被一篇名為《估值175億的旅遊獨角獸,是一座殭屍和水軍構成的鬼城?》的文章刷屏。文章作者小聲比比指控線上旅遊網站馬蜂窩存在點評大量造假的情況,包括從其他網站如大眾點評、攜程等抓取相關點評,及透過水軍撰寫虛擬點評。

文章吸引了包括本人在內的大量吃瓜群眾的眼球。畢竟一家估值175億的網際網路公司被這麼多實錘猛捶,十分罕見。

關於此事件相關的分析文章已經不少,但是從技術本身來分析的文章卻不多。作為一個技術宅,我還是想從自己的老本行NLP上探討一下馬蜂窩事件中反作弊方與作弊方的技術實現方案。

分析思路

其實在AI碼農看來,馬蜂窩事件可以簡化為作弊與反作弊的問題。該事件中至少存在三方:馬蜂窩平臺、抄襲水軍、小聲比比指控方。我們可以先假設馬蜂窩與小聲比比雙方均沒有主觀惡意,當然抄襲水軍是惡意作弊的。而主要問題就是如何透過人工智慧技術找到作弊的點評、賬號、評論和攻略。

當然如果想系統地處理反作弊問題,需要探討的人工智慧技術比較多樣,包括NLP、時間序列分析、使用者畫像、資料探勘與分析等。

而為了簡化討論、抓住重點,我們主要關注其中的NLP技術,畢竟本事件處理的主要內容都是文字。

簡單梳理一下幾個爭論的焦點,大致包括:

1.馬蜂窩是否有大量抄襲點評

2.馬蜂窩是否有大量抄襲賬號

3.馬蜂窩是否有大量水軍評論

4.馬蜂窩是否有大量洗稿攻略

我們接下來就一個一個探討。

查詢水軍:文字挖掘堪稱“烘乾神器”

最全NLP反作弊攻略,從馬蜂窩注水事件說起

根據馬蜂窩官網提供的資料,馬蜂窩全站擁有超過2100萬條點評,是馬蜂窩對外展示的核心競爭力之一。小聲比比聲稱:2100萬條真實點評有1800萬條是從大眾點評和攜程裡抄襲過來。而且他們的判斷標準十分嚴苛:一字不差才算抄襲,十句話有一句不同就不算抄襲。

我們可以試想一下,如果讓你實現一個程式,判斷兩個文字存在抄襲,你會怎麼辦?

從一道面試題說起

不知各位程式設計師在刷面試的時候有沒有遇到求“最長公共子串”的演算法題?

——已知子串是在原字串中是連續不間斷的字串,輸入兩個字串X、Y,求X、Y的最長公共子串。

這個面試題其實就適合我們判斷抄襲的業務場景——如果最長公共子串超過一定長度,就認為X、Y之間存在抄襲。

比如設計公式:

兩個字串X、Y之間的相似度=最長公共子串的長度/X與Y長度的最大值

當相似度大於閾值的時候認為文字之間存在抄襲。

這個面試題的標準答案是貪心演算法(或者說動態規劃),其時間複雜度是O(n2)。它的優點很明顯:子串的判斷是完全匹配的,絕對屬於實錘,判斷抄襲文字的準確率是非常高的

然而理想很豐滿,現實很骨感。在實際應用中,我們會發現它不太好用。

首先是該演算法不夠靈活,召回率低。

TIPS:召回率率與準確率的區別:

1.召回率,所有抄襲文字中被判斷為抄襲的文字所佔的比例。

2.準確率,所有被判斷為抄襲的文字中真是抄襲文字所佔的比例。

3.準確率與召回率往往是一對矛盾,難以同時兼顧。

所以,如果作弊者在文字中新增一些無損原意的資訊或者替換一些同義詞,該演算法就無法查出。如對於句子“我們這些路痴好不容易找到了飯店的西門”,我們把“飯店”變為“餐館”,把“我們”變為“俺們”,或者加入一些馬蜂窩的網址,就使得新生成的句子與原句子不完全相同。這樣就難以相互抄襲了。幸好馬蜂窩的抄襲水軍技術不行,直接大量硬抄,被這麼輕易抓住也是活該。但如果他們稍微聰明一點做一些文字處理呢?

而且,該演算法的另一個缺點更為致命:速度慢。對於2100萬條真實點評,只有O(n2)的時間複雜度,處理起來還是挺辛苦的。

那怎麼改進呢?NLP的工程師們早就想到這個問題,並且為此專門衍生出了NLP中一個非常核心的領域——文字表示。至於什麼是文字表示,簡單的說就是不將文字視為字串,而視為在數學上處理起來更為方便的向量。而怎麼把字串變為向量,就是文字表示的核心問題。

最簡單的文字表示:詞袋子模型

詞袋子模型是一種非常經典的文字表示。顧名思義,它就是將字串視為一個“裝滿字元(詞)的袋子”,袋子裡的詞語是隨便擺放的。而兩個詞袋子的相似程度就以它們重合的詞及其相關分佈進行判斷。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

舉個例子,對於“我們這些路痴好不容易找到了飯店的西門”這句話,我們先進行分詞,將所有出現的詞儲存為一個詞表。然後依據“詞語是否出現在詞表中”可以將這句話變為[1,0,1,1,1,0,0,1,…]這樣的向量,其中向量的每個維度唯一對應著詞表中的一個詞。可見這個向量的大部分位置是0值,這種情況叫作“稀疏”。為了減少儲存空間,我們可以只儲存非零值的位置。

表示成向量的方法有個非常大的好處是判斷相似度速度非常快,只要計算兩個向量的餘弦值(cos)就夠了。這隻要O(n)的時間複雜度,比之前的方法快了整整一個數量級!

在實際應用中,這種方法非常常用。而且對於中等篇幅的文字詞袋子模型的效果還不錯。召回率比較高。

下圖是演示兩個英文文字透過詞袋子模型判斷相似度的例子。

最全NLP反作弊攻略,從馬蜂窩注水事件說起最全NLP反作弊攻略,從馬蜂窩注水事件說起

但詞袋子模型的缺點也很明顯:

1.其準確率往往比較低。

2.只統計詞語是否出現或者詞頻,會被無意義的詞彙所影響。如“這裡的豬腦、肥腸好吃”與“這裡的沙拉好吃”會被認為很相似。一個改進方式是進行文字預處理

3.對於句子級別的短文字識別能力較弱。如對於句子“我點了牛肚、肥腸、藕片、金針菇之類,味道還不錯”,其關鍵資訊是“牛肚、肥腸、藕片、金針菇”,透過他們我們能判斷出這家店應該是火鍋、麻辣燙之類的。但這樣語義層面的資訊簡單的詞袋子模型識別不出來。它改進的方式是用上深度學習,至少要用上詞向量。

4.無法關注詞語之間的順序關係這是詞袋子模型最大的缺點。如“武松打老虎”跟“老虎打武松”在詞袋子模型中是認為一樣的。它改進的方式是用上更復雜的深度學習,如CNN、RNN、Attention等。

文字預處理

剛才說到文字預處理技術。他們典型的方法包括:

1.去除停用詞,如“的”“是”“我”等等。

2.文字、字母、標點符號統一,比如繁體統一轉換為簡體、大寫統一轉換為小寫、標點統一轉換為半形等。其實就是準備幾個字典加幾個正規表示式就行。

3.統計詞頻與逆文件頻率——TFIDF。不僅考慮詞語是否出現,還考慮其出現的頻率(TF)。不僅考慮這個詞在當下文字的出現的機率,還考慮出現該詞語的文件佔總文件出現的頻率(DF)。其基本假設是如果一個詞語在不同的文件中反覆出現,那麼它對於識別該文字並不重要。如高頻詞“我們”、“那麼”之類。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

基於深度學習的文字表示:詞向量

在詞袋子模型中,每個詞只對應一個詞表向量中的某一個位置,向量其他位置為0。這種術語叫作“one-hot表示”,導致每個詞都是孤立、離散的。而詞向量出來之後,幾乎顛覆了大家的認知——原來可以用一個稠密的短向量來表示一個詞。比如“國王”這個詞可以對應向量[0.5,0.713],“女王”這個詞可以對應向量[0.713,0.5]。至於每一維度的數值是什麼意思可以先不管,直接拿來用。

詞向量最神奇的一點是可以用簡單的向量運算表達類比關係。比如可以直接用等式“國王-男人+女人=女王”來表達“國王與男人的關係類似女王與女人的關係”。這就帶有了很強的語義資訊。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

下圖是Word2vec的兩個典型的機器學習模型圖(CBOW和Skip-gram)。CBOW模型透過一個詞的上下文(N個詞)預測當前詞,而Skip-gram則是反過來,基於一個詞來預測其上下文(N個詞)。兩種不同的演算法都可以得到每個詞的詞向量。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

基於深度學習的文字表示:句向量

既然有了詞級別的向量表示,那也可以有句子級別的向量表示。當然最簡單的句子級別向量表示就是將句子中所有詞的詞向量加起來,也很常用。這種方法本質上也是一種詞袋子模型,因為它也沒有考慮到詞語間的順序。

那怎麼建模句子向量呢?一種簡單的方法是透過神經網路將輸入的詞向量經過CNN\RNN\self-attention機制得到整個句子的表示,最後用一層max pooling轉換到固定長度的向量。計算兩個句子的餘弦值(cos)作為它們的相似度。

直接用深度神經網路算出相似度

一種更加激進的方法是直接用神經網路建模句子之間的相似度,句子向量都不必用。如下圖所示,在搜尋引擎的場景下,把使用者的搜尋語句(query)和搜尋引擎展示的網頁文字(document)都輸入給神經網路。之後分別輸出query與各個document的相似度,以使用者是否點選作為標註進行建模。得到模型後,就可以直接給任意兩句話計算相似度了。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

可見,這種方法比較依賴海量的標註資料。而搜尋引擎天然具有這海量的標註資料。那如果我沒有搜尋引擎這麼多的資料怎麼辦?其實像百度這樣的搜尋引擎公司都開放了api,直接用它們訓練好的模型就是了。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

打造綜合解決方案

現實的業務場景往往十分複雜,需要多種演算法進行組合。對於判斷馬蜂窩點評抄襲的場景,綜合以上的介紹,我們可以形成下面的簡單方案:

1.先用基於統計的詞袋子模型快速篩選一批相似點評

2.再用再用字串匹配確定一批實錘

3.把中間地帶的文字用深度學習篩選一遍,撈一批一批漏網之魚

4.最後再用人工校驗,分析badcase,進一步最佳化模型……

識別使用者:文字分類看穿“忽男忽女”

馬蜂窩事件中,另一個雙方都承認的實錘是存在一批抄襲賬號。而小聲比比方面對抄襲賬號的判斷標準也比較嚴格:同時抄襲150個大眾點評賬號的才算作弊賬號。

當然這批馬蜂窩的抄襲水軍的技術的確不行,簡單的規則就可以撈出一大把。但我們仍可以試想一下,如果抄襲者聰明一些,每個機器人賬號只抄襲幾個賬號,那如何找出他們?

其實,我們可以利用抄襲賬號的另一個實錘:性別自相矛盾。如果同一個使用者的一部分點評明顯是男性,另一部分明顯是女性,就是一個自相矛盾,就基本可以判斷其是抄襲賬號。

最全NLP反作弊攻略,從馬蜂窩注水事件說起


這些問題理論上還可以擴充套件到年齡、身份的自相矛盾。這些本質上就是一個文字分類的問題。我們將從傳統方法、機器學習、深度學習的角度加以說明。

傳統方法:關鍵詞匹配

關鍵詞匹配是指關鍵詞與頁面中的內容進行匹配。如果文字中出現了某些典型關鍵詞,就可以直接判斷該文字所屬的分類。如上圖的例子,我們可以抽出女性關鍵詞:“老公”、“男友”等。男性關鍵詞:“老婆”、“女友”等。我們將已知關鍵詞拿到文中去進行匹配,就可以識別賬號評論的性別。

但這種關鍵詞匹配的方法同樣存在準確率高、召回率低的問題。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

機器學習方法:詞袋子模型+樸素貝葉斯/邏輯迴歸/支援向量機

詞袋模型上文已提到過,是一種基於統計的將文字中的詞進行統一表示的方法。而得到這些文件的向量表示後,可以採用樸素貝葉斯、邏輯迴歸或支援向量機等機器學習的演算法模型對文字加以分類,從而識別出各文字中的人物年齡、性別等資訊,進而找出矛盾點及識別出賬號的真偽。

如下圖顯示了詞袋模型與支援向量機結合對郵件進行分類的過程。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

採用機器學習的方法使模型的召回率有所提升,但正如前文所說,詞袋模型無法實現對文字順序的判斷,因此準確率可能不滿足要求。

傳統改進方法是進行大量的特徵工程。比如增加詞語的詞性、命名實體相關特徵,或者採用更好的分詞器。另一個思路是增加2gram、3gram特徵。

所謂2gram、3gram就是把句子中相鄰的2個、3個詞語拼成一個大一點的詞,當成一個整體進行統計,放入詞表中。這樣至少就能識別2個、3個詞語之間的順序關係。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

深度學習進行文字分類

採用基於深度學習方法的文字分類技術主要包括卷積神經網路(CNN),迴圈神經網路(RNN),注意力機制(Attention)等。自2012年深度學習技術快速發展後,尤其CNN、RNN在NLP領域獲得了廣泛應用,使得文字分類的準確率不斷提升。

如下如顯示了TextCNN的結構模型,將詞向量經過卷積層、池化層、全連線層後,最終得出分類結果。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

盤點評論:鬧了笑話的評論都犯了哪些錯

馬蜂窩事件中關於評論的內容又有哪些可以分析的點呢?

模板評論

如下圖,關於遊記的回覆內容每一條都出現了幾千次,這樣一個有固定模板的評論,透過詞頻統計發現。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

機翻關鍵詞

如下圖,可以很明顯看到該條評論是來源於“簡明英漢詞典”,這一點的發現貌似只能結合片語統計和用肉眼看。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

“投毒”

如下圖,為在對方平臺的評論處掛上自己網站的連結。這種情況的發現類似機翻關鍵詞的尋找。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

可見,傳統的要找到這些典型的抄襲評論的證據,都需要用肉眼看。而為了提高效率,可以結合統計詞頻的方法。

但其實隨著大資料技術的發展,我們可以用更多的視覺化技術幫助人工去尋找作弊關鍵點。一個典型的方法是繪製詞雲。其實本質上也是統計詞頻,但是透過視覺化技術可以講詞頻較高的詞語、短語放大標出。這樣可以有個更加直觀的認識,形成更加專業的分析報告。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

鑑別洗稿

另一個很典型的作弊現象是發現了很多攻略是洗稿作品,有專門的營銷目的。如下圖顯示了針對攻略的洗稿,將對方網站的攻略內容該改頭換面到自己的網站下。圖的右側為將原文(左側)標題和圖片進行了篡改。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

而鑑別洗稿NLP技術其實目前還是開放問題,因為這屬於長文字的相似度判斷。長文字相似與短文字相似最大的區別是長文字的資訊量更加豐富,處理起來更加困難。如句子之間的順序、段落間的謀篇佈局、篇章整體的主題等等,都遠比句子級別的資訊更復雜。

這裡提供一個簡單的綜合解決方案:

1.先在詞語級別抽取資訊:用基於統計的詞袋子模型快速篩選一批相似攻略。這個方法的好處是速度快、召回率高,但準確率低。這在面對海量文章進行判斷時比較有用,把絕大部分明顯不是抄襲的攻略都過濾掉。

2.再在句子級別抽取資訊:採用字串匹配判斷是否存在數個以上的句子完全相同。這是洗稿文章典型特徵。而這種方法準確率高,但召回率低。而且特別容易被洗稿團隊繞過。

3.這之後可以把中間地帶的文字拆成句子用深度學習篩選一遍,撈一批漏網之魚

4.另外,也可以參考篇章級別抽取資訊。這裡涉及到的NLP技術包括情感傾向分析與主題模型。

5.最後再用人工校驗,分析badcase,進一步最佳化策略……

主題模型:篇章資訊的提取利器

這裡著重提一下主題模型,它是一種根據文字抽取其主題相關的資訊科技,其核心演算法是機率圖生成模型,典型的演算法是LDA。雖然現在深度學習這麼火,但還有一種演算法分析框架在NLP領域非常重要,就是機率圖模型。機率圖的重要一類是有向圖,其基本思路就是將問題抽象出不同的狀態,狀態之間存在符合一定分佈的轉移機率。機率圖的目的就是求出關鍵的轉移機率來分析問題。下圖就是LDA演算法的機率圖。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

好吧,這個圖太抽象了,想要解釋清楚會比較複雜。這裡用一個簡單的例子說明一下。比如我們想抽取汪峰的每首歌詞的三個主題資訊的分佈,我們姑且將它們命名為“情感、實物、行動”(嚴格來說LDA只能找出三個主題的分佈,並知道這三個主題是什麼意思,本質上是一種軟性聚類。)。

不同的歌詞的主題分佈是不一樣的,比如有些歌是“情感”相關的主題比例更多一些,有些歌是“行動”相關的主題更多。主題模型的目的就是得到任何一篇歌詞的主題分佈,提取其篇章層面資訊

而LDA的基本假設是存在一個先驗分佈(狄利克雷分佈)其能夠產生各首歌的主題分佈(多項分佈)。而每個主題又能夠產生該主題下的每個詞語的分佈(多項式分佈)。最終得到每個歌詞裡所有詞的分佈。這個假設比較符合人們對於主題的機率意義理解,符合文字充詞語是離散分佈的特點。因此LDA在實際的應用中效果也比較好。

最全NLP反作弊攻略,從馬蜂窩注水事件說起

開啟NLP世界的大門

到此為止,我們基本介紹完了馬蜂窩事件中的NLP技術。如果大家想更深入地學習NLP,可以參考以下推薦課程和NLP相關api。

原文連結:https://mp.weixin.qq.com/s/LiptE1-7ZKznBrq0aEH3KA

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562039/viewspace-2221157/,如需轉載,請註明出處,否則將追究法律責任。

相關文章