天天看點

《資料整理實踐指南》一2.3 可視化

本節書摘來自異步社群《資料整理實踐指南》一書中的第2章,第2.3節,作者【美】q. ethan mccallum(麥卡倫),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

我覺得特别有幫助的另一種技術是根據字段值建立直方圖。這對于大規模資料集尤其有用,而前面提到的簡單的統計方式隻能看到資料的表面。直方圖是每個值在資料集中出現次數的統計,是以直方圖還适用于非數值字段,而統計方法就不适用。

舉個例子,假設有個包含推薦關鍵字的資料集,這些關鍵字是使用google、bing或其他搜尋引擎進行搜尋的詞,使使用者能夠浏覽網站的網頁。一個大型網站每天可以通過搜尋引擎帶來數百萬的pv,其中搜尋關鍵字可能有數百萬,在一段時間後可能會有數十億的唯一關鍵字。對于這些關鍵字,由于它們不是數值類型,而是字元串類型,是以不能使用傳統的統計方法(如最小值、最大值或平均值)。

幸運的是,可以使用直方圖對大規模的非數值資料集進行彙總。一階直方圖計算每個關鍵字的來源數。但是,如果資料集中有數十億的關鍵字,直方圖就會非常大,可能沒什麼用。可以執行一次聚合操作,使用每個關鍵字給網站帶來的來源數作為值,結果就會小得多,而且彙總資訊更有用。該直方圖會顯示每個關鍵字的來源數。由于對于來源數有的差别很小,可以通過分箱操作進一步彙總(比如來源數為1~10、11~20、21~29等)。當然,具體的分箱數取決于資料。

對于很多簡單的資料集,一個指令管道就可以生成一個有用的直方圖。比如,假設有個簡單的文本檔案(sample.txt),包含一些枚舉字段(比如urls、keywords、names和months)。為了快速生成資料直方圖,可以運作如下指令。

該指令如何工作呢?cat指令會讀取檔案,把内容發送給stdout。管道符号(|)會捕獲到這些資料,把它發送給管道的下一個指令(是以使用管道符非常友善!),即sort指令,它實作期望的操作:對資料進行排序。在這個例子中,實際上并不關心資料是否有序,隻是想把相同的行組合在一起,因為下一個指令uniq依賴于組合的結果。uniq指令(命名非常貼切,雖然不知道如何工作)每次隻輸出一條唯一的記錄,如果指定-c選項,會在每行結果前面輸出該行出現的次數。是以,該指令會最終顯示檔案中每行出現的次數:這就是直方圖!

請看示例2-1。

示例2-1 生成字段months的直方圖

對于稍微複雜的資料集,比如t分隔的檔案,隻需要增加一個過濾器,提取想要的字段。提取字段的方法有多種,“最好”的方式取決于資料的特性以及篩選條件。最簡單的方式可能是通過cut指令實作,尤其是對于t分隔的資料,隻需要通過指令行參數就可以指定要哪個字段或哪些字段。舉個例子,假設有個檔案,第一個字段是names,第二個字段是ages。如果想計算每個年齡有多少人,可以執行如下代碼。

第一個字段表示計數,第二個字段表示年齡。從結果可以看出,14歲有2個,15歲有1個,16歲有1個,17歲有2個。

篩選列的另一種常用方法是使用awk(awk的功能要複雜得多),其文法稍微有些複雜。

對于真實的資料集(即包含大量資料點的資料集),直方圖可以直覺地展示資料的近似分布情況,可以便于評估。舉個例子,你可能期望是個較平滑的函數,可能是直線或高斯分布(看起來像個鐘形曲線),甚至可以呈指數形式衰減(長尾分布),但是應該特别重視圖中的不連續點:它可能表示資料有問題。

關于直方圖,其中一個有用的例子是對于兩個約750萬關鍵字的資料集,預估其競價排名值。資料是由第三方收集的,關于如何收集,我了解甚少。資料檔案是逗号分隔的文本檔案,包含關鍵字和相應的競價排名值。示例2-2為競價排名資料檔案。

示例2-2 競價排名資料檔案

由于該資料集是csv格式(引号括起來的字段内容包含逗号),前面給出的一些技巧這裡不适用。一種快速解決的方式是把那些包含逗号的字段删掉,然後再使用前面給出的管道方式。下面通過忽略包含雙引号字元的記錄來實作。首先,檢查一些會忽略多少條資料。

