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)。因为咱们的预测在不一样的数据集上致使在测试集上的分数低于咱们在交叉验证上的分数。在下一个任务中咱们将学习如何生成更好的特征和使用更好的模型来提升咱们的分数。
恭喜你完成了这个任务!

结束!

相关文章
相关标签/搜索