原文地址:https://www.kaggle.com/startupsci/titanic-data-science-solutions
泰坦尼克数据科学解决方案
原文作者已发布一个新的Python包 Speedml。该包将笔记中所用的技术编写为直观、强大和高效的API。
Speedml帮助我不需要多轮就从Kaggle排行榜后80%到前20%。
值得一提的是...Speedml通过减少70%的代码实现了这一点。
下载和运行:Titanic Solution using Speedml
该笔记是《数据科学解决方案》一书的指南。它向我们展示了在像Kaggle这样的网站上,解决数据科学竞赛的典型工作流程。
平台上有一些精彩笔记可作为的研究数据科学竞赛的入口。然而,大多笔记不会解释如何开发解决方案,因为它们是专家们为专家们所开发的。本笔记遵循一步一步工作流程的目标,解释我们在开发解决方案的过程中所做决策的每个步骤和基本原理。
工作流阶段
竞赛解决方案工作流会经历《数据科学解决方案》一书的七个阶段。
- 问题定义;
- 获取训练和测试数据;
- 整理、准备和清理数据;
- 分析、定义模式并探索数据;
- 建模、预测并解决问题;
- 可视化,报告并呈现解决问题的步骤和最终方案;
- 提供或提交结果。
该工作流显示了每个步骤如何遵循其他阶段的一般顺序,但也存在一下例外。
- 我们可以组合多个工作流阶段,如:通过可视化分析数据。
- 提前进入某一阶段,如:在整理数据前后都可分析数据。
- 在工作流中多次进行同一个阶段,如:可视化会被多次进行。
- 放弃某一阶段,如:没必要为了比赛而生产或提供自己的数据
问题定义
像Kaggle这样的竞赛,它在提供数据集训练我们数据科学模型,并借助测试集测试模型时,会定义需解决的问题或提出疑问。泰坦尼克生存竞赛的问题定义的描述在这里。
经过一系列训练样本——乘客是否幸存于这场灾难的学习之后,基于所给的不包含生存信息的测试数据集,我们的模型便能预测这些乘客是否幸存。
我们可能还想了解该问题领域的一些早期知识。这被描述在Kaggle竞赛描述页面。以下是值得注意的重点。
- 1912年4月15日,在泰坦尼克首航期间,她撞上冰山并沉没,在共计2224名乘客和船员中有1502名死亡或失踪,仅32%的存活率。
- 船难造成如此巨大人员伤亡的原因之一是船上没有足够的救生艇供乘客和船员使用。
- 虽然在生存和死亡间有运气成分,但相比其他人群,有些更容易幸存下来,比如:妇女、孩童和上层阶级人员。
工作流目标
数据科学解决方案工作流解决了七个主要目标。
分类。我们可能想分类样本,可能还想了解不同类别对我们的解决方案目标的影响或相关性。
关联。我们可根据训练数据集中的可用特性来解决问题。如:在训练数据集中哪些特征对我们解决方案影响最有意义?从统计学上讲,在某一特征和所解决的目标间是否存在关联?随着特征值的变化,解决方案状态是否也会变化,反之亦然?这些都可以在所给数据集的数值和离散特征中进行测试。除了后续目标和工作流阶段的生存问题,我们可能还想确定特性间的相关性。关联有把握的特征对创建、实现或纠正特征都有帮助。
转换。对于建模,有一步需要做的是预处理数据。基于模型算法的选择,我们可能需要把全部特征转换为数值型的等效值。例如,转换文本型的离散值为数值型。
填补。数据预处理可能也需要我们去评估某一特征下的全部缺失值。当没有缺失值时,模型算法或许会效果更好。
纠正。对所给的训练数据集,我们也会分析出里面有错误或者可能不准确的值,并且会尝试去纠正这些值或者除去包含错误值的样本。一种方法是检测样本或特征中的任何异常值。我们也可以完全丢弃对我们分析没有贡献或可能偏差我们结果的特征。
创建。基于现有的一个或多个特征,我们能够创建新的特征,并使其遵循相关、转换和完整性特征。
图表。基于数据和解决目标的自然性,选择合适的可视化图表。
2017-1-29 重构发布
基于如下,我们大动干戈地重构了该笔记。
- 读者回复的评论;
- 从Jupyter内核(2.7)移植到Kaggle内核(3.5)中会出现的问题;
- 回看更多最佳的实践Kernel。
用户评论
- 像把数据集的titles转换为数值型值这样的工作,训练和测试集数据可同时进行。(感谢@Sharan Naribole)
- 合理的观察——近30%的乘客有兄弟姐妹和(或)配偶。(感谢@Reinhard)
- 正确解释了logistic回归系数。(感谢@Reinhard)
移植问题
- 指定了图的维度,把图例带入图中
最佳实践
- 在项目早期进行特征相关分析。
- 便于可读,使用多绘图代替覆盖。
输入[1]:
# data analysis and wrangling
# 数据分析和整理所需要的包
import pandas as pd
import numpy as np
import random as rnd
# visualization
# 数据可视化所需要的包
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
# machine learning
# 机器学习所需要的包
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC, LinearSVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import Perceptron
from sklearn.linear_model import SGDClassifier
from sklearn.tree import DecisionTreeClassifier
获取数据
Python的Pandas包帮助我们处理数据。首先,我们把训练和测试数据集导入Pandas的DataFrames中。我们也会联合两个数据集,同时对它们执行特定操作。
输入[2]:
train_df = pd.read_csv('../input/train.csv')
test_df = pd.read_csv('../input/test.csv')
combine = [train_df, test_df]
通过描述数据分析
在项目初期,通过回答以下的问题,Pandas可帮助我们描述数据。
在数据集中哪些特征可用?
注意这些直接操作或分析的特征名。这些特征名的描述在Kaggle数据页。
输入[3]:
# 打印训练数据集的特征名
print(train_df.columns.values)
# 打印结果:
['PassengerId' 'Survived' 'Pclass' 'Name' 'Sex' 'Age' 'SibSp' 'Parch'
'Ticket' 'Fare' 'Cabin' 'Embarked']
哪些特征是分类型的?
这些值把样本分成多个相似样本的集合。在分类型的特征中,值是标称、序数、比率还是间隔的?这些个不同类型特征有助于我们选择合适的图形进行可视化。
- 类别:是否存活、性别和登船港口。序数:船票类别
哪些特征是数值型的?
哪些特征是数值型的?这些值随样本变化而变化。在数值型的特征中,值是离散的、连续的或者时序的?这些个不同类型特征助于我们选择合适的图形进行可视化。
- 连续:年龄、船费。离散:兄弟姐妹/配偶、父母/孩子
输入[4]:
# preview the data
# 查看前五行数据
train_df.head()
输出[4]:
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
哪些特征是混合型数据类型?
在同一特征中有数值型和字母数字型的数据。这些是修正目标的候选特征。
- 船票是数值型和字母数字型的混合数据类型。船舱数是字母数字型。
哪些特征可能有错误值或拼写错误?
对大数据集而言,这会比较难。但是,从一个更小的数据集中检查些许样本,这也能告诉我们哪些特征可能需要校正。
- 姓名这个特征可能包括错误值或拼写错误。因为数据中存在几种描述名称的方式,包括标题、圆括号和用于替代名称或短名称的引号。
输入[5]:
train_df.tail()
输出[5]:
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
886 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.00 | NaN | S |
887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.00 | B42 | S |
888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.45 | NaN | S |
889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.00 | C148 | C |
890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.75 | NaN | Q |
哪些特征包含空单元格,null值或空值?
这些特征需要进行校正。
- 对训练数据集来说,按null值数量由大到小的顺序:船舱数量 > 年龄 > 登船港口
- 对测试数据集来说,按数据不完整由高到低的顺序:船舱数量 > 年龄
各个特征的数据类型是什么?
(你知道这些)有助于数据转换
- 七个特征是整型或浮点型。对测试集来说是六个。
- 五个特征是字符型(对象)。
输入[6]:
train_df.info()
print('_'*40)
test_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 204 non-null object
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
________________________________________
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId 418 non-null int64
Pclass 418 non-null int64
Name 418 non-null object
Sex 418 non-null object
Age 332 non-null float64
SibSp 418 non-null int64
Parch 418 non-null int64
Ticket 418 non-null object
Fare 417 non-null float64
Cabin 91 non-null object
Embarked 418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB
在样本中,数值型特征值的分布如何?
除了一些早期见解外,(在知道分布后)这有助于我们确定实际问题的训练数据集的代表性如何。
- 样本总数891,占真实的泰坦尼克乘客数的40%(总乘客数:2224)。
- Survived是值为0或1的分类特征。
- 在样本中,38%左右的乘客存活,实际生存率为32%。
- 大部分乘客(>75%)并没有和父母或孩子一同出行。
- 接近30%乘客有兄弟姐妹和(或)配偶在船上。
- 票价差异显著,只有少数乘客(低于1%)的船费高达512美元。
- 年龄介乎65-80岁的高龄乘客很少(少于1%)。
输入[7]:
train_df.describe()
# Review survived rate using `percentiles=[.61, .62]` knowing our problem description mentions 38% survival rate.
# Review Parch distribution using `percentiles=[.75, .8]`
# SibSp distribution `[.68, .69]`
# Age and Fare `[.1, .2, .3, .4, .5, .6, .7, .8, .9, .99]`
输出[7]:
PassengerId | Survived | Pclass | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|---|
count | 891.000000 | 891.000000 | 891.000000 | 714.000000 | 891.000000 | 891.000000 | 891.000000 |
mean | 446.000000 | 0.383838 | 2.308642 | 29.699118 | 0.523008 | 0.381594 | 32.204208 |
std | 257.353842 | 0.486592 | 0.836071 | 14.526497 | 1.102743 | 0.806057 | 49.693429 |
min | 1.000000 | 0.000000 | 1.000000 | 0.420000 | 0.000000 | 0.000000 | 0.000000 |
25% | 223.500000 | 0.000000 | 2.000000 | 20.125000 | 0.000000 | 0.000000 | 7.910400 |
50% | 446.000000 | 0.000000 | 3.000000 | 28.000000 | 0.000000 | 0.000000 | 14.454200 |
75% | 668.500000 | 1.000000 | 3.000000 | 38.000000 | 1.000000 | 0.000000 | 31.000000 |
max | 891.000000 | 1.000000 | 3.000000 | 80.000000 | 8.000000 | 6.000000 | 512.329200 |
我们来看看,分类型特征的分布是如何的呢?
- 在数据集中,姓名是唯一的(count=unique=891)。
- 性别特征有两个值,65%的是男性(top=male, freq=577/count=891)。
- 在样本中,船舱数量有一些重复值,即几个乘客共用同一个船舱。
- 登船港口有三个值。S港口是大多数乘客的选择(top=S)。
- 船票号具有很高(22%)的重复值比率 (unique=681)。
输入[8]:
# include=['O']表示是分类型
train_df.describe(include=['O'])
输出[8]:
Name | Sex | Ticket | Cabin | Embarked | |
---|---|---|---|---|---|
count | 891 | 891 | 891 | 204 | 889 |
unique | 891 | 2 | 681 | 147 | 3 |
top | Lester, Mr. James | male | 347082 | G6 | S |
freq | 1 | 577 | 7 | 4 | 644 |
---------未完待续------