Kaggle入門教程

此爲中文翻譯版python

1:競賽

咱們將學習如何爲Kaggle競賽生成一個提交答案(submisson)。Kaggle是一個你經過完成算法和全世界機器學習從業者進行競賽的網站。若是你的算法精度是給出數據集中最高的,你將贏得比賽。Kaggle也是一個實踐你機器學習技能的很是有趣的方式。
Kaggle網站有幾種不一樣類型的比賽。其中的預測一個就是預測在泰坦尼克號沉沒的時候哪一個乘客會成爲倖存者。 在這個任務和下一個任務咱們將學習如何提交咱們的答案。
咱們的數據是csv格式。你能夠在這裏下載數據開始比賽。
每一行重現了一個在泰坦尼克的乘客以及和他們有關的一些信息。讓咱們來看一下各列:git

  • PassengerId:一個用以標記每一個乘客的數字id
  • Survived:標記乘客是否倖存——倖存(1)、死亡(0)。咱們將預測這一列。
  • Pclass:標記乘客所屬船層——第一層(1),第二層(2),第三層(3)。
  • Name:乘客名字。
  • Sex:乘客性別——男male、女female
  • Age:乘客年齡。部分。
  • SibSp:船上兄弟姐妹和配偶的數量。
  • Parch:船上父母和孩子的數量。
  • Ticket:乘客的船票號碼。
  • Fare:乘客爲船票付了多少錢。
  • Cabin:乘客住在哪一個船艙。
  • Embarked:乘客從哪一個地方登上泰坦尼克號。

一個好的開始就是有條理的思考各個列和咱們的預測之間的邏輯關係。
咱們都知道婦女和兒童更可能被救。所以,年齡性別極可能更好的幫助咱們預測。認爲乘客的船層可能會影響結果也是符合邏輯的,由於第一層的船艙更靠近船的甲板。Fare票價和乘客所住船層相關,並且多是高度相關的,可是也可能會增長一些額外的信息。SibSp、Parch兄弟姐妹、配偶、父母/孩子的數量極可能關係到是否被某一個或不少我的救,會有不少人去幫助你或者有不少人想到你嘗試去救你。
Embarked登船(也許有一些信息和怎麼靠近船的頂部的人的船艙有關),Ticket票號和Name名字。
這一步一般是習得相關的領域知識[要對業務比較深刻],這對於絕大多數機器學習任務來講很是很是很是的重要。
咱們很是細緻的處理特徵以便咱們能從咱們現有的數據中得到最有用的信息來幫助咱們進行預測。算法

2:觀察數據

咱們將使用Python3,pandas庫和scikit-learn庫來分析咱們的數據而且生成一個提交答案submisson。咱們將使用代碼框進行交互式編程,就和你看到的下面那個同樣。若是你對Python還不熟悉,你可能想看一看咱們的課程
一個好的第二步就是仔細觀察數據中的高級描述。在這種狀況下,咱們使用pandas的.describe()方法來查看每一列數值的特性的不一樣之處。編程

# We can use the pandas library in python to read in the csv file.
# This creates a pandas dataframe and assigns it to the titanic variable.
titanic = pandas.read_csv("titanic_train.csv")

# Print the first 5 rows of the dataframe.
print(titanic.describe())

3:缺失數據

在上一節你使用.describe()方法查看titanic數據框的時候,你可能注意到年齡列只有714個計數,而其餘列都有891個計數。這代表在年齡列有一些缺失值——空值(null,NA,非數字)。
這就意味着數據並非徹底的乾淨,咱們必須本身清洗數據。咱們不但願不得不刪除有缺失數據的行,由於更多的數據能幫助咱們訓練出一個更好的算法。固然,咱們也不想刪除整列,由於age年齡極可能對咱們的分析很是重要。
有不少種策略來處理缺失數據,可是一種簡單的方法就是將那一列的缺失值用中位數填充。
咱們能夠像字典同樣經過數據框索引選取一個單列。這樣會給咱們一個pandas Series(序列):數組

titanic['Age']

