Kaggle如何入門?

雖然有官方Tutorial: Tutorials | Kaggle,但感覺不是很全面。
有沒有參與者提供一些經驗見解?


Kaggle 是一個流行的數據科學競賽平台,已被谷歌收購,參閱《業界 | 谷歌雲官方正式宣布收購數據科學社區 Kaggle》。作為一個競賽平台,Kaggle 對於初學者來說可能有些難度。畢竟其中的一些競賽有高達 100 萬美元的獎金池和數百位參賽者。頂級的團隊在處理機場安全提升或衛星數據分析等任務上擁有數十年積累的經驗。為了幫助初學者入門 Kaggle,EliteDataScience 近日發表了一篇入門介紹文章,解答了一些初學者最常遇到的問題。機器之心對這篇文章進行了編譯介紹,另外也增加了一些機器之心之前發過的文章作為補充資源。

文章標題:Kaggle初學者五步入門指南,七大訣竅助你享受競賽

首先,我們要清楚了解:

Kaggle 競賽和「經典的」數據科學有一些重要的不同之處,但只要你以正確的心態接觸它,就也能收穫有價值的經驗。

讓我們解釋一下:

Kaggle 競賽

本質上,帶有獎金池的競賽必須滿足一些標準:

  • 問題必須困難:競賽不應該是一個下午就能解決的任務。為了得到最好的投資回報,主辦公司會提交他們最大最難的問題。
  • 解決方案必須新:要贏得最新的競賽,你通常需要進行擴展研究、定製演算法、訓練先進的模型等等。
  • 表現必須能比較:競賽必須要決出優勝者,所以你和其他對手的解決方案必須要被評分。

「經典的」數據科學

相對而言,日常所用的數據科學並不需要滿足這些標準。

  • 問題可能簡單。實際上,數據科學家應該儘力確認易於實現的成果:可以快速解決的富有成效的項目。
  • 解決方案可以是成熟的。大多數常見任務(比如探索分析、數據清理、A/B 測試、經典演算法)都已經有了已得到證明的框架。沒必要重新發明輪子。
  • 表現可以是絕對的。即使一個解決方案只是簡單地超越了之前的基準,那也非常有價值。

Kaggle 競賽鼓勵你竭盡所能,而經典數據科學則推崇效率和最大化的業務效果。

Kaggle 競賽值得參加嗎?

儘管 Kaggle 和經典數據科學之間存在差異,但 Kaggle 仍然是一種很好的入門工具。

每個競賽都是獨立的。無需設置項目範圍然後收集數據,這讓你有時間專註其它技能。

練習就是實踐。學習數據科學的最好方法是在做中學。只要沒有每場競賽都獲勝的壓力,你就可以練習各種有趣的問題。

討論和獲勝者採訪很有啟發性。每個競賽都有自己的討論板塊與獲勝者簡報。你可以窺見更有經驗的數據科學家的思考過程。

Kaggle 獲勝者採訪

怎樣入門 Kaggle?

接下來,我們將給出一個按步進行的行動規劃,然後慢慢上升到 Kaggle 競賽中。

第一步:選擇一種編程語言

首先,我們推薦你選擇一種編程語言,並堅持使用。Python 和 R 在 Kaggle 和更廣泛的數據科學社區上都很流行。

如果你是一個毫無經驗的新手,我們推薦 Python,因為這是一種通用編程語言,你可以在整個流程中都使用它。

參考:

  • 數據科學領域 R vs Python
  • 如何為數據科學學習 Python
  • 深度 | R vs Python:R 是現在最好的數據科學語言嗎?
  • 業界 | 超越 R,Python 成為最受歡迎的機器學習語言

第二步:學習探索數據的基礎

載入、瀏覽和繪製你的數據(即探索性分析)的能力是數據科學的第一步,因為它可以為你將在模型訓練過程中做的各種決策提供信息。

如果你選擇了 Python 路線,那麼我們推薦你使用專門為這個目的設計的 Seaborn 庫。其中有高層面的繪圖函數,可以繪製許多最常見和有用的圖表。

參考:

  • Seaborn 庫
  • Python Seaborn 教程
  • 資源 | 2017 年最流行的 15 個數據科學 Python 庫

第三步:訓練你的第一個機器學習模型

在進入 Kaggle 之前,我們推薦你先在更簡單更容易管理的數據集上訓練一個模型。這能讓你熟悉機器學習庫,為以後的工作做鋪墊。

關鍵在於培養良好的習慣,比如將你的數據集分成獨立的訓練集和測試集,交叉驗證避免過擬合以及使用合適的表現評價指標。

對於 Python,最好的通用機器學習庫是 Scikit-Learn。

參考:

  • Scikit-Learn 庫
  • Python Scikit-Learn 教程
  • 7 天應用機器學習速成課
  • 只需十四步:從零開始掌握 Python 機器學習(附資源)
  • 教程 | Kaggle CTO Ben Hamner :機器學習的八個步驟

第四步:解決入門級競賽

現在我們已經準備好嘗試 Kaggle 競賽了,這些競賽分成幾個類別。最常見的類別是:

  • Featured:這些通常是由公司、組織甚至政府贊助的,獎金池最大。
  • Research:這些是研究方向的競賽,只有很少或沒有獎金。它們也有非傳統的提交流程。
  • Recruitment:這些是由想要招聘數據科學家的公司贊助的。目前仍然相對少見。
  • Getting Started:這些競賽的結構和 Featured 競賽類似,但沒有獎金。它們有更簡單的數據集、大量教程和滾動的提交窗口讓你可以隨時輸入。

Getting Started 競賽非常適合初學者,因為它們給你提供了低風險的學習環境,並且還有很多社區創造的教程:https://www.kaggle.com/c/titanic#tutorials

第五步:比賽是為了更好地學習,而不是賺錢

有了上面的基礎,就可以參與到 Featured 競賽中了。一般來說,為了取得好排名,通常需要遠遠更多的時間和精力。

因此,我們建議你明智地選擇參與項目。參加競賽能幫你深入到你希望長期參與的技術領域中。

儘管獎金很誘人,但更有價值(也更可靠)的回報是為你的未來事業所獲得的技能。

享受 Kaggle 的小訣竅

