一文歸納Python特征生成方法(全)

創(chuàng)造新的特征是一件十分困難的事情蛇耀,需要豐富的專業(yè)知識和大量的時(shí)間块茁。機(jī)器學(xué)習(xí)應(yīng)用的本質(zhì)基本上就是特征工程癣蟋。
——Andrew Ng

業(yè)內(nèi)常說數(shù)據(jù)決定了模型效果上限剥险,而機(jī)器學(xué)習(xí)算法是通過數(shù)據(jù)特征做出預(yù)測的聪蘸,好的特征可以顯著地提升模型效果。這意味著通過特征生成(即從數(shù)據(jù)設(shè)計(jì)加工出模型可用特征)表制,是特征工程相當(dāng)關(guān)鍵的一步健爬。
本文從特征生成作用、特征生成的方法(人工設(shè)計(jì)么介、自動化特征生成)展開闡述并附上代碼娜遵。

1 特征生成的作用

特征生成是特征提取中的重要一步,作用在于:

  • 增加特征的表達(dá)能力壤短,提升模型效果设拟;(如體重除以身高就是表達(dá)健康情況的重要特征,而單純看身高或體重對健康情況表達(dá)就有限久脯。)
  • 可以融入業(yè)務(wù)上的理解設(shè)計(jì)特征纳胧,增加模型的可解釋性;

2 數(shù)據(jù)情況分析

本文示例的數(shù)據(jù)集是客戶的資金變動情況帘撰,如下數(shù)據(jù)字典:

cust_no:客戶編號跑慕;I1 :性別;I2:年齡 摧找;E1:開戶日期核行;  
B6 :近期轉(zhuǎn)賬日期;C1 (后綴_fir表示上個(gè)月):存款蹬耘;C2:存款產(chǎn)品數(shù)芝雪; 
X1:理財(cái)存款; X2:結(jié)構(gòu)性存款综苔;  label:資金情況上升下降情況惩系。

這里安利一個(gè)超實(shí)用Python庫,可以一鍵數(shù)據(jù)分析(數(shù)據(jù)概況休里、缺失、相關(guān)性赃承、異常值等等)妙黍,方便結(jié)合數(shù)據(jù)分析報(bào)告做特征生成。

# 一鍵數(shù)據(jù)分析
import pandas_profiling

pandas_profiling.ProfileReport(df)

3 特征生成的方法

特征生成方法可以分為兩類:聚合方式瞧剖、轉(zhuǎn)換方式拭嫁。


3.1 聚合方式

聚合方式是指對存在一對多的字段可免,將其對應(yīng)多條記錄分組聚合后統(tǒng)計(jì)平均值、計(jì)數(shù)做粤、最大值等數(shù)據(jù)特征浇借。
如以上述數(shù)據(jù)集,同一cust_no對應(yīng)多條記錄怕品,通過對cust_no(客戶編號)做分組聚合妇垢,統(tǒng)計(jì)C1字段個(gè)數(shù)、唯一數(shù)肉康、平均值闯估、中位數(shù)、標(biāo)準(zhǔn)差吼和、總和涨薪、最大、最小值炫乓,最終得到按每個(gè)cust_no統(tǒng)計(jì)的C1平均值刚夺、最大值等特征。

# 以cust_no做聚合末捣,C1字段統(tǒng)計(jì)個(gè)數(shù)侠姑、唯一數(shù)、平均值塔粒、中位數(shù)结借、標(biāo)準(zhǔn)差、總和卒茬、最大船老、最小值
df.groupby('cust_no').C1.agg(['count','nunique','mean','median','std','sum','max','min'])

此外還可以pandas自定義聚合函數(shù)生成特征,比如加工聚合元素的平方和:

# 自定義分組聚合統(tǒng)計(jì)函數(shù)
def x2_sum(group):
    return sum(group**2)

df.groupby('cust_no').C1.apply(x2_sum)    

3.2 轉(zhuǎn)換方式

轉(zhuǎn)換方式是指對字段間做加減乘除等運(yùn)算生成數(shù)據(jù)特征的過程圃酵,對不同字段類型有不同轉(zhuǎn)換方式柳畔。

3.2.1 數(shù)值類型

  • 加減乘除
    多個(gè)字段做運(yùn)算生成新的特征,這通常需要結(jié)合業(yè)務(wù)層面的理解以及數(shù)據(jù)分布的情況郭赐,以生成較優(yōu)的特征集薪韩。


