search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

為什麼需要清洗數據

大數據、數據挖掘、機器學習和可視化,近來計算界的幾件大事好像總也繞不開數據這個主角。從統計學家到軟體開發人員,再到圖形設計師,一下子所有人都對數據科學產生了興趣。便宜的硬體、可靠的處理工具和可視化工具,以及海量的免費數據,這些資源的彙集使得我們能夠比以往任何一個時期更加精準地、輕鬆地發現趨勢、預測未來。

不過,你可能還未聽說過的是,數據科學的這些希望與夢想都建立在亂七八糟的數據之上。在正式應用於我們認為是數據科學的核心的演算法和可視化之前,這些數據往往需要經過遷移、壓縮、清洗、打散、分片、分塊以及其他多種轉換處理。

本章內容將涵蓋以下幾個方面:

  • 關於數據科學的六個簡單處理步驟,包含數據清洗
  • 與數據清洗有關的參考建議
  • 對數據清洗有幫助的工具
  • 一個關於如何將數據清洗融入整個數據科學過程的入門示例
1新視角

最近我們讀報時發現《紐約時報》將數據清洗稱為看門人工作,並稱數據科學家百分之八十的時間都花費在了這些清洗任務上。從下圖中我們可以看出,儘管數據清洗是很重要的工作,但它並沒有像大數據、數據挖掘或是機器學習那樣真正地引起公眾的注意。

不會真的有人因為沒有見過人們聚眾討論看門人的工作多麼有趣、多麼酷而開始評頭論足吧?說起來還真是慚愧,這工作沒比做家務強到哪裡去,但話又說回來,與其對它棄之不理、抱怨不斷、惡語相加,還不如先把活兒幹完,這能讓我們過得更好些。

還不相信是嗎?那讓我們打個比方,你不是數據看門人,而是數據大廚。現在有人交給你一個購物籃,裡面裝滿了你從未見過的各種各樣的漂亮蔬菜,每一樣都產自有機農場,並在最新鮮的時候經過人工精挑細選出來。多汁的西紅柿,生脆的萵苣,油亮的胡椒。你一定激動地想馬上開啟烹飪之旅,可再看看周圍,廚房里骯髒不堪,鍋碗瓢盆上儘是油污,還沾著大塊叫不出名的東西。至於廚具,只有一把銹跡斑斑的切刀和一塊濕抹布。水槽也是破破爛爛的。而恰恰就在此時,你發現從看似鮮美的萵苣下面爬出了一隻甲蟲。

即使是實習廚師也不可能在這樣的地方烹飪。往輕了說,無外乎是暴殄天物,浪費了一籃子精美的食材。如果嚴重點兒講,這會使人致病。再說了,在這種地方烹飪根本毫無樂趣可言,也許全天的時間都得浪費在用生鏽的破刀切菜上面。

與廚房的道理一樣,事先花費些時間清洗和準備好數據科學工作區、工具和原始數據,都是值得的。「錯進,錯出。」這句源於上20世紀60年代的計算機編程箴言,對如今的數據科學來說亦為真理。

2數據科學過程

數據清洗是如何融入數據科學中的呢?簡短的回答就是,清洗工作是關鍵的一步,它直接影響在它之前和之後的處理工作。

稍微長一些的回答就得圍繞數據科學過程的六個步驟來描述了,請看下面的列表。數據清洗正好處於中間的位置,第三步。但是,請不要以純線性方式看待這些步驟,簡單地認為這是一個從頭到尾執行的框架,其實在項目的迭代過程中,我們會根據具體情況,反覆執行這些步驟。另外還需要指出的是,並不是每一個項目都會包含列表中所有的步驟。舉個例子,有時候我們並不需要數據收集或可視化步驟。這完全取決於項目的實際情況。

(1) 第一步是問題陳述。識別出你要解決的問題是什麼。

(2) 接下來要做的是數據收集與存儲。數據從何而來?它們在哪裡存放?格式又是什麼?

(3) 然後是數據清洗。數據需要修改嗎?有什麼需要刪除的嗎?數據應該怎麼調整才能適用於接下來的分析和挖掘?

(4) 數據分析和機器學習。數據需要哪些處理?需要什麼樣的轉換?使用什麼樣的演算法?運用什麼公式?使用什麼機器學習演算法?順序又是怎樣的呢?

(5) 數據展現和可視化實現。數據處理結果應該怎樣呈現出來呢?我們可以用一張或幾張數據表來表現,也可以使用圖畫、圖形、圖表、網路圖、文字雲、地圖等形式。但這是最佳的可視化方案嗎?有沒有更好的替代方案呢?