最後,我們將介紹幾個參與 Kaggle 的最受歡迎的訣竅,希望能幫你享受你的 Kaggle 時光。

訣竅 1:設置循序漸進的目標

如果你曾經玩過什麼讓人上癮的遊戲,你就知道循序漸進的目標的重要性。那就是好遊戲讓人著迷的訣竅。每一個目標都要足夠大,以便帶來成就感;但也不能太大,不然無法實現。

大多數 Kaggle 參與者都沒贏過任何一場競賽,這完全正常。如果把獲勝作為第一個里程碑,你可能會失望,嘗試幾次之後可能就會失去動力。循序漸進的目標會讓你的旅程更加愉快。比如:

  • 提交一個超越基準解決方案的方案
  • 在一場競賽中進入排名前 50%
  • 在一場競賽中進入排名前 25%
  • 在三場競賽中進入排名前 25%
  • 在一場競賽中進入排名前 10%
  • 贏得一場競賽!

這種策略讓你可以一路衡量你的進展和進步。

訣竅 2:查閱得票最多的 kernel

Kaggle 有一個非常厲害的功能:參與者可以提交 kernel,即用於探索一個概念、展示一種技術或分享一種解決方案的短腳本。

當你開始一場競賽或感覺進步停滯時,查閱受歡迎的 kernel 或許能給你帶來靈感。

訣竅 3:在論壇中提問

不要害怕問「愚蠢的」問題。

提問能遇到的最糟糕的事情是什麼?也許你會被忽視……僅此而已。

另一方面,你能得到很多回報,包括來自經驗更豐富的數據科學家的建議和指導。

訣竅 4:獨立發展核心技能

開始的時候,我們建議你獨自工作。這將迫使你解決應用性機器學習流程中的每一步,包括探索性分析、數據清理、特徵工程和模型訓練。

如果過早地和人組隊,你就可能會錯失發展這些基本技能的機會。

訣竅 5:組隊以拓展你的極限

雖然太早組隊不好,但在未來的比賽中組隊讓你能向其他人學習,進而拓展你的極限。過去的許多獲勝者都是團隊,這讓他們可以結合彼此的知識共同施展力量。

此外,一旦你掌握了機器學習的技術技能,你就可以與其他可能比你有更多領域知識的人合作,進一步擴展你的機遇。

訣竅 6:記住 Kaggle 可以成為你的墊腳石

記住,你不一定要成為一個長期的 Kaggle 人。如果發現你不喜歡這種形式,也沒什麼大不了的。

實際上,許多人在做自己的項目或成為全職數據科學家之前都會使用 Kaggle 作為自己的墊腳石。

所以你的關注重點應該是儘可能地學習。長遠來看,參與能給你帶來相關經驗的競賽比參加有最高獎金的競賽更好。

訣竅 7:不要擔心排名低

有些初學者擔心低排名出現在他們的個人資料中,結果一直沒有開始。當然,比賽焦慮是很正常的現象,並不只限於 Kaggle。

但是,排名低真的沒什麼關係。沒人會因此貶低你,因為他們曾經某個時候也是初學者。

即便如此,如果仍然擔心個人資料里的低排名,你可以再單獨創建一個練習賬號。一旦覺得自己能力不錯了,就可以開始用你的「主帳號」來建立豐功偉績了。(再說一下,這麼做毫無必要!)

結論

在這篇指南中,我們分享了上手 Kaggle 的 5 大步驟:

  1. 選擇一種編程語言
  2. 學習探索數據的基礎
  3. 訓練第一個機器學習模型
  4. 解決入門級競賽
  5. 比賽是為了更好地學習,而不是賺錢

最後,我們分享了享受這個平台的 7 個訣竅:

  • 設置循序漸進的目標
  • 查閱得票最多的 kernel
  • 在論壇中提問
  • 獨立發展核心技能
  • 組隊以拓展你的極限
  • 記住 Kaggle 可以成為你的墊腳石
  • 不要擔心排名低

最後附上原文鏈接

以上,希望對你有所幫助。

本文首發於微信公眾號:機器之心(almosthuman2014),如需轉載,請私信聯繫,感謝。


之前在寫答案因疏忽沒有附上原文鏈接,引起了歧義,造成了對原作者實際的侵權,以及對各位知友的誤導…我再次表示非常抱歉,我確實是像某答案描述的一樣,做了一個很努力的搬運工,無論因何種原因,在此我都很羞愧,覺得做了一件非常差的事情。我初衷真的是以分享好東西為目的,懇請原作者能對我給予原諒…這個答案本身存在的意義已經顯得很尷尬,但它既然能在高票,印證了原作者的文章是寫的很精彩的(當初也是看了很多篇之後決定分享這個)…

我思來想去。覺得這段話應該永遠的留在這讓我引以為戒(不是貪幾百個贊,因為我200個回答已經快40000贊),主要是為了接受大家的批評與自我提醒…我之前也看到過不少回答與文章與國外和某些博客的內容有大量重疊,包括我自己的文章也經常被不規範轉載。己所不欲,卻施於人,我自己的意識確實太淡泊了。匿名是因為真的感到很羞恥,大家就不要來花式吊打我了…

我會再整理一些資料附到答案的末尾,以至於這個答案不會那麼尷尬…

再次表示對不起…

關於原回答:(鏈接一開始遺失未附)

送一篇非常好的文章,https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/

首先簡單介紹一些關於 Kaggle 比賽的知識:

1. 不同比賽有不同的任務,分類、回歸、推薦、排序等。比賽開始後訓練集和測試集就會開放下載。

2. 比賽通常持續 2 ~ 3 個月,每個隊伍每天可以提交的次數有限,通常為 5 次。

3. 比賽結束前一周是一個 Deadline,在這之後不能再組隊,也不能再新加入比賽。所以想要參加比賽請務必在這一 Deadline 之前有過至少一次有效的提交

4. 一般情況下在提交後會立刻得到得分的反饋。不同比賽會採取不同的評分基準,可以在分數欄最上方看到使用的評分方法。

5. 反饋的分數是基於測試集的一部分計算的,剩下的另一部分會被用於計算最終的結果。所以最後排名會變動。

6. LB 指的就是在 Leaderboard 得到的分數,由上,有 Public LBPrivate LB 之分。

