python基礎學習之 特徵工程

ckxllf發表於2019-08-28

  一、特徵提取

  字典載入特徵:DictVectorizer

  文字特徵提取:詞頻向量(CountVectorizer)TF-IDF向量(TfidfVectorizer,FfidfTransformer) 特徵雜湊向量(HashingVectorizer)

  影像特徵的提取:提取畫素矩陣邊緣和興趣點

  1.1、字典載入特徵

  用python中的字典儲存特徵是一種常用的做法,其優點是容易理解,但是sklearn的輸入特徵必須是numpy或Scipy的陣列。可以用DictVectorizer從字典載入特徵轉化成numpy,並且對分類特徵會採用獨熱編碼。

  me=[

  {'city':'Dubai','temperature':33.},

  {'city':'London','temperature':12.},

  {'city':'San Francisco','temperature':18.}

  ]

  from sklearn.feature_extraction import DictVectorizer

  vec=DictVectorizer()

  print(vec.fit_transform(me).toarray())

  vec.get_feature_names()

  [[ 1. 0. 0. 33.]

  [ 0. 1. 0. 12.]

  [ 0. 0. 1. 18.]]

  1.2、字頻向量

  詞庫模型(Bag-of-words model)是文字模型化最常用的方法,它為每個單詞設值一個特徵值,依據是用類似單詞的文章意思也差不多

  CountVectorizer類會將文件全部轉化成小寫,然後把句子分割成塊或有意義的字母序列,並統計他們出現的次數

  可以使用stop_words選項排除一些常用的但沒有意義的助詞。

  from sklearn.feature_extraction.text import CountVectorizer

  co=[

  'UNC played Duke in basketball',

  'Duke lost the basketball game ,game over',

  'I ate a sandwich'

  ]

  vec=CountVectorizer(stop_words='english')

  print(vec.fit_transform(co).todense())

  print(vec.vocabulary_)

  # 三行資料

  [[0 1 1 0 0 1 0 1]

  [0 1 1 2 1 0 0 0]

  [1 0 0 0 0 0 1 0]]

  {'unc': 7, 'played': 5, 'duke': 2, 'basketball': 1, 'lost': 4, 'game': 3, 'ate': 0, 'sandwich': 6}

  import jieba

  from sklearn.feature_extraction.text import CountVectorizer

  corpus=[

  '朋友,小紅是我的',

  '小明對小紅說:“小紅,我們還是不是朋友”',

  '小明與小紅是朋友'

  ]

  cutcorpus=["/".join(jieba.cut(x)) for x in corpus]

  vec==CountVectorizer(stop_words=['好的','是的'])

  counts=vec.fit_transform(cutcorpus).todense()

  print(counts)

  # 檢視對映字典

  print(vec.vocabulary_)

  可以用詞頻向量的歐式距離(L2範數)來衡量兩個文件之間的距離(距離越小越相似)

  from sklearn.feature_extraction.text import CountVectorizer

  # 計算歐式距離

  from sklearn.metrics.pairwise import euclidean_distances

  vectorizer=CountVectorizer()

  for x,y in [[0,1],[0,2],[1,2]]:

  dist=euclidean_distances(counts[x],counts[y])

  print('文件{}與文件{}的距離{}'.format(x,y,dist))

  1.3、Tf-idf權重向量

  from sklearn.feature_extraction.text import TfidfTransformer

  transformer=TfidfTransformer(smooth_idf=False)

  counts=[[3,0,1],

  [2,0,0],

  [3,0,0],

  [4,0,0],

  [3,2,0],

  [3,0,2]]

  tfidf=transformer.fit_transform(counts)

  tfidf.toarray()

  array([[0.81940995, 0. , 0.57320793],

  [1. , 0. , 0. ],

  [1. , 0. , 0. ],

  [1. , 0. , 0. ],

  [0.47330339, 0.88089948, 0. ],

  [0.58149261, 0. , 0.81355169]])

  from sklearn.feature_extraction.text import TfidfVectorizer

  vectorizer=TfidfVectorizer()

  vectorizer.fit_transform(cutcorpus).toarray()

  vectorizer.vocabulary_

  {'小明': 0, '小紅': 1, '我們': 2, '是不是': 3, '朋友': 4}

  1.4、特徵雜湊值

  詞袋模型的方法很好用,也很直接,但在有些場景下很難使用,比如分詞後的詞彙字典表非常大, 達到100萬+,此時如果直接使用詞頻向量或Tf-idf權重向量的方法,將對應的樣本對應特徵矩陣載入記憶體,有可能將記憶體撐爆,在這種情況下我們該怎麼辦呢?

  我們可以應用雜湊技巧進行降維。

  Hash函式可以將一個任意長度的字串對映到_個固定長度的雜湊數字中去。Hash函式是一種典 型的多對一對映。

  正向快速:給定明文和hash演算法,在有限時間和有限資源內能計算出hash值。

  逆向困難:給定(若干)hash值,在有限時間內很難(基本不可能)逆推出明文。

  輸入敏感:原始輸入資訊修改一點資訊,產生的hash值看起來應該都有很大不同。

  碰撞避免:很難找到兩段內容不同的明文,使得它們的hash值一致(發生碰撞)。即對於任意兩個不同的資料塊,其hash值相同的可能性極小;對於一個給定的資料塊,找到和它hash值相同的資料塊極為困難。

  目前流行的Hash函式包括MD4,MD5,SHA等。

  from sklearn.feature_extraction.text import HashingVectorizer

  corpus=['smart boy','ate','bacon','a cat']

  # HashingVectorizeras是無狀態的,不需要fit

  vectorizer=HashingVectorizer(n_features=6,stop_words='english')

  print(vectorizer.transform(corpus).todense())

  [[-0.70710678 -0.70710678 0. 0. 0. 0. ]

  [ 0. 0. 0. 1. 0. 0. ]

  [ 0. 0. 0. 0. -1. 0. ]

  [ 0. 1. 0. 0. 0. 0. ]]

  from sklearn.feature_extraction.text import HashingVectorizer

  corpus=[

  'UNC played Duke in basketball',

  'Duke lost the basketball game ,game over',

  'I ate a sandwich'

  ]

  vectorizer=HashingVectorizer(n_features=6)

  counts=vectorizer.transform(corpus).todense()

  print(counts)

  counts.shape

  [[ 0. 0. -0.89442719 0. 0. -0.4472136 ]

  [-0.37796447 -0.75592895 -0.37796447 0. 0. -0.37796447]

  [ 0. 0. 0.70710678 0.70710678 0. 0. ]]

  Out[9]:(3, 6)

  二、特徵選擇

  當資料預處理完成後,我們需要選擇有意義的特徵輸入機器學習的演算法和模型進行訓練。通常來 說,從兩個方面考慮來選擇特徵: 無錫婦科醫院排行

  特徵是否發散:如果一個特徵不發散,例如方差接近於0 ,也就是說樣本在這個特徵上基本上沒有差異,這個特徵對於樣本的區分並沒有什麼用。

  特徵與目標的相關性:這點比較顯見,與目標相關性高的特徵,應當優選選擇。除方差法外,本文介紹的其他方法均從相關性考慮。

  根據特徵選擇的形式又可以將特徵選擇方法分為3種:

  1、Filter:過濾法,按照發散性或者相關性對各個特徵進行評分,設定閾值或者待選擇閾值的個數,選擇特徵。

  2、Wrapper:包裝法,根據目標函式(通常是預測效果評分),每次選擇若干特徵,或者排除若干特徵。

  3、Embedded :嵌入法,先使用某些機器學習的演算法和模型進行訓練,得到各個特徵的權值係數,根據係數從大到小選擇特徵。類似於Filter方法,但是是透過訓練來確定特徵的優劣。

  2.1、Filter過濾法

  2.1.1、方差選擇法

  使用方差選擇法,先要計算各個特徵的方差,然後根據闕值,選擇方差大於闕值的特徵。(用的不是很多)

  from sklearn.feature_selection import VarianceThreshold

  **方差選擇法,返回值為特徵選擇後的資料**

  **引數thresshold為方差的闕值,方差大於3(threshold=3)**

  vardata=VarianceThreshold(threshold=3).fit_transform(iris.data)

  vardata.shape

  (150, 1)

  2.1.2、相關係數法

  使用相關係數,先要計算各個特徵對目標值的相關係數。用feature_selection庫的SelectKBest類結合相關係數來選擇

  from sklearn.feature_selection import SelectKBest

  from scipy.stats import pearsonr

  import numpy as np

  **選擇K個最好的特徵,返回選擇特徵後的資料**

  **第一個引數為計算評估特徵是否好的函式,該函式輸入特徵矩陣和目標向量**

  **輸出二元(評分,P值)的陣列,陣列第i項為第i個特徵的評分和P值**

  f=lambda X ,Y:np.array(list(map(lambda x:pearsonr(x,Y)[0],X.T))).T

  SelectKBest(f,k=2).fit_transform(iris.data,iris.target)

  2.1.3、卡方檢驗

  from sklearn.feature_selection import SelectKBest

  from sklearn.feature_selection import chi2

  SelectKBest(chi2,k=2).fit_transform(iris.data,iris.target)

  2.1.4、互資訊法

  經典的互資訊法也是評價定性自變數對定性因變數的相關性的。相關係數,卡方檢驗,互資訊選擇原理相似,但相關係數通常只適用於連續特徵選擇

  import numpy as np

  from sklearn.feature_selection import SelectKBest

  from sklearn import metrics

  mic=metrics.mutual_info_score

  g=lambda X ,Y:np.array(list(map(lambda x:mic(x,Y),X.T))).T

  SelectKBest(g,k=2).fit_transform(iris.data,iris.target)

  2.2、Wrapper

  遞迴特徵消除法(RFE)

  遞迴消除特徵法使用一個基膜型進行多倫訓練,每輪訓練後,消除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練

  from sklearn.feature_selection import RFE

  from sklearn.linear_model import LogisticRegression

  **遞迴特徵消除法,返回特徵選擇後的資料**

  **引數estimator為基膜型**

  **n_features_to_select=2特徵個數**

  RFE(estimator=LogisticRegression(),n_features_to_select=2).fit_transform(iris.data,iris.target)

  2.3、Embedded嵌入法

  https://blog.csdn.net/jinping_shi/article/details/52433975

  使用帶懲罰項的基模型,除了篩選出特徵外同時也進行了降維。使用feature_selection庫的SelectFormModel類結合帶L1懲罰項的邏輯迴歸模型,來選擇特徵的程式碼如下

  from sklearn.feature_selection import SelectFromModel

  from sklearn.linear_model import LogisticRegression

  # L1正則化的迴歸模型

  SelectFromModel(LogisticRegression(penalty='l1',C=0.1)).fit_transform(iris.data,iris.target)

  L1懲罰項降維的原理在於保留多個對目標值具有同等相關性的特徵中的一個,所以沒選到的特徵不代表不重要。故,可結合L2懲罰項來最佳化。具體操作為:若一個特徵在L1中的權值為1 ,選擇在L2 中權值差別不大且在L1中權值為0的特徵構成同類集合,將這一集合中的特徵平分L1中的權值,故需要構建一個新的邏輯迴歸模型:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2655286/,如需轉載,請註明出處,否則將追究法律責任。

相關文章