(6) 最後一步是問題決議。你在第一步里所提出的疑問或是問題的答案究竟是什麼?數據處理結果還有哪些不足?這個方法能徹底解決問題嗎?你還能找出別的什麼辦法嗎?接下來要做的又是什麼?

在數據分析、挖掘、機器學習或是可視化實現之前,做好相關的數據清洗工作意義重大。不過,請牢記,這是一個迭代的過程,因為在項目中我們可能需要不止一次地執行這些清洗操作。此外,我們所採用的挖掘或分析方法會影響清洗方式的選取。我們可以認為清洗工作包含了分析方法所能決定的各種任務,這有可能是交換文件的格式、字元編碼的修改、數據提取的細節等。

數據清洗與數據收集和存儲(第2步)的關係也十分密切。這意味著你得收集原始數據,對它們執行存儲和清洗操作,之後再把清洗過的數據保存下來,接下來收集更多的數據,清洗新的數據並把清洗結果與前面處理完的結果數據結合起來,重新進行清洗、保存等操作,反反覆復。正因為這個過程非常複雜,所以我們要麼選擇牢牢記住曾經做過的處理,並記錄下那些可以根據需要反覆執行的步驟,要麼把工作的全部狀況告知其他相關人員。

3傳達數據清洗工作的內容

六步處理過程是圍繞著問題和解決方案這個故事線組織的,因此,在作為報表框架使用時,它的表現十分優秀。如果你已經決定使用六步框架來實現數據科學過程報表,將發現只有到了第三步你才會真正開始進行與清洗有關的工作。

哪怕你並不需要把數據科學過程製成正式的報告文檔,你仍然會發現,認真地記錄下曾經按什麼順序做了些什麼事情,對以後的工作也是極有幫助的。

請記住,哪怕是規模再小、風險再低的項目,你也要面對至少兩人規模的受眾:現在的你和六個月之後的你。請相信我說的話,因為六個月之後的你基本上不會記得今天的你做過什麼樣的清洗工作,也不記得其中的緣由,更談不上如何重新再做一次。

要解決這個問題,最簡單的方案就是保留一份工作日誌。這個日誌應該包含鏈接、屏幕截圖,或是複製粘貼你曾經運行過的具體的命令,並配上為什麼要這樣做的解釋性文字。下面是一個關於小型文本挖掘項目的日誌示例,其中記述了每個階段輸出的外部文件鏈接以及相關的清洗腳本鏈接。如果你對日誌中提到的某些技術不太熟悉的話,也沒有關係,因為這個示例的重點只是讓你了解一下日誌的樣子而已。

(1) 我們寫了一條SQL查詢語句來檢索出每條數據及其相關描述。

(2) 為了能在Python中進行詞頻分析,我們需要把數據調整成JSON格式。因此我們做了一個PHP腳本,用它來循環遍歷查詢結果,並以JSON格式保存到文件中(第一個版本的數據文件)。

(3) 這個文件里的數據有些格式上的錯誤,比如包含了沒有轉義的問號和一些多餘的內嵌HTML標籤。這些錯誤可以在第二個PHP腳本中修正。運行第二個腳本之後,我們就可以得到一份乾淨的JSON文件了(第二個版本的數據文件)。

這裡需要注意的是,我們用日誌來解釋程序做過什麼和這樣做的原因。日誌的內容可以很簡短,但要儘可能地包含一些有用的鏈接。

另外,我們還可以選擇許多更複雜的方案來傳達信息。例如,如果你對軟體項目管理中常用的版本控制系統比較熟悉的話,如Git或是Subversion,就可以好好地規劃設計一番,想想怎麼使用這些工具來跟蹤數據清洗工作。不管你使用什麼樣的系統,最重要的事情是做好日誌,哪怕只有一句話。來吧,學著把它用起來,別耽誤進度了。

4數據清洗環境

本書中涉及的數據清洗方法是通用的,適用範圍非常廣泛。你不需要任何高端專業的資料庫產品或是數據分析產品(事實上,這些廠商和產品可能已經提供了數據清洗程序或是解決方法)。我圍繞數據處理過程中的常見問題,設計了本書中的清洗教程。而我要展示的都是適用範圍較為廣泛的開源軟體和技術,它們很容易在實際工作中獲得和掌握。

