通常說“數(shù)據(jù)決定了機器學(xué)習(xí)的上限,而算法只是逼近這個上限。”這里所說的數(shù)據(jù)指的就是特征工程得到的數(shù)據(jù)。Andrew Ng說過:“創(chuàng)造新的特征是一件十分困難的事情,需要豐富的專業(yè)知識和大量的時間。機器學(xué)習(xí)應(yīng)用的本質(zhì)基本上就是特征工程?!庇纱丝梢姡卣鞴こ淘跈C器學(xué)習(xí)中占有相當(dāng)重要的地位。
特征是指從原始數(shù)據(jù)中抽取出對結(jié)果預(yù)測更有用或表達更充分的信息。更好的特征意味著“更強的靈活性+更簡單的模型+更好的結(jié)果”。
特征工程是指利用數(shù)據(jù)領(lǐng)域的相關(guān)知識和技巧處理數(shù)據(jù),使得特征能能在機器學(xué)習(xí)算法達到最佳性能的過程。
1、特征工程的處理步驟
使用機器學(xué)習(xí)算法解決問題的過程是這樣的:
a.數(shù)據(jù)采集(Data Collection):整合數(shù)據(jù),將數(shù)據(jù)規(guī)范化成一個數(shù)據(jù)集,收集起來。
b.數(shù)據(jù)預(yù)處理(Data Preprocessing):數(shù)據(jù)清洗、數(shù)據(jù)標(biāo)準化及歸一化等。
c.數(shù)據(jù)轉(zhuǎn)換(Data Transformation):特征構(gòu)造、特征提取、特征選擇。
d.數(shù)據(jù)建模(Data Modeling):建立模型,評估模型并逐步優(yōu)化。
在上述步驟中,數(shù)據(jù)預(yù)處理和數(shù)據(jù)轉(zhuǎn)換均屬于特征工程的工作。事實上,特征工程是一個迭代過程,我們需要不斷的設(shè)計特征、選擇特征、建立模型、評估模型,然后才能得到最終的模型。下面是特征工程的一個迭代過程:
a.頭腦風(fēng)暴式特征:從原始數(shù)據(jù)中提取特征,暫時不考慮其重要性,對應(yīng)于特征構(gòu)建。
b.設(shè)計特征:根據(jù)需解決的問題,可以使用自動地特征提取,或者手工特征構(gòu)造,或者兩者混合使用。
c.選擇特征:使用不同的特征重要性評分和特征選擇方法進行特征選擇。
d.評估模型:使用選擇的特征進行建模,同時使用未知的數(shù)據(jù)來評估模型精度。
綜上所述,特征工程應(yīng)包含數(shù)據(jù)預(yù)處理、特征構(gòu)造、特征提取、特征選擇等步驟。
2、數(shù)據(jù)預(yù)處理
1)數(shù)據(jù)清洗
數(shù)據(jù)清洗(Data Cleaning)是對數(shù)據(jù)進行重新審查和校驗的過程,目的在于刪除重復(fù)信息、糾正存在的錯誤,并提供數(shù)據(jù)一致性。
數(shù)據(jù)清洗包括格式內(nèi)容清洗、邏輯錯誤清洗、異常值清洗、缺失值清洗、非需求數(shù)據(jù)清洗等內(nèi)容。

a.格式內(nèi)容清洗
時間、日期格式不一致清洗:根據(jù)實際情況,把時間/日期數(shù)據(jù)庫轉(zhuǎn)換成統(tǒng)一的表示方式。例如:日期格式不一致,2019-07-20、20190720、2019/07/20、20/07/2019;時間戳單位不一致,有的用秒表示,有的用毫秒表示;使用無效時間表示,時間戳使用0表示,結(jié)束時間戳使用FFFF表示。
數(shù)值格式不一致清洗:根據(jù)實際情況,把數(shù)值轉(zhuǎn)換成統(tǒng)一的表示方式。例如:1、2.0、3.21E3、四等。
全半角等顯示格式不一致清洗:這個問題在人工錄入數(shù)據(jù)時比較容易出現(xiàn)。
內(nèi)容中有不該存在的字符清洗:某些內(nèi)容可能只包括一部分字符,比如身份證號是數(shù)字+字母,中國人姓名是漢字。最典型的就是頭、尾、中間的空格,也可能出現(xiàn)姓名中存在數(shù)字符號、身份證號出現(xiàn)漢字等問題。
內(nèi)容與該字段應(yīng)有內(nèi)容不符清洗:姓名寫了性別,身份證號寫了手機號等等,均屬這種問題。但該問題特殊性在于:并不能簡單的以刪除來處理,因為成因有可能是人工填寫錯誤,也有可能是前端沒有校驗,還有可能是導(dǎo)入數(shù)據(jù)時部分或全部存在列沒有對齊的問題,因此要詳細識別問題類型。
數(shù)據(jù)類型不符清洗:由于人為定義錯誤、轉(zhuǎn)存、加載等原因,數(shù)據(jù)類型經(jīng)常會出現(xiàn)數(shù)據(jù)類型不符的情況。例如,金額特征是字符串類型,實際上應(yīng)該轉(zhuǎn)換成int/float型。
b.邏輯錯誤清洗
重復(fù)數(shù)據(jù)清洗:存在各個特征值完全相同的兩條/多條數(shù)據(jù);數(shù)據(jù)不完全相同,但從業(yè)務(wù)角度看待數(shù)據(jù)是同一個數(shù)據(jù)。
不合理值清洗:根據(jù)業(yè)務(wù)常識,或者使用但不限于箱型圖(Box-plot)發(fā)現(xiàn)數(shù)據(jù)中不合理的特征值。例如:年齡200歲;個人年收入100000萬;
矛盾內(nèi)容修正:有些字段是可以互相驗證的,舉例:身份證號是1101031980XXXXXXXX,然后年齡填18歲。在這種時候,需要根據(jù)字段的數(shù)據(jù)來源,來判定哪個字段提供的信息更為可靠,去除或重構(gòu)不可靠的字段。
c.異常值清洗
異常值是數(shù)據(jù)分布的常態(tài),處于特定分布區(qū)域或范圍之外的數(shù)據(jù)通常被定義為異常或噪聲。異常分為兩種:“偽異?!?,由于特定的業(yè)務(wù)運營動作產(chǎn)生,是正常反應(yīng)業(yè)務(wù)的狀態(tài),而不是數(shù)據(jù)本身的異常;“真異?!保皇怯捎谔囟ǖ臉I(yè)務(wù)運營動作產(chǎn)生,而是數(shù)據(jù)本身分布異常,即離群點。
異常值檢查方法
基于統(tǒng)計分析:通常用戶用某個統(tǒng)計分布對數(shù)據(jù)點進行建模,再以假定的模型,根據(jù)點的分布來確定是否異常。例如,如通過分析統(tǒng)計數(shù)據(jù)散度情況,即數(shù)據(jù)變異指標(biāo),來對數(shù)據(jù)的總體特征有更進一步的了解,對數(shù)據(jù)的分布情況有所了解,進而通過數(shù)據(jù)變異指標(biāo)來發(fā)現(xiàn)數(shù)據(jù)中的異常點數(shù)據(jù)。常用的數(shù)據(jù)變異指標(biāo)有極差、四分位數(shù)間距、均差、標(biāo)準差、變異系數(shù)等,變異指標(biāo)的值大表示差異大、散步廣;值小表示離差小,較密集。
3σ原則:若數(shù)據(jù)服從正態(tài)分布,在3σ原則下,異常值為一組測定值中與平均值的偏差超過3倍標(biāo)準差的值。距離平均值3σ之外的值出現(xiàn)的概率為

