文本分類器
python分類器環境安裝
安裝NLTK
下載地址:http://www.nltk.org/
分類器介紹
分類器是模式識別中的一種應用,模式識別是自然語言處理的一個核心部分。
分類任務是對給定的輸入,選擇正確的"類別標簽"。并且輸入和所有其他輸入隔離。
由于分類器的各自特點分為以下幾類:
有監督分類器
如果分類的標簽集是預先定義的,稱為有監督分類器。
例如:
- 垃圾郵件的判斷。
- 根據名字的最后一個字母,分辨性別。
如果分類的建立是根據每個輸入的正確標簽的訓練預料,稱為有監督分類。
有監督分類器框架:

label和features在配對后輸入機器學習算法
簡單應用:
性別分類器:
根據英文姓名的最后一個字母,男女名字有明顯區分的特點,用來鑒別這個人的性別。
性別猜測:
from nltk.corpus import names
import random
import nltk
def gender_features(word):
return {'last_letter': word[-1]}
names = ([(name, 'male') for name in names.words('male.txt')] +
[(name, 'female') for name in names.words('female.txt')])
random.shuffle(names)
featuresets = [(gender_features(n), g) for (n, g) in names]
train_set = featuresets[500:]
classifier = nltk.NaiveBayesClassifier.train(train_set)
print classifier.classify(gender_features('Trinity'))
輸出:
female
評估分類器:
from nltk.corpus import names
import random
import nltk
def gender_features(word):
return {'last_letter': word[-1]}
names = ([(name, 'male') for name in names.words('male.txt')] +
[(name, 'female') for name in names.words('female.txt')])
random.shuffle(names)
featuresets = [(gender_features(n), g) for (n, g) in names]
train_set, test_set = featuresets[500:], featuresets[:500]
classifier = nltk.NaiveBayesClassifier.train(train_set)
radio = nltk.classify.accuracy(classifier, test_set)
print radio
輸出:
0.744
查看區分效果最好的特征:
from nltk.corpus import names
import random
import nltk
def gender_features(word):
return {'last_letter': word[-1]}
names = ([(name, 'male') for name in names.words('male.txt')] +
[(name, 'female') for name in names.words('female.txt')])
random.shuffle(names)
featuresets = [(gender_features(n), g) for (n, g) in names]
train_set, test_set = featuresets[500:], featuresets[:500]
classifier = nltk.NaiveBayesClassifier.train(train_set)
classifier.show_most_informative_features(5)
輸出結果:
Most Informative Features
last_letter = 'a' female : male = 35.8 : 1.0
last_letter = 'k' male : female = 31.7 : 1.0
last_letter = 'f' male : female = 15.9 : 1.0
last_letter = 'p' male : female = 11.2 : 1.0
last_letter = 'd' male : female = 9.9 : 1.0
這些比率稱為似然比,用來比較特征和分類結果的相關關系。如姓名末尾為"a"的男女比例是35.8:1,可以看出這個特征的區分度比較高。
樸素貝葉斯分類器
算法原理
先計算每個標簽的先驗概率,計算方法為每個標簽出現在訓練數據中的頻率。
計算公式:
P1:每個標簽的先驗概率,計算方式:每個標簽出現在訓練集里的頻率。
$$
P1(Label)=Freq/DocCount
$$
P2:每個標簽的似然得分的和與
決策樹
簡介
決策樹可以類比為輸入值選擇標簽的流程圖,流程圖由檢查特征值的決策節點和分配標簽的葉子節點組成。流程圖的初始節點稱為根節點。
姓名預測性別決策樹:

算法原理
首先定義決策樹樁:即只有一個決策節點的決策樹,基于單個特征決定輸入的分類。每個可能的特征值一個葉子,并分配一個類標簽。
建立的決策樹樁的方法:為每個可能的特征建立一個決策樹樁,看哪個決策樹樁在訓練數據有最高的準確度。作為決策樹的根節點。
決策樹的生長:
檢查選擇出來的決策樹樁,在訓練集上檢查每個葉子節點的準確度,沒達到足夠準確度的葉子被新的決策樹樁替換,然后再該路徑的訓練子集訓練新的決策樹樁,查看新決策樹樁每個葉子節點的準確度,知道所有的葉子節點滿足準確度要求。
評價標準
熵:在分類器中用來衡量數據集中無序的程度,比如訓練集中不同的標簽越混亂,熵越高,標簽越趨向同類,熵越低。
標簽數據集熵的計算公式如下:
$$
H = Σl ∈ labelsP(l) × log2P(l)
$$
如果訓練集中全是相同的標簽,如"姓名-性別"數據集,如P(male)=1,P(femal)=0.P(femal)對熵的貢獻為0,由于log2P(male)=0,對熵的貢獻也為0,所以整體的熵為0."姓名-性別"標簽數據集的熵分布函數圖如下:

可以看出,P(female)=0.5時,熵最大。也就是說類別越無序,熵越大。
信息增益:
在分類器中引入了熵之后,可以計算出分類前后的無序程度,也就是熵的大小。分類前后熵的差值就是信息增益。如果信息增益越大高,決策樹樁的分類效果越好。
算法特點
算法特點
- 簡單明了,容易理解。適合多層次的分類。
- 分支會劃分訓練數據,流轉到低節點的訓練數據集比較少,導致這些決策節點過擬合訓練集。
- 強迫特征按照一定的順序進行檢查,適合多層次的分類檢查。而相對獨立的特征區分度不好,可使用貝葉斯分類方法解決,允許特征“并行”生效。
優化方法:
- 訓練數據變小時停止分裂節點。
- 長出一顆完整決策樹時進行枝剪,剪去信息增益值低的節點。
- 采用貝葉斯分類解決相對獨立的特征。
最大熵分類器
文本信息提取
信息提取系統的流水線結構

