泰坦尼克号乘客生存情况预测分析总

🌟欢迎来到 我的博客 —— 探索技术的无限可能!


🌟博客的简介(文章目录)


泰坦尼克号乘客生存情况预测分析1
泰坦尼克号乘客生存情况预测分析2
泰坦尼克号乘客生存情况预测分析3
泰坦尼克号乘客生存情况预测分析总


在这里插入图片描述

背景描述

Titanic数据集在数据分析领域是十分经典的数据集,非常适合刚入门的小伙伴进行学习!

泰坦尼克号轮船的沉没是历史上最为人熟知的海难事件之一。1912年4月15日,在她的处女航中,泰坦尼克号在与冰山相撞后沉没,在船上的 2224 名乘客和机组人员中,共造成 1502 人死亡。这场耸人听闻的悲剧震惊了国际社会,从而促进了船舶安全规定的完善。造成海难失事的原因之一是乘客和机组人员没有足够的救生艇。尽管在沉船事件中幸存者有一些运气因素,但有些人比其他人更容易存活下来,究竟有哪些因素影响着最终乘客的生存与否呢?

数据说明

在该数据集中,共包括三个文件,分别代表训练集测试集以及测试集的答案

数据描述:

变量名称PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
变量解释乘客编号是否存活船舱等级姓名性别年龄兄弟姐妹和配偶数量父母与子女数量票的编号票价座位号登船码头
数据类型numericcategoricalcategoricalStringcategoricalcategoricalnumericnumericstringnumericstringcategorical

:以上数据类型均为经过预处理后的数据类型!

数据来源

Titanic Competition : How top LB got their score


一 数据读取与分析

泰坦尼克号乘客生存情况预测分析1

1. 数据读取

import warnings
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
#设置中文编码和负号的正常显示
plt.rcParams['font.family']='Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False

import pandas as pd
import numpy as np
data_train = pd.read_csv('train.csv') # 训练集数据
data_test = pd.read_csv('test.csv') # 测试集数据
data_train.shape, data_test.shape, data_train.columns

在这里插入图片描述

可以看到训练集总共有12列891行数据,其中Survived字段表示的是乘客是否获救,其余都是乘客个人信息,包括:

  • Survived — 获救情况(二分类,因变量)
  • PassengerId — 乘客ID
  • Pclass — 乘客等级(1/2/3等舱位)
  • Name — 乘客姓名
  • Sex — 性别
  • Age — 年龄
  • SibSp — 堂兄弟/妹个数
  • Parch — 父母与小孩个数
  • Ticket — 船票信息
  • Fare — 票价
  • Cabin — 客舱
  • Embarked — 登船港口

2. 简单描述性分析

看一下数据类型及缺失情况

data_train.info()

在这里插入图片描述

  • 数据显示,训练数据集中共有891名乘客,12列特征,其中有三列数据存在缺失:
    • Age(年龄):只有714条完整记录,有177条记录缺失;
    • Cabin(客舱):只有204条乘客已知,有687条记录缺失,缺失较多!;
    • Embarked(登船港口):只有两条记录缺失;
  • 下面来看一下数据的描述性统计
data_train.describe()

在这里插入图片描述

  • 根据表格,我们可以得出一些基本信息:

    • Survived:大概有0.383838比例的人最后获救了;
    • Pclass: 2号和3号舱的人要比1号舱的人多;
    • Age:所有乘客的平均年龄大概再29.7岁,最小的乘客0.42岁,最大的乘客80岁;
    • Fare:平均票价在32元,最高的票价在512元;
  • 查看test数据集,看分布是否与训练集一致

data_test.describe()

在这里插入图片描述

  • 训练集和测试集大致的分布相差不大;

3. 探索性分析

3.1 乘客不同特征的描述性统计

import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure(figsize=(15,10))
fig.set(alpha=0.2) # 设定图标透明度

plt.subplot2grid((2,3),(0,0)) # 分为2行3列,从(0,0)算起
data_train.Survived.value_counts().plot(kind='bar')
plt.title('获救情况(1为获救)')
plt.ylabel('人数')