屬于極個別的小概率事件。如果數(shù)據(jù)不服從正態(tài)分布,也可以用遠離平均值的多少倍標(biāo)準差來描述。

箱式圖分析:箱線圖提供了識別異常值的一個標(biāo)準,如果一個值滿足

的值,則被稱為異常值。其中,QL為下四分位數(shù),表示全部觀察值中有四分之一的數(shù)據(jù)取值比它小;QU為上四分位數(shù),表示全部觀察值中有四分之一的數(shù)據(jù)取值比它大;IQR為四分位數(shù)間距,是上四分位數(shù)QU與下四分位數(shù)QL的差值,包含了全部觀察值的一半。箱型圖判斷異常值的方法以四分位數(shù)和四分位距為基礎(chǔ),四分位數(shù)具有魯棒性:25%的數(shù)據(jù)可以變得任意遠并且不會干擾四分位數(shù),所以異常值不能對這個標(biāo)準施加影響。因此,箱型圖識別異常值比較客觀,在識別異常值時有一定的優(yōu)越性。

基于模型檢測:首先建立一個數(shù)據(jù)模型,異常是那些同模型不能完美擬合的對象;如果模型是簇的集合,則異常是不顯著屬于任何簇的對象。優(yōu)點是,有堅實的統(tǒng)計學(xué)理論基礎(chǔ),當(dāng)存在充分的數(shù)據(jù)和所用的檢驗類型的知識時,這些檢驗可能非常有效。缺點是,對于多元數(shù)據(jù),可用的選擇少一些,并且對于高維數(shù)據(jù),這些檢測可能性很差。
基于距離:基于距離的方法是基于下面這個假設(shè),即若一個數(shù)據(jù)對象和大多數(shù)點距離都很遠,那這個對象就是異常。通過定義對象之間的臨近性度量,根據(jù)距離判斷異常對象是否遠離其他對象,主要使用的距離度量方法有絕對距離(曼哈頓距離)、歐氏距離和馬氏距離等方法。優(yōu)點是,基于距離的方法比基于統(tǒng)計類方法要簡單得多,因為一個數(shù)據(jù)集合定義一個距離的度量要比確定數(shù)據(jù)集合的分布容易得多。缺點是,基于鄰近度的方法需要O(m2)時間,大數(shù)據(jù)集不適用;該方法對參數(shù)的選擇也是敏感的;不能處理具有不同密度區(qū)域的數(shù)據(jù)集,因為它使用全局閾值,不能考慮這種密度的變化。
基于密度:考察當(dāng)前點周圍密度,可以發(fā)現(xiàn)局部異常點,離群點的局部密度顯著低于大部分近鄰點,適用于非均勻的數(shù)據(jù)集。優(yōu)點是,給出了對象是離群點的定量度量,并且即使數(shù)據(jù)具有不同的區(qū)域也能夠很好的處理。缺點是,與基于距離的方法一樣,這些方法必然具有O(m2)的時間復(fù)雜度,對于低維數(shù)據(jù)使用特定的數(shù)據(jù)結(jié)構(gòu)可以達到O(mlogm);參數(shù)選擇困難,雖然算法通過觀察不同的k值,取得最大離群點得分來處理該問題,但是,仍然需要選擇這些值的上下界。
基于聚類:對象是否被人為是異常點可能依賴于簇的個數(shù)(如k很大時的噪聲簇)。該問題也沒有簡單的答案。一種策略是對于不同的簇個數(shù)重復(fù)該分析。另一種方法是找出大量小簇,其想法是:較小的簇傾向于更加凝聚;如果存在大量小簇時,一個對象是異常點,則它多半是一個真正的異常點,不利的一面是一組異常點可能形成小簇而逃避檢測。優(yōu)點是,基于線性和接近線性復(fù)雜度(k均值)的聚類技術(shù)來發(fā)現(xiàn)離群點可能是高度有效的;簇的定義通常是離群點的補,因此可能同時發(fā)現(xiàn)簇和離群點。缺點是,產(chǎn)生的離群點集和它們的得分可能非常依賴所用的簇的個數(shù)和數(shù)據(jù)中離群點的存在性;聚類算法產(chǎn)生的簇的質(zhì)量對該算法產(chǎn)生的離群點的質(zhì)量影響非常大。
在數(shù)據(jù)處理階段將離群點作為影響數(shù)據(jù)質(zhì)量的異常點考慮,而不是作為通常所說的異常檢測目標(biāo)點,因而樓主一般采用較為簡單直觀的方法,結(jié)合箱線圖和MAD的統(tǒng)計方法判斷變量的離群點。
異常值處理方法
對異常值處理,需要具體情況具體分析,異常值處理的常用方法有4種:
一是刪除含有異常值的記錄。某些篩選出來的異常樣本是否真的是不需要的異常特征樣本,最好找懂業(yè)務(wù)的再確認一下,防止我們將正常的樣本過濾掉了。
二是將異常值視為缺失值,交給缺失值處理方法來處理。
三是使用均值/中位數(shù)/眾數(shù)來修正。
四是不處理。
數(shù)據(jù)光滑處理
除了檢測出異常值然后再處理異常值外,還可以使用以下方法對異常數(shù)據(jù)進行光滑處理。
分箱方法:通過考察數(shù)據(jù)的“近鄰”(即周圍的值)來光滑有序數(shù)據(jù)的值,有序值分布到一些“桶”或箱中。由于分箱方法考察近鄰的值,因此進行局部光滑。一是用箱均值光滑,箱中每一個值被箱中的平均值替換。二是用箱中位數(shù)平滑,箱中的每一個值被箱中的中位數(shù)替換。三是用箱邊界平滑,箱中的最大和最小值同樣被視為邊界,箱中的每一個值被最近的邊界值替換。

