編者按:Zalando研究工程師Jekaterina Kokatjuhha通過解決現實生活的實際問題,介紹了如何從頭開始進行數據科學項目。
網上有許多關于數據科學和機器學習的教程,它們涉及的實操案例往往離不開講解理論,提供一些代碼,然后分析很干凈的數據。
但是,如果你想開始實踐數據科學,最好的方法其實是選取一個真實生活問題,深入數據以尋找深刻的洞見,用額外的數據來源進行特征工程,創建可獨立運行的機器學習工作流。
這篇博客文章將講解從頭創建數據科學項目的主要步驟。它基于現實生活問題——柏林租金高低的主要決定因素是什么?我們將分析這一情況,并列出機器學習初學者常犯的錯誤。
下面是我們將詳細討論的步驟:
尋找主題
自web提取數據并清洗
取得深入的洞見
基于外部API進行特征工程
從事機器學習時常犯的錯誤
特征重要性:找到主導租金高低的因素
創建機器學習模型
尋找主題
有許多問題都可以通過分析數據解決,不過尋找一個你感興趣并能給你提供動力的問題總是最好的。搜尋主題時,毫無疑問,你應該重點關注自己的偏好和興趣。
不過,我建議你不僅關注自己的興趣,也聽聽周圍的人在談論什么。什么給他們造成了困擾?他們在抱怨什么?這是數據科學項目的又一個靈感來源。如果人們在抱怨,那也許意味著現有方案并沒有很好地解決人們的問題。因此,如果你嘗試基于數據分析來處理這一問題,你可能提供一個更好的解決方案,影響人們對這一主題的看法。
這些聽起來也許都比較抽象。所以讓我談談自己是如何想到分析柏林的租金的。
“早知道這里的租金這么高,我報期望薪資的時候會報一個更高的價格?!边@是我從最近搬到柏林工作的人那里聽到的話。大多數剛搬到柏林的人抱怨他們沒想到柏林的生活成本這么高,也沒有關于公寓可能價格范圍的統計數據。如果他們事先知道這一點,他們在工作申請過程中本可以報一個更高的價,或者考慮其他選項。
我在網上搜索了一番,也查看了若干租房網站,也問了一些人,但都沒能找到關于當前市場價格的合理統計數據或可視化。所以我萌生了自己進行分析的想法。
我想要收集數據,創建一個面板,這個面板會根據你選擇的條件(例如,40平方米,米特區,帶陽臺、炊具齊全的廚房)顯示價格范圍。這本身就有助于人們理解柏林的房租價格。另外,通過應用機器學習,我將能識別決定房租價格的因素,并練習不同的機器學習算法。
自web提取數據并清洗
獲取數據
在對要做數據科學項目有一個概念之后,我們可以開始尋找數據了。網上有特別多很棒的數據倉庫,例如Kaggle、UCI ML、數據集搜索引擎、收錄學術論文及其數據集的網站。此外,你可以爬取網站數據。
不過,小心——舊數據到處都是。我在搜索關于柏林房租的信息的時候,找到了許多可視化結果,但它們或者比較陳舊,或者沒有指明年份。
有些統計甚至注明只統計了不帶家具的50平方米的兩室公寓的租金。如果我想要一個帶裝修好了的廚房的較小的公寓呢?
由于我只找到了舊數據,所以我決定爬取租房網站的信息。關于爬取網站信息,我專門寫了一篇博客,討論其細節、缺陷、設計模式:https://hackernoon.com/web-scraping-tutorial-with-python-tips-and-tricks-db070e70e071
要點是:
在爬取之前,檢查下是否有公共API可用。
文明爬取!不要在一秒內發送數百個請求使網站過載。
在提取信息的過程中及時保存數據。
數據清洗
一旦開始獲取數據,非常重要的一點是及早查看數據,以便盡早找出可能存在的問題。例如,爬取程序可能漏掉了一些重要的字段,保存程序至文件時,如果使用逗號作為分隔符,而原數據中也包含逗號,如果沒有正確處理,最終文件的格式會出現錯亂。
在爬取租房信息的時候,我的爬取程序內置了一些小小的檢查措施,查驗所有特征的缺失值數目。站長可能會更改網站的HTML結構,導致爬取程序無法獲取任何數據。
確保考慮了網站爬取的所有技術方面的問題之后,我本以為數據基本上是理想的。然而,我最終花了大約一周清洗所有數據,因為數據當中包含一些隱蔽的重復條目。
理想和現實
出現重復條目的原因有:
多次展示的同一間公寓
中介輸入時輸錯了信息,比如租金或樓層。之后他們有時會更正信息,有時會重新發布一條包含正確信息的新廣告。
同一間公寓的價格在一個月后會變動(漲價或降價)。
盡管第一種情形很容易識別(通過ID),第二種情形非常復雜。原因在于中介可能略微修改描述,改動錯誤的價格,并作為新廣告發布,因此ID也會是新的。
我設計了許多規則來識別這種情況。一旦識別出這些公寓其實是重復條目,我會根據日期對這些條目進行排序,選擇最新發布的條目。
此外,有些中介會在一個月后調整同一間公寓的房租。我聽說如果無人問津,那么會降價,相反則會漲價。
取得深入的洞見
一切就緒之后,我們可以開始分析數據了。我知道數據科學家喜歡seaborn和ggplot2,還有其他許多靜態可視化工具。
然而,可交互面板有助于你本人和其他利益相關人找出有用的洞見。這方面有許多非常棒的易用工具,例如Tableau和Microstrategy。
我花了不到30分鐘就創建了一個交互式面板,可以根據選擇的條件顯示價格范圍。
這樣一個相當簡單的面板已經可以為剛來柏林的人提供不少關于房租的洞見,如果租房網站能提供這樣一個工具,應該也會吸引不少用戶。
我們從數據可視化中已經能看到,從租金分布上來說,2.5房公寓的租金總體上反而低于2房公寓。原因在于大多數2.5房公寓不在市中心。
基于外部API進行特征工程
可視化有助于識別重要屬性,或“特征”,這些特征可以為機器學習算法所用。如果用到的特征包含很少信息,任何算法都不能給出良好的預測。如果特征很給力,即使非常簡單的算法也能得到相當不錯的結果。
在房租項目中,價格是一個連續變量,所以通常而言這是一個回歸問題。我從提取的信息中收集了特征,以預測租金。
然而,這里有一個特征比較麻煩——地址??偣灿?千6百間公寓,位于4千4百個不同粒度的地址。我們可以按郵政編碼劃分地址,然后將其轉換為獨熱編碼,不過這會損失特定位置的精確信息。
不同粒度的地址:詳細地址;只有街名,門牌號隱藏;只有郵政編碼
當你得到一個新地址的時候,你會做什么?
你要么搜一下它在哪里,要么搜下如何去哪里。
通過使用外部的API,我們可以根據公寓地址計算:
到柏林腓特烈大街站(中央車站)坐火車要多久?
到柏林市中心站的汽車行車距離
到最近地鐵站步行要多久?
公寓方圓一公里內的地鐵站數量
這四個特征顯著提升了模型的表現。
從事機器學習和數據科學項目時常犯的錯誤
爬取或獲取數據之后,在應用機器學習模型之前還有許多步驟需要完成。
我們需要可視化每個變量,看看它們的分布,找到離群值,并理解為何存在這些離群值。
如何處理具體特征中的缺失值?
將類別變量轉換成數值的最佳方式是什么?
有許多類似這樣的問題,但我會詳細解釋大多數初學者容易犯錯的那些問題。
1. 可視化
首先,你應該可視化連續特征的分布,以大概了解是否有許多離散值,變量的分布是什么樣的,以及這些是否有意義。
有許多可視化分布的方式,例如,箱形圖、直方圖、累積分布函數、提琴形圖。然而,你應該選擇能夠提供最多關于數據的信息的圖形。
基于圖形,最值得注意的問題是:你看到你想要查看的東西了嗎?回答這個問題有助于你找到關于數據的洞見或bug。
我經常從Python的seaborn圖片庫中汲取該使用哪種圖形的靈感。另一個很好的靈感來源是Kaggle網站上的kernel。
就租金而言,我繪制了每個連續特征的直方圖,期望可以在大多數特征上看到長尾。
箱形圖有助于查看每個特征的離群值。事實上,大部分離群值要么是大于200平方米的工坊,要么是租金極低的學生宿舍。
2. 是否需要根據整個數據集填充缺失值?
由于多種原因,有時候會有缺失值。如果我們排除所有包含至少一個缺失值的觀測,我們最終會得到一個縮水很多的數據集。
有許多填充缺失值的方式,比如使用均值,中位數。應該怎么做完全取決于你,但需確保只根據訓練數據計算填充值,以防數據泄露。
租金數據同時提取了關于公寓的描述。如果公寓品質、狀況、類型缺失,且描述包含相關信息,我會根據描述填充這些缺失值。
3. 如何轉換類別變量?
取決于具體實現,某些算法無法直接處理類別數據,需要以某種方式將其轉換為數值。
有許多轉換類別變量至數值特征的方式,例如標簽編碼、獨熱編碼、bin編碼和哈希編碼。然而,大多數人在應該使用獨熱編碼的時候會誤用標簽編碼。
例如,假定租金數據中公寓類型列具有下列值:[底樓, 閣樓, 復式, 閣樓, 閣樓, 底樓]。標簽編碼將其轉為[3, 2, 1, 2, 2, 1],這就引入了順序,即底樓 > 閣樓 > 復式。在決策樹及其變體之類的一些算法上,這種特征編碼方式沒什么問題,但應用回歸算法和SVM也許就會出問題。
在租金數據集中,狀況編碼為:
新:1
翻新:2
需要翻新:3
品質則編碼為:
奢侈:1
優于平常:2
平常:3
簡單:4
未知:5
4. 我需要標準化變量嗎?
標準化將所有連續變量縮放至同一尺度,也就是說,假設一個變量的取值范圍是一千到一百萬,另一個變量的取值范圍是0.1到1,標準化之后這兩個變量的取值范圍會一樣。
L1或L2正則化是緩解過擬合的常用方式,可用于多種回歸算法。然而,在應用L1或L2之前先標準化特征很重要。因為L1或L2會懲罰較大的系數,如果沒有標準化,單位較小的系數會受到更多懲罰。
另外,如果算法使用梯度下降,那么標準化特征后梯度下降能夠更快收斂。
5. 我需要對目標變量取對數嗎?
我花了一段時間才明白這個問題沒有統一的答案。
它取決于很多因素:
你想要的是百分比誤差還是絕對誤差
你用的是什么算法
殘差圖和測度的變化告訴了你什么
在回歸問題中,首先關注殘差圖和測度。有時候,目標變量的對數導向一個更好的模型,并且模型的結果仍然容易理解。然而,還有其他值得關注的變換,比如取平方根。
Stack Overflow上有很多關于這個問題的回答,我覺得EdM的回答解釋得很好:https://stats.stackexchange.com/a/320213
我在租金數據上,對價格取了對數,這樣殘差圖看起來要好一點。
左:取對數;右:未轉換數據
6. 更多重要事項
有些算法,比如回歸算法,當系數變得非常不穩定時,會陷入數據的共線性問題。更多數學方面的講解可以參考:http://www.stat.cmu.edu/~larry/=stat401/lecture-17.pdf 取決于核的選取,SVM也許會也許不會受此困擾。
基于決策樹的算法不會碰到多重共線性問題,因為它們可以在不同樹中交換特征而不影響表現。然而,特征重要性的解讀會變得更困難,因為相關變量可能顯得不那么重要。
機器學習
監督機器學習有許多算法可供選擇,我打算探索三種不同的算法,比較下它們的表現和速度。這三種算法是梯度提升(XGBoost和LightGMB)、隨機森林(scikit-learn的實現)、3層神經網絡(基于TensorFlow框架)。由于我對目標變量取了對數,因此我選擇了RMSLE作為優化過程的測度。
XGBoost和LightGBM的表現相當,隨機森林略差,而神經網絡的表現是最差的。
算法在測試集上的表現(RMSLE)
基于決策樹的算法在解讀特征上非常方便,它們可以生成特征重要性評分。
特征重要性:找到決定租金的因素
使用基于決策樹的模型擬合數據后,我們可以查看哪些特征在價格預測中起的作用最大。
特征重要性提供了一個評分,這個評分指示了在構建模型中的決策樹時,每個特征的信息量有多大。計算這種評分的一種方式是算下一種特征在所有樹中多少次用于分割數據。當然,也可以用不同的方法計算評分。
特征重要性可以揭示其他關于決定價格的主要因素的洞見。
就租金預測而言,總面積是最重要的決定價格的因素,這并不令人意外。有意思的是,一些利用外部API構建的特征同樣屬于最重要的特征。
然而,Scott Lundberg在Interpretable Machine Learning with XGBoost(基于XGBoost的可解釋的機器學習)中指出,不同的選項(測度)可能得出不一致的特征重要性。Scott Lundberg在NIPS 2017上提出了一種新的兼具精確性和一致性的計算特征重要性的方法,并提供了這一方法的開源Python實現SHAP。
基于SHAP得到的特征重要性分析如下:
x軸位置表示特征對模型預測的影響,顏色表示特征值的大小
上圖包含大量信息:(聲明:數據采集自2018年初,之后的情況可能有變動)
離市中心越近(到柏林腓特烈大街站坐火車花費的時間和到柏林市中心站的汽車行車距離),預測租金越高
總面積是最強的決定因素
如果公寓主要求你有低收入證明(德國的WBS),預測價格會比較低
下面這些區域的租金較高:Mitte、 Prenzlauer Berg、Wilmersdorf、Charlottenburg、Zehlendorf and Friedrichshain
下面這些區域的租金較低:Spandau、 Tempelhof、Wedding、 Reinickendorf
顯然,狀況較好(特征值較低意味著較好)、品質較好(特征值較低意味著較好),家具齊全,內置廚房,有電梯的公寓租金是最貴的。
比較有意思的是下面兩個特征的影響:
到最近地鐵站步行時間
方圓一公里內的地鐵站數量
到最近地鐵站步行時間
看起來,對某些公寓而言,較高的特征值意味著價格較高。原因在于,這些公寓位于柏林外富裕的住宅區。
我們也能看到,靠近地鐵站既拉高租金又降低租金。原因可能是靠近地鐵站的公寓出行更方便,但噪音比較大。我們可以進一步探索這一點,比如考慮到最近的公交站的步行時間。
方圓一公里內的地鐵站數量這一特征同理。
集成平均
在探索了不同的模型并比較其表現后,我們可以組合每個模型的結果,創建一個集成模型!
Bagging是利用多種算法的預測計算最終的聚合預測的機器學習集成模型。它的設計有助于防止過擬合并降低算法的方差。
集成模型的優勢;圖片來源:burakhimmetoglu.com
由于我已經具備了上述算法的預測,我嘗試了這些算法的各種組合方式,基于在驗證集上的RMSLE得出了7個最佳模型。
然后在測試集上計算這7個模型的RMSLE。
相比之下,集成三種基于決策樹的模型表現最佳。
我們也可以構建一個加權集成模型,給表現更好的單個模型更多的權重。背后的依據是,僅當其他模型在另一種替代預測上取得一致時,才能壓過最佳模型一頭。
在現實中,如果不進行嘗試,我們永遠不會知道平均集成會比單個模型的效果更好。
堆疊模型
平均或加權集成并不是組合不同模型預測的唯一方法。我們還能以不同方式堆疊模型!
堆疊模型背后的思路是創建若干基礎模型,然后創建一個元模型,元模型根據基礎模型的結果生成最終預測。然而,如何訓練元模型并不是顯而易見的,否則元模型很容易偏向最佳的基礎模型。burakhimmetoglu寫的Stacking models for improved predictions(堆疊模型以改進預測)很好地解釋了如何正確地做到這一點。
在我們的租金預測中,堆疊模型完全沒有提升RMSLE——甚至結果更差了??赡艿脑蛴泻芏唷苍S我的代碼寫錯了;),或者堆疊引入了過多噪聲。
如果你對更多關于集成模型和堆疊模型的內容感興趣,Triskelion的文章Kaggle Ensemble Guide(Kaggle集成指南)講解了許多不同種類的集成方法,并比較了它們的表現,也討論了堆疊模型是如何成為Kaggle競賽的王者。
總結
留心周圍人談話的內容;他們抱怨的東西可能給你提供啟發。
提供可交互的面板讓人們找到自己的洞見。
不要讓自己局限于常見的特征工程方法,比如將兩個變量相乘。嘗試尋找其他數據來源或解釋。
嘗試集成模型和堆疊模型,因為這些方法可能可以提升表現。
最后,別忘了提供數據的日期!
-
可視化
+關注
關注
1文章
1194瀏覽量
20934 -
機器學習
+關注
關注
66文章
8407瀏覽量
132567 -
數據科學
+關注
關注
0文章
165瀏覽量
10053
原文標題:以房租分析為例:如何從頭創建數據科學項目
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論