1. 程式人生 > >機器學習精簡教程之七——用scikit-learn做特徵提取

機器學習精簡教程之七——用scikit-learn做特徵提取

本文轉自:http://www.shareditor.com/blogshow/?blogId=58

現實世界中多數特徵都不是連續變數,比如分類、文字、影象等,為了對非連續變數做特徵表述,需要對這些特徵做數學化表述,因此就用到了特徵提取 (特徵數字化)

分類變數的特徵提取

比如城市作為一個特徵,那麼就是一系列雜湊的城市標記,這類特徵我們用二進位制編碼來表示,是這個城市為1,不是這個城市為0

比如有三個城市:北京、天津、上海,我們用scikit-learn的DictVector做特徵提取,如下:

#sklearn 只能處理數字化的特徵
from sklearn.feature_extraction import DictVectorizer

onehot_encoder = DictVectorizer()
instances = [{'city':'背景'},{'city':'天津'},{'city':'上海'}]#這個可以使用相同的key值city是因為它們屬於不同的字典中
print(onehot_encoder.fit_transform(instances).toarray())

輸出結果為: [[ 0.  0.  1.]
 [ 0.  1.  0.]
 [ 1.  0.  0.]]
不同編碼表示不同城市。

文字特徵提取

文字特徵無非這幾種:有這個詞還是沒有、這個詞的TF-IDF(TF-IDF(term frequency–inverse document frequency)是一種用於資訊檢索與資料探勘的常用加權技術。TF意思是詞頻(Term Frequency),IDF意思是逆向檔案頻率(Inverse Document Frequency)。
第一種情況用詞庫表示法,如下:
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
    'UNC played Duke in basketball',
    'Duke lost the basketball game'
]
vectorizer = CountVectorizer()
print(vectorizer.fit_transform(corpus).todense())
print(vectorizer.vocabulary_)
執行後: [[1 1 0 1 0 1 0 1]
 [1 1 1 0 1 0 1 0]]
{'unc': 7, 'played': 5, 'duke': 1, 'in': 3, 'basketball': 0, 'lost': 4, 'the': 6, 'game': 2}

數值為1表示詞表中的這個詞出現,為0表示未出現

詞表中的數值表示單詞的座標位置

什麼意思呢? 通俗的將就是將上面兩個句子 拆分,去重,從0到最後一個編號,打亂,執行完這個操作對應的{'unc': 7, 'played': 5, 'duke': 1, 'in': 3, 'basketball': 0, 'lost': 4, 'the': 6, 'game': 2
},然後兩個句子再和打亂後的進行對比,句子中有這個詞就為1,沒有就為0.數字化的向量長度應該是與拆分去重後的長度一致的。

第二種情況TF-IDF表示詞的重要性,如下:
from sklearn.feature_extraction.text import TfidfVectorizer

corpus = [
    'The dog ate a sandwich and I ate a sandwich',
    'The wizard transfigured a sandwich'
]
vectorizer = TfidfVectorizer(stop_words='english')
print(vectorizer.fit_transform(corpus).todense())
print(vectorizer.vocabulary_)

輸出結果為: [[ 0.75458397  0.37729199  0.53689271  0.          0.        ]
 [ 0.          0.          0.44943642  0.6316672   0.6316672 ]]
{'dog': 1, 'ate': 0, 'sandwich': 2, 'wizard': 4, 'transfigured': 3}

值最高的是第一個句子中的ate,因為它在這一個句子裡出現了兩次

值最低的自然是本句子未出現的單詞

(這裡是有點疑問的:直接去除了I and a 這樣的詞?? 第一個句子中sandwich也出現了兩次啊,為什麼ate最高呢??)

資料標準化

資料標準化就是把資料轉成均值為0,方差為1的。比如對如下矩陣做標準化:
from sklearn import preprocessing
import numpy as np
X = np.array([
    [0.,0.,5.,13.,9.,1.],
    [0.,0.,13.,15.,10.,15.],
    [0.,3.,15.,2.,0.,11.]
])
print(preprocessing.scale(X))

輸出結果為: [[ 0.         -0.70710678 -1.38873015  0.52489066  0.59299945 -1.35873244]
 [ 0.         -0.70710678  0.46291005  0.87481777  0.81537425  1.01904933]
 [ 0.          1.41421356  0.9258201  -1.39970842 -1.4083737   0.33968311]]