天天看點

特征工程1:特征的抽取

特征工程

· 定義:特征工程是指将原始資料轉換為特征向量。(比如一片文檔包含文本等類型,将這些文本類型的資料轉換為數字類型的資料,這個過程是為了計算機更好的了解資料)

· 目的:特征工程的處理直接影響模型的預測結果,目的也正是為了提高模型的預測效果。

· 内容:主要有三部分:

  1、特征抽取

  2、特征預處理

  3、資料的降維

特征抽取

· 特征提取在python scikit-learn中的API是:sklearn.feature_extraction

文本特征抽取

下面主要介紹文本特征抽取的兩種方式:count 詞頻統計和 tf-idf 重要性統計。

1. 詞頻統計

1.1 詞頻統計的API是CountVectorizer,對于每一個訓練文本,它隻考慮每種詞彙在該訓練文本中出現的頻率,注意單個字元不進行統計,因為沒有分類意義。

1.2 CountVectorizer會将文本中的詞語轉換為詞頻矩陣,然後調用fit_transform函數計算各個詞語出現的次數。

1.3. fit_transform計算詞語次數時,以空格劃分,傳統上隻适用于英文的計算,當然,如果手動将中文文章中的詞以空格劃分,也可以使用,但是太繁瑣,生産環境中肯定不會這樣處理,針對于中文,我們可以先使用jieba這個中文分詞工具進行分詞,然後再用fit_transform進行計算。

scikit-learn文本特征抽取的用法

from sklearn.feature_extraction.text import CountVectorizer # 使用 CountVectorizer 将文本中的詞語轉換為詞頻矩陣 
vec = CountVectorizer() 
article1 = "A bad beginning makes a bad ending" 
article2 = "A faithful friend is hard to find" # 使用 fit_transform 函數計算各個詞語出現的次數,傳回的是scipy中壓縮行格式(csr_matrix)的稀疏矩陣 
result = vec.fit_transform([article1, article2]) 
print(result) # 使用 get_feature_names 擷取全部的特征值,即所有文本的關鍵字 
print('所有出現過的單詞:') 
print(vec.get_feature_names()) # 使用 toarray 轉化為numpy的數組形式,可以看到詞頻矩陣的結果 
print("numpy數組,每個詞的出現次數:") 
print(result.toarray())      

輸出:

(0, 2) 1 
(0, 8) 1 
(0, 1) 1 
(0, 0) 2 
(1, 4) 1 
(1, 9) 1 
(1, 6) 1 
(1, 7) 1 
(1, 5) 1 
(1, 3) 1 
所有出現過的單詞: ['bad', 'beginning', 'ending', 'faithful', 'find', 'friend', 'hard', 'is', 'makes', 'to'] 
numpy數組,每個詞的出現次數: 
[[2 1 1 0 0 0 0 0 1 0] 
[0 0 0 1 1 1 1 1 0 1]]      
1、上面輸出的numpy數組:0軸(即每列)分别對應特征值清單中相應索引單詞的出現次數,1軸(即每行)表示每個文檔中各詞的出現頻率; 即:第一篇文章中"bad"出現兩次,"beginning"出現一次,"ending"出現一次,"makes"出現一次; 第二篇文章中'faithful', 'find', 'friend', 'hard', 'is', 'to'各出現一次。 2、每個文檔中的詞,隻是整個語料庫中所有詞的很小的一部分,這樣會造成特征向量的稀疏性(很多值為0),為了解決存儲和運算速度的問題,使用 Python 的 scipy.sparse 矩陣結構儲存,是以 fit_transform 傳回值的類型是 scipy 的矩陣類型,想以數組方式檢視,需要調用 toarray 進行轉化。

中文文本特征抽取

使用pip安裝jieba分詞庫

代碼:

from sklearn.feature_extraction.text import CountVectorizer 

import jieba 
vec = CountVectorizer() 
article1 = "生命是什麼呢,生命是時時刻刻不知如何是好" 
article2 = "生活是什麼呢,生活是這樣的,有些事情還沒有做,一定要做的,另有些事做了,沒有做好,明天不散步了" # jieba分詞傳回的是一個生成器,轉化為清單并用空格連接配接起來 
c1 = ' '.join(list(jieba.cut(article1))) 
c2 = ' '.join(list(jieba.cut(article2))) 
result = vec.fit_transform([c1, c2]) # 擷取特征,與英文相同,單個字元不統計 
print(vec.get_feature_names()) 
print(result.toarray())      

輸出:

['一定', '不知', '事情', '什麼', '做好', '如何是好', '散步', '時時刻刻', '明天', '有些', '沒有', '生命', '生活', '這樣'] 
[[0 1 0 1 0 1 0 1 0 0 0 2 0 0] 
[1 0 1 1 1 0 1 0 1 2 2 0 2 1]]      
2. TF-IDF 重要性統計      
文章分類時,用上面統計詞頻的方式是有缺陷的,比如兩篇文章中有很多相似的中性詞(我們、昨天等),根據上面詞頻統計的方法就會将他們劃為主題相似的文章,我們需要用另一種方法解決這個問題,就是 TF-IDF 統計法。

· TF-IDF 介紹

tf-idf是一種統計方法,用以評估某個字詞對于一個檔案集或一個語料庫中的其中一份檔案的重要程度。字詞的重要性随着它在檔案中出現的次數成正比增加,但同時會随着它在檔案集中出現的頻率成反比下降。

· 主要思想

如果某個詞在一篇文章中出現的機率高,并且在其他文章中很少出現,則認為此詞的重要性較高,具有很好的類别區分能力。

· API

計算tf-idf重要性的API是TfidfVectorizer,它會根據指定的公式将文檔中的詞轉換為機率表示。

代碼:

from sklearn.feature_extraction.text import TfidfVectorizer # 執行個體化 
tf = TfidfVectorizer() # 還是使用fit_transform這個方法進行轉化計算 
data = tf.fit_transform([c1, c2]) 
print('特征值:') 
print(tf.get_feature_names()) 
print('重要性:') 
print(tf.toarray())      

輸出:

特征值: 
['一定', '不知', '事情', '什麼', '做好', '如何是好', '散步', '時時刻刻', '明天', '有些', '沒有', '生命', '生活', '這樣'] 
重要性: 
[[ 0. 0.36499647 0. 0.25969799 0. 0.36499647 0. 0.36499647 0. 0. 0. 0.72999294 0. 0. ] 
[ 0.23245605 0. 0.23245605 0.1653944 0.23245605 0. 0.23245605 0. 0.23245605 0.4649121 0.4649121 0. 0.4649121 0.23245605]]      
以上代碼可以簡單的看出每個詞在每篇文章中的重要性; 比如第一篇中“生命”這個詞的重要性是0.72

總結:

1、主要介紹了特征工程的意義;

2、文本特征抽取的兩種方式:詞頻統計和TF-IDF重要性統計;

3、scikit-learn中各自API的簡單使用;