news 2026/7/8 18:00:25

Scikit-learn 1.3+ 决策树实战:泰坦尼克号生存预测准确率 0.82(附特征重要性分析)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Scikit-learn 1.3+ 决策树实战:泰坦尼克号生存预测准确率 0.82(附特征重要性分析)

Scikit-learn 1.3+ 决策树实战:泰坦尼克号生存预测准确率 0.82(附特征重要性分析)

当数据科学家面对结构化数据的分类问题时,决策树往往是工具箱中第一个被取出的利器。这种模仿人类决策过程的算法,以其直观的可解释性和接近人类思考方式的分支逻辑,在金融风控、医疗诊断等关键领域持续发光发热。本文将带您深入Scikit-learn 1.3+版本中的决策树实现,通过经典的泰坦尼克号数据集,演示如何构建准确率达82%的生存预测模型,并揭示哪些特征真正决定了乘客的命运。

1. 环境准备与数据加载

在开始建模之前,我们需要配置合适的Python环境并获取数据。建议使用Python 3.8+版本,并安装以下依赖库:

pip install scikit-learn==1.3.0 pandas numpy matplotlib graphviz

泰坦尼克号数据集可以从多个来源获取,这里我们使用Kaggle提供的版本,它包含以下关键特征:

  • pclass:船舱等级(1/2/3等舱)
  • sex:乘客性别
  • age:乘客年龄
  • sibsp:兄弟姐妹/配偶数量
  • parch:父母/子女数量
  • fare:船票价格
  • embarked:登船港口
  • survived:生存状态(目标变量)
import pandas as pd from sklearn.model_selection import train_test_split # 加载数据 titanic = pd.read_csv('titanic.csv') print(f"数据集形状: {titanic.shape}") print("\n前5行数据:") print(titanic.head())

执行后会显示类似如下的输出:

数据集形状: (891, 12) 前5行数据: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S

2. 数据预处理实战技巧

原始数据往往包含缺失值和需要转换的类别特征。以下是关键预处理步骤:

2.1 缺失值处理策略

年龄字段约有20%的缺失值,我们采用基于其他特征的预测填充法:

from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer # 选择用于预测年龄的特征 age_features = ['Pclass', 'SibSp', 'Parch', 'Fare'] # 使用随机森林回归填充年龄 imputer = IterativeImputer(max_iter=10, random_state=42) titanic['Age'] = imputer.fit_transform(titanic[age_features + ['Age']])[:, -1]

2.2 特征工程创新点

除了原始特征,我们可以构造有预测力的新特征:

# 家庭规模 titanic['FamilySize'] = titanic['SibSp'] + titanic['Parch'] + 1 # 年龄分段 titanic['AgeGroup'] = pd.cut(titanic['Age'], bins=[0, 12, 18, 35, 60, 100], labels=['Child', 'Teen', 'Adult', 'MidAge', 'Senior']) # 票价等级 titanic['FareCategory'] = pd.qcut(titanic['Fare'], 4, labels=['Low', 'Mid', 'High', 'VIP'])

2.3 类别特征编码

使用独热编码处理类别变量时需注意内存问题:

from sklearn.preprocessing import OneHotEncoder # 选择需要编码的特征 cat_features = ['Pclass', 'Sex', 'Embarked', 'AgeGroup', 'FareCategory'] # 稀疏矩阵格式节省内存 encoder = OneHotEncoder(sparse=True, handle_unknown='ignore') X_cat = encoder.fit_transform(titanic[cat_features])

3. 决策树模型构建与调优

Scikit-learn的DecisionTreeClassifier在1.3版本中优化了计算效率,特别是对大型数据集的处理。

3.1 基础模型训练

from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score # 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split( X_features, titanic['Survived'], test_size=0.2, random_state=42) # 初始化决策树 dt_clf = DecisionTreeClassifier( criterion='gini', max_depth=5, min_samples_split=20, random_state=42 ) # 训练模型 dt_clf.fit(X_train, y_train) # 评估 train_acc = accuracy_score(y_train, dt_clf.predict(X_train)) test_acc = accuracy_score(y_test, dt_clf.predict(X_test)) print(f"训练集准确率: {train_acc:.2%}") print(f"测试集准确率: {test_acc:.2%}")

