[Kaggle] How to kaggle?

成立於2010年的Kaggle是一個進行數據發掘和預測競賽的在線平臺。與Kaggle合做以後,一家公司能夠提供一些數據,進而提出一個問題,Kaggle網站上的計算機科學家和數學家,也就是如今所說的數據科學家,將受領任務,提供潛在的解決方案。html

重要的是,參與競賽的這些科學家並不侷限於一個答案,他們能夠在截止日期以前修改本身的答案,進而推進本身和整個社區向着最佳答案不斷進步。Kaggle聯合創始人兼CEO安東尼·高德布盧姆(Anthony Goldbloom)解釋說:「準確度不斷提高,他們都傾向於同一個解決方案。python

凡是玩數據科學和機器學習的老司機,有兩個網站必定不會錯過:GitHub Kaggle。前者用來分享,後者進行實戰練習。git

 

 

 

初識 Kaggle


泰坦尼克生存模型

Ref: New to Data Science?正則表達式

  1. what sorts of people were likely to survive. 
  2. In particular, we ask you to apply the tools of machine learning to predict which passengers survived the tragedy.

Practice Skills算法

  • Binary classification
  • Python and R basics

 

1、數據格式

 

Variable Definition Key
survival Survival 0 = No, 1 = Yes
pclass Ticket class 1 = 1st, 2 = 2nd, 3 = 3rd
sex Sex  
Age Age in years  
sibsp # of siblings / spouses aboard the Titanic  
parch # of parents / children aboard the Titanic  
ticket Ticket number  
fare Passenger fare  
cabin Cabin number  
embarked Port of Embarkation C = Cherbourg, Q = Queenstown, S = Southampton

 

 

2、分析預測思路

From: http://www.cnblogs.com/cutd/p/5713520.htmlexpress

業務熟悉的重要性

咱們都知道婦女和兒童更可能被救。所以,年齡性別極可能更好的幫助咱們預測。數組

認爲乘客的船層可能會影響結果也是符合邏輯的,由於第一層的船艙更靠近船的甲板。Fare票價和乘客所住船層相關,並且多是高度相關的,可是也可能會增長一些額外的信息。網絡

SibSp、Parch兄弟姐妹、配偶、父母/孩子的數量極可能關係到是否被某一個或不少我的救,會有不少人去幫助你或者有不少人想到你嘗試去救你。app

Embarked登船(也許有一些信息和怎麼靠近船的頂部的人的船艙有關),Ticket票號和Name名字。dom

這一步一般是習得相關的領域知識[要對業務比較深刻],這對於絕大多數機器學習任務來講很是很是很是的重要。

【特徵的重要性有時候要超過模型的選擇】

 

 

開始分析

如下信息取自於:http://www.cnblogs.com/cutd/tag/kaggle/

1、Pre-processing

讀數據,清理數據。

>>> import pandas
>>> import numpy
>>> import matplotlib.pyplot

>>> //讀數據
>>> titanic = pandas.read_csv("train.csv")

>>> //顯示數據統計概況
>>> print(titanic.describe())
       PassengerId    Survived      Pclass         Age       SibSp  \
count   891.000000  891.000000  891.000000  714.000000  891.000000   
mean    446.000000    0.383838    2.308642   29.699118    0.523008   
std     257.353842    0.486592    0.836071   14.526497    1.102743   
min       1.000000    0.000000    1.000000    0.420000    0.000000   
25%     223.500000    0.000000    2.000000   20.125000    0.000000   
50%     446.000000    0.000000    3.000000   28.000000    0.000000   
75%     668.500000    1.000000    3.000000   38.000000    1.000000   
max     891.000000    1.000000    3.000000   80.000000    8.000000   

            Parch        Fare  
count  891.000000  891.000000  
mean     0.381594   32.204208  
std      0.806057   49.693429  
min      0.000000    0.000000  
25%      0.000000    7.910400  
50%      0.000000   14.454200  
75%      0.000000   31.000000  
max      6.000000  512.329200

>>> //顯示某一列
>>> titanic['Age']
0      22.0
1      38.0
2      26.0
       ... 
888     NaN
889    26.0
890    32.0
Name: Age, dtype: float64

>>> //中值填充缺失值>>> //並賦值回原來的列
>>> titanic['Age'] = titanic['Age'].fillna(titanic['Age'].median())

