概述
自然語言分類是指按照預先定義的主題類別,為文檔集合中的每個文檔確定一個類別。本文將介紹一個限定類別的自然語言分類器的原理和實現。采用Python作為編程語言,采用樸素貝葉斯作為分類器,使用jieba進行分詞,并使用scikit-learn實現分類器。
訓練數據來自于鳳凰網,最終交叉驗證的平均準確率是0.927。
一、訓練數據獲取
中文自然語言分類現成可用的有搜狗自然語言分類語料庫、北京大學建立的人民日報語料庫、清華大學建立的現代漢語語料庫等。由于語言在使用過程中會不斷演進,具有一定的時效性,我們最終決定自己開發爬蟲爬取訓練數據。經過綜合考慮,我們最終將目標選定為鳳凰網。
我們選取鳳凰網移動版開展數據獲取工作,地址為http://i.ifeng.com/ 如圖1所示。移動版的頁面布局簡單清晰,但由于文章列表采用了下拉刷新的動態更新策略,直接解析頁面源碼效率太低,最終決定直接調用網頁api獲取。比如獲取十條鳳凰“軍事”的內容,訪問http://imil.ifeng.com/20_2/data.shtml 返回結果如圖2左。最終獲取到4784條新聞,都保存到MySQL數據庫,具體數據如圖2右。從中看出,軍事類的文章相對偏少,體育類的文章偏多。
二、樸素貝葉斯介紹
1.貝葉斯定理
貝葉斯定理是關于隨機事件 A 和 B 的條件概率:
其中,P(A)是A的先驗概率,之所以稱為“先驗”是因為它不考慮任何B方面的因素。P(A|B)是已知B發生后A的條件概率,也由于得自B的取值而被稱作A 的后驗概率。P(B|A)是已知A發生后B的條件概率,也由于得自A的取值而被稱作B的后驗概率。P(B)是B的先驗概率,也稱作標淮化常量(normalizing constant)。按這些術語,貝葉斯定理可表述為:
后驗概率 = (相似度 * 先驗概率)/標淮化常量
2****.貝葉斯概率觀
一般學院派的概率觀可以稱作頻率主義。一個事件,如果重復獨立地執行多次,把發生的次數除以執行的次數,就得到一個頻率。比如說拋硬幣,拋了10000次,有4976次正面向上,頻率就是0.4976。然后如果執行的次數很多很多,頻率會趨向于一個固定的值,就是這個事件的概率。理論基礎是中心極限定理。
貝葉斯概率觀與此很不同。主觀貝葉斯主義認為,概率就是個人對某個事件發生可能性的一個估計。如果對一個事件你一無所知,那么你可以隨便猜一個概率。但因為是估計,如果有新的信息,那就必須根據新信息對概率進行修正。這樣的話,隨著經歷越來越多,對概率的估計也會越來越符合“實際情況”。
3.樸素貝葉斯分類器
分類器基本原理:
對一個多維的輸入向量x,根據貝葉斯公式,有:
條件獨立性假設:
放到自然語言分類器的應用中理解,就是在給定文本的類別的條件下,文本中出現的詞的概率是相互獨立的。樸素貝葉斯之所以“樸素”,就是因為條件獨立性假設是一個較強的假設。于是:
從自然語言分類的角度上說,一個文本屬于哪個類,要計算所有類別的先驗概率和所有詞在相應類別下的后驗概率,再一起乘起來,哪個類別對應的值最大,就歸為哪類。
三、分類器實現
1.數據預處理
文本放到分類器中分類,必須先將文本數據向量化,因為scikit-learn的分類器大多輸入的數據類型都是numpy數組和類似的類型。這一步可以通過scikit-learn中特征抽取模塊feature_extraction中text.CountVectorizer、text.TfidfVectorizer和text.HashingVectorizer實現。
另外,在向量化之前,還有一步是十分必要的。上述的方法是針對英文設計實現的,因此接收的數據類型也是默認通過空格的截斷獲取分詞結果。因此要講中文向量化,必須要先分詞。這一步我們通過jieba實現。最后的輸入文本類似圖3這樣的格式。CountVectorize的轉換結果如圖4,向量的每個值代表一個詞出現的個數。HashingVectorizer的轉換結果如圖5。TfidfVectorizer的轉換結果如圖6,這里我們設置參數use_idf=False,即只使用tf,但并不等同于CountVectorize,而是相當于個數+歸一化。
2.調參
確定了模型之后,可以直接使用Scikit-learn中的GridSearchCV來尋找最佳超參數。
另外一個提高準確率的技巧是刪除停用詞。之前分詞的過程中使用的是通用的中文停用詞,比如“這”,“那”等沒有實際語義的詞。但是這里對于文章的分類來說還有一些高頻出現但是對主題沒有影響的詞,即便他們本身是有語義的。比如“時間”、“圖”等。
3.組合
組合技術即通過聚集多個分類器的預測來提高分類準確率。常用的組合分類器方法:
1)裝袋(bagging):根據均勻概率分布從數據集中重復抽樣(有放回),每個自助樣本集和原數據集一樣大,每個自助樣本集含有原數據集大約63%的數據。訓練k個分類器,測試樣本被指派到得票最高的類。
2)提升(boosting):通過給樣本設置不同的權值,每輪迭代調整權值。不同的提升算法之間的差別,一般是(1)如何更新樣本的權值;(2)如何組合每個分類器的預測。其中在Adaboost中,樣本權值是增加那些被錯誤分類的樣本的權值,分類器C_i的重要性依賴于它的錯誤率。
這里使用BaggingClassifier對原分類器進行裝袋組合,準確率有所提升。
四、分類器評估
使用scikit-learn提供的classification_report獲得分類報告如圖8。使用condusion_matrix獲得分類混淆矩陣如圖9。交叉驗證的結果如圖10。可見,取得了較理想的分類表現。圖11是部分分類結果。
關注微信公眾號“IBM數據科學家”,喜歡我們就訂閱吧!