Kaggle入门
Kaggle入门
1:竞赛
我们将学习如何为Kaggle竞赛生成一个提交答案(submisson
)。Kaggle是一个你通过完成算法和全世界机器学习从业者进行竞赛的网站。如果你的算法精度是给出数据集中最高的,你将赢得比赛。Kaggle也是一个实践你机器学习技能的非常有趣的方式。
Kaggle网站有几种不同类型的比赛。其中的预测一个就是预测在泰坦尼克号沉没的时候哪个乘客会成为幸存者。 在这个任务和下一个任务我们将学习如何提交我们的答案。
我们的数据是csv
格式。你可以在这里下载数据开始比赛。
每一行重现了一个在泰坦尼克的乘客以及和他们有关的一些信息。让我们来看一下各列:
- 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
可以传入一个参数用参数的值来替换缺失值。
在我们的例子中,我们打算用列的中位数来填充:
titanic['Age'].fillna(titanic['Age'].median())
之后我们必须将替换后的结果赋值回原来的列:
titanic['Age'] = titanic['Age'].fillna(titanic['Age'].median())
4:非数值列
前两节我们使用过.describe()
,你也许也主要到并不是所有的列都显示出来了。只有数值列显示了。我们的列中有几个是非数值的,当你开始做预测的时候这将是一个问题——我们不能将非数值列传入机器学习算法中并且期望机器学习算法能理解他们。
我们在训练我们的算法时要么必须排除这些非数值列(Name
, Sex
, Cabin
, Embarked
, Ticket
),要么就要找到一种方法将他们转换成数值列。
我们将忽略Ticket
, Cabin
,Name
这三行。因为我们不能从他们中提取出太多有用的信息。Cabin
列大多数值都是缺失的(891行中只有204行数值),而且起初看起来好像也不是特别有用的列。如果没有一些关于船票号码意义的专业领域知识和哪些名字的特点像大户或者有钱家庭,那么Ticket
和Name
列也不太可能会告诉我们太多的信息。
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
是一个叫做截距的常数。
我们可以通过赋值-2
给m
,赋值20
给b
做一个预测。我们得到这样的结果:
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%的正确率。在视频中,我们曾提到一种方式使线性回归的输出值介于0
和1
之间。这种方法叫做逻辑回归。
一个好的方法就是将逻辑回归当成是线性回归的逻辑输出,所以他的值就是0
和1
。用逻辑函数 logit function来完成。输入任何值到逻辑函数都将通过“压缩”极值匹配成0
和1
。这对我们来说非常完美,因为我们只关心两种输出结果。Sklearn
有一个逻辑回归的类我们可以使用。通过使用一个Sklearn
助手函数可以使我们所有的交叉验证和测试变得更简单。
12:处理测试集
我们的正确度已经可以了,但是还不是非常好。我们任然可以尝试一些方法来使它变得更好,在下一个任务将会讨论。
但是我们需要提交一个答案到比赛中。我们需要在测试���据上采取一个和训练数据上一样的校准的步骤来完成这个事情。如果我们没有校准操作,我们就不能够利用它做出有效的预测。
这些操作要在我们对列所有的改变之前进行。
处理titanic_test
和处理titanic
用同样的方法。
这涉及到:
- 使用训练数据集中的年龄中位数填充“Age”列的的所有缺失值。训练数据集的年龄已经使用完全相同的值替换了缺失年龄(因为值已经不同了,所以这不能作为测试集的中位数)。你应该用
titanic['Age'].median()
去找到中位数。 - 将
Sex
列中的所有male
换成0
,所有female
换成1
。 - 用
S
填充Embarked
列中的所有缺失值。 将
Embarked
列中的S
换成0
,C
换成1
,Q
换成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)。由于我们的预测在不同的数据集上导致在测试集上的分数低于我们在交叉验证上的分数。在下一个任务中我们将学习如何生成更好的特征和使用更好的模型来提高我们的分数。
恭喜你完成了这个任务!
结束!
Kaggle入门的更多相关文章
- Kaggle入门——使用scikit-learn解决DigitRecognition问题
Kaggle入门--使用scikit-learn解决DigitRecognition问题 @author: wepon @blog: http://blog.csdn.net/u012162613 1 ...
- kaggle入门项目:Titanic存亡预测 (一)比赛简介
自从入了数据挖掘的坑,就在不停的看视频刷书,但是总觉得实在太过抽象,在结束了coursera上Andrew Ng 教授的机器学习课程还有刷完一整本集体智慧编程后更加迷茫了,所以需要一个实践项目来扎实之 ...
- Kaggle 入门资料
kaggle入门之如何使用 - CSDN博客 http://blog.csdn.net/mdjxy63/article/details/78221955 kaggle比赛之路(一) -- 新手注册账号 ...
- 大数据竞赛平台——Kaggle 入门
Reference: http://blog.csdn.net/witnessai1/article/details/52612012 Kaggle是一个数据分析的竞赛平台,网址:https://ww ...
- Kaggle入门(一)——Digit Recognizer
目录 0 前言 1 简介 2 数据准备 2.1 导入数据 2.2 检查空值 2.3 正则化 Normalization 2.4 更改数据维度 Reshape 2.5 标签编码 2.6 分割交叉验证集 ...
- kaggle入门--泰坦尼克号之灾(手把手教你)
作者:炼己者 具体操作请看这里-- https://www.jianshu.com/p/e79a8c41cb1a 大家也可以看PDF版,用jupyter notebook写的,视觉效果上感觉会更棒 链 ...
- 大数据竞赛平台——Kaggle 入门篇
这篇文章适合那些刚接触Kaggle.想尽快熟悉Kaggle并且独立完成一个竞赛项目的网友,对于已经在Kaggle上参赛过的网友来说,大可不必耗费时间阅读本文.本文分为两部分介绍Kaggle,第一部分简 ...
- kaggle入门——泰坦尼克之灾
目录 引言 数据认识 总结 特征处理 建模预测 logistic分类模型 随机森林 SVM xgboost 模型验证 交叉验证 学习曲线 高偏差: 高方差 模型融合 总结 后记 引言 一直久闻kagg ...
- kaggle入门2——改进特征
1:改进我们的特征 在上一个任务中,我们完成了我们在Kaggle上一个机器学习比赛的第一个比赛提交泰坦尼克号:灾难中的机器学习. 可是我们提交的分数并不是非常高.有三种主要的方法可以让我们能够提高他: ...
随机推荐
- 设计模式之桥接模式(Bridge)--结构模型
1.意图 将抽象部分与它的实现部分分离,使它们可以独立地变化. 2.适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系. 类的抽象与它的实现都应该可以通过子类的方式加以扩展. 抽象部分与实现 ...
- (转+原)android获取系统时间
参考的网站如下: http://c.biancheng.net/cpp/html/144.html http://www.linuxidc.com/Linux/2012-03/55909.htm 代码 ...
- 纯css改变下拉列表select框的默认样式
下列CSS就可以解决,原理是将浏览器默认的下拉框样式清除,然后应用上自己的,再附一张向右对齐小箭头的图片即可. select { /*Chrome和Firefox里面的边框是不一样的,所以复写了一下* ...
- android sdk manager无法更新
问题描述: Android SDK Manager 无法下载更新,或者更新速度超慢,或者待安装包列表不显示. 解决方法: 第一,我们先修改下hosts文件.该文件的位置在系统盘 ...
- jquery 鼠标右键事件、左键单击事件判定
$(function(){ $('a').mousedown(function(e){ alert(e.which) // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键 retu ...
- javascript 小计
①if文 if(){} else if(){} else if 中间有空格 ②
- Android上使用OpenglES2.0遇到的一点问题
按照教程开发OpenglES2.0应用,遇到Logcat报错“Called unimplemented OpenGL ES API” 在论坛和stackoverflow上找到了答案. 1.manife ...
- python学习day8
目录 一.异常 二.多线程 三.守护线程与join 四.GIL与多线程锁 五.递归锁与信号量 六.线程间同步与交互 七.多进程 八.进程间通信与数据共享 九.进程池 一.异常 1.异常处理 在编程过程 ...
- URAL 1736 Chinese Hockey 网络流+建图
题目链接:点击打开链接 题意: 给定n个队伍的得分情况,输出随意一个可行解. n个队伍随意2个队伍 a, b 间有且仅有一场比赛. 比赛结果分4种: 1.a +3, b +0 2.a +0, b +3 ...
- ZCTF-final-restaurant1
和线上赛的题目差别不大,但是需要自己去泄露堆的地址.除了线上赛的溢出之外,还多了一个Use After Free的洞.我写了两种利用方法. 线上赛writeup见:http://www.cnblogs ...