☰
泰坦尼克号幸存者预测:可直接跑通的课程设计资源
2026/10/3 3:54:09 网站建设 项目流程

简介:这份泰坦尼克号幸存者预测大作业资源面向Python初学者、高校学生及需要完成期末课程设计的人群,提供一套可直接部署运行的完整机器学习实践方案。资源包共5个文件,压缩后约33KB,包含py脚本、csv数据集、ipynb交互式笔记本、gitignore配置及md说明文档,覆盖数据读取、特征分析、可视化探索与模型预测全流程,代码附有详细注释,新手也能快速理解每一步逻辑。目前已有746人学习下载,适合作为课程设计或期末大作业的参考模板。读者可从中获得完整的赛题解决思路、可复用的可视化脚本与数据探索笔记,并借助README说明快速搭建环境、对照运行结果,省去从零摸索的时间,对掌握分类预测流程与撰写实验报告均有实际帮助。

1. 泰坦尼克号幸存者预测:一份能直接跑通的大作业资源

课程设计周临近,选题还没定,或者定了却卡在数据清洗那一步——这大概是每年期末最常见的一幕。这份泰坦尼克号幸存者预测资源,就是冲着这个场景来的:一个 zip 包,解压后是titanic_data.csv、titanic_survival_exploration.ipynb、titanic_visualizations.py、README.md和.gitignore,用 Python 把从数据加载、缺失值处理、特征工程到模型训练和预测的完整链路走了一遍。它解决的不是"从零搭一个机器学习框架"这种大问题,而是"我需要在有限时间内交出一份逻辑完整、代码能跑、图表能看的课程设计"这个具体诉求。适合两类人:一是刚学完 Python 基础、想找一个结构化项目练手的新手;二是需要快速复现一份可讲解、可答辩的期末作业的在校生。代码带注释,文档有说明,部署门槛低,这是它最实在的价值。

2. 拆开压缩包:文件结构与数据字段先摸清

2.1 五个文件各干什么

解压后目录结构不复杂,但每个文件都有明确分工,先搞清楚谁负责什么,后面改代码才不会乱。

文件作用使用时机
titanic_data.csv原始数据集,包含乘客信息和幸存标签数据加载阶段
titanic_survival_exploration.ipynb主分析流程,Notebook 形式核心操作,从头到尾
titanic_visualizations.py封装好的可视化函数需要画图时导入调用
README.md环境依赖和运行说明第一次配置环境时看
.gitignore版本控制忽略规则如果上传到代码托管平台

titanic_survival_exploration.ipynb是主入口,所有分析步骤都在里面。titanic_visualizations.py是一个辅助模块,把常用的绘图逻辑抽出来,避免在 Notebook 里重复写 matplotlib 代码。这种拆分方式在课程设计里算规范,答辩时也能体现模块化思维。

2.2 数据字段与含义

titanic_data.csv是经典的泰坦尼克号乘客数据集,常见字段包括:

  • PassengerId:乘客编号,唯一标识
  • Survived:是否幸存,0 表示未幸存,1 表示幸存,这是预测目标
  • Pclass:舱位等级,1/2/3 分别代表头等舱、二等舱、三等舱
  • Name、Sex、Age:姓名、性别、年龄
  • SibSp、Parch:同船兄弟姐妹/配偶数量、父母/子女数量
  • Ticket、Fare:票号、票价
  • Cabin、Embarked:客舱号、登船港口

拿到数据后第一件事不是急着建模,而是先看缺失情况。Age、Cabin、Embarked这三个字段通常有缺失,处理方式直接影响后续模型效果。常见做法是先统计缺失比例,再决定是填充还是丢弃。

import pandas as pd # 加载数据 df = pd.read_csv('titanic_data.csv') # 查看基本信息 print(df.info()) print(df.isnull().sum()) print(df.describe())

这段代码做三件事:info()看字段类型和非空数量,isnull().sum()统计每个字段的缺失值个数,describe()看数值型字段的分布。跑完这三行,心里就有底了——哪些字段要处理,哪些字段可以直接用。

提示:如果Cabin缺失超过七成,通常直接丢弃这个字段,而不是强行填充。填充一个缺失率过高的字段,引入的噪声可能比信息还多。

3. 从数据清洗到特征工程:Notebook 里的关键步骤

3.1 缺失值处理与字段取舍

数据清洗是整条链路里最耗时间也最容易翻车的一步。这份资源的 Notebook 里对缺失值的处理思路是:Age用中位数或均值填充,Embarked用众数填充,Cabin根据缺失比例决定是否保留。