就目前而言,我們需要做的是提取句子中的實體,用來對文檔進行分類。
主要通過以下3步實現:
分詞
中文分詞算法包括兩類
- 在詞典的基礎上對語句進行子串匹配,優點是時間復雜度低O(n),缺點是對歧義和詞庫里沒有的詞,分詞效果不好。比如:IK,庖丁。
- 基于統計和機器學習的方法分詞,基于人工標注的詞性和統計特征,訓練模型,然后通過模型計算各種分詞的概率,把概率最大分詞結果作為分詞結果,常見的序列標注模型有HMM和CRF。
詞性標注
命名實體識別
采用的技術為分塊(chunking)
每一個塊是分詞的一個子集,并且分塊的片段不重疊。

? 分詞和詞性標注以及分塊
示例:
名詞短語分塊
NP塊的信息來源是詞性標注。
分塊方法:
- 正則表達式分塊
- N-gram方法
詞性標注
電商分類識別
在已有電商購物分類的情況下,如何把用戶關鍵詞輸入,映射到商品分類下。使得搜索結果約束在相關的分類下,以此提高召回率。
流程圖如下:

? 圖:關鍵詞匹配分類樹的流程圖
如:用戶輸入的關鍵詞如:"華碩(ASUS)ROG STRIX-GTX1080TI-O11G-GAMING 1569-1708MHz 11G/11100MHz GDDR5X PCI-E3.0顯卡"
分類樹節點匹配法
通過自定義關鍵詞抽取,自定義指的是詞庫為所有的商品的分類詞匯。
將提取的關鍵詞在分類樹上做映射,映射的方式可以是全詞匹配(準確度會高一些)。或者采用詞向量的方式找最相關的分類節點(準確度不可控,計算量大)。
然后將上圖中匹配上的節點回路路徑,作為一種分類情形。收集所有可能的回路,并進行路徑合并。產生所有的分類過濾情形,取最多3種(可配置)情形,所謂類別過濾條件,結合標題產生搜索結果。
這種方式經過測試數據集的驗證,準確率為0.2908883847884619
,可以看出分類的準確率并不高,不到三成。
基于統計方法
先把類別分級別,從第一級開始分類。
比如“電腦辦公”分類,統計這個大分類下的所有商品的名稱分詞后的詞語分布。
比如

? 商品名稱分詞-詞頻統計圖
可以看到,商品名稱分詞后的詞語,會對詞庫的詞頻貢獻分數。
算法原理:
假設"電腦辦公"的商品名稱,包含大量的“華碩”這個詞語,并且其他分類很少有“華碩”這個詞,可以總結出:商品名稱里的“華碩“關鍵詞,是”電腦辦公“分類里相對特有的,相比其他分類,這個詞有很好的類別區分效果。
把一個分類類比成一份文檔,所有的商品名稱組建成文檔里的文字。分類的匹配就變成了普通的文檔匹配了,可以用TF-IDF算法進行分類匹配。
影響因子:
- 詞頻(Term frequency):在訓練(索引)的時候構建的分類下詞語的統計數。即Term 在文檔中出現的個數,計算方法函數是:
public float tf(float freq) {
return (float)Math.sqrt(freq);
}
有個文檔叫做”this is book about chinese book”, 我的搜索項為”book”,那么這個搜索項對應文檔的freq就為2
,那么tf值就為根號2,即1.4142135
。Term的freq值是在索引期間存儲的。
- 逆文檔頻率:(Inerse document frequency),基于Term的一個因子,表示Term在所有文檔里的稀有程度,以此提升包含稀有詞的文檔的得分。默認實現:
public float idf(long docFreq, long numDocs) {
return (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0);
}
其中:
docFreq
指的是Term出現的文檔數,就是有多少個文檔符合這個搜索
numDocs
指的是索引庫中有多少個文檔。
- 文檔權重(Document boost):在這個應用場景下也叫分類權重。設置方法可以根據經驗值 來設置不同分類的權重。
- 調整因子(Coord):關鍵詞分詞后,出現在當前分類文檔中的個數。
計算方法函數:
public float coord(int overlap, int maxOverlap) {
return overlap / (float)maxOverlap;
}
其中:
overlap:query中檢索命中term的個數
maxOverlap:query中總共的term個數
比如:
檢索''english book”, 現在有一個文檔是”this is an chinese book”。那么,這個搜索對應這個文檔的overlap為1(因為匹配了book),而maxOverlap為2(因為檢索條件有兩個book和english)。最后得到的這個搜索對應這個文檔的coord值為0.5。
Lucene Classifier
計算每個標簽的分值
- 標簽的先驗概率:
$$
p(c)=log2freq(label)-log2sum(labels)
$$
freq(label)表示整個樣本空間里label標簽出現的次數。
sum(lables)表示樣本空間的大小。
- 標簽的似然估計:
$$
p(w|c)=wordFreqForClass(word,c)/textTermFreqForClass(c)
$$
wordFreqForClass(word,c) 函數計算方法:search with text:word AND class:c 表示標簽c下包含word的文檔數
textTermFreqForClass(c)函數計算方法:c標簽下的所有詞總數+總文檔數
