特徵選擇和特徵生成問題初探

1. 爲何要進行特徵選擇?

0x1:有哪些因素會影響模型利用先驗知識?

咱們知道,一個算法學習能夠成功預測,一個很重要的關鍵是目標問題隱含了特定模式的先驗假設(先驗知識),而算法要作的惟一的事情,就是捕獲這種先驗假設,即經過咱們熟悉的模型參數的形式來固話一個生成式或者一個判別式。html

從一個具體的虛擬的例子開始提及,可是這個例子和咱們再實際工程項目中遇到的全部問題,本質上是同樣的。python

有一個廣告公司,每個月會投入必定的廣告費,用於提高其銷售額,同時,財務部門收集了歷史上每月投入的廣告費和銷售額的結果:算法

這是一個很是具體的問題,項目的目標是須要開發一個預測器,幫助決策層判斷未來須要投入多少廣告費,而且對預期的銷售額收入有一個預期判斷。app

1. 特徵數字化編碼 - 如何數值化編碼是第一個影響最終效果的因素

算法是一個數學的運算和求導得極值過程,要求模型輸入的是一個數字化的向量,可是現實生活中的例子不必定都是純數字化的,固然這個例子自己足夠簡單,輸入和要預測的結果自己已是數字了,那咱們能夠直接進行數字化編碼,可是在其餘領域利於NLP領域,如何進行數字化特徵編碼就是一個足夠引發慎重思考的問題了。dom

在這個銷售預測的例子中,咱們將輸入樣本編碼爲 1 維向量 X,數值即廣告費的數值。預測的結果編碼爲 1 維的向量 Y,即銷售額。機器學習

咱們用 X 表示廣告費,用 Y 表示銷售額,這種從現實世界的具體物體,到用數值表示的抽象數值化變換,咱們稱之爲特徵函數,簡稱特徵。函數

若是 X 是向量空間的一個子集,每個有時候稱爲特徵向量。學習

如何將現實世界物體編碼爲輸入空間 X 的方式,對理解咱們如何利用問題相關的先驗知識,是很是重要的。編碼

2. 特徵選擇 - 對特徵進行篩選 and 扭曲變換

在完成特徵數字化編碼以後,咱們可能會遇到一些問題atom

1)特徵數量太多

固然,在本文的銷售額預測的例子中沒有這個狀況,可是咱們假設咱們引入的特徵還有例如當月季節、當月氣溫、當月流行熱點等上千個維度,由於其實這個現象在實際項目中是很常見的,因爲物體自己(例如NLP文本)或者咱們出於「多多益善」的目的常常會盡量地將咱們認爲對最終預測有幫助的特徵維度都抽取出來,做爲物體的特徵向量。

這自己也沒有太多問題,可是過多的特徵會增大算法運算過程當中的CPU和內存需求。

並且極可能還會致使模型欠擬合,這是由於在一些場景下,最終決定結果判斷的可能只能其中3-5個核心特徵,輸入太多的無關特徵,可能致使輸入了一些「假關聯」,這些「假關聯」只是剛好在 這批訓練樣本集中呈現出了某種相關性,但其實其背後並無隱含任何真實世界的統計規律。

若是模型在訓練的過程當中,「不當心」錯誤地引入了這些「假關聯」特徵,那麼能夠想象,模型的預測泛化能力是會大打折扣的。

2)在當前特徵空間中特徵向量線性不可分

這也是一個很常見的問題,線性可分看起來像是實驗課上作demo的場景,在大多數的工程項目中,咱們的特徵向量都是在當前空間線性不可分的。例以下面這張圖:

紅星和黑圈沒法經過一個線性函數直接進行二分類區分。這個時候其實有兩個辦法:

1. 選擇用非線性分類器進行訓練:
例如adaboost、decision tree、dnn這些,但其實本質上,這些模型在訓練生成模型的過程當中,已經隱含了基於線性分類器組合獲得非線性分類器的步驟了。

2. 對原始特徵進行扭曲變化,將其轉化到另外一個高緯度的新特徵空間中:
例如基於kernel trick的SVM就是這種狀況,經過在原空間樣本 X 到希爾伯特空間的特徵映射上學習每個二分類器來實現分類