plt.subplot2grid((2,3),(0,1))
data_train.Pclass.value_counts().plot(kind="bar")
plt.ylabel("人数")
plt.title("乘客等级分布")

plt.subplot2grid((2,3),(0,2))
plt.scatter(data_train.Survived, data_train.Age)
plt.ylabel("年龄")                         
plt.grid(visible=True, which='major', axis='y') # 绘制网格线
plt.title("按年龄看获救分布 (1为获救)")

plt.subplot2grid((2,3),(1,0), colspan=2)
data_train.Age[data_train.Pclass == 1].plot(kind='kde')  # 绘制密度图
data_train.Age[data_train.Pclass == 2].plot(kind='kde')
data_train.Age[data_train.Pclass == 3].plot(kind='kde')
plt.xlabel("年龄")
plt.ylabel("密度") 
plt.title("各等级的乘客年龄分布")
plt.legend(('头等舱', '2等舱', '3等舱'),loc='best') # 

plt.subplot2grid((2,3),(1,2))
data_train.Embarked.value_counts().plot(kind='bar')
plt.title("各登船口岸上船人数")
plt.ylabel("人数")

在这里插入图片描述

根据训练集数据绘制如上图所示,从图中我们可以得到一些信息:

  • 未能获救的人有500+,而获救的人大概有300+,不到人数的一半;
  • 三等舱乘客最多,接近500人,而一等和二等舱的乘客相对较少,都在200人左右;
  • 从年龄分布可以看出,遇难和获救的乘客年龄分布都比较离散,跨度大;
  • 三个不同舱的乘客年龄总体趋势大致相同,其中20岁左右的乘客主要集中再二三等舱,一等舱中40岁左右的最多;
  • 再登船港口中,其中S港口上传人数最多,有600+人,另外两个C和Q港口,都不到200人,要远远小于C港口;

根据以上结论,提出一些假设:

  • 不同舱位/乘客等级可能和财富/地位有关系,最后获救概率可能会不一样;
  • 年龄对获救概率也一定是有影响的,毕竟背景知识提到,副船长还说『小孩和女士先走』呢;
  • 获救概率与登船港口是不是有关系呢?也许登船港口不同,人的出身地位不同?

3.2 看看各乘客等级的获救情况

fig = plt.figure()
fig.set(alpha=0.2)  # 设定图表颜色alpha参数

Survived_0 = data_train.Pclass[data_train.Survived == 0].value_counts()
Survived_1 = data_train.Pclass[data_train.Survived == 1].value_counts()
df = pd.DataFrame({u'未获救':Survived_0, u'获救':Survived_1})
df.plot(kind='bar', stacked=True)
plt.title(u'不同等级乘客获救情况')
plt.xlabel(u'乘客等级')
plt.ylabel(u'人数')
plt.show()

在这里插入图片描述

data_train[['Pclass', 'Survived']].groupby('Pclass').mean()

在这里插入图片描述

从图中可以看出,等级为1的乘客,获救的概率最大,并且随着等级的递减,获救的概率也是递减状态!所以,乘客等级这必然是一个影响乘获救的重要特征!!

3.3 查看各性别的获救情况

fig = plt.figure()
fig.set(alpha=0.2)

Survived_0 = data_train.Survived[data_train.Sex == 'male'].value_counts()
Survived_1 = data_train.Survived[data_train.Sex == 'female'].value_counts()
df = pd.DataFrame({u'男性':Survived_0, u'女性':Survived_1})
df.plot(kind='bar', stacked=True)
plt.title(u'不同性别乘客获救情况')
plt.xlabel(u'获救与否')
plt.ylabel(u'人数')
plt.show()

在这里插入图片描述

data_train[['Sex','Survived']].groupby('Sex').mean()

在这里插入图片描述

从图中可以看出,相对男性来说,女性的获救率远远高于男性,看来外国人还是比较践行女性优先的!所以,性别对于最终生存与否也是有非常重要影响的!

3.4 查看各登船港口的获救情况

泰坦尼克号从英国的南安普顿港出发,途径法国瑟堡和爱尔兰昆士敦,那么在昆士敦之前上船的人,有可能在瑟堡或昆士敦下船,这些人将不会遇到海难。

