【机器学习实战2】泰坦尼克号:从数据清洗到特征工程的生存预测全流程
2026/5/10 11:40:31 网站建设 项目流程

1. 数据探索与初步分析

第一次拿到泰坦尼克号数据集时,我习惯性地先看数据结构。用pandas的head()快速浏览前几行数据,发现每个乘客有12个特征,包括年龄、性别、舱位等级等。但很快注意到Age列有缺失,Cabin列更是大面积空白——这让我想起实际项目中常遇到的"脏数据"问题。

统计Survived列发现生还率仅38%,说明这是个类别不均衡问题。进一步用groupby分析发现:头等舱乘客生还率62%,而三等舱只有24%;女性生还率74%,男性仅18%。这些数字直观展示了"妇女儿童优先"的救援原则。可视化时我用matplotlib画了堆叠柱状图,不同舱位的生存对比一目了然。

2. 数据清洗实战技巧

处理缺失值时,Age列我尝试了三种方法:均值填充、中位数填充和基于称谓的智能填充。实测发现,从Name提取Mr/Miss/Mrs等称谓后,按称谓分组用中位数填充效果最好。比如"Master"称谓(未成年男性)的年龄中位数是5岁,比整体均值29.7岁更合理。

对于Embarked缺失的两条记录,通过票号查找发现都是头等舱乘客,且票价接近80英镑。查询历史资料发现这个价位乘客多从南安普顿登船,因此填充'S'。Cabin列缺失太多,但首字母代表甲板位置可能有价值,于是提取出Deck特征后再删除原列。

# 智能填充年龄示例 titles = df['Name'].str.extract(' ([A-Za-z]+)\.', expand=False) title_median_age = df.groupby(titles)['Age'].median() df['Age'] = df.apply( lambda x: title_median_age[x['Title']] if pd.isnull(x['Age']) else x['Age'], axis=1 )

3. 特征工程深度挖掘

3.1 姓名中的隐藏信息

Name列看似无用,但提取称谓后发现有趣模式:"Dr""Rev"等职业称谓的生还率低于平均值,而"Countess"等高身份称谓生还率更高。我将称谓归纳为6类:贵族、职业人士、成年男性、成年女性、未婚女性、儿童,做成分类特征。

3.2 家庭关系特征

SibSp和Parch原始特征可以衍生出更多信息:

  • FamilySize:家庭成员总数(SibSp + Parch + 1)
  • IsAlone:是否独自乘船(FamilySize == 1)
  • 分箱处理:将家庭规模分为独行、小家庭(2-4人)、大家庭(5人以上)

3.3 舱位与票价特征

Fare票价与Pclass舱位等级高度相关,但相同舱位内票价差异也蕴含信息:

  • FarePerPerson:总票价除以家庭人数
  • FareBin:将票价分为5个等级
  • CabinPremium:根据Cabin首字母判断是否位于高级甲板

4. 特征编码与选择

对于分类特征,测试了三种编码方式:

  1. LabelEncoder:简单但会引入虚假顺序
  2. OneHotEncoder:维度爆炸但无顺序假设
  3. TargetEncoding:用目标变量均值编码,需防范数据泄露

最终方案:

  • 有序类别(如Pclass)用LabelEncoder
  • 无序类别(如Embarked)用OneHotEncoder
  • 高基数特征(如Ticket前缀)用TargetEncoding
# 目标编码示例 from sklearn.preprocessing import TargetEncoder encoder = TargetEncoder() df['Deck_encoded'] = encoder.fit_transform( df['Deck'], df['Survived'] )

5. 模型构建与优化

5.1 基线模型选择

先用逻辑回归建立基线,准确率约79%。然后尝试:

  • 随机森林:处理非线性关系效果好
  • XGBoost:自动特征选择能力强
  • SVM:小样本表现稳定

5.2 特征重要性分析

通过随机森林的feature_importance发现:

  1. 性别是最强预测因子
  2. 票价和舱位次之
  3. 自建特征Deck和Title排名靠前

5.3 超参数调优

用GridSearchCV优化随机森林:

param_grid = { 'n_estimators': [100, 200], 'max_depth': [4, 6, None], 'min_samples_split': [2, 5] } grid = GridSearchCV(RandomForestClassifier(), param_grid) grid.fit(X_train, y_train)

6. 集成学习提升效果

单模型最好成绩是XGBoost的83.5%。尝试三种集成方法:

  1. VotingClassifier:结合逻辑回归、随机森林、SVM
  2. Stacking:用XGBoost作为元模型
  3. Bagging:对随机森林做二次采样

最终Stacking方案将准确率提升到85.2%,关键代码如下:

from sklearn.ensemble import StackingClassifier base_models = [ ('rf', RandomForestClassifier(n_estimators=200)), ('xgb', XGBClassifier(max_depth=3)) ] stack = StackingClassifier( estimators=base_models, final_estimator=LogisticRegression() )

7. 避免常见陷阱

在这个项目中我踩过几个坑:

  1. 数据泄露:在填充Age缺失值时,错误地在全数据集计算均值
  2. 过拟合:早期版本在训练集达到92%但测试集只有80%
  3. 评估偏差:用accuracy评价不均衡数据,改用F1-score

解决方案:

  • 严格区分训练/测试集
  • 早停法防止过拟合
  • 使用交叉验证
  • 关注混淆矩阵而非单一指标

处理泰坦尼克号数据集就像在考古,每个特征都可能隐藏着1912年的社会密码。当我发现头等舱儿童的生还率比三等舱成人高出6倍时,突然理解了特征工程的魅力——它让数据讲出了那个夜晚的真实故事。

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

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

立即咨询