7. 自己做的 Cross Validation 得到的分數一般稱為 CV 或是 Local CV。一般來說 CV 的結果比 LB 要可靠。

8. 新手可以從比賽的 ForumScripts 中找到許多有用的經驗和洞見。不要吝嗇提問,Kaggler 都很熱情。


要想拿到一個好的成績,主要分一下幾步:


Data Exploration

在這一步要做的基本就是 EDA (Exploratory Data Analysis),也就是對數據進行探索性的分析,從而為之後的處理和建模提供必要的結論。

通常我們會用 pandas 來載入數據,並做一些簡單的可視化來理解數據。

Visualization

Python通常來說 matplotlibseaborn 提供的繪圖功能就可以滿足需求了。R的ggplot2則足以滿足功能


比較常用的圖表有:

  • 查看目標變數的分布。當分布不平衡時,根據評分標準和具體模型的使用不同,可能會嚴重影響性能。
  • Numerical Variable,可以用 Box Plot 來直觀地查看它的分布。
  • 對於坐標類數據,可以用 Scatter Plot 來查看它們的分布趨勢和是否有離群點的存在。
  • 對於分類問題,將數據根據 Label 的不同著不同的顏色繪製出來,這對 Feature 的構造很有幫助。
  • 繪製變數之間兩兩的分布和相關度圖表。

這裡有一個在著名的 Iris 數據集上做了一系列可視化的例子,非常有啟發性。

Statistical Tests

我們可以對數據進行一些統計上的測試來驗證一些假設的顯著性。雖然大部分情況下靠可視化就能得到比較明確的結論,但有一些定量結果總是更理想的。不過,在實際數據中經常會遇到非 i.i.d. 的分布。所以要注意測試類型的的選擇和對顯著性的解釋。

在某些比賽中,由於數據分布比較奇葩或是雜訊過強,Public LB 的分數可能會跟 Local CV 的結果相去甚遠。可以根據一些統計測試的結果來粗略地建立一個閾值,用來衡量一次分數的提高究竟是實質的提高還是由於數據的隨機性導致的。

Data Preprocessing

大部分情況下,在構造 Feature 之前,我們需要對比賽提供的數據集進行一些處理。通常的步驟有:

  • 有時數據會分散在幾個不同的文件中,需要 Join 起來。
  • 處理 Missing Data
  • 處理 Outlier
  • 必要時轉換某些 Categorical Variable 的表示方式。
  • 有些 Float 變數可能是從未知的 Int 變數轉換得到的,這個過程中發生精度損失會在數據中產生不必要的 Noise,即兩個數值原本是相同的卻在小數點後某一位開始有不同。這對 Model 可能會產生很負面的影響,需要設法去除或者減弱 Noise。

這一部分的處理策略多半依賴於在前一步中探索數據集所得到的結論以及創建的可視化圖表。在實踐中,我建議使用 iPython Notebook 進行對數據的操作,並熟練掌握常用的 pandas 函數。這樣做的好處是可以隨時得到結果的反饋和進行修改,也方便跟其他人進行交流(在 Data Science 中 Reproducible Results 是很重要的)。


下面給兩個例子。

Outlier

這是經過 Scaling 的坐標數據。可以發現右上角存在一些離群點,去除以後分布比較正常。

Dummy Variables

對於 Categorical Variable,常用的做法就是 One-hot encoding。即對這一變數創建一組新的偽變數,對應其所有可能的取值。這些變數中只有這條數據對應的取值為 1,其他都為 0。

如下,將原本有 7 種可能取值的 Weekdays 變數轉換成 7 個 Dummy Variables。

要注意,當變數可能取值的範圍很大(比如一共有成百上千類)時,這種簡單的方法就不太適用了。這時沒有有一個普適的方法,但我會在下一小節描述其中一種。

Feature Engineering

有人總結 Kaggle 比賽是 「Feature 為主,調參和 Ensemble 為輔」,我覺得很有道理。Feature Engineering 能做到什麼程度,取決於對數據領域的了解程度。比如在數據包含大量文本的比賽中,常用的 NLP 特徵就是必須的。怎麼構造有用的 Feature,是一個不斷學習和提高的過程。

一般來說,當一個變數從直覺上來說對所要完成的目標有幫助,就可以將其作為 Feature。至於它是否有效,最簡單的方式就是通過圖表來直觀感受。比如:

Feature Selection

總的來說,我們應該生成盡量多的 Feature,相信 Model 能夠挑出最有用的 Feature。但有時先做一遍 Feature Selection 也能帶來一些好處:

  • Feature 越少,訓練越快。
  • 有些 Feature 之間可能存在線性關係,影響 Model 的性能。
  • 通過挑選出最重要的 Feature,可以將它們之間進行各種運算和操作的結果作為新的 Feature,可能帶來意外的提高。

Feature Selection 最實用的方法也就是看 Random Forest 訓練完以後得到的 Feature Importance 了。其他有一些更複雜的演算法在理論上更加 Robust,但是缺乏實用高效的實現,比如這個。從原理上來講,增加 Random Forest 中樹的數量可以在一定程度上加強其對於 Noisy Data 的 Robustness。

看 Feature Importance 對於某些數據經過脫敏處理的比賽尤其重要。這可以免得你浪費大把時間在琢磨一個不重要的變數的意義上。

Feature Encoding

這裡用一個例子來說明在一些情況下 Raw Feature 可能需要經過一些轉換才能起到比較好的效果。

假設有一個 Categorical Variable 一共有幾萬個取值可能,那麼創建 Dummy Variables 的方法就不可行了。這時一個比較好的方法是根據 Feature Importance 或是這些取值本身在數據中的出現頻率,為最重要(比如說前 95% 的 Importance)那些取值(有很大可能只有幾個或是十幾個)創建 Dummy Variables,而所有其他取值都歸到一個「其他」類裡面。

Model Selection

準備好 Feature 以後,就可以開始選用一些常見的模型進行訓練了。Kaggle 上最常用的模型基本都是基於樹的模型:

  • Gradient Boosting
  • Random Forest
  • Extra Randomized Trees

以下模型往往在性能上稍遜一籌,但是很適合作為 Ensemble 的 Base Model。這一點之後再詳細解釋。(當然,在跟圖像有關的比賽中神經網路的重要性還是不能小覷的。)

  • SVM
  • Linear Regression
  • Logistic Regression
  • Neural Networks