特徵選擇,是另外一種應用先驗知識來處理問題的方法。這是咱們本文要重點討論的一個主題。

3)直接窮舉全部特徵子集組合可行嗎?

在理狀況下,咱們能夠嘗試 d 個特徵的全部 k 個特徵組合,而後選擇最優預測結果對應的特徵子集。然而,這種窮盡搜索方法一般在計算上是不可行的。

在實際工程中使用的算法中,咱們經常採用一些啓發式,迭代式的搜索方法來儘量地得到一個足夠好的特徵子集。

3. 模型選擇

咱們知道,雖然有不少能夠嘗試的共同的特徵學習方法,可是「沒有免費的午飯」理論指出不存在一種能處理全部問題的極端特徵學習期,任何特徵學習期均可能在某些問題上失敗。

換句話說,每個特徵學習期的成功依賴於數據分佈的某種先驗假設形式(有時這種先驗假設可能不那麼明顯)。

不一樣算法的區別在於可否成功捕獲這種先驗假設,同時也要明白,不一樣的算法,其擬合能力是不一樣的,可能對同一份訓練數據,會發生欠擬或者過擬。

Relevant Link:

https://www.jianshu.com/p/f485dc676e1c

 

2. 濾波器特徵選擇 - 不依賴具體算法模型的feature selection

濾波器方法多是最簡單的特徵選擇方法,在濾波方法中,咱們將某些特徵看做獨立於其餘特徵,而後根據一些質量度量標準來估計這些獨立特徵,而後選擇 k 個得到最高評分的特徵(此外也能夠依據最好的評分肯定特徵的數量)

0x1:線性相關係數(皮爾森相關係數)- 評價單個特徵和預測結果標籤的相關性

1. 皮爾森相關係數 - 評價單個特徵在必定的評價標準前提下和待預測標籤的相關性

一種最直接的方法是依據預測期的錯誤率來得到特徵的評分。

爲了說明這個問題,咱們考慮採用平方損失的線性迴歸問題。令

表示 m 個訓練樣本第 j 個特徵值造成的向量,令表示 m 個樣本的目標值。

僅僅使用第 j 個特徵的經驗風險最小化線性預測期的經驗平方損失是:

爲了求解這個最小化問題,令表示特徵的平均值,令表示目標的平均值。顯然:

等式右邊對 b 求導,令導數等於0,咱們獲得 b = 0。

一樣,對 a 求導,當 b = 0時,咱們獲得

將 a,b 的值代入目標函數,咱們獲得經過選擇右式的特徵組合,咱們的目的是讓左式的損失函數值最小

依據最小平方損失對特徵排序,等同於依據下面評分的絕對值進行排序(高分表示好的特徵):

上面的表達式被稱爲皮爾森相關係數。分子表示第 j 個特徵和目標值方差的經驗估計,而分母表示第 j 個特徵方差乘上目標值所得方差經驗估計的均方根。

皮爾森相關係數的取值範圍爲【-1,1】,這裏若是皮爾森相關係數等於 1 或者 -1,表示 v 和 y 之間有線性相關映射關係,且經驗風險等於0。

2. 單個特徵和待預測標籤線性相關性很低,必定意味着這個特徵很差嗎?

若是皮爾森相關係數等於0,表示 v 到 y 的最優線性映射爲各個維度都等於0,這就是說單獨只用 v 不足以預測 y。

可是這並不必定意味着 v 是一個壞的特徵,好比可能出現這種狀況,v 和其餘特徵組合起來可以很好地預測 y。

考慮一個簡單的例子,目標經過函數來產生。

假定 x1 是由上的均勻分佈產生,而,這裏 z 也是由上的均勻分佈產生。

那麼,,咱們能夠獲得

所以,對於足夠大的訓練集,第一個特徵的皮爾森相關係數可能等於0,所以它可能不被選擇,然而,若是不知道第一個特徵,沒有函數可以很好地預測目標值。

3. Pearson相關係數計算的Scikit-learn版本

