Titanic-入门kaggle

191 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

Titanic

赛题介绍

比赛名称:Titanic - Machine Learning from Disaster

赛题任务:预测在 titanic 轮船乘客是否幸存。

赛题数据:乘客基本信息和船票信息。

评价指标:提交 .csv 文件检验准确率。

赛题难度:较低(GettingStarted )。

分析数据集

VariableDefinitionKey
survivalSurvival(是否幸存)0 = No, 1 = Yes
pclassTicket class(船票等级)1 = 1st, 2 = 2nd, 3 = 3rd
sexSex(性别)
AgeAge in years(年龄)
sibsp# of siblings / spouses aboard the Titanic(旁系亲戚数量)
parch# of parents / children aboard the Titanic(直系血亲数量)
ticketTicket number(船票编号)
farePassenger fare(价格)
cabinCabin number(船仓编号)
embarkedPort of Embarkation(上船起始点)C = Cherbourg, Q = Queenstown, S = Southampton

了解完每个字段的含义后,接下来完成以下分析工作:字段是否存在缺失值,字段含义和取值空间,字段相关性等,主要目的就是选择影响我们任务目标的特征,对该特征进行学习,达到分类能力。接下来看看整个过程是怎么样吧。

引入依赖

import numpy as np
import pandas as pd

%pylab inline
import seaborn as sns

numpy:用于科学计算

pandas:用于数据处理

seaborn:绘图库,用于数据分析

读取数据

train = pd.read_csv('./data/titanic/train.csv')
test = pd.read_csv('./data/titanic/test.csv')
train.head(10)

使用 pandasread_csv() 方法可以读取文件中的数据,利用 head 方法查看部分数据情况。

image.png

每一条数据都是一位乘客的信息,具有着多个特征。我们可以发现一些小的问题:Age 特征数据中包含 NAN等。

分析数据

train.describe(include='all')
train.info()

describe 方法能够对数据进行基础统计分析,可以统计出平均值,最大值等结果。

image.png

info 方法能够对每列数据进行基础分析,查看是否存在缺失值,以及数据类型。

image.png

根据上面图可以知道:Age,Cabin,Embarked 字段都存在缺失值。

我们对整体数据有着一定了解后,需要去分析每列数据,判断是否对我们目标造成影响,

PassageId & Survived

PassageId 是数据的索引,Survived 是数据的标签,对原始数据分析是无意义,一般分析数据是不考虑着两列。

Pclass

Pclass 是船票等级,数据类型为整型数据,可能取值1 = 1st, 2 = 2nd, 3 = 3rd

# 字段的分布关系
train['Pclass'].value_counts()
"""
3    491
1    216
2    184
Name: Pclass, dtype: int64
"""
train.groupby('Pclass')['Survived'].mean().plot(kind='bar')

image.png

根据分析可以知:数字不同,数量也不同,生存的概率也不同;数字越小,等级越高,生存概率越大。该字段会影响任务目标,故该特征保留。

Name

Name 是乘客姓名,从常识讲,似乎在救援方面不会去参考某人的姓名,但是该数据包含的头衔可以被提取出来单独分析,首先用正则表达式从 Name 字段提取特征 Title。

train['Title'] = train['Name'].str.extract(' ([A-Za-z]+)\.')
test['Title'] = test['Name'].str.extract(' ([A-Za-z]+)\.')

有着不同的头衔可能与乘客生还率相关,涉及到乘客社会地位,后面可以使用头衔对 Age 填充数据起到促进作用,首先需要对 Title 进行分组,提取到的太多了,需要进行聚合,观察与生还率相关程度。

train['Title'].replace(['Capt', 'Col', 'Major', 'Dr', 'Rev'],'Officer', inplace=True)
train['Title'].replace(['Don', 'Sir', 'the Countess', 'Countess', 'Dona', 'Lady'], 'Royalty', inplace=True)
train['Title'].replace(['Mme', 'Ms', 'Mrs'],'Mrs', inplace=True)
train['Title'].replace(['Mlle', 'Miss'], 'Miss', inplace=True)
train['Title'].replace(['Master','Jonkheer'],'Master', inplace=True)
train['Title'].replace(['Mr'], 'Mr', inplace=True)