以上這些模型基本都可以通過 sklearn 來使用。

當然,這裡不能不提一下 XgboostGradient Boosting 本身優秀的性能加上 Xgboost 高效的實現,使得它在 Kaggle 上廣為使用。幾乎每場比賽的獲獎者都會用 Xgboost 作為最終 Model 的重要組成部分。在實戰中,我們往往會以 Xgboost 為主來建立我們的模型並且驗證 Feature 的有效性。順帶一提,在 Windows 上安裝 Xgboost 很容易遇到問題,目前已知最簡單、成功率最高的方案可以參考我在這篇帖子中的描述

Model Training

在訓練時,我們主要希望通過調整參數來得到一個性能不錯的模型。一個模型往往有很多參數,但其中比較重要的一般不會太多。比如對 sklearn 的 RandomForestClassifier 來說,比較重要的就是隨機森林中樹的數量 n_estimators 以及在訓練每棵樹時最多選擇的特徵數量 max_features。所以我們需要對自己使用的模型有足夠的了解,知道每個參數對性能的影響是怎樣的

通常我們會通過一個叫做 Grid Search 的過程來確定一組最佳的參數。其實這個過程說白了就是根據給定的參數候選對所有的組合進行暴力搜索。


param_grid = {"n_estimators": [300, 500], "max_features": [10, 12, 14]}
model = grid_search.GridSearchCV(estimator=rfr, param_grid=param_grid, n_jobs=1, cv=10, verbose=20, scoring=RMSE)
model.fit(X_train, y_train)

順帶一提,Random Forest 一般在 max_features 設為 Feature 數量的平方根附近得到最佳結果。

這裡要重點講一下 Xgboost 的調參。通常認為對它性能影響較大的參數有:

  • eta:每次迭代完成後更新權重時的步長。越小訓練越慢。
  • num_round:總共迭代的次數。
  • subsample:訓練每棵樹時用來訓練的數據佔全部的比例。用於防止 Overfitting。
  • colsample_bytree:訓練每棵樹時用來訓練的特徵的比例,類似 RandomForestClassifier 的 max_features。
  • max_depth:每棵樹的最大深度限制。與 Random Forest 不同,Gradient Boosting 如果不對深度加以限制,最終是會 Overfit 的
  • early_stopping_rounds:用於控制在 Out Of Sample 的驗證集上連續多少個迭代的分數都沒有提高後就提前終止訓練。用於防止 Overfitting。

一般的調參步驟是:

  1. 將訓練數據的一部分划出來作為驗證集。
  2. 先將 eta 設得比較高(比如 0.1),num_round 設為 300 ~ 500。
  3. 用 Grid Search 對其他參數進行搜索
  4. 逐步將 eta 降低,找到最佳值。
  5. 以驗證集為 watchlist,用找到的最佳參數組合重新在訓練集上訓練。注意觀察演算法的輸出,看每次迭代後在驗證集上分數的變化情況,從而得到最佳的 early_stopping_rounds。

X_dtrain, X_deval, y_dtrain, y_deval = cross_validation.train_test_split(X_train, y_train, random_state=1026, test_size=0.3)
dtrain = xgb.DMatrix(X_dtrain, y_dtrain)
deval = xgb.DMatrix(X_deval, y_deval)
watchlist = [(deval, "eval")]
params = {
"booster": "gbtree",
"objective": "reg:linear",
"subsample": 0.8,
"colsample_bytree": 0.85,
"eta": 0.05,
"max_depth": 7,
"seed": 2016,
"silent": 0,
"eval_metric": "rmse"
}
clf = xgb.train(params, dtrain, 500, watchlist, early_stopping_rounds=50)
pred = clf.predict(xgb.DMatrix(df_test))

最後要提一點,所有具有隨機性的 Model 一般都會有一個 seed 或是 random_state 參數用於控制隨機種子。得到一個好的 Model 後,在記錄參數時務必也記錄下這個值,從而能夠在之後重現 Model。

Cross Validation

Cross Validation 是非常重要的一個環節。它讓你知道你的 Model 有沒有 Overfit,是不是真的能夠 Generalize 到測試集上。在很多比賽中 Public LB 都會因為這樣那樣的原因而不可靠。當你改進了 Feature 或是 Model 得到了一個更高的 CV 結果,提交之後得到的 LB 結果卻變差了,一般認為這時應該相信 CV 的結果。當然,最理想的情況是多種不同的 CV 方法得到的結果和 LB 同時提高,但這樣的比賽並不是太多。

在數據的分布比較隨機均衡的情況下,5-Fold CV 一般就足夠了。如果不放心,可以提到 10-Fold但是 Fold 越多訓練也就會越慢,需要根據實際情況進行取捨。

很多時候簡單的 CV 得到的分數會不大靠譜,Kaggle 上也有很多關於如何做 CV 的討論。比如這個。但總的來說,靠譜的 CV 方法是 Case By Case 的,需要在實際比賽中進行嘗試和學習,這裡就不再(也不能)敘述了。

Ensemble Generation

Ensemble Learning 是指將多個不同的 Base Model 組合成一個 Ensemble Model 的方法。它可以同時降低最終模型的 Bias 和 Variance(證明可以參考這篇論文,我最近在研究類似的理論,可能之後會寫新文章詳述),從而在提高分數的同時又降低 Overfitting 的風險。在現在的 Kaggle 比賽中要不用 Ensemble 就拿到獎金幾乎是不可能的。

常見的 Ensemble 方法有這麼幾種:

  • Bagging:使用訓練數據的不同隨機子集來訓練每個 Base Model,最後進行每個 Base Model 權重相同的 Vote。也即 Random Forest 的原理。
  • Boosting:迭代地訓練 Base Model,每次根據上一個迭代中預測錯誤的情況修改訓練樣本的權重。也即 Gradient Boosting 的原理。比 Bagging 效果好,但更容易 Overfit。
  • Blending:用不相交的數據訓練不同的 Base Model,將它們的輸出取(加權)平均。實現簡單,但對訓練數據利用少了。
  • Stacking:接下來會詳細介紹。