>>> //非數值列變爲數值形式 
>>> titanic.loc[titanic['Sex']=='male','Sex']   = 0
>>> titanic.loc[titanic['Sex']=='female','Sex'] = 1

>>> //非數值列有哪幾種 
>>> print(titanic["Embarked"].unique())
['S' 'C' 'Q' nan]
>>> //缺失值使用最多的非數值類型填充
>>> titanic['Embarked'] = titanic['Embarked'].fillna('S')

>>> //非數值列變爲數值形式
>>> titanic.loc[titanic['Embarked'] == 'S', 'Embarked'] = 0
>>> titanic.loc[titanic['Embarked'] == 'C', 'Embarked'] = 1
>>> titanic.loc[titanic['Embarked'] == 'Q', 'Embarked'] = 2
清理數據

 

 

 

2、交給機器學習

線性迴歸的等式以下:(y=mx+b)

僅使用age貌似就能達到還不錯的效果。

預測

咱們可使用極好的 scikit-learn庫 來作預測:

# Import the linear regression class
from sklearn.linear_model import LinearRegression # Sklearn also has a helper that makes it easy to do cross validation
from sklearn.cross_validation import KFold # The columns we'll use to predict the target
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"] # Initialize our algorithm class
alg = LinearRegression()
# Generate cross validation folds for the titanic dataset. It return the row indices corresponding to train and test. # We set random_state to ensure we get the same splits every time we run this.
kf = KFold(titanic.shape[0], n_folds=3, random_state=1) predictions = [] for train, test in kf: # The predictors we're using the train the algorithm. Note how we only take the rows in the train folds.
    train_predictors = (titanic[predictors].iloc[train,:]) # The target we're using to train the algorithm.
    train_target = titanic["Survived"].iloc[train] # Training the algorithm using the predictors and target.
 alg.fit(train_predictors, train_target) # We can now make predictions on the test fold
    test_predictions = alg.predict(titanic[predictors].iloc[test,:]) predictions.append(test_predictions)

 

評價

定義偏差的度量標準。

從Kaggle競賽的描述,偏差的度量標準是正確預測的百分比。咱們將使用這個相同的度量標準來測試咱們本地模型的性能。

這個度量標準將基本上是:

(predictions中找到的值 vs 他們在titanic['Survived']的副本中準確對應的值的數量) / (乘客的總數)

在咱們這麼作以前,咱們須要先將三個預測數據集合併到一個列中。由於每個預測數據集是一個numpy(python科學計算庫[注:真正的科學計算庫應該是scipy,而numpy主要是矩陣數組等數據處理運算])數組,咱們可使用一個numpy方法將他們鏈接到一個列裏。
算出predictions預測值中和titanic["Survived"]副本中準確相同的值的比例。這個計算結過應該是一個浮點數(小數)並將它賦值給變量accuracy

import numpy as np # The predictions are in three separate numpy arrays. Concatenate them into one.  # We concatenate them on axis 0, as they only have one axis.
predictions = np.concatenate(predictions, axis=0) # Map predictions to outcomes (only possible outcomes are 1 and 0)
predictions[predictions > .5] = 1 predictions[predictions <=.5] = 0 accuracy = sum(predictions[predictions == titanic['Survived']])/(titanic['Survived'].count())

 

 

3、變得更好 - 邏輯迴歸

咱們有了咱們的第一個預測結果!但是結果並非很好,只有78.3%的正確率。在視頻中,咱們曾提到一種方式使線性迴歸的輸出值介於01之間。這種方法叫作邏輯迴歸
一個好的方法就是將邏輯迴歸當成是線性迴歸的邏輯輸出,因此他的值就是01。用邏輯函數 logit function來完成。輸入任何值到邏輯函數都將經過「壓縮」極值匹配成01。這對咱們來講很是完美,由於咱們只關心兩種輸出結果。
Sklearn有一個邏輯迴歸的類咱們可使用。經過使用一個Sklearn助手函數可使咱們全部的交叉驗證和測試變得更簡單。

Ref: 邏輯迴歸與線性迴歸的區別與聯繫

 

 

4、提交答案

可是咱們須要提交一個答案到比賽中。咱們須要在測試數據上採起一個和訓練數據上同樣的校準的步驟來完成這個事情。