我們隻是忽略了0.07%的記錄,這不會影響統計結果。是以,通過管道實作如下。

這看起來可能有些複雜,下面一步步對它進行探讨。首先,通過cat指令建立資料流。其次,通過grep指令比對不包含引号的記錄,−v選項表示删除包含雙引号的記錄,csv格式會使用引号把字段内容包含分隔符(這裡即逗号)的字段括起來。然後使用cut指令抽取出第二個字段(其中-d後面的逗号即表示字段分隔符)。再次,對結果記錄進行排序,這樣重複記錄就會相鄰。然後,使用uniq指令,其中-c選項會對相同行的出現次數進行計數。最後,根據第二個字段對結果輸出進行排序(即競價排名ppc)。

在實際資料中,其輸出結果很淩亂,因為ppc值差别很大(有些在逗号和美元符$之間有空格,有些沒有)。如果希望輸出結果更幹淨,可以實作一段perl腳本來清洗資料并對它們進行聚合,這往往也是更靈活的解決方案,代碼如下。

對于前面給出的樣本資料集,這段代碼會輸出類似的結果,但多出兩條之前被丢棄的$0.99記錄,此外ppc值以實際值表示,而不是不同的字元串形式。

對于真實的資料集,輸出結果如下。

值得一提的是,如果資料已經在sql資料庫,生成直方圖就非常容易。舉個例子,假定有個表名為mytable,包含前面提到的資料,資料有兩個字段,term和ppc,可以通過如下sql語句對ppc進行聚合。

不管如何生成資料,通過可視化是展示有趣的特征的最佳方式,如圖2-1所示。

《資料整理實踐指南》一2.3 可視化

對于較小的ppc值,存在非常多的關鍵詞,随着ppc值增長,資料量呈指數級衰減(注意,縱軸是以對數方式顯示的)。盡管如此,可以看到在圖的中間有個很大的“斷面”!在$15.00和$15.88之間幾乎沒有ppc值,而在$15.89到$18.00之間的值比預期的多(基于圖中的曲線可以看出),這讓我猜想可能是生成資料的方法把$15.00和$15.88之間的資料值提升了大約$0.89。仔細檢視資料集之後,發現兩點:一是确實是因為生成測試ppc值的算法導緻的,二是資料生成方不知道其算法存在這個問題!通過該資料分析,我們知道要避免把ppc值在$15.89到$18.00之間的資料映射到任何一個關鍵字,資料生成方也知道了要修正其算法。

關于該資料集,另一個有趣的特征是其最小值是$0.05。這可能是因為市場最低競價值是$0.05,也可能是算法從$0.05開始預估競價值,或者資料之前做過處理,删除了低于$0.05的競價值,或者是由于其他原因。在這個例子中,最後發現是由于第一個原因,收集資料的市場的最低定價是5美分。實際上,如果直方圖中ppc值較低的曲線放大顯示(如圖2-2所示),會發現另一個特征。雖然ppc值為$0.05的關鍵詞超過100萬條,卻沒有一條(更準确地說是少于3 000條)ppc值是$0.06到$0.09。而ppc值為$0.10的記錄卻不少(接近500 000),而值在$0.11以上的卻很少(少于30 000)。是以,看起來市場上有兩套不同的競價方案,其依賴因素不确定。

《資料整理實踐指南》一2.3 可視化

使用直方圖的另一個例子是檢視搜尋來源。當使用者在google搜尋結果頁中點選web站點上的連結時,google(有時)會把查詢關鍵詞和清單的“排名”(頁面的第一條結果值為1,第二條結果值為2等)一起傳給網站。這個資訊對網站非常有價值,因為它表示對于不同關鍵詞,該網站的内容在google搜尋結果中的排名。然而,它也可能是噪音資料。google經常通過改變頁面上的排名結果測試其算法和使用者行為。結果排序還和使用者的資訊和行為有關,比如國家、過去的搜尋和點選行為,甚至是好友推薦。是以,這種排序資料表示的是關鍵詞/url組合的多種排序中的一種,這通常會使人難于了解。有些人還認為google故意把該資料弄得不可用。

為了檢視該排名資料是否有用,我檢視了一個大型網站的來源資料,它從google的來源流量很大(每天有數百萬條)。和常見的标準web伺服器日志檔案的原始資料不同,這些資料已經儲存在資料倉庫中,已經從來源頁的url中抽取相應字段,包括日期、url、來源關鍵詞以及每次浏覽的排序。我建立了一個直方圖,顯示每個rank的pv數(如圖2-3所示)。

