注:kaggle网站上入门的数据挖掘项目,最大推荐度的代码为(原文),为进行机器学习、数据分析方面的学习,进行中文的整理。行文的翻译参考腾讯翻译君。
泰坦尼克号数据科学解决方案
这notebook是“数据科学解决方案”(DataScienceSolutions)一书的伴侣。
notebook引导我们在像Kaggle这样的网站上解决数据科学竞赛的典型工作流程。
有几本优秀的笔记本可以用来研究数据科学竞赛的参赛作品。
然而,由于这些笔记本是由专家为专家开发的,许多人会跳过一些关于如何开发解决方案的说明。这notebook的目标是遵循一步的工作流程,解释每个步骤和我们在解决方案开发过程中所做的每个决定的基本原理。
工作流阶段
竞争解决方案工作流程经历了数据科学解决方案中描述的七个阶段。
- 问题的描述和定义
- 获得训练集和车饰集
- 数据的讨论、准备和清理
- 分析、识别模式并且探索数据
- 建模、预测和解决问题
- 可视化、报告同时提出解决步骤和最终解决方案
- 提供或提交结果
工作流指示每个阶段如何跟随另一个阶段的一般步骤。但是,有例外的用例。
- 我们可以结合多个工作流阶段。我们可以通过可视化数据进行分析
- 执行早于指示的阶段。我们可能会在讨论之前和之后分析数据。
- 在我们的工作流程中多次执行一个阶段。可视化步骤可以多次使用。
- 放弃某些步骤。我们可能不需要供应阶段来生产或服务使我们的数据集为竞争。
问题和问题的定义
像Kaggle这样的竞争网站定义了要解决的问题或要问的问题,同时提供了训练您的数据科学模型和根据测试数据集测试模型结果的数据集。泰坦尼克号生存竞赛的问题或问题定义在Kaggle这里进行了描述。
从一组列有泰坦尼克号灾难中幸存或没有幸存的乘客的训练样本中,我们的模型可以根据不包含生存信息的给定测试数据集来确定这些乘客是否在测试数据集中存活下来。
我们可能还想对我们的问题领域有一些早期的了解。这是描述在Kaggle竞争描述页面这里。以下是要注意的亮点
- 1912年4月15日,泰坦尼克号在处女航中与冰山相撞沉没,2224名乘客和船员中有1502人丧生,32%的存活率。
- 海难造成人员伤亡的原因之一是没有足够的救生艇供乘客和船员使用。
- 虽然在沉船中幸存下来有一些幸运的因素,但一些群体比其他群体更有可能生存下来,比如妇女、儿童和上层阶级。
工作流程
数据科学解决方案工作流解决了七个主要目标
分类。我们可能要对样品进行分类或分类。
我们可能还想了解不同类与我们的解决方案目标之间的含义或相关性。
相关。可以根据训练数据集中的可用特征来处理该问题。
数据集中的哪些功能为我们的解决方案目标做出了重要贡献?从统计学上讲,功能和解决方案目标之间是否存在关联?随着要素值的变化,解决方案状态是否也会发生变化,反之亦然?可以对给定数据集中的数字特征和类别特征进行测试。我们还可能需要确定后续目标和工作流阶段的生存以外的特征之间的相关性。关联某些功能可能有助于创建、完成或更正功能。
转换。在建模阶段,需要准备数据。根据模型算法的选择,可能需要将所有特征转换为数值等效值。例如,将文本类别值转换为数值。
完整。数据准备也可能要求我们估计一个特征中的任何缺失值。当没有缺失值时,模型算法可能工作得最好。
更正。我们还可以分析给定的训练数据集中的错误,或者可能在特征中包含值,并尝试关联这些值或排除包含错误的样本。一种方法是检测我们的样本或特征中的任何离群点。如果某个功能与分析不相关,或者可能会显著扭曲结果,则我们可能会完全丢弃该功能。
创造。我们是否可以基于一个现有的特征或一组特征来创建新的特征,从而使新的特征遵循相关性、转换和完整性目标。
图表。如何根据数据的性质和解决方案的目标选择正确的可视化图形和图表。
重构发布2017年1月29日
我们基于(a)读者收到的评论,(b)将笔记本从Jupyter内核(2.7)移植到Kaggle内核(3.5)以及(c)审查几个最佳实践内核的问题,对笔记本进行了重大的重构。
用户评论
- 为某些操作组合训练和测试数据,例如将数据集中的标题转换为数值。 (感谢@Sharan Naribole)
- 正确观察 - 近30%的乘客有兄弟姐妹和/或配偶。 (感谢@Reinhard)
- 正确解释逻辑回归系数。 (感谢@Reinhard)
移植问题
指定绘图尺寸,将图例添加到绘图中。
##最佳做法
- 在项目早期执行特征相关分析。
- 使用多个图而不是叠加图来提高可读性。
# 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
中。 我们还组合这些数据集以在两个数据集上一起运行某些操作。
train_df = pd.read_csv('../input/train.csv')
test_df = pd.read_csv('../input/test.csv')
combine = [train_df, test_df]
通过描述数据进行数据分析
Pandas
还可以帮助描述在我们的项目早期回答以下问题的数据集。
数据集中有哪些功能可用?
注意用于直接操作或分析这些特性的特性名称。
这里的Kaggle数据页面上描述了这些功能名称。
print(train_df.columns.values)
['PassengerId' 'Survived' 'Pclass' 'Name' 'Sex' 'Age' 'SibSp' 'Parch'
'Ticket' 'Fare' 'Cabin' 'Embarked']
哪些特征是分类的?
这些值将样本分类为一组相似的样本。在范畴特征中,值是基于名义值,序数,比率或间隔的吗?除其他外,这有助于我们选择合适的图形进行可视化。
- 分类:幸存,性和沉淀。 序数:Pclass。
哪些特征是数值的?
哪些特征是数值? 这些值随样品而变化。 在数值特征中,值是离散的,连续的还是基于时间序列的? 除此之外,这有助于我们选择适当的可视化图。
- 连续:年龄,票价。 离散:SibSp,Parch
#preview the data
#数据预览
train_df.head()
PassengerId | Survived | Pclass | … | Fare Cabin Embarked | |
---|---|---|---|---|---|
0 | 1 | 0 | 3 | … | 7.2500 |
1 | 2 | 1 | 1 | … | 71.2833 |
2 | 3 | 1 | 3 | … | 7.9250 |
3 | 4 | 1 | 1 | … | 53.1000 |
4 | 5 | 0 | 3 | … | 8.0500 |
译者注:
变量说明:
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 | 船上的兄弟姐妹/配偶 | |
parch | 船上的父母/孩子 | |
ticket | 票号 |
哪些特征是混合数据类型的?
同一要素中的数字、字母数字数据。这些都是修正目标的候选目标。
- 票证是数字和字母数字数据类型的混合。船舱是字母数字的。
** 哪些特征可能包含错误或拼写错误?**
对于大型数据集来说,这很难检查,但是从较小的数据集中查看一些样本可能只是告诉我们,哪些功能可能需要更正
- 名称功能可能包含错误或拼写错误,因为有几种方法可用于描述名称,包括标题,圆括号和用于替代或短名称的引号。
train_df.tail()
PassengerId | Survived | Pclass | … | Fare Cabin Embarked | |
---|---|---|---|---|---|
886 | 887 | 0 | 2 | … 13.00 | NaN |
887 | 888 | 1 | 1 | … 30.00 | B42 |
888 | 889 | 0 | 3 | … 23.45 | NaN |
889 | 890 | 1 | 1 | … 30.00 | C148 |
890 | 891 | 0 | 3 | … 7.75 | NaN |
哪些特征包含空值、空值或空值?
这些都需要纠正。
- CAMBLE>;AGE>;特性包含许多空值,这些值按训练数据集的顺序排列。
- 在测试数据集的情况下,CAMBER>;年龄是不完整的。
各种特征的数据类型是什么?
可以在数据转换的时候帮助我们。
- 七个特征是整数或浮点数。 六个在测试数据集中。
- 五个特征是字符串。
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
样本中数值特征值的分布是什么?
这有助于我们在其他早期见解中确定实际问题域的训练数据集的代表性。
- 总样本是泰坦尼克号(2,224)上实际乘客人数的891或40%。
- Survived是一个具有0或1值的分类特征。
- 大约38%的样本存活,代表实际存活率为32%。
- 大多数乘客(> 75%)没有与父母或孩子一起旅行。
- 近30%的乘客有兄弟姐妹和/或配偶。
- 票价差异很大,很少有乘客(<1%)支付高达512美元。
- 年龄在65-80岁之间的老年乘客(<1%)很少。
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]`
PassengerId | Survived | Pclass | … | Fare Cabin Embarked | |
---|---|---|---|---|---|
count | 891.000000 | 891.000000 | 891.000000 | … | 891.000000 |
mean | 446.000000 | 0.383838 | 2.308642 | … | 0.523008 |
std | 257.353842 | 0.486592 | 0.836071 | … | 1.102743 |
min | 1.000000 | 0.000000 | 1.000000 | … | 0.000000 |
25% | 223.500000 | 0.000000 | 2.000000 | … | 0.000000 |
50% | 446.000000 | 0.000000 | 3.000000 | … | 0.000000 |
75% | 668.500000 | 1.000000 | 3.000000 | … | 1.000000 |
max | 891.000000 | 1.000000 | 3.000000 | … | 8.000000 |
分类特征的分布是什么?
- 名称在整个数据集中是唯一的(count = unique = 891)
- 性别变量为两个可能的值,男性为65%(top =男性,频率= 577 /计数= 891)。
- Embarked有三个可能的值。 大多数乘客使用为S(top= S)
- 票面类型具有高重复率(22%)的重复值(unique= 681)。
Name | Sex | … | Cabin | Embarked | |
---|---|---|---|---|---|
count | 891 | 891 | … | 204 | |
unique | 891 | 2 | … | 147 | |
top | Allison, Mrs. Hudson J C (Bessie Waldo Daniels) | male | … | B96 B98 | S |
freq | 1 577 | … | 4 | 644 |
基于数据分析的假设
我们根据迄今为止所做的数据分析得出以下假设。在采取适当行动之前,我们可以进一步验证这些假设。
相关
我们想知道每个特征与生存的关系有多大。我们希望在项目的早期完成这项工作,并在项目的后期将这些快速关联与建模关联进行匹配。
完备数据
- 我们可能想完成年龄特征,因为它与生存率是绝对相关的。
- 我们可能希望完备XX特征,因为它也可能与生存或另一个重要特征相关。
校正
- 票务特征可能会从我们的分析中删除,因为它包含高重复率(22%),并且票务与生存率之间可能没有相关性。
- 由于座舱特征高度不完整或在训练和测试数据集中包含许多空值,因此可能会删除座舱特征。
- Passengerid可能会从训练数据集中删除,因为它不会有助于生存。
- 姓名特征是相对不规范的,可能不会直接影响到生存,所以可能会被删除。
创造
- 我们可能想创建一个新的功能,叫做基于parch和sibsp的家庭,以获取船上家庭成员的总数。
- 我们可能需要设计名称功能,将标题提取为新功能。
- 我们可能想为年龄段创建新功能。这将连续的数值特征转化为有序的分类特征。
- 如果它有助于我们的分析,我们也可能希望创建一个票价范围功能。
分类
我们也可以根据前面提到的问题描述来增加我们的假设。
- 女性(Sex=female)更有可能存活下来。
- 儿童(年龄<?)更有可能幸存下来。
- 上层乘客(pclass=1)更有可能存活下来。
旋转特征分析
为了确认我们的一些观察和假设,我们可以通过旋转彼此的特征来快速分析我们的特征相关性。
我们只能在此阶段对不具有任何空值的功能执行此操作。仅对于类别(性别)、顺序(Pclass)或离散(SibSp, Parch)类型的要素,这样做也是有意义的。
- Pclass:我们观察到Pclass=1和存活(分类#3)之间有显著的相关性(>;0.5)。我们决定在我们的模型中包含这个特性。
- Sex:我们证实了在问题定义中观察到的性别=女性有很高的存活率,为74%(分类#1)。
- SibSp and Parch :这些特征对于某些值没有相关性。最好从这些单独的要素(创建#1)中衍生出一个要素或一组要素。
train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)
Pclass | Survived | |
---|---|---|
0 | 1 | 0.629630 |
1 | 2 | 0.472826 |
2 | 3 | 0.242363 |
train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)
Sex | Survived | |
---|---|---|
0 | female | 0.742038 |
1 | male | 0.188908 |
train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)
SibSp | Survived | |
---|---|---|
1 | 1 | 0.535885 |
0 | 0 | 0.464286 |
0 | 0 | 0.345395 |
3 | 3 | 0.250000 |
4 | 4 | 0.166667 |
5 | 5 | 0.000000 |
6 | 8 | 0.000000 |
通过可视化数据进行分析
现在我们可以继续使用可视化来确认我们的一些假设来分析数据。
关联数字特征
让我们首先了解数值特征与我们的解决方案目标(生存)之间的相关性。
柱状图有助于分析连续的数值变量,如年龄,在年龄带或范围将有助于识别有用的模式。柱状图可以使用自动定义的箱或等范围带指示样本的分布。这有助于我们回答与特定条带相关的问题(婴儿是否有更好的存活率?)
请注意,历史图像中的X轴表示样本或乘客的计数。
决定
这一简单的分析证实了我们的假设,作为随后工作流程阶段的决定。
- 我们应该在模型培训中考虑年龄(我们的假设分类#2)。
- 填充空值的Age(填充#1)。
- 我们应该对年龄组进行分组(创建3)。
g = sns.FacetGrid(train_df, col='Survived')
g.map(plt.hist, 'Age', bins=20)
关联数字和有序特征
我们可以使用单个图组合多个功能来识别相关性。 这可以通过具有数值的数字和分类特征来完成。
观察
-
Pclass = 3有大多数乘客,但大多数人没有幸存。 确认我们的分类假设#2。
-
Pclass = 2和Pclass = 3的婴儿乘客大部分幸存下来。 进一步限定了我们的分类假设#2。
-
Pclass = 1的大多数乘客幸免于难。 确认我们的分类假设#3。
-
Pclass在乘客年龄分布方面有所不同。
决定 -
考虑使用Pclass进行模型训练。
# grid = sns.FacetGrid(train_df, col='Pclass', hue='Survived')
grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', size=2.2, aspect=1.6)
grid.map(plt.hist, 'Age', alpha=.5, bins=20)
grid.add_legend();