fig = plt.figure(figsize=(10,15))
fig.set(alpha=0.2)

Survived_0 = data_train.Embarked[data_train.Survived == 0].value_counts()
Survived_1 = data_train.Embarked[data_train.Survived == 1].value_counts()
df = pd.DataFrame({u'未获救':Survived_0, u'获救':Survived_1})
df.plot(kind='bar', stacked=True)
plt.title(u'不同登船港口的乘客获救情况')
plt.xlabel(u'登船港口')
plt.ylabel(u'人数')
plt.show()

在这里插入图片描述

data_train[['Embarked','Survived']].groupby('Embarked').mean()

在这里插入图片描述

import seaborn as sns
import matplotlib.pyplot as plt

sns.catplot(x='Embarked', y='Survived', data=data_train, kind = 'point')
plt.title(u'各登录港口乘客的获救情况')
plt.show()

在这里插入图片描述

可以看出,再不同港口上船,生还率不同,其中C港口最高,Q次之,S港口最低;

3.5 查看携带家人数量不同的获救情况

data_train['family'] = data_train['SibSp'] + data_train['Parch']
data_train['family']

在这里插入图片描述

Survived_0 = data_train.family[data_train.Survived == 0].value_counts()
Survived_1 = data_train.family[data_train.Survived == 1].value_counts()
df = pd.DataFrame({u'未获救':Survived_0, u'获救':Survived_1})
df.plot(kind='bar', stacked=True)
plt.title(u'携带不同家人数量的乘客获救情况')
plt.xlabel(u'携带家人数量')
plt.ylabel(u'人数')
plt.show()

在这里插入图片描述

data_train[['family', 'Survived']].groupby('family').mean().plot.bar()

在这里插入图片描述

可以看到,独自一人和亲友太多,存活率都比较低

3.6 不同船舱类型的乘客获救情况

船舱的缺失值确实太多,有效值仅仅有204个,很难分析出不同的船舱和存活的关系,我们可以直接将该组特征丢弃掉,也可以简单地将数据分为是否有Cabin记录作为特征,将缺失数据归为一类,未缺失数据归为一类,一同跟与Survived进行分析

is_null = data_train.Survived[data_train.Cabin.isnull()].value_counts()
not_null = data_train.Survived[data_train.Cabin.notnull()].value_counts()
df = pd.DataFrame({'为空':is_null, '非空':not_null}).transpose()
df.plot(kind='bar', stacked=True)
plt.title('按Cabin是否为空看获救情况')
plt.xlabel('Cabin是否为空')
plt.ylabel('人数')
plt.show()

在这里插入图片描述

data_train.Survived[data_train.Cabin.notnull()].value_counts(normalize=True)

在这里插入图片描述

data_train.Survived[data_train.Cabin.isnull()].value_counts(normalize=True)

在这里插入图片描述

可以看出,有cabin记录的乘客survival比例比无记录的高很多;

3.7 缺失值处理

这里只是为了进行探索性分析,具体更详细的数据处理见特征工程部分。

通常遇到缺值的情况,有下面几种处理方式:

  • 如果缺值的样本占比较高,可以直接舍弃,以免作为特征加入,反倒带入噪声;
  • 如果缺值的样本适中,而该属性非连续值特征属性(比如类目属性),- 那就把NaN作为一个新类别,加到类别特征中
  • 如果缺值的样本适中,而该属性为连续值特征属性,可以尝试分桶处理;
  • 当缺失的样本并不是特别多的时候,我们可以试着根据已有的值,拟合一下数据,补充上。

Embarked(共有三个上船地点),缺失俩值,可以用众数填充;
Cabin将缺失信息当做一个类目;

处理Embarked和数据

由于总共有1309条数据,Embarked只缺失两个,所以用众数填充即可

data_train.Embarked[data_train.Embarked.isnull() == True] = data_train.Embarked.dropna().mode().values

data_train['Cabin'] = data_train.Cabin.fillna('U0') # 先简单填充Cabin
处理Age数据
facet = sns.FacetGrid(data_train,hue="Survived",aspect=4)
facet.map(sns.kdeplot,'Age',shade=True)
facet.set(xlim=(0,data_train['Age'].max()))
facet.add_legend()

