Kaggle-Titanic入门教程2

数据分析

原文链接

重构发行 2017.01.29

我们主要基于(a)从读者那收集的评价;(b)从Jupyter kernel2.7移植到Kaggle kernel3.5的错误;(c)阅览了一些更好的实践kernels重构了notebook。

用户评价

对于如将数据中的名称转换为数值的特定操作组合训练和测试数据。(thanks @Sharan Naribole)
正确的观察 - 近30%的乘客的兄弟姐妹或伴侣在船上。(thanks @Reinhard)
正确解释逻辑回归系数。(thanks @Reinhard)

移植错误

指定plot的维度,将legend带入plot。

最好的实践

在项目早期,进行特征相关分析。

为了可读性,采用多个图取代层叠图。

# 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的DataFrame形式的训练集和测试集开始。我们也在执行两个数据集都需要的确定操作时组合这些数据集。

train_df = pd.read_csv('../input/train.csv')
test_df = pd.read_csv('../input/test.csv')
combine = [train_df, test_df]

通过描述数据进行分析

在项目初期,Pandas也通过回答下列问题帮助描述数据集(Pandas also helps describe the datasets answering following questions early in our project.)

数据集中哪些特征是有用的?

为了直接操作或分析这些注意特证名。这些特征名在Kaggle data页面有描述。

print(train_df.columns.values)
哪些特征是类别特征?

这些值将样本分类到相似样本的集合中。类别特征的值都是名词(nominal)、序数(ordinal)、比例(ratio)或间隔(interval)? 除此之外,这有助于我们选择合适的图表进行可视化。

类别特征: Survived, Sex 和 Embarked.
序数特征: Pclass.

哪些特征是数值的?

哪些特征是数值的?这些值随着样本的不同而不同。数值特征是离散的、连续的还是基于时序的?除此之外,这有助于我们选择合适的图表进行可视化。

连续特征: Age, Fare.
离散特征: SibSp, Parch.

# preview the data
train_df.head()
哪些特征是混合数据类型?

同一特征中的数字、字母数据是待修正的候选值。

Ticket是混合了数字和字母的数据类型。Cabin是字母数字组成的。

那些特征可能包含错误或拼写错误?

对于大型数据集来说,这是很难审查的,但是从较小的数据集中查看一些样本可能会直接告诉我们,哪些特征可能需要纠正。

Name特征可能包含错误或拼写错误,因为这里用了多种方式描述名称,包括标题(titles),圆括号以及用于替代或短名称的引号。

train_df.tail()
哪些特征包含空白、空值?

这将需要被修正。

按照训练集中的顺序 Cabin > Age > Embarked 特征依次包含着一些空值。

在测试数据集的情况下,Cabin > Age是不完整的。

各种特征是什么数据类型的?

这个问题能在转换时协助我们。

七个特征是整数或浮点数。六个在测试集中。

五个特征是string类型(对象、object)。

train_df.info()
print('_'*40)
test_df.info()
样本中数值特征值的分布是什么?

