泰坦尼克号乘客生存预测
1 项目背景与研究目标泰坦尼克号乘客生存预测是 Kaggle 入门竞赛中最具代表性的二分类案例。任务要求根据乘客登船前已知的信息预测是否生还适合展示结构化数据清洗、类别特征编码、缺失值处理、特征工程和分类模型评价。本案例的目标不是单纯追求某一次划分上的最高准确率而是建立一套可复现、可解释的数据分析流程并说明每幅图对后续建模决策的影响。识别数据缺失、类别不均衡和潜在信息冗余。分析性别、舱位、年龄、家庭结构和登船港口与生还率的关系。构造能够表达社会身份、同行关系、甲板位置和团体购票的衍生特征。比较四类常用分类模型并通过交叉验证控制偶然性。使用混淆矩阵、ROC-AUC、阈值曲线和特征系数解释最终模型。数据代码和报告https://mbd.pub/o/bread/YZaUlJtpZA2 数据来源与字段说明数据来源于 Kaggle 竞赛的训练数据公开镜像共 891 行、12 列。目标字段 Survived 中1 表示生还0 表示未生还。字段含义建模处理PassengerId乘客编号仅作标识不进入模型Survived是否生还目标变量Pclass舱位等级作为类别变量独热编码Name姓名提取称谓 TitleSex性别类别变量Age年龄中位数填补并标准化SibSp / Parch同行亲属数量构造家庭规模Ticket票号统计同票号人数Fare票价标准化并构造人均票价Cabin舱室号提取甲板首字母缺失标记为未知Embarked登船港口众数填补并独热编码数据文件titanic.csvNotebookTitanic_生存预测_完整分析.ipynb。3 技术路线与评价指标数据按照 75% 训练集和 25% 测试集划分并使用 Survived 进行分层抽样以保持两部分样本中的生还比例一致。模型选择阶段在训练集内部执行五折分层交叉验证。指标含义本案例中的作用准确率全部样本中预测正确的比例反映总体判断正确率但会受到类别比例影响精确率预测生还样本中实际生还的比例衡量生还预测的可信度召回率实际生还样本中被识别出的比例衡量漏掉生还乘客的程度F1 值精确率和召回率的调和平均综合评价生还类别ROC-AUC不同阈值下的整体排序能力作为调参和模型比较的核心指标3.1 字段缺失率quality pd.DataFrame({ 数据类型: df.dtypes.astype(str), 缺失数量: df.isna().sum(), 缺失率%: (df.isna().mean() * 100).round(2), 唯一值数量: df.nunique(dropnaFalse) }).sort_values(缺失率%, ascendingFalse) print(f完全重复的记录数{df.duplicated().sum()}) display(quality) missing quality.query(缺失数量 0).sort_values(缺失率%) plt.figure(figsize(9.0, 4.8)) plt.barh(missing.index, missing[缺失率%], colorPALETTE[0]) plt.xlabel(缺失率%) plt.ylabel(字段) plt.title(图1 主要字段缺失率) for i, value in enumerate(missing[缺失率%]): plt.text(value 0.8, i, f{value:.1f}%, vacenter) save_show(01_字段缺失率.png)、Cabin 缺失率约为 77.1%若直接删除缺失记录会造成大规模样本损失。更合理的方案是保留“是否已知舱室”和甲板首字母信息并把缺失甲板编码为未知类别。3.2 生存结果分布891 名乘客中有 342 人生还、549 人未生还总体生还率为 38.38%。未生还样本占比约为 61.6%属于中等程度类别不均衡。该分布说明准确率不能作为唯一评价标准。假设模型全部预测为未生还也能获得约 61.6% 的准确率但完全无法识别生还乘客。因此后续同时报告召回率、F1 值和 ROC-AUC。3.3 性别与生还率女性乘客生还率约为 74.2%男性乘客约为 18.9%差距超过 55 个百分点。性别是数据中最强的单一解释变量之一。3.4 舱位等级与生还率一等舱、二等舱和三等舱的生还率依次下降约为 63.0%、47.3% 和 24.2%。舱位具有清晰的等级效应。3.5 年龄组与生还率、3.6 家庭规模与生还率family_df df.assign(FamilySizedf[SibSp] df[Parch] 1) family_rate family_df.groupby(FamilySize)[Survived].agg([mean, count]) family_plot family_rate[family_rate[count] 8] plt.figure(figsize(9.0, 5.2)) plt.plot(family_plot.index, family_plot[mean] * 100, markero, linewidth2.5, markersize7, colorPALETTE[0]) plt.fill_between(family_plot.index, family_plot[mean] * 100, alpha0.12, colorPALETTE[0]) plt.xlabel(家庭同行人数) plt.ylabel(生还率%) plt.title(图6 家庭规模与生还率) save_show(06_家庭规模与生还率.png) display(family_rate.rename(columns{mean:生还率,count:人数}))独自出行乘客的生还率偏低2—4 人小家庭的生还率较高家庭规模过大后生还率明显下降。该关系不是简单线性变化因此同时保留家庭规模和独行标记。小家庭成员可能更容易互相照应大型家庭在紧急撤离时则面临更高的协调难度。3.7 港口与舱位的联合关系pivot df.pivot_table(indexPclass, columnsEmbarked, valuesSurvived, aggfuncmean) pivot pivot.reindex(index[1,2,3], columns[C,Q,S]) plt.figure(figsize(7.6, 5.2)) img plt.imshow(pivot.values*100, cmapYlGnBu, vmin0, vmax100, aspectauto) plt.xticks(range(3), [瑟堡 C,皇后镇 Q,南安普顿 S]) plt.yticks(range(3), [一等舱,二等舱,三等舱]) plt.title(图7 登船港口与舱位组合的生还率) for i in range(pivot.shape[0]): for j in range(pivot.shape[1]): value pivot.iloc[i,j] if pd.notna(value): plt.text(j, i, f{value*100:.1f}%, hacenter, vacenter, colorwhite if value0.55 else black, fontweightbold) cb plt.colorbar(img) cb.set_label(生还率%) save_show(07_港口舱位生还率.png)同一港口内部仍存在明显舱位差异说明舱位效应并非由港口构成完全解释。瑟堡登船者中一等舱比例较高若只比较港口总体生还率容易受到乘客结构的混杂影响。4 特征工程与预处理原始姓名、票号和舱室号不能直接输入常规模型因此从中提取可解释的结构化变量。称谓用于表达年龄、性别和社会身份甲板首字母作为船舱位置的粗略表示同票号人数用于识别家庭或团体购票人均票价用于减少共票导致的票价偏差。衍生特征计算方式预期作用Title从 Name 提取称谓补充年龄、性别和身份信息FamilySizeSibSp Parch 1描述同行家庭规模IsAloneFamilySize 是否等于 1识别独行乘客CabinDeckCabin 的首字母缺失记 U近似表示甲板位置TicketGroupSize同一 Ticket 的出现次数识别团体购票FarePerPersonFare / TicketGroupSize估计实际人均票价数值变量使用中位数填补和标准化类别变量使用众数填补和独热编码。预处理与模型封装为同一 Pipeline保证每一折交叉验证只在训练折拟合填补值、缩放参数和编码类别。4.1 多模型表现比较梯度提升树和随机森林在交叉验证 ROC-AUC 上具有一定优势说明非线性关系确实存在逻辑回归在固定测试集上的准确率和 F1 值较为稳定整体差距并不大。模型交叉验证ROC-AUC测试集准确率测试集F1测试集ROC-AUC梯度提升树0.88840.79820.72390.8535随机森林0.87940.78920.71860.8524支持向量机0.86680.80270.73490.8587逻辑回归模型0.86500.82960.77650.86134.2 参数调优结果指标测试集结果准确率0.8117精确率0.7683召回率0.7326F1 值0.7500ROC-AUC0.86084.3 混淆矩阵4.4 ROC 曲线plt.figure(figsize(8.2,6.0)) for name, model in fitted_models.items(): prob model.predict_proba(X_test)[:,1] fpr,tpr,_ roc_curve(y_test,prob) auc roc_auc_score(y_test,prob) plt.plot(fpr,tpr,linewidth2,labelf{name}AUC{auc:.3f}) fpr,tpr,_roc_curve(y_test,final_prob) plt.plot(fpr,tpr,linewidth3,linestyle--,colorblack,labelf调优逻辑回归AUC{roc_auc_score(y_test,final_prob):.3f}) plt.plot([0,1],[0,1],linestyle:,colorgray,label随机判断) plt.xlabel(假阳性率) plt.ylabel(真阳性率) plt.title(图10 不同模型的ROC曲线) plt.legend(frameonFalse,loclower right) save_show(10_ROC曲线.png)所有模型曲线均明显高于随机判断线测试集 AUC 位于约 0.85—0.86 区间具有较好的概率排序能力。4.5 分类阈值分析thresholds np.linspace(0.20,0.80,61) threshold_rows[] for t in thresholds: pred_t(final_probt).astype(int) threshold_rows.append({阈值:t,精确率:precision_score(y_test,pred_t,zero_division0), 召回率:recall_score(y_test,pred_t,zero_division0), F1值:f1_score(y_test,pred_t,zero_division0)}) threshold_dfpd.DataFrame(threshold_rows) best_f1_rowthreshold_df.loc[threshold_df[F1值].idxmax()] plt.figure(figsize(9.0,5.5)) plt.plot(threshold_df[阈值],threshold_df[精确率],label精确率,linewidth2.2,colorPALETTE[0]) plt.plot(threshold_df[阈值],threshold_df[召回率],label召回率,linewidth2.2,colorPALETTE[4]) plt.plot(threshold_df[阈值],threshold_df[F1值],labelF1值,linewidth2.5,colorPALETTE[1]) plt.axvline(0.5,linestyle--,colorgray,label默认阈值0.5) plt.axvline(best_f1_row[阈值],linestyle:,colorblack,labelf最佳F1阈值{best_f1_row[阈值]:.2f}) plt.xlabel(分类阈值) plt.ylabel(指标值) plt.title(图11 分类阈值对模型指标的影响) plt.legend(frameonFalse) save_show(11_阈值分析.png) print(best_f1_row)阈值升高时模型判定生还更谨慎精确率通常上升而召回率下降阈值降低则相反。默认 0.5 并不是任何场景下都最优。4.6 特征系数解释女性、一等舱以及 Mrs、Miss 等称谓通常提高预测生还概率男性、三等舱和 Mr 称谓通常降低预测生还概率方向与探索性分析一致。5 结论、局限性与改进建议性别、舱位等级和称谓是最重要的生还预测因素家庭规模、甲板和票组信息提供补充解释。最终逻辑回归测试集准确率为 81.17%ROC-AUC 为 0.8608性能与可解释性较为均衡。数据量较小单次测试集指标可能受到划分影响建议使用重复分层交叉验证报告均值和标准差。同一家庭或同票号乘客可能同时出现在训练集和测试集后续可尝试基于家庭/票号的分组验证。可进一步尝试 CatBoost、XGBoost、模型融合和概率校准并使用折外预测确定分类阈值。具体细节见原文创造不易谢谢各位多多点赞收藏