在这里插入图片描述

通常使用回归、随机森林等模型来预测缺失属性的值。
经过分析:Age在该数据集里是一个相当重要的特征,所以保证一定的缺失值填充准确率是非常重要的,对结果也会产生较大影响。
这里使用随机森林预测模型,选取数据集中的数值属性作为特征(因为sklearn的模型只能处理数值属性,所以这里先仅选取数值特征,但在实际的应用中需要将非数值特征转换为数值特征);

data_train.info()

在这里插入图片描述

from sklearn.ensemble import RandomForestRegressor

cols = ['Age', 'Survived', 'Pclass', 'SibSp', 'Parch', 'Fare']
age_df = data_train[cols]
X_train = age_df[age_df.Age.notnull()][cols[1:]]
y_train = age_df[age_df.Age.notnull()][cols[0]]
X_test = age_df[age_df.Age.isnull()][cols[1:]]

rfr = RandomForestRegressor(n_estimators=1000, n_jobs=-1) #n_estimators控制随机森林决策树的数量;n_jobs=-1会使用CPU的全部内核,大幅度提升速度
rfr.fit(X_train, y_train)
y_predict = rfr.predict(X_test)
data_train.loc[data_train.Age.isnull(),'Age'] = y_predict # 缺失值填充
data_train.info()

在这里插入图片描述

3.8 不同年龄下的平均生存率

plt.figure(figsize=(18,6))
data_train['Age_int'] = data_train.Age.astype(int)
rate = data_train[['Age_int', 'Survived']].groupby('Age_int', as_index=False).mean()
sns.barplot(x='Age_int', y='Survived', data=rate)
plt.show()

在这里插入图片描述

data_train['Age'].describe()

在这里插入图片描述

从上图可以看出,训练样本共有891份,平均年龄在29.5岁,标准差为13.7岁,最小年龄0.42岁,最大年龄80岁;根据年龄,可以将乘客划分为儿童、少年、成年、老年,分析四个群体的生还情况

bins = [0, 12, 18, 65, 100]
data_train['Age_group'] = pd.cut(data_train['Age'], bins)
age_group_survived_rate = data_train.groupby('Age_group')['Survived'].mean()
age_group_survived_rate

在这里插入图片描述

age_group_survived_rate.plot(kind='bar')

在这里插入图片描述

从图中可以看出,0到12岁儿童的存活率是最高的,达到了50%左右,其次是少年群体,在45%以上,最低的就属于65岁到100岁的老年群体,存活率最低,在12%左右;所以看得出来,不管在哪,孩子永远都是第一要保护的对象;

3.9 不同称呼的乘客生存情况

通过观察名字数据,我们可以看出其中包括对乘客的称呼,如:Mr、Miss、Mrs等,称呼信息包含了乘客的年龄、性别,同时也包含了入社会地位等的称呼,如:Dr,Lady,Major(少校),Master(硕士,主人,师傅)等的称呼。

data_train['Name']

在这里插入图片描述

#方法一:
data_train['Title'] = data_train['Name'].apply(lambda x : x.split(',')[1].split('.')[0].strip())
pd.crosstab(data_train['Title'],data_train['Sex'])
#方法二:
data_train['Title'] =data_train['Name'].str.extract(' ([A-Za-z]+)\.',expand=False)
pd.crosstab(data_train['Title'],data_train['Sex'])

在这里插入图片描述

不同称呼的生存率

data_train[['Title', 'Survived']].groupby('Title').mean().plot(kind='bar')

在这里插入图片描述

从图中可以看出,不同称呼的乘客存活情况也不尽相同,存在显著差异,其中称呼为Lady、Mlle、Mme、Ms、Sir以及the countess的人群的存活率最高,均达到了100%的存活率;

3.10 票价分布与Survived的关系

票价分布情况

plt.figure(figsize=(10, 8))
data_train['Fare'].hist(bins=70)

在这里插入图片描述

data_train.boxplot(column='Fare', by='Pclass', showfliers=False)

在这里插入图片描述