Pearson Correlation速度快、易於計算,常常在拿到數據(通過清洗和特徵提取以後的)以後第一時間就執行。Scipy的pearsonr方法可以同時計算相關係數和p-value。

#!/usr/bin/python

import numpy as np
from scipy.stats import pearsonr

np.random.seed(0)
size = 300
x = np.random.normal(0, 1, size)
print "Lower noise", pearsonr(x, x + np.random.normal(0, 1, size))
print "Higher noise", pearsonr(x, x + np.random.normal(0, 10, size))

這個例子中,咱們比較了變量在加入噪音以前和以後的差別。

當噪音比較小的時候,p-value接近1,改變後的變量和改變前的變量相關性很強;

當噪音比較大的時候,p-value下降,改變後的變量和改變前的變量相關性下降

Pearson相關係數的一個明顯缺陷是,做爲特徵排序機制,他只對線性關係敏感。若是關係是非線性的,即使兩個變量具備一一對應的關係,Pearson相關性也可能會接近0。

#!/usr/bin/python

import numpy as np
from scipy.stats import pearsonr

x = np.random.uniform(-1, 1, 100000)
print pearsonr(x, x**2)[0]

0x2:卡方檢驗 - 變量之間相關性(這裏的變量包括特徵或標籤值)

卡方檢驗是一種用途很廣的計數資料的假設檢驗方法。它屬於非參數檢驗的範疇,主要是比較兩個及兩個以上樣本率( 構成比)以及兩個分類變量的關聯性分析。

其根本思想就是在於比較理論頻數和實際頻數的吻合程度或擬合優度問題。

0. 卡方檢驗概念

卡方檢驗(chi-square test),也叫做χ2檢驗。卡方檢驗有多種方法,最著名的就是皮爾遜卡方檢驗,也是卡爾·皮爾森提出。咱們一般用卡方來檢測兩個變量or樣本的獨立性。

卡方檢驗的理論假設是:一個樣本中已發生事件的次數分配會遵照某個特定的理論分配

一般的講:觀測頻數跟實際頻數應該沒有區別,除非兩個變量不是獨立的。舉個例子:XX公司不一樣部門職員的性別跟部門二者是獨立的麼?很明顯不是哦。這兒咱們的指望男女比例是1.05:1,可是在IT研發部分,比例多是3:1,在HR、客服等部門,比率多是1:3了。所以這兒的觀測值就跟實際值不一致,咱們就能夠說兩個不是獨立的。

1. 經過一個四格卡方檢驗來闡述卡方檢驗

下面的表格將實驗者分紅了2組,隨機變量分別爲:是否和牛奶、感冒人數。咱們如今但願經過卡方檢驗來揭示這兩個變量之間是否具備相關性,即它們之間是否存在依賴推導。

  感冒人數 未感冒人數 合計 感冒率
喝牛奶組 43 96 139 30.94%
不喝牛奶組 28 84 112 25.00%
合計 71 180 251 28.29%

經過簡單的統計咱們得出喝牛奶組和不喝牛奶組的感冒率爲30.94%和25.00%,二者的差異多是抽樣偏差致使,也有多是牛奶對感冒率真的有影響。

1)創建理論假設統計

爲了肯定真實緣由,咱們先假設喝牛奶對感冒發病率是沒有影響的,即喝牛奶喝感冒時獨立無關的。

因此咱們能夠得出感冒的發病率實際是(43+28)/(43+28+96+84)= 28.29%

這一步實際上裏隱含了條件獨立性假設,即將另外一個隨機變量視爲無任何影響,無任何依賴推導,直接計算邊緣條件機率。

2)根據理論假設統計從新獲得新的機率分佈 - 有點相似EM的過程

因此,理論的四格表應該以下表所示:

  感冒人數 未感冒人數 合計
喝牛奶組 139*0.2829 = 39.3231 139*(1-0.2829) = 99.6769 139
不喝牛奶組 112*0.2829 = 31.6848 112*(1-0.2829) = 80.3152 112
合計 71 180 251

若是喝牛奶喝感冒真的是獨立無關的,那麼四格表裏的理論值和實際值差異應該會很小。 