回歸方法:可以用一個函數(shù)(如回歸函數(shù))擬合數(shù)據(jù)來光滑數(shù)據(jù)。線性回歸涉及找出擬合兩個屬性(或變量)的“最佳”線,使得一個屬性可以用來預(yù)測另一個。多元線性回歸是線性回歸的擴展,其中涉及的屬性多于兩個,并且數(shù)據(jù)擬合到一個多維曲面。
d.缺失值清洗
缺失值處理
缺失值產(chǎn)生的原因:
客觀原因,比如數(shù)據(jù)存儲的失敗、存儲器損壞、機械故障導(dǎo)致某段時間數(shù)據(jù)未能收集(對于定時數(shù)據(jù)采集而言)。
人為原因,由于人的主觀失誤(如:數(shù)據(jù)錄入人員失誤漏錄了數(shù)據(jù))、歷史局限(如:數(shù)據(jù)在早期尚無記錄)、有意隱瞞數(shù)據(jù)(如:在市場調(diào)查中被訪人拒絕透露相關(guān)問題的答案,或者回答的問題是無效的)導(dǎo)致數(shù)據(jù)未能收集。
缺失值處理有3種方法:
一是直接使用含有缺失值的數(shù)據(jù)。某些算法可以直接使用含有缺失值的情況,如決策樹算法可以直接使用含有缺失值的數(shù)據(jù)。優(yōu)點是直接使用原始數(shù)據(jù),排除了人工處理缺失值帶來的信息損失。缺點是只有少量的算法支持這種方式。
二是刪除含有缺失值的數(shù)據(jù)。優(yōu)點是簡單、高效。缺點是如果樣本中的缺失值較少,則直接丟棄會損失大量的有效信息。這是對信息的極大浪費。
三是缺失值補全。用最可能的值來插補缺失值,這也是在實際工程中應(yīng)用最廣泛的技術(shù),常見方法有:均值插補、同類均值插補、建模預(yù)測、高維映射、多重插補、壓縮感知及矩陣補全。優(yōu)點是保留了原始數(shù)據(jù)。缺點是計算復(fù)雜,而且當(dāng)插補的值估計不準確時,會對后續(xù)的模型引入額外的誤差。
均值插補和同類均值插補
均值插補:如果樣本的屬性是連續(xù)值,則該屬性的缺失值就以該屬性有效值的平均值來插補。如果樣本的屬性是離散值,則該屬性的缺失值就以該屬性有效值的眾數(shù)(出現(xiàn)頻率最高的值)來插補。
同類均值插補:首先,將樣本進行分類;然后,以該類中的樣本的均值來插補缺失值。
建模預(yù)測插補
思想是,將缺失的屬性作為預(yù)測目標(biāo),通過建立模型來預(yù)測。給定數(shù)據(jù)集:

假設(shè)屬性j含有缺失值,將數(shù)據(jù)集劃分為:

將D1中的樣本作為新的訓(xùn)練集,標(biāo)簽值重新定義為屬性j的值,通過建模來完成屬性j的學(xué)習(xí)。將D2中的樣本作為測試集,通過學(xué)得的模型來預(yù)測其屬性j的值。
這種方法的效果相對較好,但是該方法有個根本缺陷:如果其他屬性和屬性j無關(guān),則預(yù)測的結(jié)果無意義。如果預(yù)測結(jié)果相當(dāng)準確,則又說明屬性j可以由其它屬性計算得到,于是屬性j信息冗余,沒有必要納入數(shù)據(jù)集中。
高維映射插補
思想是,將缺失的屬性映射到高維空間。給定數(shù)據(jù)集,假設(shè)屬性j的取值為離散值

一共K個離散值,則將該屬性擴展為K+1個屬性