data_train['Fare'].describe()

在这里插入图片描述

绘制survived与票价均值和方差的关系

fare_not_survived = data_train['Fare'][data_train['Survived'] == 0]
fare_survived = data_train['Fare'][data_train['Survived'] == 1]
 
average_fare = pd.DataFrame([fare_not_survived.mean(),fare_survived.mean()])
std_fare = pd.DataFrame([fare_not_survived.std(),fare_survived.std()])
average_fare.plot(yerr=std_fare,kind='bar',legend=False)

在这里插入图片描述

从图中可以看出,生存者的平均票价要大于未生还者的平均票价

4. 小结

根据以上探索性分析,我们可以猜测出一些结论:

  • 舱位等级:舱位越高的获救的概率最大,并且随着等级的递减,比如一等舱就比二三等舱获救概率大;
  • 性别:女性的获救率远远高于男性;
  • 登船港口:C港口最高,Q次之,S港口最低;(需结合具体背景解释原因)
  • 携带家人数量:独自一人和亲友太多,存活率都比较低;
  • 客舱:缺失值较多,很难分析出有用信息,这里简单将缺失的看成一类,未缺失的看成一类;
  • 年龄:0到12岁儿童存活率最高,在50%左右,其次是少年,最低的是65岁到100岁的老年群体;
  • 称呼:不同称呼的乘客存活情况也不尽相同,存在显著差异;其中,Lady、Mlle、Mme、Ms、Sir以及the countess存活率均在100%;
  • 票价:生存者的平均票价要大于未生还者的平均票价;

二 特征工程

泰坦尼克号乘客生存情况预测分析2

1. 合并训练集与测试集

在进行特征工程的时候,我们不仅需要对训练数据进行处理,还需要同时将测试数据同训练数据一起处理,使得二者具有相同的数据类型和数据分布。

import pandas as pd

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
train_and_test = train.append(test, sort=False) # 合并训练集与测试集
PassengerId = test['PassengerId']
train_and_test.shape

在这里插入图片描述

2. 缺失值处理

对Embarked直接用众数填充;
对Fare用均值填充;
对Age,建立模型预测;

2.1 填充Embarked字段

mode = train_and_test['Embarked'].mode().iloc[0] # 找到众数
train_and_test['Embarked'].fillna(mode, inplace=True)
train_and_test.info()

在这里插入图片描述

2.2 填充船票Fare字段

train_and_test['Fare'].mean()

在这里插入图片描述

Fare_mean = train_and_test['Fare'].mean()
train_and_test['Fare'].fillna(Fare_mean, inplace=True)
train_and_test.info()

在这里插入图片描述

2.3 填充年龄Age字段

为尽可能用多的特征去预测Age的值,先对Cabin、Embarked、Name、Sex、Ticket、Pclass等特征进行处理,模型预测见后;

3 不同特征字段的数据处理

3.1 先对Embarked、Sex以及Pclass等用dummy处理

对分类特征进行编码

cols = ['Embarked', 'Sex', 'Pclass']
train_and_test = pd.get_dummies(train_and_test, columns=cols, prefix_sep='__')
train_and_test.info()

在这里插入图片描述

3.2 票价分级处理

我们可以尝试将Fare分桶处理,使用qcut函数。qcut是根据这些值的频率来选择箱子的均匀间隔,每个箱子中含有的数的数量是相同的;

# 临时列
train_and_test['Fare_bin'] = pd.qcut(train_and_test['Fare'], 5)

#编码
train_and_test['Fare_bin_id'] = pd.factorize(train_and_test['Fare_bin'])[0]
fare_bin_dummies_df = pd.get_dummies(train_and_test['Fare_bin_id']).rename(columns=lambda x : 'Fare_' + str(x))
train_and_test = pd.concat([train_and_test, fare_bin_dummies_df], axis=1)
train_and_test.drop(['Fare_bin'], axis=1, inplace=True)

3.3 名字处理

对名字Name进行处理,提取其特征;

提取称呼

train_and_test['Title'] = train_and_test['Name'].apply(lambda x : x.split(',')[1].split('.')[0].strip())
train_and_test['Title']