3)計算理論值和實際值之間的差距

卡方檢驗的計算公式爲:,其中,A爲實際值,T爲理論值。

x2用於衡量實際值與理論值的差別程度(也就是卡方檢驗的核心思想),包含了如下兩個信息:

1. 實際值與理論值誤差的絕對大小(因爲平方的存在,差別是被放大的)
2. 差別程度與理論值的相對大小

上面牛奶的的例子咱們計算得:

卡方 = (43 - 39.3231)平方 / 39.3231 + (28 - 31.6848)平方 / 31.6848 + (96 - 99.6769)平方 / 99.6769 + (84 - 80.3152)平方 / 80.3152 = 1.077

4)卡方分佈的臨界值

上一步咱們獲得了卡方的值 = 1.077,可是這個值意味着什麼呢?如何經過卡方的值來判斷喝牛奶和感冒是否真的是獨立無關的?也就是說,怎麼知道無關性假設是否可靠?

基本上來講:

卡方值越大,假設成立的機率就越小,即隨機變量間相關性越大;

卡方值越小,假設成立的機率就越大,即隨機變量間相關性越小。

下面是卡方分佈的臨界值表。

表格裏的值表明着:若是卡方值大於對應的閾值,則至少有對應的機率,咱們的假設是成立的。

而具體應該查表格的哪一行,這裏須要用到一個自由度的概念,自由度等於:F = (行數 - 1) * (列數 - 1)。對這個例子來講,自由度F = 1 * 1 = 1。

在牛奶的這個例子中,對應的是F = 1,即咱們須要查第一行。

咱們計算獲得的卡方檢驗值爲 1.077,介於P(0.1)和P(0.5)這兩欄之間,因此咱們能夠說:

喝牛奶和感冒之間有至少50%的機率,是獨立不相關的;

可是1.077超過了和P(0.9)和和P(0.95)的閾值,因此,「喝牛奶和感冒之間獨立性假設有95%的機率成立」這句話是錯了(有點繞,理解一下)。

因此,綜上,因此喝牛奶和感冒獨立不相關的假設不成立。

Relevant Link:

https://blog.csdn.net/snowdroptulip/article/details/78770088
https://blog.csdn.net/gdanskamir/article/details/54913233

0x3:互信息估計

以上就是經典的互信息公式了。想把互信息直接用於特徵選擇其實不是太方便:

1. 它不屬於度量方式,也沒有辦法歸一化,在不一樣數據及上的結果沒法作比較;
2. 對於連續變量的計算不是很方便(X和Y都是集合,x,y都是離散的取值),一般變量須要先離散化,而互信息的結果對離散化的方式很敏感。

最大信息係數克服了這兩個問題。它首先尋找一種最優的離散化方式,而後把互信息取值轉換成一種度量方式,取值區間在[0,1]。minepy提供了MIC功能。

反過頭來看y=x^2這個例子,MIC算出來的互信息值爲1(最大的取值)。

#!/usr/bin/python

import numpy as np
from minepy import MINE

m = MINE()
x = np.random.uniform(-1, 1, 10000)
m.compute_score(x, x**2)
print m.mic()

0x4:接受操做特徵(ROC)曲線的面積

整體來講,濾波評分方法的思想是:在必定的評價標準(損失函數)下,評估特徵對最終預測標籤結果準確性的貢獻度

Relevant Link:

https://blog.csdn.net/gdanskamir/article/details/54913233
https://www.cnblogs.com/hhh5460/p/5186226.html

 

3. 貪婪特徵選擇方法 - 須要依賴具體算法模型獲得評價分值

貪婪選擇是另外一個比較經常使用的特徵選擇方法。和濾波方法不一樣,貪婪選擇方法伴隨着學習算法的過程,迭代地進行。

0x1:前向貪婪選擇方法

最簡單的貪婪選擇的例子是前向貪婪選擇方法。

咱們從一個空集開始,而後逐步每次添加一個特徵到選擇的特徵集。

給定當前選擇的特徵集,咱們遍歷全部的,而後在特徵集上應用學習算法。每個候選特徵選擇都取得一個不一樣的預測器,咱們選擇添加特徵使得預測器的風險最小(經驗最小化原則)。對應這個最小風險的候選特徵就是本輪選擇的特徵。