從理論上講,Ensemble 要成功,有兩個要素:

  • Base Model 之間的相關性要儘可能的小。這就是為什麼非 Tree-based Model 往往表現不是最好但還是要將它們包括在 Ensemble 裡面的原因。Ensemble 的 Diversity 越大,最終 Model 的 Bias 就越低。
  • Base Model 之間的性能表現不能差距太大。這其實是一個 Trade-off,在實際中很有可能表現相近的 Model 只有寥寥幾個而且它們之間相關性還不低。但是實踐告訴我們即使在這種情況下 Ensemble 還是能大幅提高成績。

Stacking

相比 Blending,Stacking 能更好地利用訓練數據。以 5-Fold Stacking 為例,它的基本原理如圖所示:

整個過程很像 Cross Validation。首先將訓練數據分為 5 份,接下來一共 5 個迭代,每次迭代時,將 4 份數據作為 Training Set 對每個 Base Model 進行訓練,然後在剩下一份 Hold-out Set 上進行預測。同時也要將其在測試數據上的預測保存下來。這樣,每個 Base Model 在每次迭代時會對訓練數據的其中 1 份做出預測,對測試數據的全部做出預測。5 個迭代都完成以後我們就獲得了一個 #訓練數據行數 x #Base Model 數量 的矩陣,這個矩陣接下來就作為第二層的 Model 的訓練數據。當第二層的 Model 訓練完以後,將之前保存的 Base Model 對測試數據的預測(因為每個 Base Model 被訓練了 5 次,對測試數據的全體做了 5 次預測,所以對這 5 次求一個平均值,從而得到一個形狀與第二層訓練數據相同的矩陣)拿出來讓它進行預測,就得到最後的輸出。

這裡給出我的實現代碼:


class Ensemble(object):
def __init__(self, n_folds, stacker, base_models):
self.n_folds = n_folds
self.stacker = stacker
self.base_models = base_models
def fit_predict(self, X, y, T):
X = np.array(X)
y = np.array(y)
T = np.array(T)
folds = list(KFold(len(y), n_folds=self.n_folds, shuffle=True, random_state=2016))
S_train = np.zeros((X.shape[0], len(self.base_models)))
S_test = np.zeros((T.shape[0], len(self.base_models)))
for i, clf in enumerate(self.base_models):
S_test_i = np.zeros((T.shape[0], len(folds)))
for j, (train_idx, test_idx) in enumerate(folds):
X_train = X[train_idx]
y_train = y[train_idx]
X_holdout = X[test_idx]
# y_holdout = y[test_idx]
clf.fit(X_train, y_train)
y_pred = clf.predict(X_holdout)[:]
S_train[test_idx, i] = y_pred
S_test_i[:, j] = clf.predict(T)[:]
S_test[:, i] = S_test_i.mean(1)
self.stacker.fit(S_train, y)
y_pred = self.stacker.predict(S_test)[:]

return y_pred、

獲獎選手往往會使用比這複雜得多的 Ensemble,會出現三層、四層甚至五層,不同的層數之間有各種交互,還有將經過不同的 Preprocessing 和不同的 Feature Engineering 的數據用 Ensemble 組合起來的做法。但對於新手來說,穩穩噹噹地實現一個正確的 5-Fold Stacking 已經足夠了。

Pipeline

可以看出 Kaggle 比賽的 Workflow 還是比較複雜的。尤其是 Model Selection 和 Ensemble。理想情況下,我們需要搭建一個高自動化的 Pipeline,它可以做到:

  • 模塊化 Feature Transform,只需寫很少的代碼就能將新的 Feature 更新到訓練集中。
  • 自動化 Grid Search,只要預先設定好使用的 Model 和參數的候選,就能自動搜索並記錄最佳的 Model。
  • 自動化 Ensemble Generation,每個一段時間將現有最好的 K 個 Model 拿來做 Ensemble。

對新手來說,第一點可能意義還不是太大,因為 Feature 的數量總是人腦管理的過來的;第三點問題也不大,因為往往就是在最後做幾次 Ensemble。但是第二點還是很有意義的,手工記錄每個 Model 的表現不僅浪費時間而且容易產生混亂。

Crowdflower Search Results Relevance 的第一名獲得者 Chenglong Chen 將他在比賽中使用的 Pipeline 公開了,非常具有參考和借鑒意義。只不過看懂他的代碼並將其中的邏輯抽離出來搭建這樣一個框架,還是比較困難的一件事。可能在參加過幾次比賽以後專門抽時間出來做會比較好。

----------------一個實際的例子-----------------

Home Depot Search Relevance

在這一節中我會具體分享我在 Home Depot Search Relevance 比賽中是怎麼做的,以及比賽結束後從排名靠前的隊伍那邊學到的做法。

首先簡單介紹這個比賽。Task 是判斷用戶搜索的關鍵詞和網站返回的結果之間的相關度有多高。相關度是由 3 個人類打分取平均得到的,每個人可能打 1 ~ 3 分,所以這是一個回歸問題。數據中包含用戶的搜索詞,返回的產品的標題和介紹,以及產品相關的一些屬性比如品牌、尺寸、顏色等。使用的評分基準是 RMSE。

這個比賽非常像 Crowdflower Search Results Relevance 那場比賽。不過那邊用的評分基準是 Quadratic Weighted Kappa,把 1 誤判成 4 的懲罰會比把 1 判成 2 的懲罰大得多,所以在最後 Decode Prediction 的時候會更麻煩一點。除此以外那次比賽沒有提供產品的屬性。

EDA

由於加入比賽比較晚,當時已經有相當不錯的 EDA 了。尤其是這個。從中我得到的啟發有:

  • 同一個搜索詞/產品都出現了多次,數據分布顯然不 i.i.d.
  • 文本之間的相似度很有用。
  • 產品中有相當大一部分缺失屬性,要考慮這會不會使得從屬性中得到的 Feature 反而難以利用。
  • 產品的 ID 對預測相關度很有幫助,但是考慮到訓練集和測試集之間的重疊度並不太高,利用它會不會導致 Overfitting?

Preprocessing