# Age 用中位数填充 df['Age'].fillna(df['Age'].median(), inplace=True) # Embarked 用众数填充 df['Embarked'].fillna(df['Embarked'].mode()[0], inplace=True) # Cabin 缺失太多,先看比例再决定 missing_ratio = df['Cabin'].isnull().sum() / len(df) if missing_ratio > 0.7: df.drop('Cabin', axis=1, inplace=True) else: df['Cabin'] = df['Cabin'].fillna('Unknown')

fillna的inplace=True表示直接在原 DataFrame 上修改,不返回新对象。median()取中位数,比均值更抗极端值。mode()[0]取众数的第一个值,因为众数可能不止一个。drop的axis=1表示删列,不是删行。

这里有个容易忽略的点:填充操作要在训练集和测试集划分之前做,还是之后做?如果先填充再划分,测试集的信息会"泄露"到训练过程中。严格做法是先划分,再分别对训练集和测试集做填充,填充值只从训练集计算。课程设计里如果数据量不大,很多人会忽略这一步,但答辩时如果被问到,能说清楚就是加分项。

3.2 类别变量编码与特征构造

机器学习模型吃的是数字,Sex和Embarked这类文本字段必须转成数值。常见做法是独热编码或标签编码。

# Sex 二值编码 df['Sex'] = df['Sex'].map({'male': 0, 'female': 1}) # Embarked 独热编码 df = pd.get_dummies(df, columns=['Embarked'], drop_first=True) # 构造家庭规模特征 df['FamilySize'] = df['SibSp'] + df['Parch'] + 1 # 构造是否独自一人特征 df['IsAlone'] = (df['FamilySize'] == 1).astype(int)

map做二值映射,适合只有两个取值的字段。get_dummies做独热编码,drop_first=True是为了避免多重共线性,去掉第一列作为基准。FamilySize把SibSp和Parch合并,反映乘客的家庭规模。IsAlone进一步把"独自一人"这个场景单独拎出来,因为历史上独自出行的乘客幸存率确实有差异。

特征构造这一步是拉开差距的地方。原始字段就那些,但通过组合和变换能造出更有表达力的特征。比如从Name里提取称呼(Mr、Mrs、Miss),从Ticket里提取前缀,这些在进阶版本里常见,这份资源里如果没做,可以自己补上。

3.3 模型训练与预测输出

特征处理完之后,就是划分数据集、选模型、训练、评估。课程设计里常用的模型是逻辑回归、决策树、随机森林。

from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score, classification_report # 选择特征列 features = ['Pclass', 'Sex', 'Age', 'Fare', 'FamilySize', 'IsAlone'] X = df[features] y = df['Survived'] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) # 训练随机森林 model = RandomForestClassifier(n_estimators=100, random_state=42) model.fit(X_train, y_train) # 预测与评估 y_pred = model.predict(X_test) print('Accuracy:', accuracy_score(y_test, y_pred)) print(classification_report(y_test, y_pred))

train_test_split的test_size=0.2表示两成数据用于测试,random_state=42固定随机种子,保证每次划分结果一致。RandomForestClassifier的n_estimators=100表示用 100 棵树,树越多模型越稳定但训练越慢。classification_report输出精确率、召回率和 F1 值,比单看准确率更全面。

跑完这段,如果准确率在 0.78 到 0.85 之间,属于正常范围。低于 0.75 就要回头检查特征处理有没有问题,高于 0.9 则要怀疑是不是数据泄露了。

4. 可视化模块怎么用:titanic_visualizations.py 的调用方式

4.1 导入与基础绘图

titanic_visualizations.py是一个独立模块,里面封装了常用的绘图函数。用法是在 Notebook 里导入,然后传入 DataFrame 调用。

import titanic_visualizations as tv # 幸存者与性别的关系 tv.plot_survival_by_sex(df) # 幸存者与舱位等级的关系 tv.plot_survival_by_pclass(df) # 年龄分布对比 tv.plot_age_distribution(df)

具体函数名以实际文件为准,但调用逻辑是一致的:传入清洗后的 DataFrame,函数内部用 matplotlib 或 seaborn 画图并显示。这种封装的好处是 Notebook 里不会堆满绘图代码,答辩演示时也清爽。

如果模块里的函数不满足需求,可以直接在 Notebook 里写 matplotlib 代码,或者修改titanic_visualizations.py添加新函数。课程设计里图表是加分项,至少要有三到四张有解释力的图:幸存率与性别、幸存率与舱位、年龄分布、票价分布。