《資料整理實踐指南》一2.3 可視化

從圖2-3的直方圖中可知,資料不是随機的,也不是很混亂。資料展現了一個非常清晰的模式,和期望的使用者行為相關。舉個例子,在排名10和排名11之間有一段很大的不連續性,同樣,排名20和排名21之間也是,依此類推。這和google的搜尋結果預設每個頁面展示10條結果對應。

在結果頁中(除了首頁,後面會讨論),可以看出更多使用者對結果的點選,第一條大于第二條,第二條大于第三條……有趣的是,更多使用者點選頁面中的最後幾條結果,而不是中間結果。通過其他方式也發現了這個行為,是以通過檢視該細粒度的直方圖,可以很大程度上證明資料的有效性。

那麼,為什麼這個模式對于第一個頁面不适用呢?注意該資料并不表示ctr(點選率),它顯示的是總浏覽量。對于很多關鍵詞,該網站的網頁排在結果頁中第一條的并不多,但是排在第二和第三的卻很多。是以,雖然第一條結果的ctr是最高的(從其他頁面中看出),但是在第一個頁面中看不出來。在第三、第四以及後續的頁面中,可以看出浏覽量逐漸趨緩,是以pv值看起來和ctr相當。

到目前為止,我們已經探讨對字段值相同記錄的計數建構直方圖。正如我們所看到的,這在很多情況下很有用,但是對很多案例而言,這種方式粒度太細,導緻無法檢視有用的模式。舉個例子,比如對于推薦模式的分析,可能是對使用者的電影推薦,對某個産品推薦另一個産品等。在這個例子中,我将探讨文章推薦。假設有這樣一個網站,内容豐富,包含數百萬篇文章,涉及領域很廣泛。為了幫助讀者從目前文章導航到下一篇他們可能感興趣的文章,該網站提供了一個簡短的推薦清單,該清單是基于人工編輯、語義相似和/或過去的通路流量模式。

假定資料集包含推薦組合:每條記錄表示一個推薦,第一個字段表示源文章的url,第二個字段表示目标文章的url。

示例2-3 推薦檔案

對于正在學習如何煮雞蛋的讀者,會顯示關于如何煮雞蛋和煎培根的文章;對于正在學習如何煮雞蛋的讀者,會顯示如何煮雞蛋,如何在雞蛋上畫鬼臉,以及如何為複活節彩蛋着色。

對于一個大型網站,檔案可能會變得非常大。我曾經工作過的一個網站有約330萬篇文章,每篇文章有30條推薦,最後整個網站有約1億條推薦。由于這些推薦内容是在夜間自動化生成的,要確定系統生成合理的推薦資訊很重要,而且很富有挑戰。手工檢查統計學上大量樣本會花費大量時間,是以需要依賴統計工具。比如,這些推薦的分布情況如何?是否有些文章被推薦了數千次,而有些文章從未被推薦過?

我們可以生成柱狀圖,顯示每篇文章被推薦了多少次。

示例2-4 生成推薦目标直方圖

“how to boil an egg(如何煮雞蛋)”這篇文章被推薦了2次,而其他4篇文章隻分别被推薦1次。這聽起來沒什麼問題,但是有330萬篇文章,在直方圖中就需要有330萬條記錄,這樣的直方圖就會變得沒什麼可用性了。更糟糕的是,由于關鍵字是url,無法像數值一樣對它們執行分箱操作。為了更好地了解資料,可以進一步聚合,按示例建立一張直方圖。

示例2-5 生成推薦目标計數直方圖

從結果可知,有四篇文章被推薦了一次,一篇文章被推薦了兩次。

在3 300萬條推薦的資料集上使用同樣的技術(即每篇文章的前10條推薦),生成如圖2-4所示的直方圖。對于累積分布函數,得到結果如圖2-5所示。

《資料整理實踐指南》一2.3 可視化

注意圖2-4的直方圖運用重對數圖尺,而圖2-5的累積分布圖呈線性垂直曲線。整體而言,資料集看起來很合理,曲線平滑,沒有明顯的不連續性。大多數文章被推薦次數很少,約300 000篇隻被推薦1次。随着被推薦數的增加,文章的數量快速減少,約一半的文章被推薦數少于7。最流行的文章大約被推薦1 800次。