其中,若樣本在屬性j上的取值為ak,則樣本在新的屬性jk上的取值為1,在其他屬性上的取值為0;若樣本在屬性j上缺失,則樣本在新的屬性jk+1上的取值為1,在其他屬性上的取值為0。
對于連續(xù)特征,高維映射無法直接處理??梢栽谶B續(xù)特征離散化之后,再進行高維映射。
高維映射是最精確的做法,它完全保留了所有的信息,也未增加任何額外的信息。比如廣告CTR預(yù)估模型,預(yù)處理時會把所有變量都這樣處理,達到幾億維。優(yōu)點是,完整保留了原始數(shù)據(jù)的全部信息。缺點是,計算量大大提升。而且只有在樣本量非常大的時候效果才好,否則會因為過于稀疏,效果很差。
多重插補
多重插補(Multiple?Imputation: MI)認為待插補值是隨機的,來自于已觀測到的值。具體實踐中,通常是估計出待插補值,然后再加上不同噪聲,形成多組可選插補值。然后根據(jù)某種選擇依據(jù),選取最合適的插補值。
多重插補法的步驟:一是通過變量之間的關(guān)系對缺失數(shù)據(jù)進行預(yù)測,利用蒙特卡洛方法生成多個完整的數(shù)據(jù)集。二是在每個完整的數(shù)據(jù)集上進行訓(xùn)練,得到訓(xùn)練后的模型以及評價函數(shù)值。三是對來自各個完整的數(shù)據(jù)集的結(jié)果,根據(jù)評價函數(shù)值進行選擇,選擇評價函數(shù)值最大的模型,其對應(yīng)的插值就是最終的插補值。
壓縮感知及矩陣補全
在現(xiàn)實任務(wù)中,希望根據(jù)部分信息來恢復(fù)全部信息。壓縮感知和矩陣補全就是用于完成這個任務(wù)。



2)數(shù)據(jù)標(biāo)準化及歸一化
數(shù)據(jù)一般都是有單位的,比如身高的單位有米、厘米等。需要對此類數(shù)值型特征進行無量綱化處理,即是使不同規(guī)格的數(shù)據(jù)轉(zhuǎn)換到同一規(guī)格。常見的無量綱化方法有標(biāo)準化和歸一化。
a.數(shù)據(jù)標(biāo)準化(Standardization)
為什么使用數(shù)據(jù)標(biāo)準化?
一是某些算法要求樣本具有0均值和1方差。
二是需要消除樣本不同屬性具有不同量級時的影響。例如,數(shù)量級的差異將導(dǎo)致量級較大的屬性占據(jù)主導(dǎo)地位,從而與實際情況相悖(比如這時實際情況是值域范圍小的特征更重要);當(dāng)使用梯度下降法尋求最優(yōu)解時,很有可能走“之字型”路線(垂直等高線走),從而導(dǎo)致需要迭代很多次才能收斂;依賴于樣本距離的算法對于數(shù)據(jù)的數(shù)量級非常敏感。
數(shù)據(jù)標(biāo)準化定義
數(shù)據(jù)標(biāo)準化公式如下:

標(biāo)準化的前提是特征值服從正態(tài)分布,標(biāo)準化后,其轉(zhuǎn)換成標(biāo)準正態(tài)分布。均值和標(biāo)準差都是在樣本集上定義的,而不是在單個樣本上定義的。標(biāo)準化是針對某個屬性的,需要用到所有樣本在該屬性上的值。
實現(xiàn)代碼
from sklearn.preprocessing import StandardScaler
#標(biāo)準化,返回值為標(biāo)準化后的數(shù)據(jù)
standardScaler? = StandardScaler().fit(X_train)
standardScaler.transform(X_train)
b.數(shù)據(jù)歸一化
MinMax歸一化
區(qū)間縮放法利用了邊界值信息,將屬性縮放到[0,1]。計算公式如下:

這種方法有一個缺陷就是當(dāng)有新數(shù)據(jù)加入時,可能導(dǎo)致max和min的變化,需要重新定義;另外,MinMaxScaler對異常值的存在非常敏感。
實現(xiàn)代碼如下:
from sklearn.preprocessing import MinMaxScaler
#區(qū)間縮放,返回值為縮放到[0, 1]區(qū)間的數(shù)據(jù)
minMaxScaler? = MinMaxScaler().fit(X_train)
minMaxScaler.transform(X_train)
MaxAbs歸一化
單獨地縮放和轉(zhuǎn)換每個特征,使得訓(xùn)練集中的每個特征的最大絕對值將為1.0,將屬性縮放到[-1,1]。它不會移動/居中數(shù)據(jù),因此不會破壞任何稀疏性。