這次比賽中我的 Preprocessing 和 Feature Engineering 的具體做法都可以在這裡看到。我只簡單總結一下和指出重要的點。

  1. 利用 Forum 上的 Typo Dictionary 修正搜索詞中的錯誤。
  2. 統計屬性的出現次數,將其中出現次數多又容易利用的記錄下來。
  3. 將訓練集和測試集合併,並與產品描述和屬性 Join 起來。這是考慮到後面有一系列操作,如果不合併的話就要重複寫兩次了。
  4. 對所有文本能做 StemmingTokenizing,同時手工做了一部分格式統一化(比如涉及到數字和單位的)同義詞替換

Feature

  • *Attribute Features

    • 是否包含某個特定的屬性(品牌、尺寸、顏色、重量、內用/外用、是否有能源之星認證等)
    • 這個特定的屬性是否匹配
  • Meta Features

    • 各個文本域的長度
    • 是否包含屬性域
    • 品牌(將所有的品牌做數值離散化)
    • 產品 ID
  • 簡單匹配

    • 搜索詞是否在產品標題、產品介紹或是產品屬性中出現
    • 搜索詞在產品標題、產品介紹或是產品屬性中出現的數量和比例
    • *搜索詞中的第 i 個詞是否在產品標題、產品介紹或是產品屬性中出現
  • 搜索詞和產品標題、產品介紹以及產品屬性之間的文本相似度

    • BOW Cosine Similairty
    • TF-IDF Cosine Similarity
    • Jaccard Similarity
    • *Edit Distance
    • Word2Vec Distance(由於效果不好,最後沒有使用,但似乎是因為用的不對)
  • Latent Semantic Indexing:通過將 BOW/TF-IDF Vectorization 得到的矩陣進行 SVD 分解,我們可以得到不同搜索詞/產品組合的 Latent 標識。這個 Feature 使得 Model 能夠在一定程度上對不同的組合做出區別,從而解決某些產品缺失某些 Feature 的問題。

值得一提的是,上面打了 * 的 Feature 都是我在最後一批加上去的。問題是,使用這批 Feature 訓練得到的 Model 反而比之前的要差,而且還差不少。我一開始是以為因為 Feature 的數量變多了所以一些參數需要重新調優,但在浪費了很多時間做 Grid Search 以後卻發現還是沒法超過之前的分數。這可能就是之前提到的 Feature 之間的相互作用導致的問題。當時我設想過一個看到過好幾次的解決方案,就是將使用不同版本 Feature 的 Model 通過 Ensemble 組合起來。但最終因為時間關係沒有實現。事實上排名靠前的隊伍分享的解法裡面基本都提到了將不同的 Preprocessing 和 Feature Engineering 做 Ensemble 是獲勝的關鍵。

Model

我一開始用的是 RandomForestRegressor,後來在 Windows 上折騰 Xgboost 成功了就開始用 XGBRegressor。XGB 的優勢非常明顯,同樣的數據它只需要不到一半的時間就能跑完,節約了很多時間。

比賽中後期我基本上就是一邊台式機上跑 Grid Search,一邊在筆記本上繼續研究 Feature。

這次比賽數據分布很不獨立,所以期間多次遇到改進的 Feature 或是 Grid Search 新得到的參數訓練出來的模型反而 LB 分數下降了。由於被很多前輩教導過要相信自己的 CV,我的決定是將 5-Fold 提到 10-Fold,然後以 CV 為標準繼續前進。

Ensemble

最終我的 Ensemble 的 Base Model 有以下四個:

  • RandomForestRegressor
  • ExtraTreesRegressor
  • GradientBoostingRegressor
  • XGBRegressor

第二層的 Model 還是用的 XGB

因為 Base Model 之間的相關都都太高了(最低的一對也有 0.9),我原本還想引入使用 gblinear 的 XGBRegressor 以及 SVR,但前者的 RMSE 比其他幾個 Model 高了 0.02(這在 LB 上有幾百名的差距),而後者的訓練實在太慢了。最後還是只用了這四個。

值得一提的是,在開始做 Stacking 以後,我的 CV 和 LB 成績的提高就是完全同步的了。

在比賽最後兩天,因為身心疲憊加上想不到還能有什麼顯著的改進,我做了一件事情:用 20 個不同的隨機種子來生成 Ensemble,最後取 Weighted Average。這個其實算是一種變相的 Bagging。其意義在於按我實現 Stacking 的方式,我在訓練 Base Model 時只用了 80% 的訓練數據,而訓練第二層的 Model 時用了 100% 的數據,這在一定程度上增大了 Overfitting 的風險。而每次更改隨機種子可以確保每次用的是不同的 80%,這樣在多次訓練取平均以後就相當於逼近了使用 100% 數據的效果。這給我帶來了大約 0.0004 的提高,也很難受說是真的有效還是隨機性了。

比賽結束後我發現我最好的單個 Model 在 Private LB 上的得分是 0.46378,而最終 Stacking 的得分是 0.45849。這是 174 名和 98 名的差距。也就是說,我單靠 Feature 和調參進到了 前 10%,而 Stacking 使我進入了前 5%。

Lessons Learned

比賽結束後一些隊伍分享了他們的解法,從中我學到了一些我沒有做或是做的不夠好的地方:

  • 產品標題的組織方式是有 Pattern 的,比如一個產品是否帶有某附件一定會用 With/Without XXX 的格式放在標題最後。
  • 使用外部數據,比如 WordNet,Reddit 評論數據集等來訓練同義詞和上位詞(在一定程度上替代 Word2Vec)詞典。
  • 基於字母而不是單詞的 NLP Feature。這一點我讓我十分費解,但請教以後發現非常有道理。舉例說,排名第三的隊伍在計算匹配度時,將搜索詞和內容中相匹配的單詞的長度也考慮進去了。這是因為他們發現越長的單詞約具體,所以越容易被用戶認為相關度高。此外他們還使用了逐字元的序列比較(difflib.SequenceMatcher),因為這個相似度能夠衡量視覺上的相似度。像這樣的 Feature 的確不是每個人都能想到的。
  • 標註單詞的詞性,找出中心詞,計算基於中心詞的各種匹配度和距離。這一點我想到了,但沒有時間嘗試。
  • 將產品標題/介紹中 TF-IDF 最高的一些 Trigram 拿出來,計算搜索詞中出現在這些 Trigram 中的比例;反過來以搜索詞為基底也做一遍。這相當於是從另一個角度抽取了一些 Latent 標識。
  • 一些新穎的距離尺度,比如 Word Movers Distance
  • 除了 SVD 以外還可以用上 NMF。
  • 最重要的 Feature 之間的 Pairwise Polynomial Interaction
  • 針對數據不 i.i.d. 的問題,在 CV 時手動構造測試集與驗證集之間產品 ID 不重疊和重疊的兩種不同分割,並以與實際訓練集/測試集的分割相同的比例來做 CV 以逼近 LB 的得分分布