可以針對不同的算法生成的推薦集運作該分析,進而幫助我們了解算法行為。舉個例子,如果一個新的算法産生的分布範圍更廣,就可以推斷有很多文章被推薦的次數和其他文章差距很大。如果分布完全不同—比如推薦次數的平均值是一個鐘形分布(在這個示例中為10)—那麼可以推斷出文章的推薦次數分布很均勻。

《資料整理實踐指南》一2.3 可視化

盡管直方圖對于時間序列資料通常沒什麼意義,類似的可視化技術可能會很有用,尤其當資料可以通過其他次元聚合時。舉個例子,web伺服器日志可以每分鐘、每小時或每天聚合統計pv數,然後把統計結果作為時間序列。這對于查找資料丢失特别有用,如果處理不當,對于某些資料分析會帶來嚴重的傾斜。

很多網站負責人會仔細觀察他們的網站流量,監測網站問題,包括市場營銷活動、搜尋引擎優化等。對于很多網站,由于受到和網站本身無關的一些因素的影響,流量的變化會變得非常複雜。其中一些原因,如季節性因素,某種程度上可以預測,這樣當網站流量下降時也不至過于擔心。盡管如此,季節性因素可能很複雜,因為它和網站類型有關,比如季節性因素對稅務咨詢網站的影響和園藝網站的影響會有很大差别。此外,常識并不總是正确,而且常識幾乎不會有量化的指導作用。在周日流量下降30%會有意義嗎?春天開學時,流量會有多少下降?對于有大量曆史流量資料的網站,可以構模組化型來預測(通過顯式或隐式的“關系網知識”),但是對于一個新的站點或一個已有站點,如何構模組化型呢?

為了解決這個問題,我嘗試使用公開可用的維基百科日志來建構一個長期、大規模的季節性模型,預測不同語言的流量。維基百科服務每天有近5億的頁面,有一半多是英語。通過自動化程式對網頁按語言(站點)、時間和頁面進行聚合。正如任何自動化程式一樣,它有時會失敗,導緻某個小時或某天的統計值變低。對于季節性模型,這會帶來災難,意味着流量的下降是不真實的。

第一次統計維基百科資料時,得到的是一些沒有意義的值,比如在2011年6月7日這一天,pv值為1.06e69?這種值可以很容易知道是不真實的,可以丢棄掉。修剪掉一些異常值後,時間序列圖如圖2-6所示。

《資料整理實踐指南》一2.3 可視化

你會發現,還是有一些異常值,有低的,也有高的。此外,整體形狀很模糊。放大後(如圖2-7所示),會發現其中一些模糊性是由于一周中每天的統計值變化。對于大多數資訊類網站,在平時會比周日多出很多流量。

《資料整理實踐指南》一2.3 可視化

由于關注的是網站流量變化的長期趨勢,我選擇檢視每周的平均值,這樣可以不受遊離點以及一周中不同日期變化的影響(如圖2-8所示)。

圖2-8看起來清晰多了。在過去幾年,整體流量一直趨于上升,和期望的一緻。圖2-8中還是有一些較大的傾角和尖峰,以及一年過程中的很多變化。由于資料是每小時以檔案形式儲存,檢測髒資料的一種方式是統計每天有多少個小時的資料。顯然,每天應該有24小時的資料(可能潛在一些時間點的細微差别,這取決于維基百科如何記錄日志)。

在圖2-8中添加小時數後,生成結果如圖2-9所示,它顯示了有很多天的資料小于24小時,還有兩天的資料超過24小時(達到30小時!)。2009年5月11日有30小時的資料,5月12日有27小時的資料。進一步檢視會發現很可能是因為資料重複。舉個例子,2009-05-01 01這個時間點有兩個檔案,每個檔案的pv數和00以及02這兩個時間點一緻。這很可能是因為系統程式在從原始web日志生成這些檔案時,複制了一些資料。

《資料整理實踐指南》一2.3 可視化

示例2-6 維基百科2009-11-05這天英文頁面的統計計數

删除重複條目可以使結果圖表變得更合理,但并不會真正解決流量的大波動問題,也無法估計丢失的資料量。值得一提的是,從2010-06-12到2010-06-15,每天都有24個小時的資料檔案,但是在圖中該時間段呈現最大的pv降幅。同樣,最大的正向影響的遊離點是2010年10月的前3周的資料,每天的流量pv數從2.4億上升到3.75億,而這個時期并沒有多出檔案。是以,這些現狀說明了我們必須對這些時間段做更深入的分析,并提醒我們從該資料集得出結論時需要小心。

繼續閱讀