若是咱們沒有校準操做,咱們就不可以利用它作出有效的預測。
這些操做要在咱們對列全部的改變以前進行。


處理titanic_test和處理titanic用一樣的方法。
這涉及到:

    • 使用訓練數據集中的年齡中位數填充「Age」列的的全部缺失值。訓練數據集的年齡已經使用徹底相同的值替換了缺失年齡(由於值已經不一樣了,因此這不能做爲測試集的中位數)。你應該用titanic['Age'].median()去找到中位數。
    • Sex列中的全部male換成0,全部female換成1
    • S填充Embarked列中的全部缺失值。
    • Embarked列中的S換成0C換成1Q換成2
      咱們也須要將Fare列的缺失值替換掉。用.fillna將測試集中的缺失值用中位數替換掉。訓練集中的Fare列沒有缺失值了,可是測試集有時會不一樣。

 

其實就是一樣的預處理,使數據都變得可處理、可操做。

titanic_test = pandas.read_csv("titanic_test.csv") titanic_test['Age'] = titanic_test['Age'].fillna(titanic_test['Age'].median()) titanic_test['Fare'] = titanic_test['Fare'].fillna(titanic_test['Fare'].median()) titanic_test.loc[titanic_test['Sex'] == 'male','Sex'] = 0 titanic_test.loc[titanic_test['Sex'] == 'female','Sex'] = 1 titanic_test['Embarked'] = titanic_test['Embarked'].fillna('S') titanic_test.loc[titanic_test['Embarked'] == 'S', 'Embarked'] = 0 titanic_test.loc[titanic_test['Embarked'] == 'C', 'Embarked'] = 1 titanic_test.loc[titanic_test['Embarked'] == 'Q', 'Embarked'] = 2

 

有了咱們須要生成一個比賽提交答案的全部東西以後,生成一個提交文件。

    1. 首先,咱們必須先在訓練數據上訓練一個算法
    2. 而後咱們在測試數據集上作一個預測
    3. 最後,咱們生成一個包含預測和乘客id的csv文件。