典型输出结果:

训练集准确率: 86.52% 测试集准确率: 82.12%

3.2 超参数调优实战

使用GridSearchCV进行参数搜索时,重点关注这些关键参数:

from sklearn.model_selection import GridSearchCV param_grid = { 'max_depth': [3, 5, 7, None], 'min_samples_split': [10, 20, 30], 'min_samples_leaf': [1, 5, 10], 'max_features': ['sqrt', 'log2', None] } grid_search = GridSearchCV( DecisionTreeClassifier(random_state=42), param_grid, cv=5, scoring='accuracy', n_jobs=-1 ) grid_search.fit(X_train, y_train) print("最佳参数组合:", grid_search.best_params_) print("最佳交叉验证得分:", grid_search.best_score_)

3.3 决策树可视化解析

安装graphviz后,可以导出决策树图形:

from sklearn.tree import export_graphviz import graphviz dot_data = export_graphviz( dt_clf, out_file=None, feature_names=feature_names, class_names=['Died', 'Survived'], filled=True, rounded=True, special_characters=True ) graph = graphviz.Source(dot_data) graph.render("titanic_decision_tree") # 保存为PDF

决策树图形中,颜色深浅表示节点纯度,我们可以清晰看到:

  1. 首要分裂特征是性别(sex_female)
  2. 二等舱及以上乘客生存率更高
  3. 儿童和携带家人的乘客有生存优势

4. 模型解释与特征重要性

决策树最强大的优势在于其可解释性。Scikit-learn提供了两种特征重要性计算方法:

4.1 Gini重要性分析

import matplotlib.pyplot as plt # 获取特征重要性 importances = dt_clf.feature_importances_ indices = np.argsort(importances)[::-1] # 绘制重要性图表 plt.figure(figsize=(12, 6)) plt.title("特征重要性 (Gini)") plt.bar(range(X_train.shape[1]), importances[indices], align="center") plt.xticks(range(X_train.shape[1]), [feature_names[i] for i in indices], rotation=90) plt.xlim([-1, X_train.shape[1]]) plt.tight_layout() plt.show()

4.2 Permutation重要性

这种方法通过打乱特征值观察模型性能下降程度计算重要性:

from sklearn.inspection import permutation_importance result = permutation_importance( dt_clf, X_test, y_test, n_repeats=10, random_state=42 ) sorted_idx = result.importances_mean.argsort()[::-1] plt.figure(figsize=(12, 6)) plt.boxplot( result.importances[sorted_idx].T, vert=False, labels=[feature_names[i] for i in sorted_idx] ) plt.title("Permutation重要性") plt.tight_layout() plt.show()

两种方法通常显示一致的重要特征排序:

  1. 性别(女性更可能幸存)
  2. 船舱等级(头等舱优先)
  3. 年龄(儿童优先)
  4. 票价(高票价乘客优先)

5. 决策树的局限性与改进方案

虽然我们的模型达到了82%的准确率,但决策树仍有明显缺陷:

5.1 过拟合问题

通过观察学习曲线可以发现过拟合迹象:

from sklearn.model_selection import learning_curve train_sizes, train_scores, test_scores = learning_curve( dt_clf, X_features, titanic['Survived'], cv=5, train_sizes=np.linspace(0.1, 1.0, 10), scoring='accuracy') plt.plot(train_sizes, np.mean(train_scores, axis=1), label='训练得分') plt.plot(train_sizes, np.mean(test_scores, axis=1), label='交叉验证得分') plt.xlabel('训练样本数') plt.ylabel('准确率') plt.legend() plt.show()

5.2 集成方法改进

使用随机森林可以显著提升性能:

from sklearn.ensemble import RandomForestClassifier rf_clf = RandomForestClassifier( n_estimators=100, max_depth=5, random_state=42 ) rf_clf.fit(X_train, y_train) rf_test_acc = accuracy_score(y_test, rf_clf.predict(X_test)) print(f"随机森林测试准确率: {rf_test_acc:.2%}")

典型结果:

随机森林测试准确率: 84.36%

5.3 业务规则提取

