本文經(jīng)授權轉載自AI科技大本營(ID:rgznai100)
如今機器學習,正在從人工設計模型,更多地轉移到自動優(yōu)化工作流中,如 H20、TPOT 和 auto-sklearn 等工具已被廣泛使用。
這些庫以及隨機搜索等方法,都致力于尋找最適合數(shù)據(jù)集的模型,以此簡化模型篩選與調優(yōu)過程,而不需要任何人工干預。
然而,特征工程作為機器學習過程中,最有價值的一個環(huán)節(jié),卻幾乎一直由人工來完成。
在本文中,我們通過引用一個數(shù)據(jù)集作為例子,來給大家介紹基礎知識,并給大家介紹一個基于 Featuretools Python 庫,來實現(xiàn)特征工程自動化的實例。
前言
特征工程也可以稱作特征構造,是基于現(xiàn)有數(shù)據(jù)構造新特征,來訓練機器學習模型的過程。可以說這個環(huán)節(jié),比我們具體使用什么模型更重要,因為機器學習算法,只會基于我們提供給它的數(shù)據(jù)進行學習,所以構造與目標任務相關的特征是極其重要的(詳見論文「A Few Useful Things to Know about Machine Learning」)。
論文鏈接:
https://homes.cs.washington.edu/~pedrod/papers/cacm12.pdf
一般來說,特征工程是一個漫長的人工過程,依賴于領域知識、直覺及數(shù)據(jù)操作。這一過程是極其單調的,而且最終的特征結果,會受人的主觀性和時間所限制。
自動特征工程,旨在幫助數(shù)據(jù)科學家,基于數(shù)據(jù)集自動地構造候選特征,并從中挑選出最適合于訓練的特征。
特征工程基礎知識
特征工程意味著,基于現(xiàn)有數(shù)據(jù)構造額外的特征,這些待分析的數(shù)據(jù),往往分布在多張相關聯(lián)的表中。特征工程需要從數(shù)據(jù)中提取信息,然后將其整合成一張單獨的表,用來訓練機器學習模型。
特征構造是一個非常耗時的過程,因為每個新特征,都需要經(jīng)過幾個步驟去構造,特別是那些需要用到多張表信息的特征。
我們可以把這些特征構造的操作合起來,分成兩個類:“轉換(transformation)”和“聚合(aggregation)”。下面我們通過幾個例子來理解一下這些概念。
“轉換”適用于單張表格,這個環(huán)節(jié)基于一個或多個,現(xiàn)有數(shù)據(jù)列構造新的特征。例如,現(xiàn)在我們有下面這張客戶數(shù)據(jù)表:
我們可以通過查找 joined 列的月份、或對 income 列取自然對數(shù),來構造新特征。這些都屬于“轉換”操作,因為它們都只用了,來自一張表的信息。
另一方面,“聚合”是需要進行跨表操作的,并且要基于一對多的關系,來把觀測值分組,然后進行數(shù)據(jù)統(tǒng)計。
例如,如果我們有另一張,關于客戶貸款信息的表格,其中每位客戶可能有多筆貸款,那么我們就可以計算,每位客戶貸款額的平均值、最大值和最小值等統(tǒng)計量了。
這一過程,包括根據(jù)不同用戶,對貸款數(shù)據(jù)表進行分組,計算聚合后的統(tǒng)計量,然后把結果整合到客戶數(shù)據(jù)中。以下是我們在 Python 中用 Pandas 執(zhí)行此過程的代碼:
這些操作本身并不難,但如果我們有上百個變量,它們分布在幾十張表中,若要手動完成這一過程,就比較困難了。
理想情況下,我們想找到一個解決方案,可以自動執(zhí)行多個表的轉換和聚合,并將結果數(shù)據(jù)整合到一張表中。雖然 Pandas 是非常棒的資源,但需要我們手動完成的數(shù)據(jù)操作工作量,仍非常巨大!
特征工具(Featuretools)
幸運的是,特征工具正是我們在找的解決方案。這個開源的 Python 庫,可以基于一組相關的表自動創(chuàng)建特征。
特征工具以“深度特征合成(Deep Feature Synthesis,簡稱 DFS)”為基礎,這個方法聽起來,比它本身要高級很多(之所以叫“深度特征合成”,不是因為使用了深度學習,而是疊加了多重特征)。
深度特征合成疊加了多重轉換和聚合操作,這在特征工具詞庫中被稱作特征基元 (feature primitives),用于通過多張表的數(shù)據(jù)來構造特征。
和機器學習中的大多數(shù)方法一樣,這是一個以簡單概念為基礎的復雜方法。通過每次學習一個構造塊,我們就可以很好地,理解這個強大的方法。
首先,我們來看一下例子中的數(shù)據(jù)。我們已經(jīng)看到上面提到的部分數(shù)據(jù)集,全部的表如下所示:
如果我們有一個機器學習任務,比如預測某位客戶是否會還清未來的一筆貸款,我們需要把有關客戶的所有信息都整合到一張表中。這些表通過變量 client_id 和 loan_id 相互關聯(lián),我們可以用一系列轉換和聚合來手動完成這一過程。然而我們很快就會發(fā)現(xiàn),我們可以使用特征工具來將這個過程自動化。
實體與實體集
首先要介紹特征工具的兩個概念:實體 (entity) 和實體集 (entityset)。簡單來說,一個實體就是一張表(即 Pandas 中的一個 DataFrame)。一個實體集是指多個表的集合以及它們之間的相互關系。我們可以把實體集看作一種 Python 的數(shù)據(jù)結構,且有其專屬的方法和屬性。
我們可以在特征工具中創(chuàng)建一個空的實體集,如下所示:
現(xiàn)在我們要把多個實體進行合并。每個實體必須帶有一個索引,即所有元素都唯一的數(shù)據(jù)列。也就是說,索引列中的每個值在表中只能出現(xiàn)一次。
clients 數(shù)據(jù)框(dataframe)的索引是 client_id,因為每位客戶都只對應表中的一行數(shù)據(jù)。我們可以通過如下語法把一個帶有索引的實體加入一個實體集:
loans 數(shù)據(jù)框也有唯一索引 loan_id,將其加入實體集的語法和處理 clients 的語法相同。然而,payments 數(shù)據(jù)框中沒有唯一的索引。若我們想把這個實體加入實體集,則需要讓 make_index = True,并指定一個索引名。雖然特征工具可以自動推斷實體中每一列的數(shù)據(jù)類型,但我們也可以通過把數(shù)據(jù)類型字典傳入?yún)?shù) variable_types 來將其覆蓋。
對于這個數(shù)據(jù)框,雖然 missed 是整數(shù),但并不是數(shù)值變量,因為它只能取兩個離散值,所以我們讓特征工具將其當作一個類別變量處理。將數(shù)據(jù)框全部加入實體集后,我們看到:
根據(jù)我們指定的修正方案,這些列的類型都被正確識別了。下一步,我們需要指定實體集中各個表之間的關聯(lián)。
表之間的關聯(lián)
研究兩表之間關系的最好方法是與父子關系進行類比。這是一種一對多的關系:每位父親可能有多個孩子。從表的角度來看,父表中的每一行對應一位父親,但子表可能有多行數(shù)據(jù),就像同一位父親的多個孩子。
例如,在我們的數(shù)據(jù)集中,clients 是 loans 的父表。每位客戶只對應 clients 表中的一行數(shù)據(jù),但可能對應 loans 表中的多行數(shù)據(jù)。同樣,loans 是 payments 的父表,因為每筆貸款可能包含多筆支付。父表通過共有的變量與子表相連接。當執(zhí)行聚合操作時,我們根據(jù)父表的變量對子表進行歸類,并計算每個子表的統(tǒng)計量。
若要標明特征工具中的關聯(lián),我們只需指定連接兩張表的變量。表 clients 和表 loans 是通過變量 client_id 相關聯(lián)的,表 loans 和表 payments 通過 loan_id 相關聯(lián)。可通過如下語法創(chuàng)建關聯(lián)并將其加入實體集:
該實體集現(xiàn)在包括三個實體以及連接這些實體之間的關系。加入實體并標明關聯(lián)后,我們的實體集就完整了,并做好了構造新特征的準備。
特征基元
在正式進行深度特征合成之前,我們需要理解特征基元這個概念。我們已經(jīng)知道了特征基元是什么,但也只是了解用什么名字來稱呼它們。下面是我們構造新特征時的基本操作:
在特征工具中,我們可以通過單個基元或者疊加多個基元來構造新特征。下面是特征工具中一些特征基元的列表(我們也可以自定義基元):
特征基元
這些基元可以拿來單獨使用或者結合起來構造新的特征。根據(jù)特定的基元,我們可以使用 ft.dfs 函數(shù)(即深度特征合成)來構造特征。我們將所選的 trans_primitives(轉換)和 agg_primitives(聚合)傳入 entityset(實體集)和 target_entity(目標實體),即我們想要添加特征的表:
得到的結果是一個含有新特征的客戶數(shù)據(jù)框(因為我們把用戶當作了 target_entity)。例如,若我們知道每位用戶加入的月份,這可以作為一個轉換特征基元:
我們也有許多聚合基元,如每位客戶的平均支付額:
雖然我們只列舉了一部分特征基元,但實際上特征工具通過結合與疊加這些基元構造了許多新的特征。
完整的數(shù)據(jù)框包含了793個新特征。
深度特征合成
現(xiàn)在我們已經(jīng)做好理解深度特征合成的全部準備了。實際上,我們在之前執(zhí)行函數(shù)時已經(jīng)使用過深度特征合成了!深度特征是指通過疊加多個基元得到的特征,深度特征合成是指構造這些特征的過程。一個深度特征的深度是為構造這個特征所使用的基元數(shù)目。
例如,MEAN(payments.payment_amount) 列是一個深度為 1 的深度特征,因為它在構造過程中只使用了一個聚合基元。LAST(loans(MEAN(payments.payment_amount)) 是一個深度為 2 的特征,它由兩個聚合基元疊加構成:將 LAST 疊加在了 MEAN 上。這個特征代表客戶最近一筆支付額的平均值。
我們可以疊加特征到任何想達到的深度,但事實上,我從來沒有用過深度超過 2 的特征。關于這一點很難解釋清楚,但我鼓勵感興趣的人嘗試更進一步的探索。
我們無需手動指定特征基元,特征工具可以幫助我們自動選擇特征。為此,我們同樣使用 ft.dfs 函數(shù)來調用但無需傳入任何特征基元:
特征工具構造了許多供我們使用的新特征。雖然這一過程可以自動構造新特征,但它不會取代數(shù)據(jù)科學家的位置,因為我們還要清楚如何使用這些特征。例如,如果我們的目標是預測某位客戶是否會償還貸款,那么我們要找出與指定結果相關度最高的特征。此外,如果我們有領域知識,則可以利用領域知識來選出特定的特征基元,或通過深度特征合成從候選特征中得到種子特征。
下一步
自動特征工程解決了一個問題,但也制造了另一個問題:特征過多。雖然在擬合模型前我們很難說哪些特征是重要的,但肯定不是所有特征都與目標任務相關。而且,特征過多可能會導致模型性能很差,因為不那么重要的特征會影響到那些更重要的特征。
由特征過多導致的問題又被公認為“維度的詛咒”。對于模型來說,特征數(shù)量上升了(即數(shù)據(jù)維度增加了),學習特征和目標之間的映射規(guī)則也會變得更加困難。實際上,使模型有良好表現(xiàn)所需的數(shù)據(jù)量與特征數(shù)目呈指數(shù)關系。
“維度的詛咒”可以通過特征降維(也被稱為特征選擇)來減輕:這是一個剔除不相關特征的過程。我們可以通過多種途徑實現(xiàn):主成分分析 (PCA)、SelectKBest、使用模型的特征重要性或使用深度神經(jīng)網(wǎng)絡來自動編碼。和今天要探討的內容相比,特征降維應該另起一篇文章來單獨討論更合適。到現(xiàn)在為止,我們已經(jīng)知道如何使用特征工具,從諸多數(shù)據(jù)表中輕松構造大量的特征了!
總結
同機器學習中的許多主題一樣,基于特征工具的自動特征工程是一個以簡單概念為基礎的復雜方法?;趯嶓w集、實體和關聯(lián)等概念,特征工具可以通過深度特征合成來構造新的特征。深度特征合成將包含了表間一對多關聯(lián)的“聚合”特征基元依次疊加,“轉換”函數(shù)被用于單張表中的一列或多列數(shù)據(jù),以此來從多張表中構造新的特征。
在之后的文章中,AI科技大本營也會介紹在實際應用(如 Kaggle 競賽)中如何使用這項技術。模型的好壞取決于我們?yōu)樗峁┑臄?shù)據(jù),而自動特征工程有助于使特征構造過程的效率更高。希望本文介紹的自動特征工程可以幫到大家。
關于特征工具的更多信息,包括更高級的應用方法,可以查看在線文檔。
原文鏈接:https://towardsdatascience.com/automated-feature-engineering-in-python-99baf11cc219
聯(lián)系客服