在这里插入图片描述

# 将各式称呼进行统一化处理
# 头衔映射表
titleDict = {
    "Capt" :      "Officer", 
    "Col"  :      "Officer",
    "Major":      "Officer",
    "Jonkheer":   "Royalty",
    "Don":        "Royalty",
    "Sir" :       "Royalty",
    "Dr":         "Officer",
    "Rev":        "Officer",
    "the Countess":"Royalty",
    "Dona":       "Royalty",
    "Mme":        "Mrs",
    "Mlle":       "Miss",
    "Ms":         "Mrs",
    "Mr" :        "Mr",
    "Mrs" :       "Mrs",
    "Miss" :      "Miss",
    "Master" :    "Master",
    "Lady" :      "Royalty"
}
train_and_test['Title'] = train_and_test['Title'].map(titleDict)
train_and_test['Title'].value_counts()

在这里插入图片描述

one_hot编码

train_and_test['Title'] = pd.factorize(train_and_test['Title'])[0]
title_dummies_df = pd.get_dummies(train_and_test['Title'], prefix=train_and_test[['Title']].columns[0])
train_and_test = pd.concat([train_and_test, title_dummies_df], axis=1)
train_and_test.info()

在这里插入图片描述

提取长度特征

train_and_test['Name_length'] = train_and_test['Name'].apply(len)
train_and_test['Name_length']

在这里插入图片描述

3.4 Cabin处理

Cabin缺失值过多,将其分为有无两类,进行编码,如果缺失,即为0,否则为1;

train_and_test.loc[train_and_test.Cabin.isnull(), 'Cabin'] = 'U0'
train_and_test['Cabin'] = train_and_test['Cabin'].apply(lambda x : 0 if x == 'U0' else 1)
train_and_test['Cabin']

在这里插入图片描述

3.5 Ticket处理

Ticket有字母和数字之分,对于不同的字母,可能在很大程度上就意味着船舱等级或者不同船舱的位置,也会对Survived产生一定的影响,所以我们将Ticket中的字母分开,为数字的部分则分为一类。

train_and_test['Ticket_Letter'] = train_and_test['Ticket'].str.split().str[0]
train_and_test['Ticket_Letter'] = train_and_test['Ticket_Letter'].apply(lambda x : 'U0' if x.isnumeric() else x)

# 将Ticket_Letter factorize
train_and_test['Ticket_Letter'] = pd.factorize(train_and_test['Ticket_Letter'])[0]
train_and_test['Ticket_Letter']

在这里插入图片描述

4. 利用随机森林预测Age缺失值

from sklearn.ensemble import RandomForestRegressor  # 随机森林回归

missing_age = train_and_test.drop(['PassengerId', 'Survived', 'Name', 'Ticket'], axis=1) # 去除字符串类型的字段
missing_age_train = missing_age[missing_age['Age'].notnull()]
missing_age_test = missing_age[missing_age['Age'].isnull()]

X_train = missing_age_train.iloc[:,1:]
y_train = missing_age_train.iloc[:,0]
X_test = missing_age_test.iloc[:,1:]

rfr = RandomForestRegressor(n_estimators=1000, n_jobs=-1)
rfr.fit(X_train, y_train)
y_predict = rfr.predict(X_test)
train_and_test.loc[train_and_test['Age'].isnull(), 'Age'] = y_predict
train_and_test.info()

在这里插入图片描述

5. 各特征与Survived的相关系数排序

根据生存情况与其他各特征的相关系数,按系数倒序排序,筛选出重要特征 – 重要特征

train_and_test.corr()['Survived'].abs().sort_values(ascending=False)

在这里插入图片描述

6. 保存特征处理后的数据

train_and_test.to_csv('经过特征工程处理后的数据.csv', index=None)

7. 小结