咱們可使用.fillna方法替換序列中的任何缺失值。.fillna能夠傳入一個參數用參數的值來替換缺失值。
在咱們的例子中,咱們打算用列的中位數來填充:app

titanic['Age'].fillna(titanic['Age'].median())

以後咱們必須將替換後的結果賦值回原來的列:dom

titanic['Age'] = titanic['Age'].fillna(titanic['Age'].median())

4:非數值列

前兩節咱們使用過.describe(),你也許也主要到並非全部的列都顯示出來了。只有數值列顯示了。咱們的列中有幾個是非數值的,當你開始作預測的時候這將是一個問題——咱們不能將非數值列傳入機器學習算法中而且指望機器學習算法能理解他們。
咱們在訓練咱們的算法時要麼必須排除這些非數值列(Name, Sex, Cabin, Embarked, Ticket),要麼就要找到一種方法將他們轉換成數值列。
咱們將忽略Ticket, Cabin,Name這三行。由於咱們不能從他們中提取出太多有用的信息。Cabin列大多數值都是缺失的(891行中只有204行數值),並且起初看起來好像也不是特別有用的列。若是沒有一些關於船票號碼意義的專業領域知識和哪些名字的特色像大戶或者有錢家庭,那麼TicketName列也不太可能會告訴咱們太多的信息。機器學習

5:轉換性別Sex

性別列是非數值的,可是咱們想把它保留——他可能很是有用。咱們將每個性別用數值碼替換將其轉換成一個數值列。以後機器學習算法可以使用這些類別去作預測。
爲了完成這個目的,咱們首先要找出列中全部的惟一性別(咱們知道有male男和female女,可是有沒有可能誰在數據集用的是其餘缺失值代碼呢?)。咱們將0賦值給male,將1賦值給female。
咱們能夠選擇Sex列的全部值爲male的行而且用0替換male:函數

titanic.loc[titanic['Sex']=='male','Sex'] = 0
titanic.loc[titanic['Sex']=='female','Sex'] = 1
# 有一個問題就是我本身測試的時候,describe()方法仍是不顯示性別。

6:轉換登船Embarked

咱們如今能夠用和轉換Sex列相同的方法將Embarked列轉換成數值碼。Embarked列的惟一值是S,C,Q和缺失值nan。每一個字母是一個登船港口名字的縮寫。
第一步是替換列中的缺失值。大部分共同的登船港口都是S,因此咱們假設每一個人都是從那兒上船的。將Embarked列的缺失值全都替換成S
咱們分別將0賦值給S,將1賦值給C,將2賦值給Q,替換每一個值相應的代碼:性能

# Find all the unique values for "Embarked".
print(titanic["Embarked"].unique())
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

7:交給機器學習

如今咱們的數據已經清洗得乾淨了一點了,咱們準備開始探索一些機器學習。咱們開始的一些行數據看起來像這樣:
Age |Sex |Survived
----|----|--------
10 | 0 |0
5 | 1 |1
30 | 0 |0
若是咱們想利用Age列的數據來預測是否有人倖存或者沒有幸存,咱們可使用一種叫作線性迴歸的方法。線性迴歸的等式以下:(y=mx+b),y的值是咱們設法預測的,m是一個叫作斜率的係數,x是一列的值,b是一個叫作截距的常數。
咱們能夠經過賦值-2m,賦值20b作一個預測。咱們獲得這樣的結果:

Age Sex Survived Predictions
10 0 0 -2*10+20=0
5 1 1 -2*5+20=10
30 0 0 -2*30+20=-40

若是咱們將獲得的預測結果中任何大於0的值轉換成1,任何小於等於0的值換成0,咱們將獲得這樣的結果:

Age Sex Survived Predictions
10 0 0 0
5 1 1 1
30 0 0 0

這個簡單的模型預測倖存者至關好。線性模型能夠是一個很是強大的算法,可是也有一些缺點:

  • 若是一個列和一個結果不是線性相關,這就不會有好的效果。例如:若是除了80歲以上的老年女性也不幸存,那麼線性迴歸將不會有好效果。
  • 它不能給你倖存率,只有具體的數值來代表某人是否倖存。

咱們以後會討論如何處理這兩個問題。如今,咱們將學習如何自動的計算線性迴歸的迴歸係數,如何用多列數據來預測一個結果。

8:交叉驗證

咱們如今使用線性迴歸在咱們的訓練數據集上作預測。
咱們想用除咱們作預測以外的不一樣的數據來訓練算法。若是咱們想避免過擬合這是很是關鍵的。過擬合是當一個模型擬合它自己過於複雜,不顯著。每一個數據都有其獨有的特色且不存在於全集。例如:若是我要求你利用一輛車的馬力和其餘特徵,而且給你一個隨機的很是高的最高速度數據集,來預測一輛車的最高速度,你將會創建一個速度太高的模型。解決的辦法就是用你沒有用來訓練模型的數據去測試性能。
每個機器學習算法均可以過擬合,即便有的(像線性迴歸)很是不容易。若是你測試(評估)你的算法和你訓練算法是用的同一個數據集,那麼你極可能不知道它的性能好究竟是算法很好仍是由於過擬合它本身的噪聲。
幸運的是,交叉驗證是一個很簡單的避免過擬合的方法。交叉驗證,你將你的數據分紅一些數字部分(或子類)。咱們使用3做爲一個例子。而後你這樣作:

  • 合併第一二部分,訓練一個模型,在第三部分上作預測。
  • 合併第一三部分,訓練一個模型,在第二部分上作預測。
  • 合併第二三部分,訓練一個模型,在第一部分上作預測。

這種方式,評價咱們生成的預測的精度的整個數據集和曾經訓練咱們的模型沒有相同的數據。

9: 預測

咱們可使用極好的scikit-learn庫來作預測。咱們將使用skelearn的一個助手來將數據分紅交叉驗證的子類,而後用每個子類分別來訓練算法作預測。最後,咱們將獲得一個預測列表,每個列表項包含了相關子類的預測數據。

# 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)

10:測試(評價)偏差

如今咱們有了預測結果,咱們能夠測試咱們的偏差了。
第一步咱們須要先定義偏差的度量標準,因此咱們先算出咱們模型的精度。從Kaggle競賽的描述,偏差的度量標準是正確預測的百分比。咱們將使用這個相同的度量標準來測試咱們本地模型的性能。
這個度量標準將基本上是predictions中找到的值和他們在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())

11:邏輯迴歸

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

12:處理測試集

咱們的正確度已經能夠了,可是還不是很是好。咱們任然能夠嘗試一些方法來使它變得更好,在下一個任務將會討論。
可是咱們須要提交一個答案到比賽中。咱們須要在測試數據上採起一個和訓練數據上同樣的校準的步驟來完成這個事情。若是咱們沒有校準操做,咱們就不可以利用它作出有效的預測。
這些操做要在咱們對列全部的改變以前進行。
處理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

13:生成一個提交文件

如今咱們有了咱們須要生成一個比賽提交答案的全部東西了。
首先,咱們必須先在訓練數據上訓練一個算法。而後咱們在測試數據集上作一個預測。最後,咱們生成一個包含預測和乘客id的csv文件。
一旦你完成了下面步驟的代碼,你就能用submission.to_csv('kaggle.csv, index=False')輸出一個csv結果。這將會給你的第一個條件全部須要的東西——雖然這沒有給你很好的準確率。(~0.75)

# Initialize the algorithm class
alg = LogisticRegression(random_state=1)

# Train the algorithm using all the training data
alg.fit(titanic[predictors], titanic["Survived"])

# Make predictions using the test set.
predictions = alg.predict(titanic_test[predictors])

# Create a new dataframe with only the columns Kaggle wants from the dataset.
submission = pandas.DataFrame({
        "PassengerId": titanic_test["PassengerId"],
        "Survived": predictions
    })

14:下一步

咱們只是生成了一個調教文件,可是準確率不是很好(0.75)。因爲咱們的預測在不一樣的數據集上致使在測試集上的分數低於咱們在交叉驗證上的分數。在下一個任務中咱們將學習如何生成更好的特徵和使用更好的模型來提升咱們的分數。
恭喜你完成了這個任務!

結束!

相關文章
相關標籤/搜索