至於 Ensemble 的方法,我暫時還沒有辦法學到什麼,因為自己只有最簡單的 Stacking 經驗。

Summary

Takeaways

  1. 比較早的時候就開始做 Ensemble 是對的,這次比賽到倒數第三天我還在糾結 Feature。
  2. 很有必要搭建一個 Pipeline,至少要能夠自動訓練並記錄最佳參數。
  3. Feature 為王。我花在 Feature 上的時間還是太少。
  4. 可能的話,多花點時間去手動查看原始數據中的 Pattern。

Issues Raised

我認為在這次比賽中遇到的一些問題是很有研究價值的:

  1. 在數據分布並不 i.i.d. 甚至有 Dependency 時如何做靠譜的 CV
  2. 如何量化 Ensemble 中 Diversity vs. Accuracy 的 Trade-off。
  3. 如何處理 Feature 之間互相影響導致性能反而下降。

Beginner Tips

給新手的一些建議:

  1. 選擇一個感興趣的比賽。如果你對相關領域原本就有一些洞見那就更理想了。
  2. 根據我描述的方法開始探索、理解數據並進行建模。
  3. 通過 Forum 和 Scripts 學習其他人對數據的理解和構建 Feature 的方式。
  4. 如果之前有過類似的比賽,可以去找當時獲獎者的 Interview 和 Blog Post 作為參考,往往很有用。
  5. 在得到一個比較不錯的 LB 分數(比如已經接近前 10%)以後可以開始嘗試做 Ensemble。
  6. 如果覺得自己有希望拿到獎金,開始找人組隊吧!
  7. 到比賽結束為止要繃緊一口氣不能斷,盡量每天做一些新嘗試。
  8. 比賽結束後學習排名靠前的隊伍的方法,思考自己這次比賽中的不足和發現的問題,可能的話再花點時間將學到的新東西用實驗進行確認,為下一次比賽做準備
  9. 好好休息!

Reference

  1. Beating Kaggle the Easy Way - Dong Ying
  2. Solution for Prudential Life Insurance Assessment - Nutastray
  3. Search Results Relevance Winner』s Interview: 1st place, Chenglong Chen

用你最喜歡的編程語言和工具庫,獨立完成所有101和 Playground 級別的訓練賽。


Kaggle入門其實是一個很簡單的問題,感謝某勃學家認真的搬運我隊友的blog,連裡面鏈接還都是原文的。

不過不引用原文也不告知原作者,圖還全沒了這是幾個意思嘛。

下面是原文鏈接,隊友dnc1994幾乎一人之力第一次參加kaggle比賽打進top 5%,非常厲害。


https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/

還是資詞一下原創吼不吼啊!

做人要厚道,小心被續啊,已舉報。


不太對題,但是也算對參與Kaggle的同學們一些提醒吧。
機器學習是解決問題的方法一種,但首先必須要理解你的問題本身
如果你要預測航班到點時間,你要怎麼做呢?
1.幫助航空公司明白哪些航班會誤點,他們可以迅速解決問題
2.幫助人們買到不容易誤點的航班
3.提醒人們明天航班可能會誤點
很多時候在項目里,你對問題本身都一團霧水的時候怎麼能夠希望一個有效的模型能解決問題呢?
理解問題還能幫助你做好如下決策
1.我的模型的預測精確度需要到多少?
2.什麼樣的假陽性是可接受的?
3.我能用什麼數據?如果要預測明天的航班看天氣數據就行,如果要預測一個月以後的航班呢?

找出優化指標
還是拿出航班延誤的例子。 首先我們要決定是用分類還是用回歸?拍個腦袋,用回歸吧。
人們通常會優化平方和因為它良好的統計特性,但是在我們的問題里,航班延誤10小時和20小時一樣糟糕,所以平方和合適么?

決定用什麼數據
比方說我已經有了航空公司的航班號,起飛機場,飛機型號,起飛抵達時間
我還需要買別的信息么?更精準的天氣信息?也就是說可用的信息並非固定的,只要你想就可以更多

清理數據
一旦有了數據,你的數據可不是齊整的,如機場命名不一致,沒有延誤信息,奇怪的數據格式,天氣數據與機場地理位置不一致
把數據整理到可用,不是件容易的事。如果還需要整合很多數據源,那麼它可能會佔你80%的時間。

建個模型
這才到了Kaggle部分, 訓練,交叉驗證,Ya
現在你建了一個碉堡的模型,我們要用它。

詳細請見 「機器學習」是什麼


關於入門:
kaggle 的入門可以從101playground 開始,重要的是要開始做,萬事開頭難。
然後平時要多多看高手的文章,獲獎經驗。有的高手獲獎者甚至會把自己的源代碼放上去,你就是去僅僅跑一遍,也能學到非常多的東西。

關於kaggle的問題分類:
一般就是regression,classification, timeseries這幾類。

kaggle的問題一般解決過程:
拿到數據之後,第一步就是data exploration. 這一步就是各種畫圖,找規律,找靈感,找可能的feature. 會R的可以shiny app做一些UI來輔助自己對數據的理解。
然是後選strategy, 從經典的機器學習演算法中,選擇自己要用的模型。一般這個大家都是用現成的包,沒什麼好說的。
如果數據量比較大的話,可能要做batch sampling,上work station.
通常先做一個超級簡單的能跑的模型,之後就是無窮無盡的feature engineering了。。。

一些tips:
classification 問題的大殺器是xgboost.
最終大殺器是ensemble learning.
feature 為王.
細節上,script 最好用svn或者git管理,做的時間長了容易亂。
另外,好像recruiting competitions 更簡單一些,因為沒有什麼獎金。