决策树可以转化为if-then规则,用于业务系统:

from sklearn.tree import _tree def tree_to_rules(tree, feature_names): tree_ = tree.tree_ feature_name = [ feature_names[i] if i != _tree.TREE_UNDEFINED else "undefined!" for i in tree_.feature ] def recurse(node, depth, rules): if tree_.feature[node] != _tree.TREE_UNDEFINED: name = feature_name[node] threshold = tree_.threshold[node] rules.append(f"如果 {name} ≤ {threshold:.2f}:") recurse(tree_.children_left[node], depth + 1, rules) rules.append("否则:") recurse(tree_.children_right[node], depth + 1, rules) else: rules.append(f"→ 预测为 {class_names[np.argmax(tree_.value[node])]}") rules = [] recurse(0, 1, rules) return rules rules = tree_to_rules(dt_clf, feature_names) print("\n".join(rules[:10])) # 打印前10条规则

示例输出:

如果 sex_female ≤ 0.50: 如果 pclass_3 ≤ 0.50: → 预测为 Survived 否则: 如果 age ≤ 9.50: → 预测为 Survived 否则: 如果 fare ≤ 23.35: → 预测为 Died 否则: → 预测为 Survived 否则: 如果 age ≤ 3.50: → 预测为 Survived

在实际项目中,这种白盒特性使得决策树成为需要解释性的场景(如金融风控、医疗诊断)的首选算法。虽然深度学习在某些领域表现更优,但决策树凭借其直观性和可解释性,仍然是数据科学家工具箱中不可或缺的利器。

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

Unity移动端动画性能优化:从Mixamo资源到Animator实战调优

1. 项目概述:从云端资源到移动端流畅体验的挑战如果你正在为你的移动端Unity项目寻找高质量的3D角色动画,Mixamo绝对是一个绕不开的名字。这个由Adobe运营的在线资源库,提供了海量免费且高质量的FBX格式角色动画,从基础的走、跑、…

作者头像 李华
网站建设 2026/7/8 17:57:33

Unity游戏实时翻译:XUnity自动翻译器原理与五分钟上手教程

1. 项目概述:为什么你需要XUnity自动翻译器?如果你是一个Unity游戏玩家,尤其是喜欢尝试各种独立游戏或海外作品的玩家,那么你一定遇到过语言障碍。满屏的英文、日文或者其他语言,即使游戏本身再有趣,看不懂…

作者头像 李华
网站建设 2026/7/8 17:54:38

Cocos2d-x 4.0集成Tiled地图编辑器:数据驱动2D游戏地图开发实战

1. 项目概述:告别地图拼接的“石器时代”如果你做过2D游戏,尤其是横版卷轴、俯视角RPG或者策略类游戏,一定经历过手动拼接地图的“痛苦”。在Photoshop或者绘图软件里,把一个个32x32、64x64像素的小图块,像拼拼图一样&…

作者头像 李华
网站建设 2026/7/8 17:54:02

UE5.6全局光照性能优化:集成AMD FSR 3.1.4实战指南

1. 项目概述:当UE5.6的全局光照遇上AMD FSR 3.1.4 如果你正在用UE5.6捣鼓一个对画面要求比较高的项目,比如数字孪生或者写实风格的游戏,大概率会为全局光照(Global Illumination, GI)的性能开销头疼。实时光…

作者头像 李华
网站建设 2026/7/8 17:50:48

基于TPA3128D2与PIC32MZ的高效D类音频放大系统设计

1. 项目概述:构建高效D类音频放大系统在DIY音频和嵌入式系统开发领域,如何在小体积内实现高保真、大功率的音频输出一直是个挑战。传统AB类放大器虽然音质出色,但发热量大、效率低下;而数字功放虽然效率高,却常被诟病音…

作者头像 李华
网站建设 2026/7/8 17:50:32

Trae不是IDE:任务驱动的智能代码协作者解析

1. 项目概述:Trae 不是 IDE,而是一套“智能编码协作者”工作流Trae 这个名字最近在开发者圈子里出现频率很高,但很多人第一次看到时会下意识念成“tray”(托盘)或者“tree”(树),其实…

作者头像 李华