下面列出了你需要準備的工具和技術。

  • 幾乎在每一章中,我們都會用到終端窗口和命令行界面,比如Mac OS X上的Terminal程序或者是Linux系統上的bash程序。而在Windows上,有些命令可以通過Windows的命令提示符運行,但其他的命令則需要通過功能更強的命令行程序來運行,比如CygWin。
  • 幾乎在每一章中,我們還會用到文本編輯器或者是適合程序員使用的編輯器,如Mac上的Text Wrangler,Linux上的vi或emacs,或是Windows上的Notepad++、Sublime編輯器等。
  • 在絕大數章節里,我們需要使用Python 2.7版本的客戶端程序,如Enthought Canopy,另外還需要足夠的許可權來安裝一些包文件。其中大部分例子都可以直接在Python 3中運行,但有些不可以,所以如果你安裝的是Python 3的話,可以考慮再安裝一個2.7版本。
  • 在第3章「數據清洗的老黃牛——電子表格和文本編輯器」中,我們需要使用電子表格程序(主要是Microsoft Excel和Google Spreadsheets)。
  • 在第7章「RDBMS清洗技術」中,我們需要使用MySQL資料庫和一個用於訪問該資料庫的客戶端軟體。
5入門示例

準備好了嗎?現在讓我們磨好手裡的廚刀並結合六步框架來解決一些簡單的數據清洗問題吧。這個例子會用到對公眾開放的安然(Enron)公司電子郵件數據集。這是一個非常有名的數據集,當中所有的往來郵件都源自現已停業的安然公司前僱員。作為美國政府調查安然公司賬目欺詐的一部分,僱員之間的郵件已被公開並可供任何人下載。來自各個領域的研究人員已經發現,這些郵件有助於研究商務溝通、社交網路等問題。
你可以在維基百科上閱讀更多關於安然公司和導致它破產的金融醜聞。在另外一個頁面上,你可以閱讀關於安然公司電子郵件語料庫的信息。

在這個例子當中,我們會採用六步框架來解決一個簡單的數據科學問題。假設我們需要揭露在某一段時間裡安然公司內部電子郵件的使用趨勢和特徵。先讓我們按照日期來對安然僱員之間的往來郵件數量做個統計,然後再通過圖形來顯示統計出來的數據。

首先,我們需要按照上面的指南下載一份MySQL版本的安然公司語料庫。另一個(備份)源的地址是。根據指南,我們需要把數據導入到MySQL伺服器中一個稱為Enron的資料庫模式中。導入之後的數據可以通過MySQL命令行界面或是基於網頁的PHPMyAdmin工具進行查詢。

這是我們的第一個數據統計查詢,語句如下:

SELECT date(date) AS dateSent count(mid) AS numMsg FROM message GROUP BY dateSent ORDER BY dateSent;

從結果中我們馬上就會注意到,許多郵件的日期都不正確。比如,很多日期要麼早於或晚於公司的存續期(如1979),要麼與事實邏輯不符(如0001或2044)。郵件雖舊,但也不至於那麼舊!

下表是截取出來的一部分數據片段(完整的結果集長達約1300行)。這些數據的日期格式都是正確的。但是,有些日期值有著明顯的錯誤。

dateSent

numMsg

0002-03-051
0002-03-073
0002-03-082
0002-03-121
1979-12-316
1997-01-011
1998-01-041
1998-01-051
1998-10-303

這些錯誤日期的產生很有可能是由郵件客戶端配置不當導致的。這裡,我們有三種處理方案可以選擇。

  • 什麼都不處理:也許,我們可以選擇忽略這些錯誤數據,直接開始構建線性圖。但是,最小的錯誤日期始於0001年,最大的錯誤日期至2044年結束,所以我們可以想象,最終的線性圖時間軸上將有1300個刻度線,每個刻度上面顯示著1或者2。光是聽起來就沒有什麼吸引人的地方,也沒提供什麼有用的信息,所以不處理就等同於數據毫無用處。
  • 修正數據:我們可以嘗試算出錯誤消息對應的正確日期,從而生成正確的數據集來創建圖形。
  • 扔掉受影響的郵件:我們可以做出一個明智的決定,放棄那些日期不在預定範圍之內的郵件。

為了在選項二和選項三之間做個決斷,我們需要先計算一下1999~2002年有多少封郵件會受到影響。為此,我們編寫了下面的SQL語句:

SELECT count(*) FROM message WHERE year(date)<1998or year(date)2002;Result:325

結果顯示一共有325封郵件包含日期錯誤,乍一看確實有點多,但請等一下,實際上這些數據只是佔了全部數據量的百分之一。現在需要好好斟酌一下了,或許我們可以手工修復這些日期,但也可以假定不在乎這百分之一的損失。那就乾脆扔掉這些數據直接選擇第三個方案吧。下面是調整后的查詢語句:

SELECT date(date) AS dateSent count(mid) AS numMsg FROM message WHERE year(date) BETWEEN 1998 AND 2002 GROUP BY dateSent ORDER BY dateSent;

數據清洗完成之後一共生成了1211條結果,每一行都有其對應的郵件數量。下面的內容截取自新的數據結果集:

dateSent

numMsg

1998-01-041
1998-01-051
1998-10-303
1998-11-021
1998-11-031
1998-11-044
1998-11-051
1998-11-132

在新的數據中,1998年1月的兩個日期看起來有些問題,因為其他郵件都始於10月,而且10月之後的郵件數量更為規律一些。這很奇怪,同時也反映了另一個問題:我們是否還有必要在x軸上標記每一個日期,即使這一天一封郵件都沒有發出?

如果我們的答案是肯定的話,那就需要顯示每一個日期,即使它對應的郵件數量是0。這意味著我們需要再做一輪數據清洗工作,生成那些沒有郵件往來的日期所對應的數據。

但是請等一下,對於這個問題的處理,我們可以稍微變通一下。是不是真的要在原始數據中加入零數據,其實這取決於我們用什麼樣的工具來創建圖表以及圖表的種類。舉個例子來說,Google的Spreadsheets就能在初始數據中缺少日期的情況下,在 x 軸上自動進行零值數據補齊,創建線性圖或是條狀圖。在我們的數據中,這些需要補齊的零值就是1998年所缺失的日期。

下面的三幅圖演示了這些工具所呈現的結果,並反映出它們是如何處理日期軸上的零值數據的。請注意,Google Spreadsheets在頭部和尾部所展現的長長的零值數據。

D3 JavaScript可視庫也能完成同樣的工作,零值數據也是自動補齊的,如下圖所示。
關於如何使用D3完成一個簡單的線性圖,請參考教程:。

Excel的線性圖也有同樣的數據補齊功能,如下所示。

接下來,我們需要考慮一下是否需要零值數據,要不要讓它們在 x 軸上顯示(數據查詢結果總數為1211,而在指定的年限範圍,即1998~2002年,一共有1822天)。或許顯示零值日期並不會起到什麼作用;此外,倘若圖表過於擁擠,有些較小的空隙我們就看不到了。

為了比較兩種圖表之間的差別,我們可以快速地把相同的數據再次放入Google Spreadsheets(你也可以在Excel或D3中完成這個任務),但這次我們只需選擇數量這一個欄位來構建圖表就可以了,這樣一來,Google Spreadsheets就不會在 x 軸上顯示日期了。最後生成的結果圖表中只包含數量數據,零值數據不會被填充進來。長長的尾巴不見了,圖表中各個重要的部分(中間部分)也都被保留了下來。

值得慶幸的是,這次生成的圖表與之前的相比還是很像的,並省去了前後兩端冗長的內容。根據比較結果和我們先前的計劃(還記得我們要做的只是創建一個簡單的條形圖吧),現在終於可以繼續下一步工作,不用煩惱是否需要創建零值數據了。

當一切都完成之後,最終的條形圖會為我們顯示出安然公司曾經的幾次郵件峰值。最大的峰值出現在2001年10月和11月,恰好是醜聞被揭露的時候。還有兩次較小一點的峰值發生在2001年6月26日和27日,以及2000年12月12日和13日,那時的安然也有新聞事件發生(分別是加利福尼亞州的能源危機事件和公司領導層的變動)。

如果數據分析已經讓你開始興奮的話,那麼接下來你可以好好利用這些數據來發揮你的奇思妙想。願這些清洗乾淨的數據可以讓你的分析工作更上一層樓!

1.6小結

當所有工作全都做完的時候,事實印證了《紐約時報》的報道。我們從這個簡單的練習中可以看出,即便是回答一個小小的數據問題,數據清洗就佔了整個過程80%的工作量(在這個全文共計900個單詞的案例中,光是談論數據清洗的基本原理和方案就用了700個單詞)¹。數據清洗的的確確是數據科學過程的關鍵部分,它不僅涉及對技術問題的理解,同時還要求我們做出相應的價值判斷。作為數據清洗工作的一部分,我們甚至需要在尚未完成分析與可視化步驟的時候,預先考慮它們的輸出結果將是什麼樣子。

¹這裡指的是英文原版字數統計。——譯者注

重新審視數據清洗在這一章的工作中所扮演的角色,我們很容易發現,清洗效果的提升能夠大幅減少後續處理的時間。

End.



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