參加kaggle的好處:
其實就不用說了,學到很多東西,而且通常數據量比較大,所以一個比賽做下來對自己的編程能力提升很高。另外如果成績好的話,在簡歷上絕對是牛逼的一筆,是一些high level job的撬門磚。

kaggle的局限性:
1. kaggle把實際中的數據挖掘問題大大的簡化了,給你的直接是非常好的dataset. 而實際中的問題,做機器學習是萬里長征的最後一步,整個長征都是在做data cleanning...
2. kaggle和統計關係不大,需要用到的統計知識幾乎為零。想要通過做kaggle來學統計是南轅北轍的,還是老老實實去讀個學位吧。

其他:
kaggle的leader board很有意思,public leader board顯示的僅僅是你提交答案一部分的數據分數。不到最後一刻,不知道誰才是真正的winner, 這個過程感覺蠻刺激的。。。


謝邀,
傳送門:kaggle是一個怎樣的競賽模式?


推薦篇文章:機器學習系列(3)_邏輯回歸應用之Kaggle泰坦尼克之災


個人覺得Kaggle是訓練data mining特別好的地方,而對於機器學習的提升並不是特別大。你可以去看已經結束的比賽的winner的解決方案,大部分都是ensemble learning,很少有數學上極其優美的解法。

可以從以下幾個方面入手:
1. Feature Engineering
- continue variable
- categorical variable
2. Classic machine learning algorithm
- LR, KNN, SVM, Random Forest, GBRT, FM, NN
3. Cross validation, model selection
- grid search, random search, hyper-opt
4. Ensemble learning
推薦這篇 Kaggle Ensembling Guide
5. 多看看之前比賽的winner解決方案


前幾天剛好寫了一篇專欄「Kaggle入門,看這一篇就夠了 - 知乎專欄」,看到這個問題忍不住來回答一下。

不知道題主本身是什麼水平,現在就假設一個具有數學/CS/統計背景的同學,對Python和R非常熟悉,想要通過Kaggle比賽來提升自己的實戰能力,最好從以下幾個步驟進行:

1. 了解比賽:獨立完成練習賽。練習賽中的題目數據量小,難度低,同時有標準的官方解釋和大量的民間資源,非常適合上手找感覺。專欄中「0基礎如何上手Kaggle」這一部分中非常貼心的給出了三個經典練習的參考資源供大家練習。

2. 學習比賽:善用平台資源,認真閱讀以往Kaggle項目的Kernels,學習以往的比賽中頂級選手處理這些案例的方法,有問題可以在社區(如Forum)向其他人請教,像這樣水平很高還對新人無比友好的社區大家一定要珍惜。

3. 參加比賽:找幾個隊友,選擇合適的項目,正式開啟Kaggle之旅!這一部分可以參考專欄中的「對於新人,如何在Kaggle中提升排位?」

4. 進階比賽:對於基礎好、目標高的同學,專欄中還給大家提供了一篇「如何在Kaggle首戰中進入前10%」的文章作為參考,也是乾貨滿滿~

我想關注這個問題的大部分人來講,可能並不具備以上背景和能力。那麼,對這樣的同學,我建議從學習一到兩門編程語言開始(Python和R),之後再按照以上步驟來走。

最後,祝你打怪愉快!


我是數據分析門外漢,但因為在設計相關產品,也在入門中。。。公司有3個Top 100的Kaggler,有時候午飯扯淡時會給我們掃掃盲。對於如何入門,他們都是說多看別人的script,自己多試試看。樓上幾個高票回答都說的很好啦。

我歪個樓,說說我覺得好玩的事。大牛們分享Kaggle比賽經驗時,會有很多吐槽。他們會告訴我們什麼是比賽竅門,而什麼是平時真實的數據分析技能,比如:

  • Kaggle的數據通常會有一些leak。也就是說舉辦方一不小心把一個預測性非常強的feature給放出來了,木有藏好。所以很多時候是大家一起來找茬,靠找到這個leak規律贏,比如,timestamp的順序,某個ID什麼的。但這都不是真的data science。極端例子是 Titanic Public Leaderboard - 可以達到100%準確率。。。
  • Kaggle排名很多時候是在糾結於n位小數點兒的準確度,所以大家會花很多時間在互相stack中精進0.00001之類的。這個技能在大多數真實數據分析中,其實不是非常有用。(除非是在做精度要求極高的建模,比如,人命關天的醫療模)
  • Kaggle的有每日上傳script的上限次數,並且有一個很明確的fitness function供人實驗。這個和真實分析有一些區別-會有一定的策略來更好的利用比賽的形式。
  • Kaggle和真實分析一樣的大命題是如何防止overfitting。很多在public leaderboard遙遙領先的人,最後在private leaderboard放出來的時候名次大跌就是沒修鍊到火候。之前聽說調參有江湖先生算命一樣的玄學本質。。我也覺得是對的。。。

好像有些跑題。回來圓一下,咳咳,入門的目的很重要。Kaggle的社區氛圍很好,是很有學習價值的比賽。但如果要拼名次還是有很多捷徑/技巧的。如果是真想學好機器學習應用,光靠Kaggle還是會跑偏的。。。


先從101和Playground開始,重要的是開始做~


先找一些knowledge類的問題練練手
可以學習python 以及他的庫 scipy,numpy,pandas,scikit-learn
也可以使用R語言或者weka
做的時候需要考慮features怎麼選取,慢慢摸索,不斷改進,相信你也會有進步


我很想說,有solid背景和比賽經驗,而且想跳到quant坑裡的請pm我簡歷,該信息長期有效。


Take UC Berkely: COMPSCI 189


多看script,多看forum。


Kaggle系列第一期:Titanic baseline - 知乎專欄

正在做一個專欄,以kaggle各個比賽為引,面向初學者

包含機器學習及數據可視化內容,樓主若有興趣可以一觀


推薦閱讀:

常用的機器學習演算法比較?
不同激活函數(activation function)的神經網路的表達能力是否一致?
實驗室原型到產品,距離、差距有多遠?
基於深度學習的自然語言處理在 2016 年有哪些值得期待的發展?
如何評價Yann LeCun 說的「要研究機器學習,本科應盡量多學物理和數學課」?

TAG:數據挖掘 | 統計學 | 機器學習 | 計算機科學 | Kaggle |