特征工程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的簡單使用;
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM