要點
在常見的機器學習/深度學習項目里,數據準備占去整個分析管道的60%到80%。
市場上有各種用于數據清洗和特征工程的編程語言、框架和工具。它們之間的功能有重疊,也各有權衡。
數據整理是數據預處理的重要擴展。它最適合在可視化分析工具中使用,這能夠避免分析流程被打斷。
可視化分析工具與開源數據科學組件之間,如R、Python、KNIME、RapidMiner互為補充。
避免過多地使用組件能夠加速數據科學項目。因此,在數據準備步驟中利用流式獲取框架或流式分析產品會是一個不錯的選擇。
機器學習和深度學習項目在大多數企業中變得越來越重要。一個完整的項目流程包括數據準備(data preparation)、構建分析模型以及部署至生產環境。該流程是一個洞察-行動-循環(insights-action-loop),此循環能不斷地改進分析模型。Forrester把這個完整的流程和其背后的平臺稱為洞察平臺(Insights Platform)。
當你打算使用機器學習或深度學習技術來構建分析模型時,一個重要的任務是集成并通過各種數據源來準備數據集,這些數據源包括比如文件、數據庫、大數據存儲、傳感器或社交網絡等等。此步驟可占整個分析項目的80%。
本文比較了用于數據準備的幾種方法,它們分別是提取-變換-加載(extract-transform-load,ETL)批處理、流式獲取(streaming ingestion)和數據整理(data wrangling)。同時借助于先進的分析技術和開源框架(如R、Apache Spark、KNIME、RapidMiner),討論了各種不同的選擇及其折中。本文還討論了數據準備如何與可視化分析相關聯,以及不同用戶角色(如數據科學家或業務分析人員)應如何共同構建分析模型的最佳實踐。
數據準備是數據科學的核心。它包括數據清洗和特征工程。另外領域知識(domain knowledge)也非常重要,它有助于獲得好的結果。數據準備不能完全自動化,至少在初始階段不能。通常,數據準備占去整個分析管道(流程)的60%到80%。但是,為了使機器學習算法在數據集上獲得最優的精確性,數據準備必不可少。
數據清洗可使數據獲得用于分析的正確形狀(shape)和質量(quality)。它包括了許多不同的功能,例如:
基本功能(選擇、過濾、去重、...)
采樣(平衡(balanced)、分層(stratified)、...)
數據分配(創建訓練+驗證+測試數據集、...)
變換(歸一化、標準化、縮放、pivoting、...)
分箱(Binning)(基于計數、將缺失值作為其自己的組處理、...)
數據替換(剪切(cutting)、分割(splitting)、合并、...))
加權與選擇(屬性加權、自動優化、...)
屬性生成(ID生成、...)
數據填補(imputation)(使用統計算法替換缺失的觀察值)
特征工程會為分析選取正確的屬性。我們需要借助數據的領域知識來選取或創建屬性,這些屬性能使機器學習算法正確地工作。特征工程過程包括:
頭腦風暴或特征測試
特征選擇
驗證這些特征如何與模型配合使用
如果需要,改進特征
回到頭腦風暴/創建更多的特征,直到工作完成
請注意,特征工程已是建模(構建分析模型)步驟里的一部分,但它也利用數據準備這一功能(例如提取字符串的某些部分)。
數據清洗和特征工程是數據準備的一部分,也是機器學習和深度學習應用的基礎。這二者并不是那么容易,都需要花費功夫。
數據準備會出現在分析項目的不同階段:
數據預處理:從數據源獲取數據之后直接處理數據。通常由開發人員或數據科學家實現,它包括初始轉換、聚合(aggregation)和數據清洗。此步驟在數據的交互式分析開始之前完成。它只執行一次。
數據整理:在交互式數據分析和建模期間準備數據。通常由數據科學家或業務分析師完成,以便更改數據集和特征工程的視圖。此步驟會迭代更改數據集的形狀,直到它能很好地查找洞察或構建良好的分析模型。
讓我們看一看典型的用于模型構建的分析流程:
數據訪問
數據預處理
探索性數據分析(Exploratory Data Analysis)(EDA)
模型構建
模型驗證
模型執行
部署
步驟2的重點是在構建分析模型之前進行的數據預處理,而數據整理則用于步驟3和步驟4(在分析數據和構建模型時,數據整理允許交互式調整數據集)。注意,這三個步驟(2、3、4)都可以包括數據清洗和特征工程。
以下截圖是“數據準備”、“數據預處理”和“數據整理”這幾個術語的Google搜索趨勢。可以看出,數據整理受到了越來越多的關注:
圖1:“數據準備”、“數據預處理”和“數據整理”的Google搜索趨勢
“inline數據整理”(inline data wrangling)是“數據整理”的一種特殊形式。在inline數據整理里,你可以利用可視化分析工具。這些工具不僅能用于可視化和模型構建,而且還能用于直接交互式整理。inline數據整理有巨大的優勢,如下圖所示:
圖2:解耦數據預處理(decoupled data preprocessing)與inline數據整理的比較
分析管道中的數據預處理和數據整理步驟通常由不同類型的用戶完成。以下是參與分析項目的各種用戶角色:
業務分析師:具有特定領域知識的商業/行業專家
數據科學家:數學、統計與編程(數據科學/腳本編寫)專家;能夠編寫底層代碼或使用更上層的工具
平民數據科學家(Citizen Data Scientist):類似于數據科學家,但處于更上層;需要使用更上層的工具而非編寫代碼;取決于工具的易用性,相關工作甚至可以由業務分析師來完成
開發者:軟件開發專家(企業應用程序)
這些用戶必須密切合作,以便在數據科學項目中取得成功(另見“如何避免分析中的反模式:機器學習的三個要點”,這篇文章能幫你更好地了解這些用戶角色)。
雖然本文重點是介紹數據準備,但一圖勝千言,并且人類只能解釋直觀可見的東西而非那些復雜的非結構化數據集,因此了解數據準備與可視化分析的關系也非常重要。有關更多細節,請參閱文章為什么應該使用可視化分析來做出更好的決策。目前主要的可視化分析工具有Qlik、Tableau和TIBCO Spotfire。
那么可視化分析是如何與數據整理相關聯的呢?RITO研究公司的首席分析師說,“讓分析師停下他們手里正在進行的工作,而去切換到另一個工具是令人發狂的。這破壞了他們的工作流程。 他們不得不返回重拾思路,重新開始。這嚴重影響了他們的生產力和創造力”。
以下章節給出了數據準備的幾種備選方案。我們將用非常著名的Titanic數據集(來自于Kaggle)來演示一些實用的例子。Titanic數據集被分為訓練集和測試集,它將用于構建分析模型,這些模型用來預測哪個乘客可能會存活或死亡:
圖3:Kaggle Titanic數據集的元數據
圖4:Kaggle Titanic數據集的數據行示例
原始數據集不能直接用于構建分析模型。它含有重復、缺失值以及包含各種不同信息的單元格。因此,在應用機器學習算法時,需要先將原始數據集處理好,以便獲得最佳結果。以下是一些數據清洗和特征工程的例子:
通過特征提取(feature extraction)創建新列:獲取每位乘客的姓名前綴,從而推斷出其性別,例如,先生、夫人、小姐、大師
通過聚合創建新列,以查看每位乘客的旅行團中有多少人:“家庭大小= 1 + SibSp + Parch”
通過提取第一個字符來創建新列,以便排序和分析艙室:提取“艙室”列的第一個字符
刪除數據集中的重復項,例如,乘客既在訓練集中又在測試集中
通過填補將數據添加到空單元格,以便能夠處理數據缺失的行,例如,年齡:將“不可用”替換為所有乘客的平均年齡或將其離散到對應的箱(bin)中;艙室:用“U”(未知)替換空值;或應用高級填補方法,例如,通過鏈式方程的多重填補(multiple imputation by chained equations)(MICE)
利用數據科學功能,例如,縮放、歸一化、主成分分析(PCA)或Box-Cox,使所有數據處于“相似形狀”,以便能夠進行合理的分析
以下章節闡述了各種編程語言、框架和數據準備工具。請注意,沒有哪種方案適用于所有問題。此外,這些方案之間也有很多重疊(overlapping)。因此,根據用戶角色和用例,許多問題可以使用不同的方案來解決。
一些編程語言是專為數據科學項目而設計,或者是對它有非常好的支持,特別是R和Python。它們包含了機器學習算法的各種實現,諸如過濾或提取的預處理功能,以及諸如縮放、歸一化或混洗(shuffle)的數據科學功能。數據科學家需要編寫相對底層的代碼來進行探索性數據分析與準備。與使用Java或C#的傳統編程相反,使用R或Python進行數據預處理時,你不需要編寫太多的代碼;它更多地是讓你了解統計概念以及算法的數據和經驗,這些數據和經驗可用于數據預處理和模型構建。
這些編程語言是為數據科學家準備數據和構建分析模型而建立,它們并不適用于企業部署(將分析模型部署到具有高規模和高可靠性的新數據中)。因此,市場上提供了商業的enterprise runtime幫助你實現企業部署。通常,它們支持相同的源代碼,因此你不需要為企業部署重寫任何東西。對于R,你可以使用開源的Microsoft R Open(之前的Revolution R),或TIBCO Enterprise Runtime for R。后者具有不受GPL開源許可證限制的優勢,因此你可以使用在任何嵌入式或外部環境里。
下面的代碼摘錄于一個不錯的R教程,它演示了如何使用基本的R語言來預處理和分析Titanic數據集:
### 使用基本的R語言進行數據預處理:# 存活是“是/否”# =>類型轉換:沒有numeric值和對應的數據處理/分析data.combined$Survived <- as.factor(data.combined$survived)#="" 從全稱里解析出姓和頭銜data.combined[1:25,="" 'name']name.splits="">-><- str_split(data.combined$name,="" ',')name.splits[1]last.names="">-><- sapply(name.splits,="" '[',="" 1)last.names[1:10]#="" 特征工程:創建家庭大小特征#(兄弟姐妹/配偶+父母/孩子+1)temp.sibsp="">-><- c(train$sibsp,="" test$sibsp)temp.parch="">-><- c(train$parch,="" test$parch)data.combined$familysize="">-><- as.factor(temp.sibsp="" +="" temp.parch="" +="">->
除了對預處理的基本支持外,這些編程語言還提供了許多額外的數據科學軟件包。例如,許多數據科學家利用R中非常強大的caret包來簡化數據準備和減少代碼量。該軟件包簡化了復雜回歸和分類問題的模型準備與訓練過程。它為數百個現有的R模型實現(在底層使用了各種各樣的API)提供了一個通用接口。以下代碼段使用了caret的通用API對Titanic數據集進行預處理:
### 使用R caret包進行數據預處理:# 利用caret的preProcess函數對數據做歸一化preproc.data.combined <- data.combined[,="" c('ticket.party.size',="" 'avg.fare')]preproc="">-><- preprocess(preproc.data.combined,="" method="c('center'," 'scale'))#="" -="">你看到的是相對值而非絕對值(即彼此之間的關系):postproc.data.combined <- predict(preproc,="">->->
另一個用于數據預處理的R包是dplyr包。它不像caret包那樣強大,并且只專注于操作、清洗和匯總(summarize)非結構化數據。 Dplyr旨在為數據操作的每個基本動作都提供一個函數:
filter()(和slice())arrange()select()(和rename())distinct()mutate()(和transmute())summarise()sample_n (和sample_frac())
因此,學習和理解許多數據操作任務變得容易。對于data.table包也是這樣。正如你所見的,在R語言里你有許多方法來預處理數據集。
諸如R或Python這樣的編程語言可用于處理小數據集。但是,它們并不是為處理真正的大數據集而創建;與此同時,我們經常需要分析幾個GB、TB甚至PB級別的數據。類似于Apache Hadoop或Apache Spark的大數據框架則是為處于邊緣的(即數據所在位置)彈性擴展(elastic scalability)和數據預處理而創建。
這些大數據框架側重于“底層”編碼,并且配置起來比R或Python環境要復雜得多。商業軟件,如Hortonworks、Cloudera、MapR或Databricks可以幫助解決此問題。通常,數據科學家與開發人員相互合作來完成大數據項目。后者負責集群配置、部署和監控,而數據科學家則利用R或Python API編寫用于數據預處理和構建分析模型的代碼。
源代碼通常看起來與僅使用R或Python的代碼非常相似,但數據預處理是在整個集群上并行完成的。下面的示例演示了如何使用Spark的Scala API對Titanic數據集進行預處理和特征工程:
### 使用Scala和Apache Spark API進行數據預處理:# 特征工程:創建家庭大小特征# (兄弟姐妹/配偶+父母/孩子+1)val familySize: ((Int, Int) => Int) = (sibSp: Int, parCh: Int) => sibSp + parCh + 1val familySizeUDF = udf(familySize)val dfWithFamilySize = df.withColumn('FamilySize', familySizeUDF(col('SibSp'), col('Parch')))// 為年齡列填充空值val avgAge = trainDF.select('Age').union(testDF.select('Age')) .agg(avg('Age')) .collect() match { case Array(Row(avg: Double)) => avg case _ => 0}
當然,你可以使用Spark的Java或Python API做同樣的事情。
通常,你想要敏捷并且快速得到結果。這常常需要在準備和分析數據集時大量地試錯。你可以利用現存的各種快捷易用的數據科學工具。這些工具提供了:
開發環境和運行/執行服務器
使用拖放與代碼生成的可視化“編碼”
集成各種數據科學框架,如R、Python或更強大的(諸如Apache Hadoop、Apache Spark或底層的H2O.ai)大數據框架
數據科學家可以使用這些工具來加速數據預處理和模型建立。此外,該類工具還幫助解決了數據預處理和機器學習算法的實現,因此沒有太多項目經驗的平民數據科學家也可以使用它們。一些工具甚至能夠提出建議,這些建議有助于用戶預處理、顯示和分析數據集。這些工具在底層人工智能的驅動下變得越來越智能。
下面的例子展示了如何使用兩個開源數據科學工具KNIME和RapidMiner來預處理Titanic數據集:
使用KNIME來預處理Titanic數據集
使用RapidMiner來預處理Titanic數據集
你可以使用可視化IDE來配置預處理,而非如前所述的用R或Scala編寫源代碼。對大多數用戶來說,這使得數據準備和分析變得更容易,并且數據的維護和移交也變得更容易。
數據整理(有時也稱為data munging)是一種使用圖形工具的數據準備方法,該方法簡單直觀。這些工具側重于易用性和敏捷的數據準備。因此,它不一定由開發人員或數據科學家完成,而是所有的用戶都可以(包括業務分析師或平民數據科學家)。DataWrangler和Trifacta Wrangler是數據整理的兩個示例。
用于數據整理的Trifacta
請注意,這些工具沒有數據預處理框架那么強大,因此它們經常用于數據準備的最后一公里。它們不會替換其它的集成選項,如ETL(提取-變換-加載)工具,或使用R、Python、KNIME、RapidMiner等進行的數據預處理。
如引言中所討論,因為數據整理與實際數據分析相互解耦,所以數據整理自身的工具可能會存在一些不足之處。可視化分析工具中的數據整理允許在數據的探索性分析期間進行inline數據整理。單個的用戶使用單一的工具就能夠完成它。例如,請參閱TIBCO Spotfire示例,它結合了可視化分析與inline數據整理(以及其它的數據科學功能來構建分析模型):
可視化分析工具TIBCO Spotfire中的inline數據整理
數據整理工具和帶有inline數據整理的可視化分析工具可以被每種用戶角色使用:業務分析師、(平民)數據科學家或開發人員,這些工具能夠加速數據準備和數據分析。
本文重點介紹了用于建立機器學習模型的數據準備。你可以使用編程語言(如R或Python)、數據科學工具(如KNIME或RapidMiner)、數據整理(使用DataWrangler或Trificata)或inline數據整理(通過TIBCO Spotfire)。通常,在開始這一切之前,你需要能夠訪問你擁有的所有數據,這些數據存儲于各種或多或少整理過的數據源中(如關系數據庫、數據倉庫、大數據集群)。因此,在以下兩部分,我們將簡要介紹用于數據獲取(data ingestion)的ETL和流式分析工具,通常數據獲取還包括數據準備的某些部分,特別是數據聚合和數據清洗。
ETL工具是為開發者集成各種數據源而設計的,它包括了許多遺留和專有(proprietary)接口(如Mainframe或EDIFACT接口),這些接口具有十分復雜的數據結構。它還包括了數據清洗(在上下文中通常被稱為“數據質量”工具),并將重點放在易用性和使用可視化編碼的企業部署上(類似于如KNIME或RapidMiner的數據科學工具,但是專注于ETL和數據質量)。它們還支持大數據框架,如Apache Hadoop和Apache Spark。此外,它們還為質量改進提供了開箱即用(out-of-the-box )的支持,例如,地址驗證。ETL和DQ通常在長時間運行的批處理進程中實現,因此如果你需要使用實時數據構建模型,那么這有時可能會產生負面影響。
ETL和DQ工具的例子是一些開源工具,如Pentaho或Talend,或專有供應商Informatica。市場正在向更簡單易用的Web用戶界面轉移,這些簡單易用的界面能夠讓其他用戶角色也執行一些基本的任務。
數據獲取與流式分析工具可用于在流(stream)中添加和預處理數據。這些框架允許批量地或實時地預處理數據。下圖展示了一個典型的流式分析流程,它包括數據獲取、預處理、分析、處理和輸出:
流式分析流程的步驟
目前市場上有各種各樣的框架和工具。它們都以這種或那種方式支持類似Hadoop或Spark的大數據框架。舉幾個例子:
數據獲取開源框架(僅關注數據獲取和預處理步驟):Apache NiFi、StreamSets、Cask Hydrator
流式處理開源框架(完整的流式分析流程):Apache Storm、Apache Flink、Apache Apex
流式處理商業軟件(完整的流式分析流程):Software AG Apama、IBM Streams、TIBCO StreamBase
使用這些工具(包括ETL)的巨大優勢是,你可以使用同一套工具或框架(對歷史數據)進行數據預處理,以及(對新數據)進行實時處理(以便在變化的數據里使用分析模型)。這將會是一個不錯的選擇,用戶不僅可以保持小而精的工具集,而且還能通過一套工具同時獲得ETL/獲取和實時處理。下圖是一個使用TIBCO StreamBase對Titanic數據集進行預處理的例子:
Titanic數據集的流式預處理
對于數據獲取和ETL工具,流式分析的市場正在轉向更簡單的Web用戶界面,這些簡單的用戶界面讓其他用戶角色也能執行一些基本的任務。但這不會取代現有的工具在更高級別用例里的使用,而是為分析師或數據科學家提供了新的選擇。在沒有開發人員的幫助下,他們能夠更容易和更直接地部署一些規則、關聯或分析模型。
使用機器學習或深度學習技術構建分析模型并不容易。數據準備占去整個分析管道的60%到80%。市場上有各種用于數據清洗和特征工程的編程語言、框架和工具。它們之間的功能有重疊,也各有權衡。
數據整理是數據預處理的重要擴展(add-on)。它最適合在可視化分析工具中使用,這能夠避免分析流程被打斷。可視化分析工具與開源數據科學組件(component)之間,如R、Python、KNIME、RapidMiner互為補充。
避免過多地使用組件能夠加速數據科學項目。因此,在數據準備步驟中利用流式獲取框架或流式分析產品會是一個不錯的選擇。我們只需要編寫一次預處理的步驟,然后將其用于歷史數據的批處理中,從而進行分析模型的構建,同時,還可以將其用于實時處理,這樣就能將我們構建的分析模型用到新的事件中。
Kai W?hner,TIBCO軟件的技術傳播者和社區管理者,TIBCO軟件是市場上領先的集成和分析中間件提供商。他主要的專業領域包括大數據、高級分析、機器學習、集成、SOA、微服務、BPM、云、物聯網和編程語言(如Java EE、Groovy或Golang)。他經常在其博客網站上撰寫關于新技術的博客、文章和會議演講。