当前位置: 首页 > news >正文

【Python Kaggle实战】从泰坦尼克号数据挖掘到模型调优:一个完整机器学习工作流解析

1. 初识泰坦尼克号数据集

第一次接触Kaggle的泰坦尼克号数据集时,我被这个经典案例的丰富性所吸引。这个数据集包含了891名乘客的详细信息,从姓名、年龄到船票等级,甚至包括他们最终是否生还。作为机器学习入门项目,它完美涵盖了数据清洗、特征工程、模型训练等全流程。

用Python加载数据后,我习惯先用pandas快速浏览数据全貌:

import pandas as pd train_df = pd.read_csv('train.csv') print(train_df.info()) print(train_df.describe())

输出结果显示Age列有177个缺失值,Cabin缺失更多达687个。这提醒我需要先处理数据质量问题。有趣的是,通过简单的train_df.head()就能看到那个时代的船票价格差异——头等舱票价高达512美元,而三等舱最低仅7.65美元,这暗示着社会阶层可能与生存率存在关联。

2. 数据清洗的艺术

2.1 缺失值处理实战

面对缺失的年龄数据,我尝试了三种方法对比:

  1. 直接删除缺失行(损失30%数据)
  2. 用均值填充(受异常值影响大)
  3. 用中位数填充(最终选择)
# 可视化年龄分布 import matplotlib.pyplot as plt plt.figure(figsize=(10,4)) plt.subplot(121) train_df['Age'].hist(bins=30) plt.subplot(122) train_df['Age'].plot.box() plt.show() # 中位数填充 train_df['Age'].fillna(train_df['Age'].median(), inplace=True)

对于Cabin字段,我创造性地提取了甲板信息作为新特征。即使原始数据缺失,通过标记为'U'(Unknown)仍保留了数据价值:

train_df['Deck'] = train_df['Cabin'].apply(lambda x: x[0] if pd.notna(x) else 'U')

2.2 异常值处理技巧

票价(Fare)字段存在极端值,我使用IQR方法识别异常值:

Q1 = train_df['Fare'].quantile(0.25) Q3 = train_df['Fare'].quantile(0.75) IQR = Q3 - Q1 outliers = train_df[(train_df['Fare'] < Q1-1.5*IQR) | (train_df['Fare'] > Q3+1.5*IQR)]

处理时没有简单删除,而是结合Pclass(船舱等级)进行分组替换,因为头等舱的高票价本身具有实际意义。

3. 特征工程的魔法

3.1 从姓名挖掘社会地位

原始Name字段看似无用,但提取出的称谓(Title)却成为关键特征:

titles = train_df['Name'].apply(lambda name: name.split(',')[1].split('.')[0].strip()) print(titles.value_counts()) # 将稀有称谓归类 rare_titles = ['Lady', 'Countess','Capt', 'Col', 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'] train_df['Title'] = train_df['Title'].replace(rare_titles, 'Rare')

3.2 构建家庭特征

将SibSp和Parch组合成新特征后,发现了有趣的模式:

train_df['FamilySize'] = train_df['SibSp'] + train_df['Parch'] + 1 train_df['IsAlone'] = (train_df['FamilySize'] == 1).astype(int) # 可视化家庭规模与生存率 import seaborn as sns sns.barplot(x='FamilySize', y='Survived', data=train_df)

结果显示2-4人家庭的生存率最高,而独行旅客或大家庭生存率较低,这符合"妇女儿童优先"的救援原则。

3.3 票价分级处理

原始Fare值跨度大,我将其离散化为5个等级:

train_df['FareBand'] = pd.qcut(train_df['Fare'], 5, labels=[1,2,3,4,5]) test_df['FareBand'] = pd.qcut(test_df['Fare'], 5, labels=[1,2,3,4,5])

4. 模型构建与优化

4.1 基础模型对比

我测试了五种常见算法的baseline表现:

模型验证集准确率训练时间(s)
逻辑回归0.7930.15
随机森林0.8210.82
梯度提升树0.8311.23
SVM0.7980.76
KNN0.7790.05
from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score rf = RandomForestClassifier(n_estimators=100, random_state=42) scores = cross_val_score(rf, X_train, y_train, cv=5) print(f"交叉验证准确率: {scores.mean():.3f} ± {scores.std():.3f}")

4.2 超参数调优实战

使用GridSearchCV进行精细调参:

param_grid = { 'n_estimators': [100, 200, 300], 'max_depth': [3, 5, 7], 'min_samples_split': [2, 5, 10] } grid_search = GridSearchCV(RandomForestClassifier(random_state=42), param_grid, cv=5, scoring='accuracy') grid_search.fit(X_train, y_train) print(f"最佳参数: {grid_search.best_params_}") print(f"最佳分数: {grid_search.best_score_:.3f}")

调优后的随机森林在验证集准确率提升到0.86,关键参数显示适度的树深度(max_depth=5)能更好防止过拟合。

4.3 特征重要性分析

可视化特征重要性帮助理解模型决策:

importances = grid_search.best_estimator_.feature_importances_ features = X_train.columns indices = np.argsort(importances)[::-1] plt.figure(figsize=(12,6)) plt.title("特征重要性") plt.bar(range(X_train.shape[1]), importances[indices]) plt.xticks(range(X_train.shape[1]), features[indices], rotation=90) plt.show()

结果显示性别(Sex)、票价等级(FareBand)和称谓(Title)是最具预测力的特征,这与历史记载的救援优先级一致。

5. 模型集成与提交

5.1 集成学习策略

尝试了三种集成方法提升效果:

  1. 投票集成:结合逻辑回归、随机森林和SVM的预测
  2. 堆叠集成:用随机森林作为元模型
  3. Bagging扩展:使用ExtraTrees算法
from sklearn.ensemble import VotingClassifier estimators = [ ('rf', RandomForestClassifier(n_estimators=300, max_depth=5, random_state=42)), ('gb', GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, random_state=42)) ] voting = VotingClassifier(estimators, voting='soft') voting.fit(X_train, y_train)

5.2 Kaggle提交技巧

最终提交时,我发现了几个关键点:

  • 测试集预处理必须与训练集完全一致
  • 需要处理测试集中出现的训练集未见的类别
  • 多次提交取平均能提升稳定性
# 最终提交管道 pipeline = Pipeline([ ('preprocessor', preprocessor), ('classifier', voting) ]) pipeline.fit(X_train, y_train) predictions = pipeline.predict(test_df) submission = pd.DataFrame({ 'PassengerId': test_df['PassengerId'], 'Survived': predictions }) submission.to_csv('final_submission.csv', index=False)

经过多次迭代,我的最佳提交在Kaggle上达到了0.813的准确率,进入前8%。这个过程中最宝贵的不是分数,而是学会如何通过特征工程揭示数据背后的故事。比如发现头等舱中年女士的生存率高达96%,而三等舱男性的生存率不足17%,这些洞察比模型参数更有价值。

http://www.jsqmd.com/news/841711/

相关文章:

  • TVA动态批处理保延迟低于100ms
  • 基于OpenCV与MediaPipe的手势与头部姿态控制鼠标实现
  • 开源AI角色库:如何用结构化提示词打造个性化数字人格
  • 13 移动端 WEB 前端 WEB 开发 HTML5 + CSS3 + 移动 WEB
  • NotebookLM工程研究辅助效能倍增术(实测数据:文献处理效率↑370%,技术方案产出周期↓62%)
  • NotebookLM戏剧辅助失效的9种典型误用场景:中央戏剧学院教研组紧急发布的避坑清单
  • vue基于springboot框架的幼儿园管理系统
  • 手把手教你用TI C2000 DSP的SCI串口实现printf调试(附完整代码)
  • 为什么Zotero Format Metadata的Short Title句子式大写转换功能对学术写作如此重要?
  • 【限时开放】NotebookLM气候专项Prompt Library(含AR6 WGII章节级语义索引模板):仅向高校科研组开放72小时
  • 【国家林草局重点实验室内部资料】:NotebookLM+森林生态数据库的6类高价值应用场景(含敏感数据脱敏处理流程)
  • 别再纠结电流还是电压了!用Simulink仿真混合式步进电机细分驱动,手把手教你选对控制方式
  • STM32F103C8T6平衡小车避坑指南:TB6612电机驱动、编码器与MPU6050的HAL库实战配置
  • Vxe-Table与Element-Plus混搭开发ERP表格,我踩过的那些坑和填坑代码
  • 均匀辐照度和局部遮光条件下光伏系统的新型样条-MPPT技术附Simulink仿真
  • 【软考高级架构】论文范文20——论软件设计方法及其应用
  • Zabbix监控
  • ssm中国篮球人才管理系统(10050)
  • 基于Arduino与NeoPixel的声控LED棒球帽制作全攻略
  • Scroll Reverser:macOS上实现多设备独立滚动方向的终极解决方案
  • MASA模组汉化包完整教程:如何让Minecraft模组界面说中文
  • 基于CW32L083单片机的超低功耗温湿度计设计与优化实战
  • 现代Web全栈技术栈实践:从Next.js到PostgreSQL的标准化开发方案
  • 宠物领养平台(10052)
  • 2026年国内铸铝门别墅大门入户门非标门工厂选购指南 | 国家重装超防门标准制定者领衔三大源头工厂深度评测服务全国 - 企业品牌优选推荐官
  • 2026年锡林浩特酒店:美速酒店为何成为商务出行优选? - 2026年企业推荐榜
  • 2026成都健身器材厂家技术解析:成都健身房健身器材/成都室外体育健身器材/成都室外健身器材/成都小区健身器材/选择指南 - 优质品牌商家
  • Python实战:基于边际谱稀疏性指标的自适应VMD模态数K值寻优
  • 废品买卖回收管理系统(10053)
  • 基于树莓派4B与BrainCraft HAT打造全自动YouTube音乐播放终端