news 2026/4/24 2:19:27

Kaggle Titanic生存预测:从数据清洗到特征工程,一个菜鸟的完整踩坑实录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kaggle Titanic生存预测:从数据清洗到特征工程,一个菜鸟的完整踩坑实录

Kaggle Titanic生存预测:从数据清洗到特征工程,一个菜鸟的完整踩坑实录

凌晨两点,我的第三杯咖啡已经见底。屏幕上的数据集像一团乱麻——这就是传说中的Kaggle入门神题Titanic生存预测?作为一个刚转行数据科学的Java程序员,我盯着train.csv里那些缺失的年龄值和意义不明的船舱编号,第一次体会到什么叫"从入门到放弃"的真实含义。

1. 数据观察:当理想照进现实

打开训练集的第一眼,我就被现实狠狠教育了。教科书里整洁的Iris数据集根本不存在于真实世界,这里只有:

import pandas as pd train = pd.read_csv('train.csv') print(train.isnull().sum()) # 输出结果: # Age 177 # Cabin 687 # Embarked 2

三个致命发现

  1. 年龄缺失近20%,船舱号缺失77%——这数据能要?
  2. 票价(Fare)的分布跨度从0到512美元,标准差是49.7
  3. 姓名列里居然藏着贵族头衔(Mr/Miss/Dr等)

提示:真实项目的数据清洗会占用70%时间,这个认知让我放弃了"一夜搞定"的幻想

2. 数据清洗:与缺失值的斗智斗勇

2.1 船舱数据的"摆烂式"处理

面对687个缺失的Cabin值,我尝试了三种策略:

处理方式代码实现适用场景
直接填充'U'df['Cabin'] = df['Cabin'].fillna('U')低重要性特征
提取首字母df['Deck'] = df['Cabin'].str[0]有规律的结构化缺失
完全丢弃df.drop('Cabin', axis=1)缺失率>50%且无分析价值

最终选择方案一,因为后续发现船舱甲板位置(Deck)与生存率存在关联:

sns.barplot(x='Deck', y='Survived', data=train[train['Deck']!='U'])

2.2 年龄预测的随机森林魔法

年龄缺失的处理让我第一次体会到特征工程的魅力。通过构建包含以下特征的临时数据集:

  • Pclass (船舱等级)
  • Title (从姓名提取的头衔)
  • FamilySize (家庭成员数)

用随机森林预测缺失年龄:

from sklearn.ensemble import RandomForestRegressor # 构建训练集 age_train = df[df['Age'].notnull()] age_test = df[df['Age'].isnull()] # 训练预测模型 rfr = RandomForestRegressor(n_estimators=200) rfr.fit(age_train[features], age_train['Age']) # 填充预测值 df.loc[df['Age'].isnull(), 'Age'] = rfr.predict(age_test[features])

这个操作让我的模型准确率直接提升了3个百分点——原来这就是"用数据创造数据"的奥义。

3. 特征工程:从原始数据中"榨取"价值

3.1 姓名中的隐藏金矿

原始Name列看起来毫无用处,直到我发现可以用正则表达式提取头衔:

df['Title'] = df['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)

统计后惊讶发现:

  • 头衔与生存率强相关(女性头衔生存率72%,男性仅18%)
  • 罕见头衔如'Lady'生存率100%

于是进行了头衔归类:

title_mapping = { 'Mr': 'AdultMale', 'Mrs': 'AdultFemale', 'Miss': 'YoungFemale', 'Master': 'Boy', 'Dr': 'Professional', 'Rev': 'Professional', 'Col': 'Military' }

3.2 家庭关系的生存密码

将SibSp(兄弟姐妹/配偶)和Parch(父母/子女)组合成新特征:

df['FamilySize'] = df['SibSp'] + df['Parch'] + 1 df['IsAlone'] = (df['FamilySize'] == 1).astype(int)

可视化结果令人震惊——独身旅客生存率仅30%,而2-4人家庭生存率超过50%:

4. 模型构建:从盲目调包到有的放矢

4.1 算法选型踩坑记

第一次尝试时,我直接照搬教程里的随机森林:

from sklearn.ensemble import RandomForestClassifier rfc = RandomForestClassifier() rfc.fit(X_train, y_train)

结果Kaggle得分只有0.765——比基准线还低。通过交叉验证对比才发现梯度提升树(GradientBoosting)更适合这个数据集:

算法交叉验证准确率训练时间(s)
随机森林0.8123.2
逻辑回归0.7981.1
梯度提升树0.8324.7
SVM0.8038.3

4.2 同组效应:数据中的"潜规则"

分析中发现一个有趣现象:某些家族的生存呈现"全活"或"全灭"模式。于是增加特征:

# 计算每个姓氏的平均生存率 surname_survival = df.groupby('Surname')['Survived'].mean() # 标记特殊家族 df['FamilySurvival'] = df['Surname'].map(surname_survival) df['FamilySurvival'] = df['FamilySurvival'].fillna(0.5) # 默认值

这个操作让我的最终排名进入了前15%——原来历史数据中真的藏着"妇女儿童优先"的执行痕迹。

5. 经验总结:新手避坑指南

  1. 不要急于建模:我前三次提交失败都是因为没处理好Embarked缺失值
  2. 可视化是神器seaborn.pairplot()帮我发现了Fare的异常值
  3. 业务理解决定上限:知道"头等舱优先救援"的历史事实后,Pclass特征的重要性突然明朗

凌晨四点,当我第17次提交后看到"Your score: 0.843"时,终于理解了为什么说Titanic是机器学习界的"Hello World"——它用最温柔的方式教会我:数据科学不是写代码,而是用数据讲故事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 2:19:17

**脉冲计算新范式:用 Rust实现高效神经形态硬件加速器的代码实践**在传统冯·诺依曼架构逐渐逼近物理极限的今天,**脉冲计算

脉冲计算新范式:用 Rust 实现高效神经形态硬件加速器的代码实践 在传统冯诺依曼架构逐渐逼近物理极限的今天,脉冲计算(Spiking Neural Computing, SNC) 正成为下一代AI硬件设计的核心方向之一。它模拟生物神经系统中通过“脉冲”传…

作者头像 李华
网站建设 2026/4/24 2:18:30

Windows HEIC缩略图终极指南:三步解决iPhone照片预览难题

Windows HEIC缩略图终极指南:三步解决iPhone照片预览难题 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC/HEIF files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 还在为Wind…

作者头像 李华
网站建设 2026/4/24 2:18:24

Windows 7也能流畅运行Blender 3.x:完整兼容解决方案

Windows 7也能流畅运行Blender 3.x:完整兼容解决方案 【免费下载链接】BlenderCompat Windows 7 support for Blender 3.x and newer 项目地址: https://gitcode.com/gh_mirrors/bl/BlenderCompat 还在为Windows 7系统无法运行最新版Blender而烦恼吗&#xf…

作者头像 李华
网站建设 2026/4/24 2:17:13

Entity Framework Core中的外键关系处理

在使用Entity Framework Core(EF Core)进行数据库模型设计时,如何正确地处理实体之间的关系是一个常见的问题。本文将通过一个实际的例子来解释如何在EF Core中正确地设置外键关系,并确保实体的唯一性。 背景介绍 假设我们有两个实体类:ConceptDataEntry 和 GlobalLocat…

作者头像 李华