持續喝個過程知道咱們選擇了 k 個特徵,這裏 k 表示預先定義的能夠承擔的特徵數,或者獲得一個足夠精度的預測器。

0x2:反向終止算法

和前向貪婪選擇方法相對的是,反向終止算法。咱們從所有特徵組合的集合開始,而後逐步從特徵集合中一次減小一個特徵。

給定咱們當前選擇的特徵集。每一個這樣的作法取得一個不一樣的預測期,而後咱們選擇去掉特徵 i 是的預測期從特徵集獲得最小的風險(在訓練集或者驗證集上)

0x3:基於有監督學習模型的特徵排序 (Model based ranking)

這種方法的思路是直接使用你要用的有監督機器學習算法,針對每一個單獨的特徵和響應變量(標籤值y)創建預測模型。

其實Pearson相關係數等價於線性迴歸裏的標準化迴歸係數。

假如某個特徵和響應變量之間的關係是非線性的,能夠用基於樹的方法(決策樹、隨機森林)、或者擴展的線性模型等。基於樹的方法比較易於使用,由於他們對非線性關係的建模比較好,而且不須要太多的調試。但要注意過擬合問題,所以樹的深度最好不要太大,再就是運用交叉驗證。

咱們在著名的波士頓房價數據集上使用sklearn的隨機森林迴歸給出一個單變量選擇的例子:

#!/usr/bin/python

import numpy as np
from sklearn.cross_validation import cross_val_score, ShuffleSplit
from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor

#Load boston housing dataset as an example
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]

rf = RandomForestRegressor(n_estimators=20, max_depth=4)
scores = []
for i in range(X.shape[1]):
     score = cross_val_score(rf, X[:, i:i+1], Y, scoring="r2",
                              cv=ShuffleSplit(len(X), 3, .3))
     scores.append((round(np.mean(score), 3), names[i]))
res = sorted(scores, reverse=True)
for i in res:
    print i

0x3:稀疏誘導範數

 

4. 特徵操做與歸一化

特徵操做或歸一化包括在每個源特徵上的簡單變換。這些變換可能使得咱們假設類的近似偏差或估計偏差更低或者可以獲得一個更快的算法。

與特徵選擇的問題相似,特徵操做與歸一化充滿了「玄學」,它須要咱們具體問題具體分析,這裏沒有絕對好或絕對壞的變換,而是每個特徵變換與在這些特徵矢量上的學習算法,以及這個問題相關的先驗假設密切相關。

0x1:經常使用的特徵變換

接下來,咱們用表示在 m 個訓練樣本上的特徵 f,一樣,咱們用表示全部樣本特徵的經驗均值。

1. 中心化

經過變換,這個變換使得特徵有 0 均值。

2. 歸一化範圍

這個變換使得每個特徵的範圍都是【0,1】,

固然,很容易將範圍變換爲【0,b】或【-b,b】

3. 標準化

這個變換使得全部特徵有 0 均值和 1 方差。形式上,令表示特徵的經驗方差,那麼設置

4. 裁剪變換

這個變換裁剪特徵的高值或低值

5. sigmoidal變換

這個變換在特徵上用到了sigmoid函數,例如,這裏 b 是用戶自定義參數。這個變換能夠認爲是一種軟版本的裁剪變換。它對接近於 0 的值值有一些做用,而且與遠離 0 的裁剪變換很類似。

6. 對數變換

這個變換是,這裏 b 是用戶自定義參數。這個變換普遍地用於當特徵是計數型特徵的狀況下。例如,假定特徵表示在一個文檔中某個詞出現的次數。那麼,某個詞出現一次與沒有出現的區別,要比一個詞出現1000次仍是1001次更爲重要。

簡單來講,對數變換對值較小時的變化更敏感,值越大,敏感度越低。從本質上看,和標準化和歸一化的思想很相似。

Relevant Link:

https://www.cnblogs.com/hhh5460/p/5186226.html 
相關文章
相關標籤/搜索