c.標(biāo)準化與歸一化對比
標(biāo)準化與歸一化的異同
相同點:它們的相同點在于都能取消由于量綱不同引起的誤差;都是一種線性變換,都是對向量X按照比例壓縮再進行平移。
不同點:一是目的不同,歸一化是為了消除綱量壓縮到[0,1]區(qū)間;標(biāo)準化只是調(diào)整特征整體的分布。二是歸一化與最大,最小值有關(guān);標(biāo)準化與均值,標(biāo)準差有關(guān)。三是歸一化輸出在[0,1]之間,標(biāo)準化無限制。
什么時候用歸一化?什么時候用標(biāo)準化?
如果對輸出結(jié)果范圍有要求,用歸一化。
如果數(shù)據(jù)較為穩(wěn)定,不存在極端的最大最小值,用歸一化。
如果數(shù)據(jù)存在異常值和較多噪音,用標(biāo)準化,可以間接通過中心化避免異常值和極端值的影響。
歸一化與標(biāo)準化的應(yīng)用場景
在分類、聚類算法中,需要使用距離來度量相似性的時候(如SVM、KNN)、或者使用PCA技術(shù)進行降維的時候,標(biāo)準化(Z-score standardization)表現(xiàn)更好。
在不涉及距離度量、協(xié)方差計算、數(shù)據(jù)不符合正太分布的時候,可以使用第一種方法或其他歸一化方法。比如圖像處理中,將RGB圖像轉(zhuǎn)換為灰度圖像后將其值限定在[0, 255]的范圍。
基于樹的方法不需要進行特征的歸一化。例如隨機森林,bagging與boosting等方法。
基于參數(shù)的模型或者基于距離的模型需要歸一化。因為基于參數(shù)的模型或者基于距離的模型,需要對參數(shù)或者距離進行計算,都需要進行歸一化。
一般來說,建議優(yōu)先使用標(biāo)準化。對于輸出有要求時再嘗試別的方法,如歸一化或者更加復(fù)雜的方法。很多方法都可以將輸出范圍調(diào)整到[0, 1],如果我們對于數(shù)據(jù)的分布有假設(shè)的話,更加有效的方法是使用相對應(yīng)的概率密度函數(shù)來轉(zhuǎn)換。
除了上面介紹的方法外,還有一些相對沒這么常用的處理方法:RobustScaler、PowerTransformer、QuantileTransformer和QuantileTransformer等。
3)分箱(Binning)
數(shù)據(jù)分箱(Binning)是一種數(shù)據(jù)預(yù)處理技術(shù),用于減少輕微觀察錯誤的影響。落入給定小間隔bin的原始數(shù)據(jù)值由代表該間隔的值(通常是中心值)代替。這是一種量化形式。 統(tǒng)計數(shù)據(jù)分箱是一種將多個或多或少連續(xù)值分組為較少數(shù)量的“分箱”的方法。例如,如果您有關(guān)于一組人的數(shù)據(jù),您可能希望將他們的年齡安排到較小的年齡間隔。對于一些時間數(shù)據(jù)可以進行分箱操作,例如一天24小時可以分成早晨[5,8),上午[8,11),中午[11,14),下午[14,19),夜晚[10,22),深夜[19,24)和[24,5)。因為比如中午11點和12點其實沒有很大區(qū)別,可以使用分箱技巧處理之后可以減少這些“誤差”。
4)獨熱編碼(One-Hot Encoding)
獨熱編碼(One-Hot Encoding)是一種數(shù)據(jù)預(yù)處理技巧,它可以把類別數(shù)據(jù)變成長度相同的特征。例如,人的性別分成男女,每一個人的記錄只有男或者女,那么我們可以創(chuàng)建一個維度為2的特征,如果是男,則用(1,0)表示,如果是女,則用(0,1)。即創(chuàng)建一個維度為類別總數(shù)的向量,把某個記錄的值對應(yīng)的維度記為1,其他記為0即可。對于類別不多的分類變量,可以采用獨熱編碼。
5)特征哈希(Hashing Trick)
對于類別數(shù)量很多的分類變量可以采用特征哈希(Hashing Trick),特征哈希的目標(biāo)就是將一個數(shù)據(jù)點轉(zhuǎn)換成一個向量。利用的是哈希函數(shù)將原始數(shù)據(jù)轉(zhuǎn)換成指定范圍內(nèi)的散列值,相比較獨熱模型具有很多優(yōu)點,如支持在線學(xué)習(xí),維度減小很多燈。具體參考數(shù)據(jù)特征處理之特征哈希(Feature Hashing)。
6)嵌套法(Embedding)
嵌套法(Embedding)是使用神經(jīng)網(wǎng)絡(luò)的方法將原始輸入數(shù)據(jù)轉(zhuǎn)換成新特征,嵌入實際上是根據(jù)您想要實現(xiàn)的任務(wù)將您的特征投影到更高維度的空間,因此在嵌入空間中,或多或少相似的特征在它們之間具有小的距離。 這允許分類器更好地以更全面的方式學(xué)習(xí)表示。例如,word embedding就是將單個單詞映射成維度是幾百維甚至幾千維的向量,在進行文檔分類等,原本具有語義相似性的單詞映射之后的向量之間的距離也比較小,進而可以幫助我們進一步進行機器學(xué)習(xí)的應(yīng)用,這一點比獨熱模型好很多。
7)取對數(shù)(Log Transformation)
取對數(shù)就是指對數(shù)值做log轉(zhuǎn)換,可以將范圍很大的數(shù)值轉(zhuǎn)換成范圍較小的區(qū)間中。Log轉(zhuǎn)換對分布的形狀有很大的影響,它通常用于減少右偏度,使得最終的分布形狀更加對稱一些。它不能應(yīng)用于零值或負值。對數(shù)刻度上的一個單位表示乘以所用對數(shù)的乘數(shù)。在某些機器學(xué)習(xí)的模型中,對特征做對數(shù)轉(zhuǎn)換可以將某些連乘變成求和,更加簡單,這不屬于這部分范圍了。
如前所述,log轉(zhuǎn)換可以將范圍很大的值縮小在一定范圍內(nèi),這對某些異常值的處理也很有效,例如用戶查看的網(wǎng)頁數(shù)量是一個長尾分布,一個用戶在短時間內(nèi)查看了500個和1000個頁面都可能屬于異常值,其行為可能差別也沒那么大,那么使用log轉(zhuǎn)換也能體現(xiàn)這種結(jié)果。
8)特征交互(Feature Interaction)
在回歸模型中加入交互項是一種非常常見的處理方式。它可以極大的拓展回歸模型對變量之間的依賴的解釋。具體參見回歸模型中的交互項簡介(Interactions in Regression)。
3、特征構(gòu)造
待完善。。。
4、特征提取
待完善。。。
5、特征選擇
1)特征選擇介紹
a.特征重要性分類
對于一個學(xué)習(xí)任務(wù),給定屬性集,其中某些屬性可能對于學(xué)習(xí)來說是很關(guān)鍵的,但有些屬性可能就意義不大。
一是相關(guān)特征。對當(dāng)前學(xué)習(xí)任務(wù)有用的屬性成為相關(guān)特征。
二是無關(guān)特征。對當(dāng)前學(xué)習(xí)任務(wù)無用的屬性稱為無關(guān)特征。
三是冗余特征。不會對我們的算法帶來新的信息,或者這種特征的信息可以由其他的特征推斷出。
b.特征選擇目的
從給定的特征集合中選出相關(guān)特征子集的過程稱作特征選擇(Feature Selection)。特征選擇應(yīng)獲取盡可能小的相關(guān)特征子集,不顯著降低分類精度、不影響分類分布以及特征子集應(yīng)具有穩(wěn)定、適應(yīng)性強等特點。
特征選擇可能會導(dǎo)致模型預(yù)測能力的降低。因為被剔除的特征中可能包含了有效的信息,拋棄了這部分信息會一定程度上降低預(yù)測準確率。這是計算復(fù)雜度和預(yù)測能力之間的折衷:如果保留盡可能多的特征,則模型的預(yù)測能力會有所提升,但是計算復(fù)雜度會上升。如果剔除盡可能多的特征,則模型的預(yù)測能力會有所下降,但是計算復(fù)雜度會下降。
2)特征選擇方法
a.Filter方法(過濾式)
先進行特征選擇,然后去訓(xùn)練學(xué)習(xí)器,特征選擇過程與后續(xù)學(xué)習(xí)算法無關(guān)。相當(dāng)于先對特征進行過濾操作,然后用特征子集來訓(xùn)練分類器。
主要思想是:對每一維特征“打分”,即給每一維的特征賦予權(quán)重,這樣的權(quán)重就代表著該特征的重要性,然后依據(jù)權(quán)重排序。
主要方法有:Chi-squared test(卡方檢驗);Information gain(信息增益);Correlation coefficient scores(相關(guān)系數(shù))。
主要優(yōu)點是:運行速度快,是一種非常流行的特征選擇方法。
主要缺點是:無法提供反饋。特征選擇的標(biāo)準/規(guī)范制定是在特征搜索算法中完成,學(xué)習(xí)算法無法給特征搜索算法傳遞對特征的需求。另外,可能處理某個特征時由于任意原因表示該特征不重要,但是該特征與其它特征結(jié)合起來則可能變得很重要。
b.Wrapper方法(包裹式)
直接把最后要使用的分類器作為特征選擇的評價函數(shù),對于特定的分類器選擇最優(yōu)的特征子集。
主要思想是:將子集的選擇看作是一個搜索尋優(yōu)問題,生成不同的組合,對組合進行評價,再與其他的組合進行比較。這樣就將子集的選擇看作是一個優(yōu)化問題,這里有很多的優(yōu)化算法可以解決,尤其是一些啟發(fā)式的優(yōu)化算法,如GA、PSO(如:優(yōu)化算法-粒子群算法)、DE、ABC(如:優(yōu)化算法-人工蜂群算法)等。
主要方法有:遞歸特征消除(Recursive Feature Elimination, RFE)算法。
主要優(yōu)點是:對特征進行搜索時圍繞學(xué)習(xí)算法展開的,對特征選擇的標(biāo)準/規(guī)范是在學(xué)習(xí)算法的需求中展開的,能夠考慮學(xué)習(xí)算法所屬的任意學(xué)習(xí)偏差,從而確定最佳子特征,真正關(guān)注的是學(xué)習(xí)問題本身。由于每次嘗試針對特定子集時必須運行學(xué)習(xí)算法,所以能夠關(guān)注到學(xué)習(xí)算法的學(xué)習(xí)偏差/歸納偏差,因此包裹式方法能夠發(fā)揮巨大的作用。
主要缺點是:運行速度遠慢于過濾算法,實際應(yīng)用包裹式方法沒有過濾方法流行。
c.Embedded方法(嵌入式)
將特征選擇嵌入到模型訓(xùn)練中,其訓(xùn)練可能是相同模型,但是特征選擇完成后,還能給予特征選擇完成的特征和模型訓(xùn)練出的超參數(shù),再次訓(xùn)練優(yōu)化。
主要思想是:在模型既定情況下學(xué)習(xí)出對提高模型準確性最好的特征。也就是在確定模型的過程中,挑選出那些對模型的訓(xùn)練有重要意義的特征。
主要方法有:用帶有L1的正則化項完成特征選擇(也可以結(jié)合L2懲罰項來優(yōu)化)、隨機森林平均不純度減少法、平均精確度減少法。
主要優(yōu)點是:對特征進行搜索時圍繞學(xué)習(xí)算法展開的,能夠考慮學(xué)習(xí)算法所屬的任意學(xué)習(xí)偏差。對訓(xùn)練模型的次數(shù)小于Wrapper方法,比較節(jié)省時間。
主要缺點是:運行速度慢。
3)代碼實現(xiàn)——過濾式
a.Pearson相關(guān)系數(shù)
Pearson相關(guān)系數(shù)是一種最簡單的,能幫助理解特征和響應(yīng)變量之間關(guān)系的方法,該方法衡量變量之間的線性相關(guān)性。主要用于連續(xù)型特征的篩選,不適用于離散型特征的篩選。
優(yōu)點是:相關(guān)系數(shù)計算速度快、易于計算,經(jīng)常在拿到數(shù)據(jù)(經(jīng)過清洗和特征提取之后的)之后第一時間就執(zhí)行。Pearson相關(guān)系數(shù)能夠表征豐富的關(guān)系,符合表示關(guān)系的正負,絕對值能夠表示強度。
缺點是:相關(guān)系數(shù)作為特征排序機制,它只對線性關(guān)系敏感,如果關(guān)系是非線性的,即便兩個變量具有一一對應(yīng)的關(guān)系,相關(guān)系數(shù)也可能接近0。
代碼實現(xiàn)如下:
import numpy as np
from scipy.stats import pearsonr
np.random.seed(2019)
size=1000
x = np.random.normal(0, 1, size)
# 計算兩變量間的相關(guān)系數(shù)
print("Lower noise{}".format(pearsonr(x, x + np.random.normal(0, 1, size))))
print("Higher noise {}".format(pearsonr(x, x + np.random.normal(0, 10, size))))
b.最大信息系數(shù)(maximal information coefficient)
如果變量不是獨立的,那么我們可以通過考察聯(lián)合概率分布與邊緣概率分布乘積之間的Kullback-Leibler散度來判斷它們是否“接近”于相互獨立。
代碼實現(xiàn)如下:
x = np.random.normal(0,10,300)
z = x * x
pearsonr(x, z)
# 輸出-0.1
from minepy import MINE
m = MINE()
m.compute_score(x, z)
print(m.mic())
# 輸出1.0
c.距離相關(guān)系數(shù)(Distance correlation)
距離相關(guān)系數(shù)是為了克服Pearson相關(guān)系數(shù)的弱點而生的。距離相關(guān)系數(shù)計算公式如下:

代碼實現(xiàn)如下:
from scipy.spatial.distance importpdist, squareform
import numpy as np
from numbapro import jit, float32
def distcorr(X, Y):
? ?X = np.atleast_1d(X)
???Y = np.atleast_1d(Y)
???if np.prod(X.shape) == len(X):
???????X = X[:, None]
???if np.prod(Y.shape) == len(Y):
???????Y = Y[:, None]
???X = np.atleast_2d(X)
???Y = np.atleast_2d(Y)
???n = X.shape[0]
???if Y.shape[0] != X.shape[0]:
???????raise ValueError('Number of samples must match')
???a = squareform(pdist(X))
???b = squareform(pdist(Y))
???A = a - a.mean(axis=0)[None, :] - a.mean(axis=1)[:, None] + a.mean()
???B = b - b.mean(axis=0)[None, :] - b.mean(axis=1)[:, None] + b.mean()
???dcov2_xy = (A * B).sum()/float(n * n)
???dcov2_xx = (A * A).sum()/float(n * n)
???dcov2_yy = (B * B).sum()/float(n * n)
???dcor = np.sqrt(dcov2_xy)/np.sqrt(np.sqrt(dcov2_xx) * np.sqrt(dcov2_yy))
??? return dcor
d.卡方檢驗
卡方檢驗是一種用途很廣的計數(shù)資料的假設(shè)檢驗方法,由卡爾-皮爾遜提出??ǚ街得枋鰞蓚€事件的獨立性,或者描述實際觀察值與期望值的偏離程度。
卡方值越大,說明兩個變量越不可能是獨立無關(guān)的,也就是說卡方值越大,兩個變量的相關(guān)程度也越高。選擇合適的閾值,大于閾值的特征留下,小于閾值的特征刪除。這樣篩選出一組特征子集就是輸入模型訓(xùn)練的特征。只適用于分類問題中離散型特征篩選,不能用于分類問題中連續(xù)型特征的篩選,也不能用于回歸問題的特征篩選。
代碼實現(xiàn)如下:
#導(dǎo)入sklearn庫中的SelectKBest和chi2
from sklearn.feature_selection importSelectKBest ,chi2
#選擇相關(guān)性最高的前5個特征
X_chi2 = SelectKBest(chi2,k=5).fit_transform(X, y)
X_chi2.shape
輸出:(27, 5)
e.基于學(xué)習(xí)模型的特征排序(Model?based ranking)
這種方法的思路是直接使用機器學(xué)習(xí)算法,針對每個單獨的特征和響應(yīng)變量建立預(yù)測模型。如果特征與響應(yīng)變量之間的關(guān)系是非線性的,則有許多替代方案,例如基于樹的方法(決策樹和隨機森林)、擴展的線性模型等。基于樹的方法是最簡單的方法之一,因為它們可以很好地模擬非線性關(guān)系,無需太多調(diào)整。但是要避免的主要是過度擬合,因此樹的深度應(yīng)該相對較小,并且應(yīng)該應(yīng)用交叉驗證。
代碼實現(xiàn)如下:
from sklearn.cross_validation import cross_val_score,ShuffleSplit
from sklearn.datasets importload_boston
from sklearn.ensemble importRandomForestRegressor
#Load boston housing dataset as anexample
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
rf =RandomForestRegressor(n_estimators=20, max_depth=4)
scores = []
# 使用每個特征單獨訓(xùn)練模型,并獲取每個模型的評分來作為特征選擇的依據(jù)。
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]))
print(sorted(scores, reverse=True))
# 輸出:[(0.636, 'LSTAT'), (0.59, 'RM'), (0.472, 'NOX'), (0.369,'INDUS'), (0.311, 'PTRATIO'), (0.24, 'TAX'),(0.24, 'CRIM'), (0.185, 'RAD'), (0.16, 'ZN'), (0.087, 'B'), (0.062, 'DIS'), (0.036, 'CHAS'), (0.027, 'AGE')]
4)代碼實現(xiàn)——包裹式
a.線性模型與正則化
當(dāng)所有特征在相同尺度上時,最重要的特征應(yīng)該在模型中具有最高系數(shù),而與輸出變量不相關(guān)的特征應(yīng)該具有接近零的系數(shù)值。即使使用簡單的線性回歸模型,當(dāng)數(shù)據(jù)不是很嘈雜(或者有大量數(shù)據(jù)與特征數(shù)量相比),并且特征(相對)獨立時,這種方法也能很好地工作。
b.隨機森林選擇
隨機森林算法具有準確率高、魯棒性好、易于使用等優(yōu)點,這使得它成為了目前最流行的機器學(xué)習(xí)算法之一。隨機森林提供了兩種特征選擇的方法:mean decrease impurity和mean decrease accuracy。
平均不純度減少(mean?decrease impurity)
工作原理如下:
一是隨機森林由多顆CART決策樹構(gòu)成,決策樹中的每一個節(jié)點都是關(guān)于某個特征的條件,為的是將數(shù)據(jù)集按照不同的響應(yīng)變量一分為二。
二是CART利用不純度可以確定節(jié)點(最優(yōu)條件),對于分類問題,通常采用基尼不純度;對于回歸問日,通常采用的是方差或者最小二乘擬合。
三是當(dāng)訓(xùn)練決策樹的時候,可以計算出每個特征減少了多少樹的不純度。對于一個決策樹森林來說,可以算出每個特征平均減少了多少不純度,并把它平均減少的不純度作為特征選擇的標(biāo)準。
四是隨機森林基于不純度的排序結(jié)果非常鮮明,在得分最高的幾個特征之后的特征,得分急劇下降。
代碼實現(xiàn)如下:
from sklearn.datasets importload_boston
from sklearn.ensemble importRandomForestRegressor
import numpy as np
#Load boston housing dataset as anexample
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names =boston["feature_names"]
# 訓(xùn)練隨機森林模型,并通過feature_importances_屬性獲取每個特征的重要性分數(shù)。
rf = RandomForestRegressor()
rf.fit(X, Y)
print("Features sorted by theirscore:")
print(sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_), names), reverse=True))
平均精確度減少(mean?decrease accuracy)
工作原理如下:
一是通過直接度量每個特征對模型精確率的影響來進行特征選擇。
二是主要思路是打亂每個特征的特征值順序,并且度量順序變動對模型的精確率的影響。對于不重要的變量來說,打亂順序?qū)δP偷木_率影響不會太大;對于重要的變量來說,打亂順序就會降低模型的精確率。
代碼實現(xiàn)如下:
from sklearn.cross_validation importShuffleSplit
from sklearn.metrics import r2_score
from collections import defaultdict
X = boston["data"]
Y = boston["target"]
rf = RandomForestRegressor()
scores = defaultdict(list)
#crossvalidate the scores on a numberof different random splits of the data
for train_idx, test_idx inShuffleSplit(len(X), 100, .3):
???X_train, X_test = X[train_idx], X[test_idx]
???Y_train, Y_test = Y[train_idx], Y[test_idx]
???#使用修改前的原始特征訓(xùn)練模型,其acc作為后續(xù)混洗特征值后的對比標(biāo)準。
????r = rf.fit(X_train, Y_train)
????acc = r2_score(Y_test, rf.predict(X_test))
????#遍歷每一列特征
???for i in range(X.shape[1]):
???????X_t = X_test.copy()
???????#對這一列特征進行混洗,交互了一列特征內(nèi)部的值的順序
???????np.random.shuffle(X_t[:, i])
???????shuff_acc = r2_score(Y_test, rf.predict(X_t))
???????#混洗某個特征值后,計算平均精確度減少程度。
???????scores[names[i]].append((acc-shuff_acc)/acc)
print("Features sorted by theirscore:")
print(sorted([(round(np.mean(score), 4), feat) for feat, score in scores.items()], reverse=True))
5)代碼實現(xiàn)——嵌入式
a.穩(wěn)定性選擇(Stability Selection)
穩(wěn)定性選擇常常是一種既能夠有助于理解數(shù)據(jù),又能夠挑選出優(yōu)質(zhì)特征的這種選擇。
工作原理如下:
第一,穩(wěn)定性選擇是一種基于二次抽樣和選擇算法相結(jié)合較新的方法,選擇算法可以是回歸、SVM或其他類似的方法。
第二,它的主要思想是在不同的數(shù)據(jù)子集和特征子集上運行特征選擇算法,不斷的重復(fù),最終匯總特征選擇結(jié)果。比如可以統(tǒng)計某個特征被認為是重要特征的頻率(被選為重要特征的次數(shù)除以它所在的子集被測試的次數(shù))。
第三,理想情況下,重要特征的得分會接近100%。稍微弱一點的特征得分會是非0的數(shù),而最無用的特征得分將會接近于0。
代碼實現(xiàn)如下:
from sklearn.linear_model importRandomizedLasso
from sklearn.datasets importload_boston
boston = load_boston()
#using the Boston housing data.
#Data gets scaled automatically bysklearn's implementation
X = boston["data"]
Y = boston["target"]
names =boston["feature_names"]
rlasso = RandomizedLasso(alpha=0.025)
rlasso.fit(X, Y)
print("Features sorted by theirscore:")
print(sorted(zip(map(lambda x: round(x, 4), rlasso.scores_), names), reverse=True))
b.遞歸特征消除(Recursive Feature Elimination,RFE)
原理介紹如下:
第一,遞歸特征消除的主要思想是反復(fù)構(gòu)建模型(如SVM或者回歸模型),然后選出最好的(或者最差的)的特征(可以根據(jù)系數(shù)來選),把選出來的特征放到一邊,然后在剩余的特征上重復(fù)這個過程,直到所有特征都遍歷了。
第二,這個過程中特征被消除的次序就是特征的排序。因此,這是一種尋找最優(yōu)特征子集的貪心算法。
第三,RFE的穩(wěn)定性很大程度上取決于在迭代的時候底層用哪種模型。假如RFE采用的普通回歸,沒有經(jīng)過正則化的回歸是不穩(wěn)定的,那么RFE就是不穩(wěn)定的。假如RFE采用的是Ridge,而用Ridge正則化的回歸是穩(wěn)定的,那么RFE就是穩(wěn)定的。
代碼實現(xiàn)如下:
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names =boston["feature_names"]
# use linear regression as the model
lr = LinearRegression()
# rank all features, i.e continue the elimination until the last one
rfe = RFE(lr, n_features_to_select=1)
rfe.fit(X,Y)
print("Features sorted by their rank:")
print(sorted(zip(map(lambda x: round(x,4), rfe.ranking_), names)))
結(jié)果輸出:
Features sorted by their rank:
[(1, 'NOX'), (2, 'RM'), (3, 'CHAS'), (4, 'PTRATIO'), (5, 'DIS'),(6, 'LSTAT'), (7, 'RAD'), (8, 'CRIM'), (9, 'INDUS'), (10, 'ZN'),(11, 'TAX'), (12, 'B'), (13, 'AGE')]