import numpy as np

# 前后兩個(gè)月資金和
df['C1+C1_fir'] = df['C1']+df['C1_fir']
# 前后兩個(gè)月資金差異
df['C1-C1_fir'] = df['C1']-df['C1_fir']
# 產(chǎn)品數(shù)*資金
df['C1*C2'] = df['C1']*df['C2']
# 前后兩個(gè)月資金變化率
df['C1/C1_fir'] = df['C1']/df['C1_fir']  - 1
df.head()
  • 多個(gè)列統(tǒng)計(jì)
    直接用聚合函數(shù)統(tǒng)計(jì)多列的方差、均值等


import numpy as np

df['C1_sum'] = np.sum(df[['C1_fir','C1']], axis = 1)
df['C1_var'] = np.var(df[['C1_fir','C1']], axis = 1)
df['C1_max'] = np.max(df[['C1_fir','C1']], axis = 1)
df['C1_min'] = np.min(df[['C1_fir','C1']], axis = 1)
df['C1-C1_fir_abs'] = np.abs(df['C1-C1_fir'])
df.head()
  • 排名編碼特征
    按特征值對全體樣本進(jìn)行排序捌锭,以排序序號作為特征值俘陷。這種特征對異常點(diǎn)不敏感,也不容易導(dǎo)致特征值沖突观谦。
# 排序特征

df['C1_rank'] = df['C1'].rank(ascending=0, method='dense')
df.head()

3.2.2 字符類型

  • 截取
    當(dāng)字符類型的值過多拉盾,通常可對字符類型變量做截取豁状,以減少模型過擬合捉偏。如具體的家庭住址倒得,可以截取字符串到城市級的粒度。

  • 字符長度
    統(tǒng)計(jì)字符串長度夭禽。如轉(zhuǎn)賬場景中霞掺,轉(zhuǎn)賬留言的字?jǐn)?shù)某些程度可以刻畫這筆轉(zhuǎn)賬的類型。

  • 頻次
    通過統(tǒng)計(jì)字符出現(xiàn)頻次讹躯。如欺詐場景中地址出現(xiàn)次數(shù)越多菩彬,越有可能是團(tuán)伙欺詐。

# 字符特征
# 由于沒有合適的例子蜀撑,這邊只是用代碼實(shí)現(xiàn)邏輯挤巡,加工的字段并無含義。

#截取第一位字符串
df['I1_0'] = df['I1'].map(lambda x:str(x)[:1])
# 字符長度
df['I1_len'] = df['I1'].apply(lambda x:len(str(x)))

display(df.head())
# 字符串頻次
df['I1'].value_counts()

3.2.3 日期類型

常用的有計(jì)算日期間隔酷麦、周幾矿卑、幾點(diǎn)等等。

# 日期類型
df['E1_B6_interval'] = (df.E1.astype('datetime64[ns]') - df.B6.astype('datetime64[ns]')).map(lambda x:x.days)
df['E1_is_month_end'] = pd.to_datetime(df.E1).map(lambda x :x.is_month_end)
df['E1_dayofweek'] = df.E1.astype('datetime64[ns]').dt.dayofweek
df['B6_hour'] = df.B6.astype('datetime64[ns]').dt.hour
df.head()

4 自動化特征生成

傳統(tǒng)的特征工程方法通過人工構(gòu)建特征沃饶,這是一個(gè)繁瑣母廷、耗時(shí)且容易出錯的過程。自動化特征工程是通過Fearturetools等工具糊肤,從一組相關(guān)數(shù)據(jù)表中自動生成有用的特征的過程琴昆。對比人工生成特征會更為高效,可重復(fù)性更高馆揉,能夠更快地構(gòu)建模型业舍。

4.1 FeatureTools上手

Featuretools是一個(gè)用于執(zhí)行自動化特征工程的開源庫,它有基本的3個(gè)概念:
1)Feature Primitives(特征基元):生成特征的常用方法升酣,分為聚合(agg_primitives)舷暮、轉(zhuǎn)換(trans_primitives)的方式∝眩可通過如下代碼列出featuretools的特征加工方法及簡介下面。

import featuretools as ft

ft.list_primitives()

2)Entity(實(shí)體) 可以被看作類似Pandas DataFrame, 多個(gè)實(shí)體的集合稱為Entityset。實(shí)體間可以根據(jù)關(guān)聯(lián)鍵添加關(guān)聯(lián)關(guān)系Relationship绩聘。

# df1為原始的特征數(shù)據(jù)
df1 = df.drop('label',axis=1)

# df2為客戶清單(cust_no唯一值)
df2 = df[['cust_no']].drop_duplicates()
df2.head()

# 定義數(shù)據(jù)集
es = ft.EntitySet(id='dfs')

# 增加一個(gè)df1數(shù)據(jù)框?qū)嶓w
es.entity_from_dataframe(entity_id='df1',         
             dataframe=df1,
             index='id',
             make_index=True)

# 增加一個(gè)df2數(shù)據(jù)實(shí)體
es.entity_from_dataframe(entity_id='df2',         
             dataframe=df2,
             index='cust_no')


# 添加實(shí)體間關(guān)系:通過 cust_no鍵關(guān)聯(lián) df_1 和 df 2實(shí)體
relation1 = ft.Relationship(es['df2']['cust_no'], es['df1']['cust_no'])
es = es.add_relationship(relation1)

3)dfs(深度特征合成) : 是從多個(gè)數(shù)據(jù)集創(chuàng)建新特征的過程沥割,可以通過設(shè)置搜索的最大深度(max_depth)來控制所特征生成的復(fù)雜性

## 運(yùn)行DFS特征衍生
features_matrix,feature_names = ft.dfs(entityset=es,
                                       target_entity='df2',
                                       relationships = [relation1],
                                       trans_primitives=['divide_numeric','multiply_numeric','subtract_numeric'],
                                       agg_primitives=['sum'],
                                       max_depth=2,n_jobs=1,verbose=-1)

4.2 FeatureTools問題點(diǎn)

4.2.1 內(nèi)存溢出問題
Fearturetools是通過工程層面暴力生成所有特征的過程,當(dāng)數(shù)據(jù)量大的時(shí)候凿菩,容易造成內(nèi)存溢出机杜。解決這個(gè)問題除了升級服務(wù)器內(nèi)存衅谷,減少njobs椒拗,還有一個(gè)常用的是通過只選擇重要的特征進(jìn)行暴力衍生特征。

4.2.2 特征維度爆炸
當(dāng)原始特征數(shù)量多会喝,或max_depth陡叠、特征基元的種類設(shè)定較大,F(xiàn)earturetools生成的特征數(shù)量巨大肢执,容易維度爆炸枉阵。這是就需要考慮到特征選擇、特征降維预茄,常用的特征選擇方法可以參考上一篇文章: Python特征選擇


注:本文源碼鏈接:【Github】兴溜。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耻陕,隨后出現(xiàn)的幾起案子拙徽,更是在濱河造成了極大的恐慌,老刑警劉巖诗宣,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膘怕,死亡現(xiàn)場離奇詭異,居然都是意外死亡召庞,警方通過查閱死者的電腦和手機(jī)岛心,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篮灼,“玉大人忘古,你說我怎么就攤上這事∽缬眨” “怎么了髓堪?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長娘荡。 經(jīng)常有香客問我干旁,道長,這世上最難降的妖魔是什么它改? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任疤孕,我火速辦了婚禮,結(jié)果婚禮上央拖,老公的妹妹穿的比我還像新娘祭阀。我一直安慰自己,他們只是感情好鲜戒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布专控。 她就那樣靜靜地躺著,像睡著了一般遏餐。 火紅的嫁衣襯著肌膚如雪伦腐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天失都,我揣著相機(jī)與錄音柏蘑,去河邊找鬼幸冻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咳焚,可吹牛的內(nèi)容都是我干的洽损。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼革半,長吁一口氣:“原來是場噩夢啊……” “哼碑定!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起又官,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤延刘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后六敬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碘赖,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年外构,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了崖疤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡典勇,死狀恐怖劫哼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情割笙,我是刑警寧澤权烧,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站伤溉,受9級特大地震影響般码,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乱顾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一板祝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧走净,春花似錦券时、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至说搅,卻和暖如春炸枣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工适肠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霍衫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓侯养,卻偏偏與公主長得像慕淡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子沸毁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容