特征工程这一章主要做了以下工作:

  • 合并训练集和测试集
    • 为了使二者具有相同的数据类型和数据分布;
  • 缺失值处理:
    • Embarked:众数填充;
    • Fare:平均值填充;
    • Age:随机森林预测填充;
  • 各特征字段的数据处理:
    • Embarked,Sex,Pclass: 直接dummy编码;
    • Fare: 先分桶处理,再dummy编码;
    • Name: 先提取称呼,再对称呼进行人群分类,最后dummy处理;
    • cabin:缺失值较多,根据是否缺失划分类别,缺失为0,否则为1;
    • Ticket:只保留其中字母,并对字母进行数字转换;
  • 随机森林建模预测Age缺失值;
  • 对各特征与生存与否进行了相关系数大小排序;

三 建模以及模型评价

泰坦尼克号乘客生存情况预测分析3

1. 数据分离

将经过特征工程处理后的数据分开,分成最初的训练数据和测试数据;

1.1 读取数据

import pandas as pd
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
truth = pd.read_csv('gender_submission.csv')
train_and_test = pd.read_csv('经过特征工程处理后的数据.csv')
PassengerId = test['PassengerId']

1.2 划分训练集和测试集

index = PassengerId[0] - 1
train_and_test_drop = train_and_test.drop(['PassengerId', 'Name', 'Ticket'], axis=1)
train_data = train_and_test_drop[:index]
test_data = train_and_test_drop[index:]

train_X = train_data.drop(['Survived'], axis=1)
train_y = train_data['Survived']
test_X = test_data.drop(['Survived'], axis=1)
test_y = truth['Survived']
train_X.shape, train_y.shape, test_X.shape

在这里插入图片描述

注:以下模型建模时,均使用默认参数,不涉及过多参数调优、交叉验证、复杂模型等,主要旨在比较再默认参数下不同模型的差异

2. 建模以及模型评价

本章主要实现建模及模型评价部分,为了简便起见,直接调用sklearn现成的函数,所有模型均采用默认参数,不涉及过多参数调优、算法优化等复杂过程,由于能力有限,这里只列举了一些常见的基础模型和集成模型,至于其他模型,读者可自行查阅资料补充

from sklearn.linear_model import LogisticRegression # 逻辑回归
from sklearn.ensemble import RandomForestClassifier # 随机森林
from sklearn.svm import SVC # 支持向量机
from sklearn.neighbors import KNeighborsClassifier # K最近邻
from sklearn.tree import DecisionTreeClassifier # 决策树
from sklearn.ensemble import GradientBoostingClassifier # 梯度提升树GBDT
import lightgbm as lgb # LightGBM算法
from xgboost.sklearn import XGBClassifier # XGBoost算法
from sklearn.ensemble import ExtraTreesClassifier # 极端随机树
from sklearn.ensemble import AdaBoostClassifier # 
from sklearn.ensemble import BaggingClassifier

from sklearn.metrics import roc_auc_score # 准确率评价模型好坏
import warnings
warnings.filterwarnings("ignore")

2.1 逻辑回归

lr = LogisticRegression() # logit 逻辑回归
lr.fit(train_X, train_y)
pred_lr = lr.predict(test_X) 
accuracy_lr = roc_auc_score(test_y, pred_lr)
print("逻辑回归的预测结果:", accuracy_lr)

在这里插入图片描述

2.2 随机森林-RF

rfc = RandomForestClassifier()
rfc.fit(train_X, train_y)
pred_rfc = rfc.predict(test_X)
accuracy_rfc = roc_auc_score(test_y, pred_rfc) 
print("随机森林的预测结果:", accuracy_rfc)

在这里插入图片描述

2.3 支持向量机-SVM

svm = SVC()
svm.fit(train_X,train_y)
pred_svm = svm.predict(test_X)
accuracy_svm = roc_auc_score(test_y, pred_svm) 
print("支持向量机的预测结果:", accuracy_svm)

在这里插入图片描述

2.4 K最近邻-KNN

knn = KNeighborsClassifier()
knn.fit(train_X,train_y)
pred_knn = knn.predict(test_X)
accuracy_knn = roc_auc_score(test_y, pred_knn) 
print("K最近邻分类器的预测结果:", accuracy_knn)

在这里插入图片描述

2.5 决策树

dtree = DecisionTreeClassifier()
dtree.fit(train_X,train_y)
pred_dtree = dtree.predict(test_X)
accuracy_dtree = roc_auc_score(test_y, pred_dtree) 
print("决策树模型的预测结果:", accuracy_dtree)

