LibShortText簡要入門

2shou發表於2015-01-07

LibShortText是一個開源的Python短文字(包括標題、簡訊、問題、句子等)分類工具包。它在LibLinear的基礎上針對短文字進一步優化,主要特性有:
– 支援多分類
– 直接輸入文字,無需做特徵向量化的預處理
– 二元分詞(Bigram),不去停頓詞,不做詞性過濾
– 基於線性核SVM分類器(參見SVM原理簡介:最大間隔分類器),訓練和測試的效率極高
– 提供了完整的API,用於特徵分析和Bad Case檢驗

安裝

下載並在解壓後的目錄下make就OK了。
注意:不支援Windows系統;Mac OS和Linux之間的庫不通用

效能對比

關於LibShortText的效能,我們可以拿scikit-learn的樸素貝葉斯(參見用scikit-learn實現樸素貝葉斯分類器)和SVM(也是基於LibLinear)就前文提到的網頁標題分類問題進行橫向對比:

分類器 準確率 計算時間(秒)
scikit-learn(nb) 76.8% 134
scikit-learn(svm) 76.9% 121
libshorttext 79.6% 49

測試環境為低配版MBA2013

顯然LibShortText無論在準確率和效率上都要更勝一籌。

API說明

雖然LibShortText提供了訓練和測試的類命令列操作方式,但直接從Python指令碼呼叫更加靈活和強大,瞭解和訓練、預測和分析相關的API是有幫助的。

預處理

Converter模組負責將文字轉化為數值化的資料集(資料格式與LibSVM相同),由於內建的分詞器僅支援英文,如果要用於中文短文字的分類,就必須替換分詞器(如下程式碼所示)。分詞器是一個將文字轉化為單詞列表的函式,值得注意的是:分詞器不會和模型一起儲存,當過載模型時也必須過載分詞器。

pythonfrom libshorttext.libshorttext.converter import *

text_converter = Text2svmConverter()
text_converter.text_prep.tokenizer = comma_tokenizer
convert_text(train_file, text_converter, svm_file)

訓練文字的格式如下:

娛樂 組圖:劉亦菲短裙秀腿 濃妝變冷豔時髦女

模型

LibShortText提供兩組引數供訓練時使用:
– train_arguments實際上是LibLinear的訓練引數,可設定鬆弛引數C等
– feature_arguments是特徵的表現形式,如詞數、詞頻、TF-IDF等

預測

獲得模型後,我們可以預測新文字的類別,LibShortText提供了兩個API:

  • predict_text(text_file, model) — 針對以行分隔的測試文字
  • predict_single_text(single_text, model) — 針對單條文字

類別預測將返回一個PredictResult的物件,包含下列屬性:

  • predicted_y — 預測的類別(對單條文字預測時是字串物件,對測試文字預測時是列表物件
  • decvals — 被預測文字對所有類別的決策變數,與文字到分類超平面的距離有關。它是一個列表而非字典物件,如果你希望和類別關聯起來,可藉助model的get_labels():
pythondecvals = zip(model.get_labels(), predict_result.decvals)
  • true_y — 真實的類別(僅對測試文字預測時存在
  • get_accuracy() — 獲得測試的準確率(僅對測試文字預測時存在

分析

analyzer的作用是分析LibShortText的預測結果,通過它我們可以瞭解哪些特徵更為關鍵、哪些類別容易被混淆。
比如分析一條體育新聞的標題:

pythonanalyzer = Analyzer(model)
analyzer.analyze_single(`國青錯失絕殺0-0韓國 下輪平越南就出線`)

終端輸出如下:

sports news game food porn
……
國 青 4.600e-01 -1.349e-01 -4.283e-03 0.000e+00 0.000e+00
……
decval 1.192e+00 3.396e-01 3.132e-01 2.196e-01 1.910e-01

可見「國」和「青」一起促成最關鍵的sports類特徵。
又比如,選擇被誤分的樣本,呼叫gen_confusion_table()輸出sports、star和movie的混淆表格,以瞭解哪些類別的特徵界限比較模糊。

pythonanalyzer = Analyzer(model)
insts = InstanceSet(predict_result).select(wrong, with_labels([`sports`, `movie`, `star`]))
analyzer.gen_confusion_table(insts)

終端輸出如下(第一行表示預測類別,第一列表示真實類別):

star movie sports
star 0 19 5
movie 21 0 1
sports 15 4 0

完整demo請見lst_classifier.py

來自:建造者說