2025美赛C题决策树实战指南:从数据预处理到模型调优

1次阅读
没有评论

共计 2777 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

背景痛点分析

美赛 C 题通常涉及复杂的社会经济或环境系统建模,数据特点包括:

2025 美赛 C 题决策树实战指南:从数据预处理到模型调优

  • 混合型数据:同时包含数值型(如温度、GDP)和类别型(如地区、政策等级)变量
  • 缺失值常见:调查数据常存在 10%-30% 的缺失比例
  • 多维度特征:原始特征可能达 50+ 个,但有效特征有限

新手常见问题:

  1. 直接使用原始数据导致树结构过于复杂
  2. 对类别型特征简单赋值(如用 1 - 5 代替红 / 黄 / 蓝)造成信息损失
  3. 忽略特征间的交互作用

算法选型依据

主流决策树算法对比:

算法 分裂标准 支持特征类型 适用场景
ID3 信息增益 仅类别型 分类问题
C4.5 信息增益比 混合类型 分类优先
CART 基尼系数 混合类型 分类 / 回归

选择 scikit-learn 的 DecisionTreeClassifier 原因:

  • 默认使用 CART 算法,兼容数值和类别特征
  • 提供 pruning 等防过拟合机制
  • 与 sklearn 生态无缝衔接(管道 /Pipeline)

核心实现步骤

数据预处理

# 缺失值处理
from sklearn.impute import SimpleImputer

# 数值列用中位数填充
num_imputer = SimpleImputer(strategy='median') 
df[num_cols] = num_imputer.fit_transform(df[num_cols])

# 类别列用众数填充
cat_imputer = SimpleImputer(strategy='most_frequent')
df[cat_cols] = cat_imputer.fit_transform(df[cat_cols])

# 类别特征编码
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(handle_unknown='ignore')
cat_encoded = encoder.fit_transform(df[cat_cols]).toarray()

# 特征合并
import numpy as np
X = np.hstack([df[num_cols].values, cat_encoded])
y = df['target'].values

模型构建

from sklearn.tree import DecisionTreeClassifier

# 关键参数说明
model = DecisionTreeClassifier(
    max_depth=5,          # 控制树深防过拟合
    min_samples_split=10, # 节点最少样本数
    criterion='gini',     # 也可选 'entropy'
    class_weight='balanced' # 处理类别不平衡
)

model.fit(X_train, y_train)

可视化实现

from sklearn.tree import export_graphviz
import graphviz

dot_data = export_graphviz(
    model, 
    out_file=None,
    feature_names=num_cols + encoder.get_feature_names_out().tolist(),
    class_names=['Class0','Class1'],
    filled=True
)
graph = graphviz.Source(dot_data)
graph.render('decision_tree')  # 生成 PDF 文件 

模型调优策略

网格搜索示例

from sklearn.model_selection import GridSearchCV

param_grid = {'max_depth': [3, 5, 7],
    'min_samples_split': [5, 10, 15],
    'criterion': ['gini', 'entropy']
}

grid = GridSearchCV(DecisionTreeClassifier(),
    param_grid,
    cv=5,  # 5 折交叉验证
    scoring='f1_macro'  # 美赛常用指标
)
grid.fit(X_train, y_train)

print(f'最佳参数:{grid.best_params_}')

剪枝技术

  1. 预剪枝(Pre-pruning):
  2. 通过 max_depth 等参数限制生长
  3. 使用 min_impurity_decrease 设置分裂阈值

  4. 后剪枝(Post-pruning):

    path = model.cost_complexity_pruning_path(X_train, y_train)
    ccp_alphas = path.ccp_alphas
    
    pruned_models = []
    for ccp_alpha in ccp_alphas:
        pruned_model = DecisionTreeClassifier(ccp_alpha=ccp_alpha)
        pruned_model.fit(X_train, y_train)
        pruned_models.append(pruned_model)

特征重要性分析

import matplotlib.pyplot as plt

importance = model.feature_importances_
feat_names = num_cols + encoder.get_feature_names_out().tolist()

plt.figure(figsize=(10,6))
plt.barh(range(len(importance)), importance, tick_label=feat_names)
plt.title('Feature Importance')
plt.show()

竞赛避坑指南

类别不平衡处理

  • 设置 class_weight 参数
  • 使用 SMOTE 过采样:
    from imblearn.over_sampling import SMOTE
    smote = SMOTE(random_state=42)
    X_res, y_res = smote.fit_resample(X_train, y_train)

连续特征分箱

# 等宽分箱
pd.cut(df['temperature'], bins=5)

# 等频分箱
pd.qcut(df['income'], q=4)

模型序列化

import joblib

# 保存完整 pipeline(含预处理和模型)joblib.dump(pipeline, 'submission_model.pkl') 

# 比赛提交时同时保存:# 1. 模型文件
# 2. 预处理参数(如分箱边界、编码映射)# 3. 使用的 Python 版本说明 

延伸思考

  1. 如何处理基数超过 100 的分类特征?(如城市名称)
  2. 当特征间存在强相关性时,决策树表现会受什么影响?
  3. 如何将决策树模型转化为可解释的决策规则?

通过以上流程,参赛者可系统性地完成从数据清洗到模型部署的全过程,避免常见失误。建议在实际应用中先构建基线模型,再逐步迭代优化。

正文完
 0
评论(没有评论)