現在開始資料探勘中最玄妙也是最重要的部分:特徵工程(feature engineering)。
初學機器學習,一般只是對此概念及相關內涵有所了解,此處試圖以實踐性的角度,詳細闡述特徵工程。引用一句老掉牙的話,資料和特徵決定了機器學習的上限,而模型和演算法只是逼近這個上限而已。
好特徵即使使用一般的模型,也能得到很好的效果!好特徵的靈活性在於它允許你可以選擇不複雜的模型,同時,執行速度也更快,也更容易理解和維護。好的特徵,即使引數不是最優解,模型效能也能表現很好,因此,不需要太多時間去尋找最優引數,大大的降低了模型的複雜度,使模型趨向簡單。模型的效能包括模型的效果,執行的效率及模型的可解釋性。特徵工程的最終目的就是提公升模型的效能。
許多課程中將前述part-3的資料分析與預處理合併為特徵工程,無論如何,整體的思路和流程是這樣的,我們要將原始資料處理成格式化的矩陣餵給模型,前面part-3將資料整理得漂亮了一些,接下來特徵工程是為了將「資料」變為「特徵」。說到「資料」,它還是一些有意義的數值,有含義,有量綱,而「特徵"則可以認為僅僅是一些數字了,模型需要有用的特徵來分類和**,但是它並不理解它是否有含義,在這個精準醫療的比賽中,可以看到大佬們創造出了各種各樣的特徵提高了模型的準確度,這些特徵大多很」奇葩「,但是只要是有用的,我們就要使用,學習構造這樣的特徵的一套理論。
這一部分中,我們首先介紹特徵工程那一套理論,包括一些有效的方法、一套實踐起來比較有效的流程,然後貼出鄙人比賽的**作為示例,並看一下一些大佬的特徵的樣子拓寬思路。這一部分會引用許多網上的內容,文中會給出幾個鏈結供詳細學習~
特徵工程到底是什麼? - 城東的回答 - 知乎
預處理: 無量綱化,對定量特徵二值化,對定性特徵啞編碼,資料變換
特徵選擇:
降維:主成分分析法(pca)、線性判別分析法(lda)
下面,對這三部分結合資料分別談一下個人的經驗和思路。part-3中反覆引用的一本不錯的書,書中將特徵工程歸到資料預處理一部分,對應於資料變換和資料規約兩節,其具體內容也大同小異。
本人認為,特徵工程基本分為兩部分:特徵構造(特徵生成)和特徵選擇(特徵提取)。
遵循上面的框架,首先是
特徵構造,區別於資料的預處理,這部分可以歸納為「資料」的
「編碼化」、「無量綱化」。
① 無量綱化:資料的標準歸一化,對於後續的訓練速度和模型的準確性有很大作用,不再贅述(基礎知識就不囉嗦了),都可以用sklearn包實現,選擇合適的方法也是一門學問。
② 編碼:分為二值化編碼,以及著名的獨熱(one-hot)編碼又稱啞編碼。處理的物件是我們上游工作流程得到的df物件,字段內容一般是,非數值型(文字)、離散數值、連續型數值。此中設計到不少實踐性很強的內容,略述如下。
非數值型的特徵此處要進行處理了,模型不能識別非數字的東西,此處一般指的是文字型字段。例如性別,可以設定為,這不是二值化處理。需要說明的是,對於性別這一類的在dataframe物件中可以用map函式進行處理,十分方便,具體可見下面的**。除了文字型字段,若是離散的、大小無意義的數字的字段,也需獨熱處理。在面對大量獨熱編碼時,乙個乙個用map函式十分不便,而用sklearn上的onehotencoder() 會將df物件變為陣列,無法後續處理,也不便於觀察特徵的名字(當然你可以把這一步放到最後),同樣sklearn的無量綱化操作也是這樣,破壞美麗的df資料結構。
此處,需要傳授一些人生經驗,不要聽信sklearn那些預處理工具。無量綱化直接用pandas自帶的統計量進行計算,啞編碼用pd.get_dummies(),十分方便。
對於連續值的編碼,即離散化處理,連續值本來直接送給模型就很好,如果有必要簡化、編碼,可以將連續值分段,再參考獨熱編碼。比如年齡字段可以這樣處理,但是本題沒有這麼做;具體的年齡數值很有用處,年齡的相關性極大,但是又不能說50歲就是25歲的2倍,編碼處理也許也有幫助。
③ 特徵構造
資料變換,明顯也使得資料無量綱,需要注意的是資料變換的本質上是什麼呢?沒錯,實際上就是構造
新特徵。sklearn裡實現了polynomialfeatures 以及 functiontransformer,
乙個是多項式特徵,乙個是函式變換。
特徵組合,基本利用
簡單的四則運算,但是一般基於對問題專業知識的理解,對現有幾個字段加以組合生成新的特徵。
這個**非常明了:
此處對特徵構造總結一下。編碼(數值規約)是對字段內容(離散型、文字)的特徵化,而資料變換則是創造新的特徵,方法除了多項式的,函式變換的,四則運算也是最基本的手段。此時,我們得到的『資料』更像是一些高維的『特徵』了,也許我們只有40個字段,經過這個階段的處理可以有1000個特徵(因為各種函式變換,你想有多少特徵都可以)。這就是這一階段的目的,但是沒有特徵篩選的支撐這一工作也毫無意義,喂過多的特徵會使模型準確性下降。下面我們認識一下特徵選擇。
特徵選擇的方法各種資料上說了一大堆,一般分為過濾、包裹、嵌入,鄙人根據自己理解,作如下分類:
① 基於指標的篩選:
大佬的文章中介紹了方差選擇法(variancethreshold)、相關係數法(pearsonr)、卡方檢驗法(chi2)和互資訊法(mine),輔助使用selectkbest()工具依據每個特徵的指標選出k個最佳特徵,相關係數只能評價線性關係,而卡方檢驗和互資訊可以找到更多有用的特徵,鄙人在比賽中輔助使用了互資訊和相關係數,並沒有完整的應用流程,還需在實踐中加強。
有時間鄙人會擴充套件一下這部分的內容,在此先略過。。
② 基於模型的篩選:
特徵遞迴消除: rfe(estimator, n_features_to_select, step, estimator_params, verbose)
要注意selectfrommodel(logisticregression(penalty="l1", c=0.1))這樣的是不穩定的,這裡向大家推薦sklearn.linear_model的兩個方法:
隨機lasso回歸 randomizedlasso(alpha='aic', scaling=.5, sample_fraction=.75,
n_resampling=200, selection_threshold=.25,
fit_intercept=true, verbose=false, normalize=true, precompute='auto',
max_iter=500, eps=np.finfo(np.float).eps, random_state=none,
n_jobs=1, pre_dispatch='3*n_jobs', memory=none)
隨機邏輯回歸 randomizedlogisticregression(c=1, scaling=.5, sample_fraction=.75,
n_resampling=200, selection_threshold=.25, tol=1e-3,
fit_intercept=true, verbose=false, normalize=true,
random_state=none, n_jobs=1, pre_dispatch='3*n_jobs', memory=none)
原型是這樣的,相當於線性模型的整合演算法,可以穩定的選出重要的模型,具體使用不妨查查資料、看看原始碼。另外,火熱的深度學習也可以用來篩選特徵,有興趣的可以去查查~
③ 降維:當特徵選擇完成後,可以直接訓練模型了,但是可能由於特徵矩陣過大,導致計算量大,訓練時間長的問題,因此降低特徵矩陣維度也是必不可少的。l1的正則也是一種降維。pca是為了讓對映後的樣本具有最大的發散性;而lda是為了讓對映後的樣本有最好的分類效能。與篩選不同的是,篩選是捨棄掉某些特徵、保留一些特徵,而降維後,留下的維度已不再是原來的任一特徵,類似於特徵之間作了複雜的變換和函式運算,因此降維的過程是新特徵生成。但是將降維歸到特徵選擇中,大概因為這一般是呼叫模型前的最後一步了,一般還是認為這是在篩選特徵而不是構造特徵。
總結如下:(加上隨機lasso)
特徵工程流程歸納:
無量綱化(標準歸一化)→ 編碼 → 特徵構造 → 特徵篩選 → 降維(如果維度大)
實際上,特徵構造和特徵選擇是反覆迭代的關係
。上面知乎的回答中的有一位大佬是這樣總結的:
還是知乎那個問題裡,資料分析jacky 的回答也不錯,理論很系統,例項也很豐富,建議翻到下面看一下。他將流程歸納為資料處理、特徵選擇、維度壓縮。
特徵工程到底是什麼? - 資料分析jacky的回答 - 知乎
實戰天池精準醫療大賽之一 資料分析
1 缺失資料 有大量的缺失值,特徵分四類,分別是B肝 血常規 肝功能 腎功能,一般的缺失值都是缺失整個類別資料 由於患者未做某項檢查 除血常規以外,其餘三項都有大量的缺失值,尤其是B肝類檢查,多一半都是空值。如果去掉這些資料,將會損失3 4的資料量。假設 醫生不要求做該項檢查,說明他認為該項指標基本...
天池精準醫療大賽 個人賽後總結(一)
一條工程狗也有自己的資料探勘夢,自己 這部分主要是如何處理缺失值的問題。特徵大概可以劃分為四大類 肝功能 腎功能 血常規 B肝 缺失資料均為整類缺失,即檢查人沒有做該部分的檢查 除了血常規意外其他三大類均有大量缺失值,尤其是B肝這一項,缺失值達到了一半以上。初步考慮 填充缺失量如此大的資料將帶來無法...
資料探勘實戰 資料預處理之缺失值處理
kaggle的titanic 比賽不少題解有標準的處理流程,這裡參考 kaggle titanic 生存 詳細流程 梳理 嘗試提取常用的缺失值處理方法 這裡還是借助google colab 來學習 讀取資料 import pandas as pd data pd.read csv data trai...