根据其他早期的见解,这有助于我们确定实际问题领域的训练集的代表性。

  • “泰坦尼克号”(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]`
类别特征的分布是什么?
  • 数据集中Name是唯一的 (count=unique=891)。

  • Sex可变为两个可能的值,男性为65%(top=male, freq=577/count=891)。

  • Cabin值有多个样本的重复。或者几个乘客共享一个小屋。

  • Embarked有三种取值。大多数乘客都是S值。(顶部= S)

  • Ticket特征具有高重复值(22%)(唯一= 681)。

train_df.describe(include=['O'])
基于数据分析的假设

基于至今为止所做的数据分析,我们可以得到以下假设。我们可能会在采取适当行动之前进一步验证这些假设。

关联

我们想知道每一个特征与Survival的相关度。我们想在项目早期完成这个,并且在项目后期中,将这些快速相关联特征与模型化的匹配。

填充
  1. 因为Age特征与survival直接相关我们可能想去填充Age特征

  2. 我们可能想填充Embarked特征,因为它可能也与survival或其他重要的特征相关。

修正
  1. Ticket特征可能会从我们的分析中丢弃,因为它包含着高重复率(22%),并且在Ticket与survival之间可能没有关联。

  2. Cabin特征可能因为它高度的不完整性或在训练集和测试集中包含太多空值而被丢弃。

  3. PassengerId因为对survival没有贡献而可能从训练集中删除。

  4. Name特征相对不独立,可能不能对survival产生直接贡献,所以可能会被丢弃。

创造
  1. 我们可能想基于Parch和SibSp创建一个名为Family的新特征,来获得在船上的家庭成员的个数。

  2. 我们可能想改造Name特征,提取Title作为新特征。

  3. 我们可能想为年龄区间创造一个新特征。这使得连续数值特征转化为序列类别特征。

  4. 如果能对我们分析有所帮助,我们可能也想去创建一个Fare范围特征。

归类

我们也可以根据以前提到的问题描述增加我们的假设。

  1. 女人(Sex=female)更可能存活。

  2. 儿童(Age < ?)更可能存活。

  3. 上层阶级乘客(Pclass=1)更可能存活。

旋转特征分析

为了确认我们的一些观察和假设,我们可以通过相互转换特征来快速分析我们的特征相关性。我们只能在这个阶段为没有任何空值的特征做到这一点。这仅对于类别(Sex),序数(Pclass)或离散(SibSp,Parch)类型的特征才有意义。

train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)

Pclass 我们观察到Pclass=1与存活率之间显著的相关性(>0.5)(基于数据分析的假设.归类 #3)。我们决定将这个特征加入到模型中。

train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)

Sex 我们确定在问题定义的观察中发现Sex=female有74%的很好的存活率(基于数据分析的假设.归类 #1).

train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)

SibSp 和 Parch 这些特征对于某些值有零相关性。最好从这些单个特征中衍生出一个或一组特征。 (基于数据分析的假设.创造 #1).

可视化数据分析

现在我们可以继续使用可视化分析数据来确定一些我们的假设。

数值特征的相关性

让我们从理解数值特征和解决方案目标(存活)之间的相关性开始。

矩形图对于分析连续数值变量(如Age)是有用的,它的分段或范围将帮助识别有用的模式。矩形图可以使用自定义的分箱或等距范围的分段来表明样本的分布。这将帮助我们回答与特定区间相关的问题。(婴儿有更好的存活率吗?)

注意可视化矩形图的x轴表示样本或乘客的数量。

观察
  • 幼儿(Infants) (Age <=4)有更高的存活率。
  • 老年乘客(Age = 80) 存活。
  • 大量15-25 岁乘客没有存活。
  • 大多数乘客年龄在15-35岁之间。
决策

这个简单的分析证实了我们的假设是后续工作流程阶段的决策。

  • 我们应该考虑将Age加入到模型训练中(基于数据分析的假设.归类 #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();
类别特征的相关性

现在,我们可以探索类别特征和我们的解决目标之间的相关性。

观察
  • 女性乘客比男性有更好的存活率。证实基于数据分析的假设.归类 #1

  • Embarked=C时例外,男性有更高的存活率。这可能是因为在Pclass与Embarked之间存在相关性,Pclass和Survived之间也存在相关性,不一定是Embarked与Survived之间存在直接关联。

  • 与在Embarked = C和Q的Pclass = 2的男性相比,Pclass=3的男性有更好的存活率。基于数据分析的假设.填充 #2。

  • 对于Pclass=3的男性乘客而言,不同登船口有不同的存活率。基于数据分析的假设.关联 #1。

决策
  • 将Sex特征添加到模型训练中。
  • 填充并增加Embarked特征到模型训练中。
# grid = sns.FacetGrid(train_df, col='Embarked')
grid = sns.FacetGrid(train_df, row='Embarked', size=2.2, aspect=1.6)
grid.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette='deep')
grid.add_legend()
类别和数值特征的相关性

我们可能也想将(非数值)类别特征和数值特征相关联。我们考虑将Embarked (非数值类别), Sex (非数值类别), Fare (连续数值), 和Survived (数值类别)相关联。

观察
  • 支付更高票价的乘客有更好的存活率。证实我们的假设(基于数据分析的假设.创造 #4)

  • 登船港口与存活率相关。证实基于数据分析的假设.关联 #1 和 基于数据分析的假设.填充 #2

决策

考虑将Fare特征分段。

# grid = sns.FacetGrid(train_df, col='Embarked', hue='Survived', palette={0: 'k', 1: 'w'})
grid = sns.FacetGrid(train_df, row='Embarked', col='Survived', size=2.2, aspect=1.6)
grid.map(sns.barplot, 'Sex', 'Fare', alpha=.5, ci=None)
grid.add_legend()

总结

  1. 了解数据
  2. 提出假设
  3. 使用统计与可视化方式验证假设

Kaggle教程系列

Kaggle-Titanic入门教程1
Kaggle-Titanic入门教程2
Kaggle-Titanic入门教程3

你可能感兴趣的:(Kaggle,数据竞赛,机器学习,数据竞赛入门,翻译)