train[['Title','Survived']].groupby(['Title']).mean().plot.bar()

image.png

根据图片显示,不同的头衔乘客生还率有着显著的区别,故该特征保留。

Sex

Sax 是乘客性别,当出现危险时候,普遍的逃生策略为:妇女和儿童优先,Sex 对生还率还是会有着一定影响力的。

sns.barplot(x='Sex', y='Survived', data=train)

image.png

可以很直观发现,女性的生还率明显高于男性生还率。

Age

Age 指乘客年龄,当出现危险时候,普遍的逃生策略为:妇女和儿童优先,年龄也会对生还率造成一定影响,但是 Age 字段存在大量缺失值,我们需要 Age 进行填补,乘客的年龄可以根据头衔划分出多个区间,根据区间去寻找生还率相关性。

# 将值 NAN 补充成 -0.5
train['Age'] = train['Age'].fillna(-0.5)
test['Age'] = test['Age'].fillna(-0.5)
# age进行分组
train['AgeGroup'] = pd.cut(train['Age'], [-1, 0, 5, 12, 18, 24, 60, np.inf],
      labels = ['Unkonw', 'Baby', 'Child', 'Teenager', 'Student', 'Adult', 'Senior'])

test['AgeGroup'] = pd.cut(test['Age'], [-1, 0, 5, 12, 18, 24, 60, np.inf],
      labels = ['Unkonw', 'Baby', 'Child', 'Teenager', 'Student', 'Adult', 'Senior'])
train[['AgeGroup', 'Survived']].groupby(['AgeGroup']).mean().plot.bar()

至于如何补足年龄,可以根据头衔进行分组,求出每个头衔的平均年龄值,去补足每一个年龄值为 NAN 的数据。

train[['Title','Age']].groupby(['Title']).describe()

SibSp & Parch

SibSp 代表乘客非直系亲属的数量,Parch 代表直系亲属的数量,这两个字段可能会对乘客生还率造成一定影响,一定数量的家庭一般都会一起生还。

sns.barplot(x='SibSp', y='Survived', data=train)
sns.barplot(x='Parch', y='Survived', data=train)

Ticket

Ticket 指船票的编号,其实与生还率没用存在一定相关性,不保留。

量化数据

不同的字段具有着不同值,我们需要对这些值进行量化,全部转化成数字,方便模型进行使用。一些特征的值是文本的形式,往往这样的特征需要转换为数值型的特征才能进行建模分析。

for col in ['Cabin', 'Embarked', 'AgeGroup', 'Title']:
    lbl = LabelEncoder()
    train[col] = train[col].astype(object)
    test[col] = test[col].astype(object)

    train[col] = train[col].fillna('-1')
    test[col] = test[col].fillna('-1')

    lbl.fit(list(train[col]) + list(test[col])) # 取值空间
    
    train[col] = lbl.transform(train[col])
    test[col] = lbl.transform(test[col])

image.png

划分数据集

将数据集划分成训练集和测试集,训练集去进行训练,保证模型参数更新,测试集主要测试模型参数是否正确,是否符合预期。

from sklearn.model_selection import train_test_split

x_train, x_val, y_train, y_val = train_test_split(train.drop(['PassengerId','Survived'], axis=1),
                                                 train['Survived'])

构建模型训练

此问题是分类问题,故采用逻辑回归模型进行处理。

from sklearn.linear_model import LogisticRegression

clf = LogisticRegression()
clf.fit(x_train, y_train)
clf.score(x_val, y_val)

最后对 kaggle 任务的测试集进行测试,得出结果后按要求写入 .csv 文件中,进行提交即可。