有這麼一句話在業界普遍流傳:數據和特徵決定了機器學習的上限,而模型和算法只是逼近這個上限而已,在樓主本人親自作的機器學習項目中也發現,不一樣的機器學習算法對結果的準確率影響有限,好的特徵工程以及數據集才影響到了模型本質的結果。那特徵工程究竟是什麼呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始數據中提取特徵以供算法和模型使用。經過總結和概括,人們認爲特徵工程包括如下方面:html
該圖引用於別人的博客,在文章的最後能夠看到參考連接。算法
但根據我我的的理解,這張圖雖然比較全面,可是我認爲特徵工程的核心工做是一個線性的階段性的過程,而不是圖中描述的不少並行化過程。數組
特徵工程主要有三個主要階段,本文也將從這三個階段講解特徵工程:一、特徵清洗、數據清洗。二、特徵處理、數據處理。三、特徵選擇網絡
特徵是機器學習系統的原材料,對最終模型的影響是毋庸置疑的。定義:特徵工程是將原始數據轉化爲特徵,更好表示預測模型處理的實際問題,提高對於未知數據的準確性。它是用目標問題所在的特定領域知識或者自動化的方法來生成、提取、刪減或者組合變化獲得特徵。app
數據特徵會直接影響你使用的預測模型和實現的預測結果。準備和選擇的特徵越好,則實現的結果越好。影響預測結果好壞的因素:模型的選擇、可用的數據、特徵的提取。dom
優質的特徵每每描述了數據的固有結構。大多數模型均可以經過數據中良好的結構很好的學習,即便不是最優的模型,優質的特徵也能夠獲得不錯的效果。優質特徵的靈活性可讓你使用簡單的模型運算的更快,更容易理解,更容易維護。優質的特徵能夠在使用不是最優的模型參數的狀況下獲得不錯的預測結果,這樣你就沒必要費力去選擇最適合的模型和最優的參數了。機器學習
首先,咱們你們都知道,數據特徵會直接影響咱們模型的預測性能。你能夠這麼說:「選擇的特徵越好,最終獲得的性能也就越好」。這句話說得沒錯,但也會給咱們形成誤解。事實上,你獲得的實驗結果取決於你選擇的模型、獲取的數據以及使用的特徵,甚至你問題的形式和你用來評估精度的客觀方法也扮演了一部分。此外,你的實驗結果還受到許多相互依賴的屬性的影響,你須要的是可以很好地描述你數據內部結構的好特徵。函數
(1)特徵越好,靈活性越強工具
只要特徵選得好,即便是通常的模型(或算法)也能得到很好的性能,由於大多數模型(或算法)在好的數據特徵下表現的性能都還不錯。好特徵的靈活性在於它容許你選擇不復雜的模型,同時運行速度也更快,也更容易理解和維護。性能
(2)特徵越好,構建的模型越簡單
有了好的特徵,即使你的參數不是最優的,你的模型性能也能仍然會表現的很nice,因此你就不須要花太多的時間去尋找最有參數,這大大的下降了模型的複雜度,使模型趨於簡單。
(3)特徵越好,模型的性能越出色
顯然,這一點是毫無爭議的,咱們進行特徵工程的最終目的就是提高模型的性能。
惰性是推進科技發展的動力,不少算法工程也在思考,能不能經過模型的方式來自動的學習和構成特徵呢?"全部的想法都會有實現的一天",如今市面上有效的特徵構造模型有 FM(Factorization Machine 因子分解機)、深度學習(提取訓練好的模型中隱層做爲特徵)能夠本身學習出一些特徵以及特徵之間的組合關係,有人使用過主題模型 LDA、word2vec、FM 來做爲特徵生成的模型,將模型訓練的中間結果,好比 LDA 的主題分佈、word2vec 生成的詞向量用於 LR 這樣的線性模型,線上測試效果都很是好。
經過上面的例子咱們能夠知道特徵構造大體思路,也就是從場景目標出發,去找出與之有關的因素。可是在實際場景除了天馬行空想特徵以外,還須要對於想出來的特徵作一可行性評估:獲取難度、覆蓋度、準確度等,好比笛卡爾積會使得特徵維度增長的很是快,會出現大量覆蓋度低的特徵,若是把這些覆蓋度低的特徵加入到模型中訓練,模型會很是不穩定;然而這一系列的工做就是傳說中的特徵工程。
下面從特徵工程的多個子問題全方位分析特種工程。
經過特徵提取,咱們能獲得未經處理的特徵,這時的特徵可能有如下問題:
在模型訓練過程當中,咱們會對訓練數據集進行抽象、抽取大量特徵,這些特徵中有離散型特徵也有連續型特徵。若此時你使用的模型是簡單模型(如LR),那麼一般咱們會對連續型特徵進行離散化操做,而後再對離散的特徵,進行one-hot編碼或啞變量編碼。這樣的操做一般會使得咱們模型具備較強的非線性能力。
在實際生產環境中,業務數據並不是如咱們想象那樣完美,可能存在各類問題,好比上報異常、惡意做弊行爲、爬蟲抓取等。爲了讓模型可以學到真實的行爲規律,咱們須要對已經構造的原始特徵進行清洗,排除掉髒數據。主要包括一下兩個方面:
1. 結合業務狀況進行數據的過濾,例如去除 crawler 抓取,spam,做弊等數據。
2. 異常點檢測,採用異常點檢測算法對樣本進行分析,經常使用的異常點檢測算法包括
例如極差,四分位數間距,均差,標準差等,這種方法適合於挖掘單變量的數值型數據。全距(Range),又稱極差,是用來表示統計資料中的變異量數(measures of variation) ,其最大值與最小值之間的差距;四分位距一般是用來構建箱形圖,以及對機率分佈的簡要圖表概述。
主要經過距離方法來檢測異常點,將數據集中與大多數點之間距離大於某個閾值的點視爲異常點,主要使用的距離度量方法有絕對距離 ( 曼哈頓距離 ) 、歐氏距離和馬氏距離等方法。
考察當前點周圍密度,能夠發現局部異常點,例如 LOF 算法
歸一化有不少好處,好比能夠加快梯度降低尋找最優解的速度,能夠提高模型的精度,同時也使得特徵之間具備可比性,固然全部的事情都是雙面的,通過歸一化處理以後,會損失掉源特徵的一些信息,但這個損失相對應帶來的好處咱們仍是能夠接受的。
歸一化能夠分爲如下三種類型:
這種歸一化方法比較適用在數值比較集中的狀況。這種方法有個缺陷,若是 max 和 min 不穩定,很容易使得歸一化結果不穩定,使得後續使用效果也不穩定。實際使用中能夠用經驗常量值來替代 max 和 min。
使用preproccessing庫的MinMaxScaler類對數據進行區間縮放的代碼以下:
from sklearn.preprocessing import MinMaxScaler MinMaxScaler().fit_transform(iris.data)
在徹底隨機的狀況下,咱們能夠假設咱們的數據是符合標準正態分佈的,也就是均值爲 0,標準差爲 1;那麼其歸一化函數以下:
from sklearn.preprocessing import StandardScaler #標準化歸一化 StandardScaler().fit_transform(iris.data)
在數據分化比較大的場景中,有些數值很大,有些很小。經過一些數學函數,將原始值進行映射。該方法包括 log、指數,正切等。須要根據數據分佈的狀況,決定非線性函數的曲線,好比 log(V, 2) 仍是 log(V, 10) 等。
實際業務中咱們能夠根據本身對數據的理解進行不一樣的歸一化方法,下面是手遊推薦業務使用到的歸一化函數:
正向特徵,特徵越大打分越大,例如付費金額
,其中
反向特徵,特徵越大打分越小,例如首次付費距離當前天數
,其中
彙總特徵,取均值,例如活躍天=score/天數
這樣的歸一化爲啥會比其餘歸一化更好呢!或許數學家們能夠從公式上進行推到證實,而咱們的理解是,其實每一個業務的數據都會有特定的分佈,好比徹底隨機的時候數據知足正態分佈,那麼所選擇的方法必需要符合這種數據分佈的特色,通常狀況下會根據本身對業務數據的瞭解,對公式進行調整,可是歸一化的思路仍是跟上面提到的同樣的。
離散化能夠理解爲將連續的特徵值轉換爲爲離散的特徵值的過程,也稱爲分區或分箱。離散化對於線性模型來講是很是有幫助的,緣由是它能夠將目標值 Y 與特徵值的線性轉爲目標值與離散化以後轉化的向量裏的每一個元素之間的線性關係,這樣向量的每一個份量都有一個權重,引入了非線性,提高了模型擬合能力。以前作過實驗,使用一樣的特徵,有通過離散化處理的特徵訓練出來的模型,會比沒有通過離散化訓練出來的模型效果好 20%以上;如今使用比較多的特徵離散化的方法有,等頻離散、等距離散、樹模型離散。
arr = np.random.randn(20) pd.cut(arr , 4)
[(-1.234, -0.551], (-1.234, -0.551], (-0.551, 0.13], (0.81, 1.491], (-1.234, -0.551], ..., (-0.551, 0.13], (-0.551, 0.13], (0.13, 0.81], (0.81, 1.491], (0.81, 1.491]] Length: 20 Categories (4, interval[float64]): [(-1.234, -0.551] < (-0.551, 0.13] < (0.13, 0.81] < (0.81, 1.491]]
arr = np.random.randn(20) pd.cut(arr , [-5,-1,0,1,5])
[(0, 1], (-1, 0], (0, 1], (-1, 0], (0, 1], ..., (-5, -1], (-1, 0], (-5, -1], (0, 1], (-5, -1]] Length: 20 Categories (4, interval[int64]): [(-5, -1] < (-1, 0] < (0, 1] < (1, 5]
一些屬性是類別型而不是數值型,舉一個簡單的例子,由{紅,綠、藍}組成的顏色屬性,最經常使用的方式是把每一個類別屬性轉換成二元屬性,即從{0,1}取一個值。所以基本上增長的屬性等於相應數目的類別,而且對於你數據集中的每一個實例,只有一個是1(其餘的爲0),這也就是獨熱(one-hot)編碼方式(相似於轉換成啞變量)。
若是你不瞭解這個編碼的話,你可能會以爲分解會增長不必的麻煩(由於編碼大量的增長了數據集的維度)。相反,你可能會嘗試將類別屬性轉換成一個標量值,例如顏色屬性可能會用{1,2,3}表示{紅,綠,藍}。這裏存在兩個問題:首先,對於一個數學模型,這意味着某種意義上紅色和綠色比和藍色更「類似」(由於|1-3| > |1-2|)。除非你的類別擁有排序的屬性(好比鐵路線上的站),這樣可能會誤導你的模型。而後,可能會致使統計指標(好比均值)無心義,更糟糕的狀況是,會誤導你的模型。仍是顏色的例子,假如你的數據集包含相同數量的紅色和藍色的實例,可是沒有綠色的,那麼顏色的均值可能仍是獲得2,也就是綠色的意思。
one-hot編碼和dummy編碼是比較像的兩種編碼,二者的區別是,若是離散型特徵有5個屬性,one-hot編碼會生成5個特徵,而dummy編碼則生成4個。
from sklearn.preprocessing import OneHotEncoder data = iris.target.reshape((-1,1)) print(data.shape) data = OneHotEncoder().fit_transform(data) print(data.shape)
(150, 1) (150, 3)
時間特徵既能夠看做是連續型,也能夠看做是離散型。
連續型:持續時間(單頁瀏覽時長)、間隔時間(上次購買、點擊離如今的時間)
離散型:哪一個時段(0-24),星期幾,工做日/週末/法定假日。
文本型特徵常見的處理方法有兩類,第一類採用最普通的詞袋(bag of words)模型,以及在此基礎上加入ngram擴充詞袋,以及使用tfidf加權特徵值。第二類是基於Word2vec生成詞向量。
文本數據預處理後,去掉停用詞,剩下的詞組成的list, 在詞庫中的映射稀疏向量,這就是詞袋模型。如下摘自sklearn文檔
因爲普通的詞袋模型沒有很好的考慮上下文的關係,只把每一個單詞當作單個特徵來處理,所以就有了ngram改進普通的詞袋模型,普通的詞袋模型是1-gram,兩個單詞爲2-gram,以此類推。
本來的詞袋模型實際上是表徵的詞袋中每個詞在該文檔中的出現次數 ,但若是這個詞僅在因此樣本中都出現了不少次,該詞的特徵值就失去了良好的特徵表達能力,所以就出現了tfidf來平衡權值。TFIDF的主要思想是:若是某個詞或短語在一篇文章中出現的頻率TF高,而且在其餘文章中不多出現,則認爲此詞或者短語具備很好的類別區分能力,適合用來分類。TFIDF其實是:TF * IDF,TF詞頻(Term Frequency),IDF反文檔頻率(Inverse Document Frequency)。
在一份給定的文件裏,詞頻(term frequency,TF)指的是某一個給定的詞語在該文件中出現的頻率。這個數字是對詞數(term count)的歸一化,以防止它偏向長的文件。(同一個詞語在長文件裏可能會比短文件有更高的詞數,而無論該詞語重要與否。)對於在某一特定文件裏的詞語 來講,它的重要性可表示爲:
以上式子中 是該詞
在文件
中的出現次數,而分母則是在文件
中全部字詞的出現次數之和。
逆向文件頻率(inverse document frequency,IDF)是一個詞語廣泛重要性的度量。某一特定詞語的IDF,能夠由總文件數目除以包含該詞語之文件的數目,再將獲得的商取對數獲得
,有時候爲了防止出現0的狀況,會加上平滑
。
前面提到的基於詞袋的三種特徵方法是天然語言處理之前的方法,都是會生成很稀疏的矩陣,並且對錶達詞與詞之間的類似性能力有限。而word2vec能夠將天然語言中的字詞轉爲計算機能夠理解的稠密向量(Dense Vector)。Python版的word2vec工具箱:gensim
2013年,Google開源了一款用於詞向量計算的工具——word2vec,引發了工業界和學術界的關注。首先,word2vec能夠在百萬數量級的詞典和上億的數據集上進行高效地訓練;其次,該工具獲得的訓練結果——詞向量(word embedding),能夠很好地度量詞與詞之間的類似性。隨着深度學習(Deep Learning)在天然語言處理中應用的普及,不少人誤覺得word2vec是一種深度學習算法。其實word2vec算法的背後是一個淺層神經網絡。另外須要強調的一點是,word2vec是一個計算word vector的開源工具。當咱們在說word2vec算法或模型的時候,其實指的是其背後用於計算word vector的CBoW模型和Skip-gram模型。不少人覺得word2vec指的是一個算法或模型,這也是一種謬誤。在本文,因爲篇幅緣由,就不對word2vec作詳細的原理介紹,之後會專門寫一篇介紹Word2vec原理的文章。
當前樣本集的各類統計信息,包括均值、最大值、1分位數、4分位數等。
import pandas as pd
import numpy as np series = pd.Series(np.random.randn(500)) series.describe() count 500.000000 mean -0.063427 std 1.007670 min -3.032698 25% -0.749055 50% 0.001290 75% 0.607432 max 2.900834 dtype: float64
1.user_id&&category: 10001&&女裙,10002&&男士牛仔
2.user_id&&style:10001&&蕾絲,10002&&全棉
實際應用過程當中不會直接將用戶id號和商品組合而產生很是稀疏的矩陣,會事先對用戶作一個聚類。
GBDT + LR是一套經典的特徵組合+訓練的方式,最先由Facebook提出。
思路大概是用先用GBDT訓練模型,因爲樹模型是具備很好的解釋性的,從根節點到葉子節點的路徑就是一條特徵組合,而後能夠將組合特徵和原始特徵一塊兒訓練。
在實際業務中,可能會由於各類緣由會形成數據的缺失,好比某些用戶年齡、性別、設備這類型的特徵沒法獲取到,同時線上模型又有使用這些類型的特徵,那麼缺失了這些特徵的用戶在線上打分的時候會出現比較大的誤差;一般會有幾種方式來進行處理:數值型特徵可使用均值或者中位數進行簡單的替換,年齡這類型的特徵能夠經過關係鏈進行加權打分,固然也能夠經過把缺失的所有都歸爲一類,用戶默認值來替代。
固然對於新用戶或者新 item 來講其實也是屬於一種缺失值狀況,對於這種狀況已經屬於領一個很是大的領域,那就是推薦系統的啓動問題。對於冷啓動我問題,如今的作法會從兩個方面着手,一種是經過集體智慧來解決,另一種是經過網絡模型;第一種方法就是使用協同過濾的思想,與這個新用戶相似的用戶表現來知道新用戶的推薦。第二種利用網絡把 item 周圍信息考慮進去,好比下面會提到的層次平滑,熱傳導模型也能夠經過引入基礎屬性到二部圖中,達到解決冷啓動問題。
當數據預處理完成後,咱們須要選擇有意義的特徵輸入機器學習的算法和模型進行訓練。一般來講,從兩個方面考慮來選擇特徵:
特徵選擇的緣由是由於特徵維度過高,可能出現冗餘:部分特徵的相關度過高了,消耗計算性能;也可能會出現噪聲:部分特徵是對預測結果沒有幫助甚至有負影響。
特徵選擇的目的是選擇模型最優特徵子集。特徵與特徵之間多多少少會有一些相互做用,好比有些特徵是包含其餘特徵,有些特徵與另外一些特徵存在相關性的,也有一些特徵須要與其餘特徵組合起來才能起做用,還有一些特徵是會存在負相關的,若是隻使用正是由於特徵之間的這些關係,合理的選擇適合的特徵集合對於模型效果有很是大的做用。現有的特徵選擇方法能夠大致分紅三種類型:
特徵選擇主要有兩個目的:
這種方法是衡量單個特徵值與目標變量也就是樣本 label 值之間的關聯。但這種方法的缺點是沒有考慮到特徵之間的關聯,有可能把有用的關聯特徵過濾掉。
對於分類問題(y離散),可採用:
卡方檢驗,互信息
對於迴歸問題(y連續),可採用:
皮爾森相關係數,最大信息係數
經典的互信息(互信息爲隨機變量X與Y之間的互信息I(X;Y)I(X;Y)爲單個事件之間互信息的數學指望)也是評價定性自變量對定性因變量的相關性的,互信息計算公式以下:
互信息直接用於特徵選擇其實不是太方便:一、它不屬於度量方式,也沒有辦法歸一化,在不一樣數據及上的結果沒法作比較;二、對於連續變量的計算不是很方便(X和Y都是集合,x,y都是離散的取值),一般變量須要先離散化,而互信息的結果對離散化的方式很敏感。
最大信息係數克服了這兩個問題。它首先尋找一種最優的離散化方式,而後把互信息取值轉換成一種度量方式,取值區間在[0,1]。
from sklearn.feature_selection import SelectKBest from minepy import MINE #因爲MINE的設計不是函數式的,定義mic方法將其爲函數式的,返回一個二元組,二元組的第2項設置成固定的P值0.5 def mic(x, y): m = MINE() m.compute_score(x, y) return (m.mic(), 0.5) #選擇K個最好的特徵,返回特徵選擇後的數據 SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
MIC的統計能力遭到了一些質疑 ,當零假設不成立時,MIC的統計就會受到影響。在有的數據集上不存在這個問題,但有的數據集上就存在這個問題。
經典的卡方檢驗是檢驗定性自變量對定性因變量的相關性。假設自變量有N種取值,因變量有M種取值,考慮自變量等於i且因變量等於j的樣本頻數的觀察值與指望的差距,構建統計量:
from sklearn.datasets import load_iris from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 iris = load_iris() X, y = iris.data, iris.target X.shape (150, 4) X_new = SelectKBest(chi2, k=2).fit_transform(X, y) X_new.shape (150, 2)
皮爾森相關係數是一種最簡單的,能幫助理解特徵和響應變量之間關係的方法,該方法衡量的是變量之間的線性相關性,結果的取值區間爲[-1,1],-1表示徹底的負相關,+1表示徹底的正相關,0表示沒有線性相關。
Pearson Correlation速度快、易於計算,常常在拿到數據(通過清洗和特徵提取以後的)以後第一時間就執行。Scipy的 pearsonr 方法可以同時計算 相關係數 和p-value.
import numpy as np from scipy.stats import pearsonr np.random.seed(0) size = 300 x = np.random.normal(0, 1, size) # pearsonr(x, y)的輸入爲特徵矩陣和目標向量 print("Lower noise", pearsonr(x, x + np.random.normal(0, 1, size))) print("Higher noise", pearsonr(x, x + np.random.normal(0, 10, size))) >>> # 輸出爲二元組(sorce, p-value)的數組 Lower noise (0.71824836862138386, 7.3240173129992273e-49) Higher noise (0.057964292079338148, 0.31700993885324746)
這種方法的思路是直接使用你要用的機器學習算法,針對每一個單獨的特徵和響應變量創建預測模型。假如特徵和響應變量之間的關係是非線性的,能夠用基於樹的方法(決策樹、隨機森林)、或者擴展的線性模型 等。基於樹的方法比較易於使用,由於他們對非線性關係的建模比較好,而且不須要太多的調試。但要注意過擬合問題,所以樹的深度最好不要太大,再就是運用交叉驗證。
在我以前講解隨機森林模型的博客中介紹了隨機森林的一個重要特性OOB估計,能夠在不進行交叉驗證的狀況下高效的計算特徵對模型的重要程度。
from sklearn.cross_validation import cross_val_score, ShuffleSplit from sklearn.datasets import load_boston from sklearn.ensemble import RandomForestRegressor import numpy as np # 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", # 注意X[:, i]和X[:, i:i+1]的區別 cv=ShuffleSplit(len(X), 3, .3)) scores.append((format(np.mean(score), '.3f'), names[i])) print(sorted(scores, reverse=True))
這種方法和前幾種方法不太同樣,前幾種方法是計算單個特徵與結果值之間的相關程度從而刪選特徵,這種方法僅從特徵的統計特性來考慮,沒有考慮和結果值之間的相關度。
假設某特徵的特徵值只有0和1,而且在全部輸入樣本中,95%的實例的該特徵取值都是1,那就能夠認爲這個特徵做用不大。若是100%都是1,那這個特徵就沒意義了。當特徵值都是離散型變量的時候這種方法才能用,若是是連續型變量,就須要將連續變量離散化以後才能用。並且實際當中,通常不太會有95%以上都取某個值的特徵存在,因此這種方法雖然簡單可是不太好用。能夠把它做爲特徵選擇的預處理,先去掉那些取值變化小的特徵,而後再從接下來提到的的特徵選擇方法中選擇合適的進行進一步的特徵選擇。
from sklearn.feature_selection import VarianceThreshold X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]] sel = VarianceThreshold(threshold=(.8 * (1 - .8))) sel.fit_transform(X) array([[0, 1], [1, 0], [0, 0], [1, 1], [1, 0], [1, 1]])
Wrapper 這一類特徵選擇方法,應該來講是比較科學的,可是也是很是耗時,工業界在生產環境中不多使用,很是耗時,也是一個 NP 複雜的問題,通常經過不斷迭代,而後每次加入一個特徵,來訓練模型,使用模型評估好比 AUC 或者 MSE 等函數評估是否將特徵加入到特徵子集中。
遞歸消除特徵法使用一個基模型來進行多輪訓練,每輪訓練後,移除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練。
sklearn官方解釋:對特徵含有權重的預測模型(例如,線性模型對應參數coefficients),RFE經過遞歸減小考察的特徵集規模來選擇特徵。首先,預測模型在原始特徵上訓練,每一個特徵指定一個權重。以後,那些擁有最小絕對值權重的特徵被踢出特徵集。如此往復遞歸,直至剩餘的特徵數量達到所需的特徵數量。
RFECV 經過交叉驗證的方式執行RFE,以此來選擇最佳數量的特徵:對於一個數量爲d的feature的集合,他的全部的子集的個數是2的d次方減1(包含空集)。指定一個外部的學習算法,好比SVM之類的。經過該算法計算全部子集的validation error。選擇error最小的那個子集做爲所挑選的特徵。
from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression #遞歸特徵消除法,返回特徵選擇後的數據 #參數estimator爲基模型 #參數n_features_to_select爲選擇的特徵個數 RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)
單變量特徵選擇方法獨立的衡量每一個特徵與響應變量之間的關係,另外一種主流的特徵選擇方法是基於機器學習模型的方法。有些機器學習方法自己就具備對特徵進行打分的機制,或者很容易將其運用到特徵選擇任務中,例如迴歸模型,SVM,決策樹,隨機森林等等。
以前我寫的一篇文章對比了L一、L2正則化的區別,L1正則化具備截斷性,L2正則化具備縮放效應,因此咱們能夠很好的利用線性模型的兩種正則化選擇特徵、
使用L1範數做爲懲罰項的線性模型(Linear models)會獲得稀疏解:大部分特徵對應的係數爲0。當你但願減小特徵的維度以用於其它分類器時,能夠經過 feature_selection.SelectFromModel
來選擇不爲0的係數。特別指出,經常使用於此目的的稀疏預測模型有 linear_model.Lasso
(迴歸), linear_model.LogisticRegression 和 svm.LinearSVC(分類):
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)
GBDT在計算每一個節點的重要程度時能夠同時用來作特徵選擇,RF能夠用他的OOB估計來評價特徵的重要程度
樹模型中GBDT也可用來做爲基模型進行特徵選擇,使用feature_selection庫的SelectFromModel類結合GBDT模型,來選擇特徵的代碼以下:
from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier #GBDT做爲基模型的特徵選擇 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
前面寫了不少特徵構造和處理的方法,可能更多時間咱們更想知道一個特徵是否真的靠譜,在時間有限的狀況下,用貪心的思想,每次選擇表現最好的特徵加入到模型訓練中,這個時候就會特徵評估這個東西了,特徵評估可能會從幾個維度進行衡量:
一、特徵自身的質量
二、特徵與目標值的相關性
當特徵選擇完成後,能夠直接訓練模型了,可是可能因爲特徵矩陣過大,致使計算量大,訓練時間長的問題,所以下降特徵矩陣維度也是必不可少的。常見的降維方法除了以上提到的基於L1懲罰項的模型之外,另外還有主成分分析法(PCA)和線性判別分析(LDA),線性判別分析自己也是一個分類模型。PCA和LDA有不少的類似點,其本質是要將原始的樣本映射到維度更低的樣本空間中,可是PCA和LDA的映射目標不同:PCA是爲了讓映射後的樣本具備最大的發散性;而LDA是爲了讓映射後的樣本有最好的分類性能。因此說PCA是一種無監督的降維方法,而LDA是一種有監督的降維方法。
from sklearn.decomposition import PCA #主成分分析法,返回降維後的數據 #參數n_components爲主成分數目 PCA(n_components=2).fit_transform(iris.data)
https://cloud.tencent.com/developer/article/1005443
http://www.cnblogs.com/jasonfreak/p/5448385.html
http://www.javashuo.com/article/p-mldamdbd-bd.html
http://blog.csdn.net/sangyongjia/article/details/52440063
https://www.cnblogs.com/iloveai/p/word2vec.html
http://www.javashuo.com/article/p-actaxjun-bm.html
寒小陽-特徵工程