# Initialize the algorithm class
alg = LogisticRegression(random_state=1) # Train the algorithm using all the training data
alg.fit(titanic[predictors], titanic["Survived"])  # 1. # Make predictions using the test set.
predictions = alg.predict(titanic_test[predictors])  # 2. # Create a new dataframe with only the columns Kaggle wants from the dataset.
submission = pandas.DataFrame({              # 3. "PassengerId": titanic_test["PassengerId"], "Survived": predictions })

 

一旦你完成了上面步驟的代碼,你就能用 submission.to_csv('kaggle.csv, index=False')輸出一個csv結果。

這將會給你的第一個條件全部須要的東西——雖然這沒有給你很好的準確率。(~0.75)

因爲咱們的預測在不一樣的數據集上致使在測試集上的分數低於咱們在交叉驗證上的分數。

在下一個任務中咱們將學習如何生成更好的特徵和使用更好的模型來提升咱們的分數。

 

 

開始改進

1、改進特徵 - 隨機森林

詳見:http://www.cnblogs.com/cutd/p/5713525.html

經過求全部樹的平均預測值,咱們能獲得一個更好的總體預測和最小的過擬合。

感謝上帝,sklearn已經實現了一個很是棒的隨機森林。(具體在python章節再詳談)

alg = RandomForestClassifier(random_state=1, n_estimators=10, min_samples_split=2, min_samples_leaf=1)

提升隨機森林的精度:

    • 增長咱們使用的樹的數量。
    • 調整min_samples_splitmin_samples_leaf變量來減小過擬合。

 

 

2、更多的特徵

生成新特徵

使用pandas數據框的.apply 方法來生成新特徵。

挖掘特徵 - 頭銜

咱們能夠從乘客的名字中提取出他們的頭銜。頭銜的格式是Master.,Mr.,Mrs.。有一些很是常見的頭銜,也有一些「長尾理論」中的一次性頭銜只有僅僅一個或者兩個乘客使用。

  1. 第一步使用正則表達式提取頭銜,
  2. 而後將每個惟一頭銜匹配成(map)整型數值。
  3. 以後咱們將獲得一個準確的和Title相對應的數值列。

挖掘特徵 - 家族

咱們也能夠生成一個特徵來表示哪些人是一個家族。由於倖存看起來很是依靠你的家族和你旁邊的人,這是一個成爲好特徵的好機會。
爲了完成這個任務,咱們將經過FamilySize鏈接某些人的姓來獲得一個家庭編號。而後咱們將基於他們的家庭編號給每一個人賦值一個代碼。

 

 

3、找出最好的特徵

在任何的機器學習任務中,特徵工程都是最重要的部分,有許多的特徵可讓咱們計算。可是咱們也須要找到一種方法來計算出哪一個特徵是最好的。
一種方法就是使用單特徵選擇器(univariate feature selection),這種方法的本質是一列一列的遍歷計算出和咱們想要預測的結果(Survived)最密切關聯的那一列。
和之前同樣,sklearn有一個叫作SelectKBest的函數 將會幫助咱們完成特徵選擇。這個函數會從數據中選出最好的特徵,而且容許咱們指定選擇的數量。 

Goto: [Feature] Feature selection【更爲詳細】

 

 

 

繼續改進

1、改進特徵 - 梯度提高(Gradient Boosting)

另一種方法是以決策樹爲基礎的梯度提高分類器

提高包含了一個接一個的訓練決策樹,而且將一個樹的偏差傳入到下一棵樹。因此每一顆樹都是以它以前的全部樹爲基礎構造的。

不過若是咱們建造太多的樹會致使過擬合。

    • 當你獲得了100棵左右的樹,這會很是容易過擬合和訓練出數據集中的怪特徵。
    • 當咱們的數據集極小時,咱們將會把樹的數量限制在25

另一種防止過擬合的方法就是限制在梯度提高過程當中創建的每一棵樹的深度。咱們將樹的高度限制到3來分避免過擬合。
咱們將試圖用提高來替換掉咱們的隨機森林方法而且觀察是否會提高咱們的預測準確率。

 

 

2、改進特徵 - 集成(Ensembling)

爲了提高咱們的預測準確率,咱們能作的一件事就是 集成不一樣的分類器。集成的意思就是咱們利用一系列的分類器的信息來生成預測結果而不是僅僅用一個。在實踐中,這意味着咱們是求他們預測結果的平均值。
一般來講,咱們集成越多的越不一樣的模型,咱們結果的準確率就會越高。多樣性的意思是模型從不一樣列生成結果,或者使用一個很是不一樣的方法來生成預測結果。

    • 集成一個隨機森林和一個決策樹大概不會獲得一個很是好的結果,由於他們很是的類似。
    • 換句話說,集成一個線性迴歸和一個隨機森林能夠工做得很是棒。

一個關於集成的警示就是咱們使用的分類器的準確率必須都是差很少的。集成一個分類器的準確率比另一個差得多將會致使最後的結果也變差。

在這一節中,咱們將會集成基於大多數線性預測訓練的邏輯迴歸(有一個線性排序,和Survived有一些關聯)和一個在全部預測元素上訓練的梯度提高樹。
在咱們集成的時候會保持事情的簡單——咱們將會求咱們從分類器中獲得的行機率(0~1)的平均值,而後假定全部大於0.5的匹配成1,小於等於0.5的匹配成0

 

 

3、完成一個提交

作兩件事:

    • 在測試集上匹配咱們的變化

    • 在測試集上作預測

如今,咱們有了一個提交!這應該能讓你在排行榜獲得0.799的分數。你可使用submission.to_csv("kaggle.csv",index=False)生成一個提交文件。
你任然能夠在特徵工程上作不少事情:

    • 嘗試用和船艙相關的特徵。
    • 觀察家庭大小特徵是否會有幫助——一個家庭中女性的數量多使全家更可能倖存?
    • 乘客的國籍能爲其倖存提升什麼幫助?

在算法方面咱們也有很是多的事情能夠作:

    • 嘗試在集成中加入隨機森林分類器。
    • 在這個數據上支持向量機也許會頗有效。
    • 咱們能夠試試神經網絡
    • 提高一個不一樣的基礎分類器也許會更好。

集成方法:

    • 多數表決是比機率平均更好的集成方法?

這個數據集很容易過擬合,由於沒有不少的數據,因此你將會獲得很小的準確率提高。

 

End.

相關文章
相關標籤/搜索