文本特徵選擇(信息熵、Gini、IV、卡方值)

信息熵:描述信息系統的混亂程度(不確定度)。信息越確定,越單一,信息熵越小。信息越不確定,越混亂,信息熵越大。因此一個系統的信息熵越高就越無序,信息熵越低就越有序,信息熵越高,使其有序所要消耗的信息量就越大。

條件熵:在某種情況下的混亂度。

信息增益=整體信息熵-條件熵

指的就是熵的減少量,代表了在一個條件下,信息複雜度(不確定性)減少的程度。信息增益是特徵選擇中的一個重要指標,它定義為一個特徵能夠為分類系統帶來多少信息,帶來的信息越多,該特徵越重要。

文本分類中,要計算各個單詞信息增益例子:

信息增益法,把特徵詞看做一個變數特徵,那麼詞的變數只有缺失與存在的兩種情況下,那麼特徵詞的信息增益=系統的信息熵-特徵詞的條件熵(文本分類中,根據特徵詞的條件熵倒排就可以做特徵選擇,即條件熵越小改特徵詞越重要)

某個詞的條件熵=存在的概率*存在時的信息熵+缺失的概率*缺失時的信息熵

比如:在一個只有火鍋和燒烤兩個分類下,有100條短文本,68條為火鍋分類,32條為燒烤。其中有10條文本含有牛肉這個詞語,其中8條屬於火鍋分類,2條是屬於燒烤分類。

那麼牛肉這個詞語在這個文本分類當中的信息增益計算過程為:

整體信息熵=-frac{68}{100}1og_{2}(frac{68}{100})-frac{32}{100}1og_{2}(frac{32}{100}) 存在牛肉單詞熵==-frac{8}{10}1og_{2}(frac{8}{10})-frac{2}{100}1og_{2}(frac{2}{10}) 存在牛肉單詞熵==-frac{60}{90}1og_{2}(frac{60}{90})-frac{30}{90}1og_{2}(frac{30}{90}) 牛肉這個單詞的信息增益=整體信息熵-frac{10}{100}存在牛肉信息熵-frac{90}{100}不存在牛肉信息熵

牛肉這個單詞在文本分類中基尼不純度計算:

Gini(存在牛肉)=1-(8/10)^{2}-(2/10)^{2} =0.32 Gini(不存在牛肉)=1-(60/90)^{2}-(30/90)^{2}=0.45 Gini=Gini(存在牛肉)*(10/100)+Gini(不存在牛肉)*(90*100)=0.437

牛肉這個單詞在文本分類中的IV(信息價值):

WOE(存在牛肉的證據權重)=ln(frac{8/2}{68/32}) =0.6312

WOE(不存在牛肉的證據權重)=ln(frac{60/30}{68/32}) =-0.0606

IV(存在牛肉)=(frac{8}{68}-frac{2}{32})WOE(存在牛肉的證據權重)=0.0348 IV(不存在牛肉)=(frac{60}{68}-frac{30}{32})WOE(不存在牛肉的證據權重)=0.0033 IV(牛肉)=IV(存在牛肉)+IV(不存在牛肉)

卡方值(實際觀察值和理論之間的偏差度量):

卡方=x^{2}=Sigmafrac{(A-T)^{2}}{T}=frac{(8-6.8)^{2}}{6.8}+frac{(60-61.2)^{2}}{61.2}+frac{(2-3.2)^{2}}{3.2}+frac{(30-28.8)^{2}}{28.8}=0.7352

class_df_list: 變數意思是有3條文本信息屬於a分類,5條文本屬於b分類b.

term_set: 就是文本中的詞集,可以理解為字典。

term_class_df_mat:表示所有文本中各個詞分別在哪個分類中出現過就+1,就是一個詞語分類多維數組,維度取決於分類的個數。

代碼:

def feature_selection_ig(class_df_list, term_set, term_class_df_mat): A = term_class_df_mat B = np.array([(sum(x) - x).tolist() for x in A]) #與A對稱 C = np.tile(class_df_list, (A.shape[0], 1)) - A #未出現在分類中的詞集多維數組 N = sum(class_df_list) D = N - A - B - C #與C對稱 term_df_array = np.sum(A, axis = 1) class_set_size = len(class_df_list) p_t = term_df_array / N #每個詞存在的情況下的概率矩陣 p_not_t = 1 - p_t #每個詞缺失的情況下的概率矩陣 #避免有些詞在某些分類中沒有出現過而概率為0的情況,採用拉普拉斯平滑定理:分子加1分母加2平滑法。 p_c_t_mat = (A + 1) / (A + B + class_set_size) p_c_not_t_mat = (C+1) / (C + D + class_set_size) p_c_t = np.sum(p_c_t_mat * np.log(p_c_t_mat), axis =1) p_c_not_t = np.sum(p_c_not_t_mat * np.log(p_c_not_t_mat), axis =1) term_score_array = p_t * p_c_t + p_not_t * p_c_not_t #按term_score_array升序排列,然後倒序,因為計算公式中忽略掉-號,其實也就是得出降序後的索引位置 sorted_term_score_index = term_score_array.argsort()[: : -1] term_set_fs = [term_set[index] for index in sorted_term_score_index] return term_set_fs

參考:

文本挖掘之特徵選擇(python 實現) 了解信息增益和決策樹


推薦閱讀:

大數據:特徵工程預測用戶行為
什麼年代了!你還在寫 ETL 代碼抽取特徵?
如何獲取可區分性的特徵(loss functon篇上)

TAG:特徵工程 | 文本分析 | Python |