(Kaggle人工智能比赛复现)3万字长文教你如何一步步复现《泰坦尼克号生存预测》

Kaggle泰坦尼克号生存预测完整实战教程

泰坦尼克号生存预测(Titanic - Machine Learning from Disaster)是Kaggle上著名的入门竞赛之一。本文将以超详细的方式,带领大家从零开始完成这个比赛,包括数据理解、探索性分析、特征工程、模型构建(传统机器学习模型和PyTorch深度学习模型)、模型调优以及最终的Kaggle提交流程。无论你是刚入门的数据科学新人,还是有一年左右工作经验的算法工程师,都可以通过本教程逐步复现泰坦尼克号生存预测的完整解决方案。

我们将使用Python的科学计算生态(如Pandas、NumPy、Matplotlib/Seaborn等)进行数据分析,并使用scikit-learn构建基线模型,最后通过PyTorch构建一个多层感知机(MLP)模型来进行预测。所有代码均提供完整版本,读者可以直接复制运行。文章采用Markdown格式组织,包含清晰的标题、代码块和表格等排版元素,同时穿插必要的公式(使用KaTeX书写)和引用资料,帮助理解关键概念和确保内容的可复现性

1. 比赛背景与数据介绍

1.1 比赛任务简介

泰坦尼克号沉船事件背景:1912年4月15日,英国豪华邮轮泰坦尼克号在首航途中撞上冰山沉没。这次灾难中,2224名乘客和船员中有1502人遇难,成为历史上最臭名昭著的海难之一 (Kaggle-titanic by agconti) (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。事故发生后,人们痛定思痛,促成了航运安全法规的改进。然而,在这场灾难中,乘客的生还情况并非完全随机的运气,一些群体的生存率明显高于其他群体——例如女性、儿童和上层阶级乘客往往更有可能幸存,这也印证了当时“女士和小孩优先”的避难原则 。

比赛的任务与目标:Kaggle泰坦尼克号生存预测比赛要求参赛者根据乘客的特征(如姓名、年龄、性别、船舱等级等)建立模型,预测每一位乘客在这场灾难中是否幸存。换句话说,我们需要完成一个二分类任务:预测乘客的生存状态(生存用1表示,遇难用0表示) (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。这个任务不仅是机器学习的经典入门案例,也可以帮助我们体会在数据中发现影响生存的规律。例如,我们可以通过模型回答:“什么样的人更有可能幸存?” (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)

Kaggle入门竞赛:泰坦尼克号比赛是Kaggle的入门级知识型竞赛(Getting Started Competition),非常适合初学者练习完整的数据科学项目流程 (Kaggle-titanic by agconti)。通过此项目,我们可以熟悉以下内容:

  • 数据处理流程:从数据读取、清洗、探索,到特征工程和数据可视化。
  • 模型构建与评估:从简单的基线模型(如逻辑回归、决策树等)开始,逐步过渡到更复杂的模型(如随机森林、神经网络),并学会使用交叉验证、评价指标来评估模型性能。
  • 模型优化:学习调整超参数、融合多个模型提高性能的方法。
  • Kaggle提交流程:了解如何生成预测结果并提交到Kaggle,以及查看排行榜成绩。
  • 工具使用:熟练使用Pandas进行数据分析、Matplotlib/Seaborn进行可视化,scikit-learn和PyTorch进行建模。
  • 工程实践:掌握在Google Colab等环境运行代码的方法,了解版本控制和实验复现的最佳实践。

总之,通过本次实践,读者将全面体验一个数据科学项目的端到端流程,从而为今后参加Kaggle比赛或实际机器学习项目打下基础。

1.2 数据集来源及文件说明

Kaggle提供了泰坦尼克号乘客数据的两个主要数据集:训练集(train.csv)测试集(test.csv),以及一个示例提交文件gender_submission.csv。 (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)

  • 训练集(train.csv):包含891名乘客的详细信息,每名乘客占一行,其中包含他们是否幸存的标注(即“地面真相”)。也就是说,训练集提供了模型学习所需的特征和对应的目标标签 (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。在后续分析中,我们会使用该数据集来训练模型,并根据其结果调整模型参数。

  • 测试集(test.csv):包含另外418名乘客的详细信息。与训练集不同,测试集并不提供每名乘客是否幸存的结果标签 (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。我们的任务是利用在训练集上学到的模式,预测这些乘客的生存情况。最终,我们需要对测试集中的每个乘客给出“Survived”值的预测(0或1)。

  • 示例提交文件(gender_submission.csv):这是一个示例的结果提交文件,帮助参赛者了解提交格式。这个文件提供了一个基于性别的简单预测:假设所有女性乘客都幸存、所有男性乘客都遇难 (Kaggle 泰坦尼克号挑战赛目标 使用泰坦尼克号乘客数据(名字,年龄,票价等)预测谁将存活或者死去。 数据 在数据中有 - 掘金)。虽然这个假设并不精确,但鉴于我们在数据探索中将会看到的性别与生存率的关联,它作为起点并不算糟糕 (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。参赛者应根据自己模型的预测来生成类似格式的提交。

数据字段解释:泰坦尼克号数据集包含乘客的各种属性,我们在建模前需要理解每个字段的含义。以下是数据集中主要特征的说明(每列代表一个字段):

  • PassengerId:乘客ID,乘客的唯一标识符。
  • Survived:是否幸存(标签,0表示遇难,1表示存活)。注意:这个字段在测试集中不存在,因为这是我们需要预测的目标。
  • Pclass:客舱等级(1 = 一等舱,2 = 二等舱,3 = 三等舱)。这是乘客社会经济地位的指标,一等舱乘客往往是上流社会人士,三等舱则为普通或低收入乘客。
  • Name:乘客姓名(包括头衔)。例如Braund, Mr. Owen Harris。其中可以包含乘客的称谓(如Mr., Mrs., Miss等),这些头衔也蕴含了一定信息(性别、婚姻状况、社会地位等),在特征工程中将会被提取利用。
  • Sex:乘客性别(male男性 或 female女性)。
  • Age:乘客年龄(以岁为单位,部分乘客年龄缺失)。对于年龄小于1岁的婴儿以小数表示(如0.42表示约5个月大)。年龄与幸存与否有可能存在关联,例如儿童的幸存率可能不同于成人。
  • SibSp:兄弟姐妹/配偶同行数。这个数值表示乘客在船上有多少兄弟姐妹或配偶同船。定义:兄弟姐妹包括亲兄弟、亲姐妹、继兄弟、继姐妹;配偶指丈夫或妻子(未婚伴侣不计在内) (Titanic_Dataset_Exploratory_Analysis)。
  • Parch:父母/子女同行数。表示乘客在船上有多少父母或子女同船。定义:父母包括亲生父母、继父母;子女包括亲生子女、继子女。不包含其他亲属。
  • Ticket:船票编号。每个乘客的船票号码,可能含字母和数字的组合。部分乘客可能共用相同的船票编号(例如家人一起购票),因此从Ticket中我们可能推断一些团体信息。
  • Fare:票价。乘客为船票支付的费用(英镑)。票价与客舱等级、社会经济地位相关联,也是一个潜在的影响因素。
  • Cabin:舱房号。标识乘客所在的客舱,通常以舱甲板的字母加编号表示(例如C85)。该字段缺失值较多(许多乘客没有舱房编号,可能是因为他们住在较低舱等或公共舱室),是否有Cabin记录本身可能也是一种信息(例如有具体Cabin号的通常是一二等舱乘客)。
  • Embarked:登船港口。乘客从哪个港口登船。共有三个可能值:C = Cherbourg(瑟堡), Q = Queenstown(皇后镇), S = Southampton(南安普顿)。这是乘客出发地的信息,可能与其社会经济地位和目的地有关。

理解这些字段对于后续的分析和特征工程非常重要。例如,PclassFare反映了乘客的社会经济地位,SexAge反映了生理特征,SibSpParch可以结合成“家庭大小”等新特征,Embarked可能与乘客背景相关。接下来我们会详细探索各特征与生存率的关系。

1.3 Kaggle评分机制

在Kaggle泰坦尼克号比赛中,评价模型优劣的指标是预测准确率(Accuracy) (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。具体来说,提交的结果会与真实的生存情况进行比较,计算预测正确的百分比——这就是最终的得分。例如,如果在418名测试集乘客中模型正确预测了350人的生存状态,那么准确率即为 350 / 418 ≈ 0.8376 350/418 \approx 0.8376 350/4180.8376,通常Kaggle会以百分制或小数形式显示(例如83.76%或0.8376)。

需要注意的是,准确率只是衡量模型性能的一种方式。在这个比赛中,正负样本(幸存和遇难)分布大致为3:5左右,并不算极端失衡,所以准确率是合理的评估指标。然而,在更一般的机器学习任务中,若类别不平衡严重,光看准确率可能会有迷惑性,此时往往需要引入其他指标(如精确率、召回率、F1分数、AUC等)来辅助判断模型好坏。

Kaggle提交与排名:参赛者需要根据测试集预测生成一个提交文件(CSV格式),其中包含两列:PassengerIdSurvived(预测值,0或1) (Kaggle 泰坦尼克号挑战赛目标 使用泰坦尼克号乘客数据(名字,年龄,票价等)预测谁将存活或者死去。 数据 在数据中有 - 掘金)。提交文件的格式必须严格符合要求,多一列或少一列都会导致提交失败 (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。提交后,Kaggle会即时给出Public Leaderboard上的成绩(基于部分测试数据评估的准确率)。参赛者可以多次提交模型结果,不断改进。比赛期限结束后,会基于隐藏的Private Leaderboard排名决定最终名次(对于这个入门练习赛,名次不涉及奖金或晋级,但可以当作练习成果的验证)。我们在教程最后会详细讲解如何生成提交并查看分数。

接下来,我们将开始数据分析的过程,从数据读取、清洗到探索性分析,一步一步理解影响泰坦尼克号生存的因素。

2. 数据加载、探索与可视化

在这部分,我们将读取比赛数据,了解数据的基本情况,并通过探索性数据分析(EDA)和可视化手段,寻求不同特征与乘客生存率之间的关系。良好的EDA有助于我们发现数据中的模式,为后续的特征工程和建模提供指导。

2.1 数据加载和概览

首先,使用Pandas读取提供的CSV文件。确保将train.csvtest.csv放在工作目录下(如果在Kaggle Notebook或Colab环境中,可以根据实际路径调整)。我们还可以使用Pandas的函数查看数据的基本信息,例如行列数、字段类型、缺失值等。下面的代码实现数据加载并做初步检查:

import pandas as pd

# 读取训练集和测试集
train_df = pd.read_csv('train.csv')
test_df = pd.read_csv('test.csv')

# 查看训练集的维度(行数, 列数)
print("Train dataset shape:", train_df.shape)
print("Test dataset shape:", test_df.shape)

# 查看训练集前5行
train_df.head()

运行上述代码后,我们将得到训练集和测试集的基本尺寸以及训练集的前几条记录。根据数据描述可知,训练集包含891行、12列(包含标签列Survived),测试集包含418行、11列(不含Survived)。具体输出结果类似于:

Train dataset shape: (891, 12)
Test dataset shape: (418, 11)

训练集的前5行数据大致如下(这里为了篇幅,每行仅部分字段显示):

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...  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   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

从中可以初步看到一些规律:如样本0是一位22岁的三等舱男性(未幸存,Survived=0),样本1是一等舱38岁女性(幸存,Survived=1),等等。这些信息与我们前面描述的字段含义相符合。

接下来,我们查看数据的基本统计信息和缺失值情况:

# 查看各字段的数据类型和非空值数
train_df.info()
print("-" * 40)
test_df.info()

输出将列出每个字段的数据类型(int, float, object等)以及非空值的数量。对于训练集,我们预期输出(部分字段):

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  

可以看到,训练集总共有891条乘客记录,每个字段的非空值数量:大部分字段在891左右,但Age只有714个非空值(说明有177个年龄数据缺失),Cabin只有204个非空值(缺失高达687条,占绝大多数),Embarked有889个非空值(缺失2条)。这些缺失数据需要在后续的数据清理中加以处理。

测试集(418行)的字段类型类似,其中AgeCabin也有缺失,另外Fare在测试集中可能也有缺失值(稍后确认)。测试集没有Survived列。

让我们进一步查看数值型特征的描述性统计,以及Survived标签的分布:

# 数值型字段的统计描述
train_df.describe()

该命令将输出训练集中数值字段(不包括object类型)的统计量,例如计数、均值、标准差、最小值、四分位数、中位数、最大值等。例如,部分输出为:

            PassengerId    Survived      Pclass         Age       SibSp       Parch        Fare
count       891.000000   891.00000   891.000000  714.000000  891.000000  891.000000  891.000000
mean        446.000000     0.38384     2.308643   29.699118    0.523008    0.381594   32.204208
std         257.353842     0.48659     0.836071   14.526497    1.102743    0.806057   49.693429
min           1.000000     0.00000     1.000000    0.420000    0.000000    0.000000    0.000000
25%         223.500000     0.00000     2.000000   20.125000    0.000000    0.000000    7.910400
50%         446.000000     0.00000     3.000000   28.000000    0.000000    0.000000   14.454200
75%         668.500000     1.00000     3.000000   38.000000    1.000000    0.000000   31.000000
max         891.000000     1.00000     3.000000   80.000000    8.000000    6.000000  512.329200

从中我们可以获取一些有用信息:

  • 生存率总体情况Survived一列的均值为0.38384,表示训练集中生存者的比例约为38.38%,遇难者约61.62%。换句话说,在891名训练集乘客中,约有342人生存,549人遇难(0.38384 * 891 ≈ 342),确认了数据的总体分布。这意味着如果盲目预测所有人遇难,准确率也有61.6%,但我们的目标是超过这个基线,尽可能准确地区分出幸存者。
  • 年龄Age的平均数约29.70岁,中位数28岁,最年长乘客80岁,四分位范围20~38岁。这是一艘跨大西洋的客轮,乘客年龄跨度大,后续我们会关注不同年龄段的生存率。注意有177个年龄缺失需要填补。
  • 船舱等级Pclass的均值为2.308,反映训练集里三等舱乘客居多(一等舱用1表示,三等舱用3表示,均值>2说明三等舱比例较高)。最大值3,最小值1,符合取值范围。我们稍后可以统计各舱等人数和生存率。
  • 家庭相关SibSp最大值8(意味着有乘客在船上有8个兄弟姐妹或配偶,确实有家庭可能非常庞大),Parch最大6。四分位数表明多数乘客没有携带直系家庭成员上船(75%分位处SibSp=1, Parch=0)。
  • 票价Fare分布跨度大,从0到512不等。平均票价32.20英镑,中位数14.45,表明票价分布可能偏态分布(有少数乘客支付了极高票价——512.33是船上最贵的票,应是豪华套房)。票价与舱等高度相关,一等舱票价通常昂贵,三等舱便宜甚至免费(可能船员或者特殊情况)。

最后,我们查看一下训练集中各字段缺失值数量,以便制定缺失值处理策略:

# 统计训练集每列缺失值数量
train_df.isnull().sum()

结果会显示每个字段缺失值的个数,例如:

PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64

这证实了我们之前通过info推断的缺失情况:Age缺失177条,Cabin缺失687条,Embarked缺失2条,其余字段无缺失。测试集的缺失值情况也类似,我们稍后在特征工程环节再统一处理。

2.2 目标变量分析:幸存者 vs 遇难者

在深入研究特征之前,先快速了解一下目标变量Survived本身的分布情况以及基础统计。

首先,可以计算幸存者(1)和遇难者(0)的数量:

# 计算幸存者和遇难者的人数
survived_count = train_df['Survived'].sum()
died_count = len(train_df) - survived_count
survival_rate = survived_count / len(train_df)
print(f"总乘客数: {
     len(train_df)}")
print(f"幸存者人数: {
     survived_count}, 遇难者人数: {
     died_count}")
print(f"幸存率: {
     survival_rate:.2%}")

输出大致为:

总乘客数: 891
幸存者人数: 342, 遇难者人数: 549
幸存率: 38.38%

如前所述,生存率约为38%,遇难率约62%。这意味着数据是偏向遇难者居多的。虽然幸存和遇难都占了相当比例,但遇难是多数类。在建模时,我们需要关注模型在这两类上的表现,而不仅仅追求整体准确率。

我们可以使用图形来更直观地看幸存与否的分布。例如,绘制一个简单的计数图:

import seaborn as sns
import matplotlib.pyplot as plt

# 绘制Survived的计数图
sns.countplot(x='Survived', data=train_df)
plt.xticks([0, 1], ['Died (0)', 'Survived (1)'])
plt.title("Count of Survival Status")
plt.show()

(如果绘图环境不可用,可忽略显示图形的代码,但建议在本地或Colab上运行查看图像。)

该图将显示Survived=0Survived=1的条形高度对比,可以直观看出遇难人数多于幸存人数。之后的分析我们会将Survived与其他特征组合,看看不同人群的生存率差异。

2.3 特征与生存率关系分析

现在,我们逐个探究各个特征对生存率的影响。常识和历史告诉我们,一些因素(如性别、年龄、舱等)应该与泰坦尼克号乘客的幸存概率密切相关,我们将在数据中验证这些假设。

2.3.1 性别(Sex)与生存率

首先考察性别。众所周知,泰坦尼克沉没时实行了“女士优先”的救生原则,因此我们预计女性乘客的生存率会显著高于男性。

让我们计算不同性别的生存率:

# 按性别计算生存率
survival_by_sex = train_df.groupby('Sex')'Survived'.mean()
print(survival_by_sex)

输出应为类似:

Sex
female    0.742038
male      0.188908
Name: Survived, dtype: float64

即女性乘客的生存率约为0.742(74.2%),男性仅为0.189(18.9%)。这验证了我们的预期:几乎四分之三的女性幸存,而只有不到五分之一的男性幸存 (〖从零开始学Kaggle竞赛〗泰坦尼克之灾_kaggle比赛泰坦尼克- 从灾难中学习机器学习提交比赛需要提交什么文件-优快云博客)。这是一条非常强的信息,对预测有直接的意义。也难怪Kaggle提供的示例提交(gender_submission.csv)直接以性别为依据猜测生还情况,虽然简单,但女性=生存、男性=遇难的规则已经能达到约78%多的准确率(因为男性居多且大部分男性遇难了)。

我们也可以通过可视化更直观地呈现这一差异。例如使用条形图或分组柱状图:

# 绘制不同性别的生存率柱状图
sns.barplot(x='Sex', y='Survived', data=train_df)
plt.title("Survival Rate by Sex")
plt.ylabel("Survival Rate")
plt.show()

这个图会显示男性和女性对应的生存率柱状高度(带置信区间)。可以清楚看到女性柱的高度远高于男性柱,印证女性生存率更高。

结论:性别是影响生存的一个极其显著的因素。在后续建模时,我们必须将性别作为一个重要特征纳入模型。同时,性别特征的表现也为特征工程提供思路,例如我们可能不需要对这个特征做太复杂的转换,因为它本身就是很强的信号。

2.3.2 客舱等级(Pclass)与生存率

泰坦尼克号按照舱等划分乘客社会阶层:一等舱乘客多为富裕的上层阶级,住在上层甲板且靠近甲板,脱险可能性更高;三等舱多为底层甲板的普通乘客。我们预计舱等越高(数值越小的一等舱),生存率越高

计算不同Pclass的生存率:

# 按客舱等级计算生存率
survival_by_class = train_df.groupby('Pclass')'Survived'.mean()
print(survival_by_class)

可能输出:

Pclass
1    0.629630
2    0.472826
3    0.242363
Name: Survived, dtype: float64

这表示:一等舱乘客的生存率约为62.96%,二等舱约为47.28%,而三等舱只有约24.24%。差异显著:一等舱幸存率大概是三等舱的2.6倍 (Titanic_Dataset_Exploratory_Analysis)。这与我们关于社会阶层和逃生机会的推测一致——上层阶级(Pclass=1)由于更靠近甲板、获得救生艇的优先权,生还机会更大,而三等舱乘客处境最为不利。

用图表展示更直观:

# 绘制不同舱等的生存率
sns.barplot(x='Pclass', y='Survived', data=train_df)
plt.title("Survival Rate by Passenger Class")
plt.ylabel("Survival Rate")
plt.show()

图中会显示1、2、3等舱的平均生存率条形。可以看到,舱等与生存率大致呈正相关:1等舱最高,3等舱最低。

进一步,我们还可以观察性别和舱等的交互作用。例如,一等舱的女性、生存率也许接近100%;三等舱男性生存率可能更低于平均。这种组合信息可以通过透视表或分组进一步分析:

# 组合Sex和Pclass,计算各组生存率
survival_by_sex_class = train_df.groupby(['Sex', 'Pclass'])'Survived'.mean()
print(survival_by_sex_class)

输出示例:

Sex     Pclass
female  1         0.968085
        2         0.921053
        3         0.500000
male    1         0.368852
        2         0.157407
        3         0.135447
Name: Survived, dtype: float64

这表格显示:

  • 女性在1等舱生存率高达96.8%,在2等舱也有92.1%,即使在3等舱也有50%。
  • 男性在1等舱生存率约36.9%,2等舱15.7%,3等舱仅13.5%。

由此可见,如果你是三等舱男性,生还可能性非常渺茫;而一二等舱女性几乎都得救了。这种显著差异后面也许可以作为新特征,例如组合SexPclass

2.3.3 登船港口(Embarked)与生存率

泰坦尼克号从英国南安普顿(S)出发,中途停靠法国瑟堡(C)和爱尔兰皇后镇(Q)接乘客,然后驶向纽约。因此登船港口Embarked某种程度和乘客社会背景有关(例如在瑟堡登船的多数是一等舱富人,在南安普顿登船的三等舱乘客更多 (Titanic_Dataset_Exploratory_Analysis))。我们来看不同登船港口乘客的生存率:

# 按登船港口计算生存率
survival_by_embark = train_df.groupby('Embarked')'Survived'.mean()
print(survival_by_embark)

假设输出:

Embarked
C    0.553571
Q    0.389610
S    0.336957
Name: Survived, dtype: float64

即:

  • 从Cherbourg(瑟堡)登船的乘客生存率最高,约55.4%;
  • Queenstown(皇后镇)登船的约38.96%;
  • Southampton(南安普顿)登船的最低,约33.7%。

这表明登船港口似乎确实与生存率有关 (Titanic_Dataset_Exploratory_Analysis)。一开始看可能令人奇怪:为什么瑟堡登船的生存率更高?结合背景分析,原因可能是从瑟堡登船的乘客中一等舱比例高(大量富人从法国上船),而从南安普顿上的多为三等舱移民,因此整体生存率受到舱等结构影响 (Titanic_Dataset_Exploratory_Analysis)。事实上,数据分析发现瑟堡登船的乘客有50%以上是一等舱,而南安普顿登船的一等舱不到20% (Titanic_Dataset_Exploratory_Analysis)。所以港口本身并非直接影响生存率,而是因为它与乘客群体构成相关。这提示我们:Embarked可以作为特征,但它可能主要是间接反映了社会阶层。在特征工程时,我们可以保留Embarked,也可能将其与Pclass交叉考虑。

用柱状图展示:

# 绘制不同登船港口的生存率
sns.barplot(x='Embarked', y='Survived', data=train_df)
plt.title("Survival Rate by Embarked Port")
plt.ylabel("Survival Rate")
plt.show()

图上C港口柱子最高,S最低,中间是Q。这与我们上面的数字一致:瑟堡登船的幸存率最高。

2.3.4 年龄(Age)与生存率

年龄对生存率的影响需要一点更细致的分析。当时救生原则除了“女士优先”还有“儿童优先”。直觉上,儿童更容易获救,而老年人和青壮年的生存率可能较低。不过需要结合性别与舱等,因为一等舱儿童和三等舱儿童的命运也可能不同。

首先简单地看一下幸存者和遇难者的年龄分布差异。我们可以比较生存者的年龄平均值或中位数,或者绘制年龄分布图(例如直方图或核密度图):

# 计算幸存者和遇难者的平均年龄(忽略缺失值)
avg_age_survived = train_df[train_df['Survived']==1]['Age'].mean()
avg_age_died = train_dftrain_df['Survived'==0]'Age'.mean()
median_age_survived = train_dftrain_df['Survived'==1]'Age'.median()
median_age_died = train_dftrain_df['Survived'==0]'Age'.median()
print(f"幸存者平均年龄: {
     avg_age_survived:.1f}, 中位数: {
     median_age_survived}")
print(f"遇难者平均年龄: {
     avg_age_died:.1f}, 中位数: {
     median_age_died}")

根据数据,可能得到:

幸存者平均年龄: ~28.3岁, 中位数: 28.0
遇难者平均年龄: ~30.6岁, 中位数: 28.0

平均而言幸存者略年轻一些,但中位数都是28岁。差异不是非常显著。为了更深入地看年龄影响,我们可以将年龄按区间分组或者绘制生存与否的年龄分布图。例如,把乘客分为儿童(<=12岁)、青少年(13-18)、青年(19-30)、中年(31-50)、老年(>50) 等等,看各组生存率;或者直接绘图。

用直方图/密度图比较:

# 绘制年龄分布直方图,按生存与否分色
plt.figure(figsize=(8,4))
train_dftrain_df['Survived'==1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

快撑死的鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值