4.2 图表选择与答辩讲解

图表不是越多越好,而是要能支撑结论。比如"女性幸存率明显高于男性"这个结论,用柱状图就比饼图直观。"三等舱幸存率最低"用分组柱状图展示。年龄分布用直方图或核密度图。

答辩时老师常问的问题是:"你这个图说明了什么?"所以每张图旁边最好用 Markdown 单元格写一两句解释,把图表和业务结论挂上钩。这比单纯贴图更有说服力。

注意:如果titanic_visualizations.py里用了 seaborn,确保环境里装了对应版本。否则导入时会报ModuleNotFoundError,这是最常见的翻车点之一。

5. 避坑与排查:跑不通时先看这几条

5.1 缺失值填充后模型报错

现象:fit时报ValueError: Input contains NaN, infinity or a value too large。

原因:填充操作只处理了部分字段,或者填充后又做了删除行操作导致索引错位。

解决:在fit之前加一行print(X.isnull().sum()),确认所有特征列都没有缺失。如果有,补上填充逻辑。

5.2 独热编码后列数对不上

现象:训练时特征列数和预测时不一致,报ValueError: feature_names mismatch。

原因:get_dummies在训练集和测试集上分别调用,导致生成的列不同。

解决:先合并再编码,或者用align对齐列。常见做法是在划分之前就完成所有编码操作。

5.3 中文显示乱码

现象:图表标题和标签里的中文变成方框。

原因:matplotlib 默认字体不支持中文。

解决:在绘图前设置字体。

import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False

SimHei是黑体,Windows 系统一般都有。Mac 系统可以换成Arial Unicode MS。axes.unicode_minus设为False是为了正常显示负号。

5.4 Notebook 内核启动失败

现象:打开.ipynb后提示找不到内核或内核崩溃。

原因:环境里没装 jupyter,或者 Python 版本不匹配。

解决:在命令行执行pip install jupyter,然后用jupyter notebook启动。如果还是不行,检查README.md里有没有指定 Python 版本。

5.5 随机森林训练太慢

现象:fit跑了好几分钟还没结束。

原因:n_estimators设得太大,或者数据量比预期大。

解决:先把n_estimators降到 50 试试,确认流程能跑通再往上加。课程设计里 100 棵树足够,没必要堆到 500。

6. 进阶技巧:把准确率从 0.80 推到 0.85 以上

6.1 特征交叉与分箱

基础特征跑完之后,想再提一两个点,可以试试特征交叉和分箱。比如把Age分成儿童、青年、中年、老年四段,把Fare按分位数切成四档。

# Age 分箱 df['AgeBin'] = pd.cut(df['Age'], bins=[0, 12, 18, 35, 60, 100], labels=['Child', 'Teen', 'YoungAdult', 'Adult', 'Senior']) df = pd.get_dummies(df, columns=['AgeBin'], drop_first=True) # Fare 分位数分箱 df['FareBin'] = pd.qcut(df['Fare'], 4, labels=False)

pd.cut按指定边界切分,pd.qcut按分位数切分。分箱之后再做独热编码,相当于把连续变量离散化,有时候能捕捉到非线性关系。

6.2 模型对比与交叉验证

单跑一个随机森林不够有说服力,可以对比逻辑回归、决策树、随机森林三个模型,用交叉验证取平均准确率。

from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import cross_val_score models = { 'LogisticRegression': LogisticRegression(max_iter=1000), 'DecisionTree': DecisionTreeClassifier(random_state=42), 'RandomForest': RandomForestClassifier(n_estimators=100, random_state=42) } for name, model in models.items(): scores = cross_val_score(model, X, y, cv=5, scoring='accuracy') print(f'{name}: {scores.mean():.4f} (+/- {scores.std():.4f})')

cross_val_score的cv=5表示五折交叉验证,scoring='accuracy'指定评估指标。输出的是五次得分的均值和标准差,比单次划分更稳定。答辩时拿出这张对比表,说服力比只报一个数字强得多。

6.3 我踩过的一个坑

有一次帮人看这份代码,准确率死活上不去,一直在 0.76 左右。查了半天发现是Sex字段编码反了——male编成了 1,female编成了 0。逻辑上不影响模型训练,但解释特征重要性的时候结论全反了。从那以后我每次做完编码都强制走一遍df.head()和df['Sex'].value_counts(),确认映射方向没搞反。这个习惯看起来多余,但省过我好几次返工。

希望这份资源能帮你把课程设计顺利交出去,也帮你在答辩时多几分底气。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询