在这里插入图片描述

2.6 梯度提升决策树-GBDT

gbdt = GradientBoostingClassifier()
gbdt.fit(train_X, train_y)
pred_gbdt = gbdt.predict(test_X)
accuracy_gbdt = roc_auc_score(test_y, pred_gbdt) 
print("GBDT模型的预测结果:", accuracy_gbdt)

在这里插入图片描述

2.7 LightGBM算法

lgb_train = lgb.Dataset(train_X, train_y)
lgb_eval = lgb.Dataset(test_X, test_y, reference = lgb_train)

gbm = lgb.train(params = {}, train_set = lgb_train, valid_sets = lgb_eval)
pred_lgb = gbm.predict(test_X, num_iteration = gbm.best_iteration)
accuracy_lgb = roc_auc_score(test_y, pred_lgb) 
print("LightGBM模型的预测结果:", accuracy_lgb)

在这里插入图片描述

2.8 XGBoost算法

xgbc = XGBClassifier()
xgbc.fit(train_X, train_y)
pred_xgbc = xgbc.predict(test_X)
accuracy_xgbc = roc_auc_score(test_y, pred_xgbc) 
print("XGBoost模型的预测结果:", accuracy_xgbc)

2.9 极端随机树

etree = ExtraTreesClassifier()
etree.fit(train_X, train_y)
pred_etree = etree.predict(test_X)
accuracy_etree = roc_auc_score(test_y, pred_etree)
print("极端随机树模型的预测结果:", accuracy_etree)

在这里插入图片描述

2.10 AdaBoost算法

abc = AdaBoostClassifier()
abc.fit(train_X, train_y)
pred_abc = abc.predict(test_X)
accuracy_abc = roc_auc_score(test_y, pred_abc) 
print("AdaBoost模型的预测结果:", accuracy_abc)

在这里插入图片描述

2.11 基于Bagging的K最近邻

bag_knn = BaggingClassifier(KNeighborsClassifier())
bag_knn.fit(train_X, train_y)
pred_bag_knn = bag_knn.predict(test_X)
accuracy_bag_knn = roc_auc_score(test_y, pred_bag_knn)
print("基于Bagging的K紧邻模型的预测结果:", accuracy_bag_knn)

在这里插入图片描述

2.12 基于Bagging的决策树

bag_dt = BaggingClassifier(DecisionTreeClassifier())
bag_dt.fit(train_X, train_y)
pred_bag_dt = bag_dt.predict(test_X)
accuracy_bag_dt = roc_auc_score(test_y, pred_bag_dt)
print("基于Bagging的决策树模型的预测结果:", accuracy_bag_dt)

在这里插入图片描述

3. 小结

import seaborn as sns
import matplotlib.pyplot as plt

sns.set(rc={'figure.figsize':(15,6)}) # 设置画布大小
accuracys = [accuracy_lr, accuracy_rfc, accuracy_svm, accuracy_knn, accuracy_dtree, accuracy_gbdt, accuracy_lgb,accuracy_xgbc, accuracy_etree, accuracy_abc, accuracy_bag_knn, accuracy_bag_dt, ]
models = ['Logistic', 'RF', 'SVM', 'KNN', 'Dtree', 'GBDT', 'LightGBM', 'XGBoost', 'Etree', 'Adaboost', 'Bagging-KNN', 'Bagging-Dtree']
bar = sns.barplot(x=models, y=accuracys)

# 显示数值标签
for x, y in enumerate(accuracys):
    plt.text(x, y, '%s'% round(y,3), ha='center')

plt.xlabel("Model")
plt.ylabel("Accuracy")
plt.show()

在这里插入图片描述

根据上述条形图可以看出,在全部模型默认参数的情况下,逻辑回归的预测准确率最高,达到了0.911,其次是LightGBM模型,也在0.9以上,达到80%准确率以上的模型有RF、GBDT、XGBoost、ETree、Adaboost以及基于Bagging的决策树,其他模型的预测准确率则较低;

如果本文有存在不足的地方,欢迎大家在评论区留言。

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZShiJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值