从Kaggle竞赛入门:用随机森林搞定泰坦尼克号预测的完整避坑指南(含特征工程与调参) 从Kaggle竞赛入门用随机森林搞定泰坦尼克号预测的完整避坑指南含特征工程与调参1. 为什么选择泰坦尼克号数据集作为机器学习入门项目泰坦尼克号幸存者预测是Kaggle平台上最经典的入门竞赛之一被称为机器学习界的Hello World。这个数据集之所以成为绝佳的学习案例是因为它完美融合了现实世界数据的复杂性和教学友好性。数据集包含891名乘客的12个特征字段既有结构化数据如年龄、票价也有非结构化数据如姓名让你能全面练习数据清洗、特征工程和模型调优的全流程。我在第一次接触这个项目时曾天真地以为直接扔进随机森林就能得到不错的结果。现实给了我一记响亮的耳光——未经处理的原始数据得到的预测准确率甚至不如全部预测死亡的基准线。这促使我深入理解每个特征背后的意义也让我意识到特征工程的重要性远超模型选择。2. 数据探索超越简单的统计描述2.1 结构化数据的基础分析首先加载数据并查看基本信息import pandas as pd train_df pd.read_csv(train.csv) test_df pd.read_csv(test.csv) print(f训练集形状: {train_df.shape}) print(f测试集形状: {test_df.shape}) print(train_df.info())关键发现年龄(Age)有约20%缺失值船舱号(Cabin)有大量缺失(77%)票价(Fare)在测试集中有1个缺失值登船港口(Embarked)在训练集中有2个缺失值2.2 可视化分析的进阶技巧不要满足于简单的直方图和箱线图试试这些更有洞察力的可视化import seaborn as sns import matplotlib.pyplot as plt # 年龄与生存率的核密度估计 plt.figure(figsize(10,6)) sns.kdeplot(datatrain_df, xAge, hueSurvived, fillTrue, alpha0.5, paletteSet2) plt.title(Age Distribution by Survival Status) plt.show()这个可视化揭示了几个关键点儿童(0-10岁)生存率明显更高20-30岁年龄段的死亡率显著老年人(60岁)生存率较低3. 特征工程从原始数据中挖掘黄金3.1 从姓名中提取社会地位信息原始数据中的姓名字段看似无用实则包含宝贵信息# 提取称呼(Title) train_df[Title] train_df[Name].str.extract( ([A-Za-z])\., expandFalse) # 查看称呼分布 print(train_df[Title].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) train_df[Title] train_df[Title].replace(Mlle, Miss) train_df[Title] train_df[Title].replace(Ms, Miss) train_df[Title] train_df[Title].replace(Mme, Mrs)称呼与生存率的关系TitleSurvival RateMrs79.4%Miss70.7%Master57.5%Mr15.7%Rare35.7%3.2 处理缺失值的智能策略对于年龄缺失值不要简单使用整体中位数填充# 按性别、船舱等级和称呼分组填充年龄 train_df[Age] train_df.groupby([Sex, Pclass, Title])[Age].apply( lambda x: x.fillna(x.median()))3.3 创建有意义的组合特征尝试创建这些能提升模型表现的新特征# 家庭规模 兄弟姐妹数 父母子女数 1(自己) train_df[FamilySize] train_df[SibSp] train_df[Parch] 1 # 是否独自旅行 train_df[IsAlone] 0 train_df.loc[train_df[FamilySize] 1, IsAlone] 1 # 票价每人(考虑家庭规模) train_df[FarePerPerson] train_df[Fare] / train_df[FamilySize]4. 模型构建与调优超越默认参数4.1 基础随机森林模型from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score # 选择特征和目标变量 features [Pclass, Sex, Age, SibSp, Parch, Fare, Embarked, Title, FamilySize, IsAlone] X pd.get_dummies(train_df[features]) y train_df[Survived] # 基础模型 rfc RandomForestClassifier(random_state42) scores cross_val_score(rfc, X, y, cv5) print(f基础模型准确率: {scores.mean():.4f} (±{scores.std():.4f}))4.2 网格搜索调参实战不要盲目搜索所有参数先理解每个参数的影响from sklearn.model_selection import GridSearchCV param_grid { n_estimators: [100, 200, 300], max_depth: [5, 8, 10, None], min_samples_split: [2, 5, 10], min_samples_leaf: [1, 2, 4], max_features: [sqrt, log2] } grid_search GridSearchCV( estimatorRandomForestClassifier(random_state42), param_gridparam_grid, cv5, n_jobs-1, verbose1 ) grid_search.fit(X, y) print(f最佳参数: {grid_search.best_params_}) print(f最佳得分: {grid_search.best_score_:.4f})调参前后对比指标默认参数调优后准确率0.8120.835过拟合程度较高较低4.3 特征重要性分析训练后查看特征重要性指导后续特征工程best_rfc grid_search.best_estimator_ feature_importance pd.DataFrame({ Feature: X.columns, Importance: best_rfc.feature_importances_ }).sort_values(Importance, ascendingFalse) plt.figure(figsize(10,6)) sns.barplot(xImportance, yFeature, datafeature_importance) plt.title(Feature Importance) plt.show()关键发现性别是最重要的预测因素票价和年龄紧随其后称呼(Title)的重要性高于原始预期登船港口(Embarked)贡献较小5. 提交结果前的最后检查清单在生成最终提交文件前确保完成以下步骤数据一致性检查训练集和测试集的特征工程处理是否一致所有分类变量是否都进行了相同的编码模型验证是否在保留的验证集上测试过交叉验证结果是否稳定提交文件格式确保预测结果与乘客ID正确对应检查文件格式是否符合Kaggle要求# 最终预测与提交 test_df pd.read_csv(test.csv) # 在测试集上重复所有特征工程步骤... predictions best_rfc.predict(X_test) output pd.DataFrame({ PassengerId: test_df.PassengerId, Survived: predictions }) output.to_csv(submission.csv, indexFalse)在第一次参加这个比赛时我犯了一个低级错误——忘记对测试集进行相同的特征工程处理导致提交结果异常糟糕。现在每次提交前我都会专门检查这个清单。