news 2026/4/24 21:56:25

机器学习中的不平衡分类问题:以成人收入预测为例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
机器学习中的不平衡分类问题:以成人收入预测为例

1. 成人收入不平衡分类项目解析

在机器学习分类任务中,我们经常会遇到类别分布不平衡的情况。成人收入数据集(Adult Income Dataset)就是一个典型的例子,它需要根据个人特征预测年收入是否超过5万美元。这个数据集的特点是少数类(>50K)约占25%,多数类(<=50K)约占75%,属于中等程度的不平衡分类问题。

1.1 数据集背景与特点

该数据集源自1994年美国人口普查数据,包含45,222条完整记录(去除缺失值后),14个特征变量和1个目标变量。特征类型多样,包括:

  • 数值型:年龄、教育年限、资本收益等
  • 分类型:工作类型、婚姻状况、职业等

数据集中的缺失值用"?"表示,约占总数据的7.4%。在预处理阶段,我们选择直接删除含有缺失值的记录,因为占比不大且不影响整体数据分布。

注意:在实际项目中,当缺失值比例较高时,直接删除可能不是最佳选择。可以考虑使用均值/众数填充、模型预测填充等方法,具体取决于数据特性和业务场景。

1.2 不平衡分类的挑战

虽然75:25的类别比例看起来不算极端不平衡,但仍然会带来一些建模挑战:

  1. 准确率陷阱:如果简单预测所有样本为多数类,就能获得75%的准确率
  2. 模型偏向:许多算法会倾向于优化多数类的预测性能
  3. 评估失真:传统的准确率指标可能无法反映模型真实性能

针对这些问题,我们需要:

  • 选择合适的评估指标(如F1-score、AUC-ROC等)
  • 使用分层抽样保证训练/测试集的类别比例一致
  • 考虑采用过采样、欠采样或代价敏感学习等方法

2. 数据探索与预处理

2.1 数据加载与清洗

首先,我们使用Pandas加载数据并处理缺失值:

from pandas import read_csv from collections import Counter # 加载数据 filename = 'adult-all.csv' dataframe = read_csv(filename, header=None, na_values='?') # 删除缺失值 dataframe = dataframe.dropna() # 查看数据形状和类别分布 print(dataframe.shape) target = dataframe.values[:,-1] counter = Counter(target) for k,v in counter.items(): per = v / len(target) * 100 print('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))

输出结果:

(45222, 15) Class= <=50K, Count=34014, Percentage=75.216% Class= >50K, Count=11208, Percentage=24.784%

2.2 特征工程策略

针对不同类型的特征,我们需要采取不同的处理方式:

  1. 数值型特征

    • 标准化/归一化(如MinMaxScaler)
    • 检查是否需要非线性变换(如对数变换)
    • 考虑分箱处理(特别是对于资本收益等长尾分布的特征)
  2. 分类型特征

    • 有序类别:使用标签编码(Label Encoding)
    • 无序类别:使用独热编码(One-Hot Encoding)
    • 高基数类别:考虑目标编码(Target Encoding)或频率编码
  3. 特殊处理

    • "教育年限"和"教育程度"可能包含重复信息,需要评估保留哪个
    • "最终权重"(Final Weight)需要理解其统计含义再决定如何处理

2.3 特征可视化分析

通过绘制数值特征的分布直方图,我们可以发现:

from matplotlib import pyplot # 选择数值型列 num_ix = dataframe.select_dtypes(include=['int64', 'float64']).columns subset = dataframe[num_ix] # 绘制直方图 subset.hist(figsize=(12,10)) pyplot.show()

从直方图中可以观察到:

  • 年龄呈近似正态分布
  • 资本收益和资本损失具有极端偏态分布
  • 每周工作时间呈现双峰分布

这些观察结果将指导我们后续的特征工程决策。

3. 建模与评估框架

3.1 评估策略设计

为了可靠地评估模型性能,我们采用以下策略:

  1. 分层重复K折交叉验证

    • K=10,重复3次
    • 保持每折中类别比例与整体一致
    • 减少评估结果的方差
  2. 评估指标选择

    • 主要指标:分类准确率(与文献基准比较)
    • 辅助指标:F1-score、AUC-ROC(更全面评估不平衡分类性能)
  3. 基线模型

    • 使用DummyClassifier预测多数类
    • 预期准确率约75.2%

实现代码:

from sklearn.dummy import DummyClassifier from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.metrics import accuracy_score # 基线模型 baseline = DummyClassifier(strategy='most_frequent') cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) scores = cross_val_score(baseline, X, y, scoring='accuracy', cv=cv, n_jobs=-1) print('Baseline Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

3.2 特征预处理管道

构建一个统一的预处理管道,确保在交叉验证中正确应用转换:

from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder, MinMaxScaler from sklearn.pipeline import Pipeline # 定义预处理步骤 preprocessor = ColumnTransformer( transformers=[ ('num', MinMaxScaler(), num_ix), ('cat', OneHotEncoder(handle_unknown='ignore'), cat_ix) ]) # 完整建模管道 def make_pipeline(model): return Pipeline(steps=[ ('preprocessor', preprocessor), ('classifier', model) ])

这种设计确保了:

  • 数值特征被归一化到[0,1]范围
  • 分类特征被适当编码
  • 处理过程不会泄露测试集信息到训练集中

4. 模型比较与选择

4.1 候选模型测试

我们评估了五种不同类型的模型:

  1. 决策树(CART)
  2. 支持向量机(SVM)
  3. 装袋决策树(Bagging)
  4. 随机森林(RF)
  5. 梯度提升树(GBM)

每种模型使用默认参数(除n_estimators=100外),通过统一的评估框架进行比较:

from sklearn.tree import DecisionTreeClassifier from sklearn.svm import SVC from sklearn.ensemble import (RandomForestClassifier, GradientBoostingClassifier, BaggingClassifier) models = { 'CART': DecisionTreeClassifier(), 'SVM': SVC(gamma='scale'), 'BAG': BaggingClassifier(n_estimators=100), 'RF': RandomForestClassifier(n_estimators=100), 'GBM': GradientBoostingClassifier(n_estimators=100) } results = {} for name, model in models.items(): pipeline = make_pipeline(model) scores = evaluate_model(X, y, pipeline) results[name] = scores print(f'{name}: {mean(scores):.3f} (±{std(scores):.3f})')

4.2 结果分析与模型选择

测试结果可能类似于:

Baseline: 0.752 (±0.000) CART: 0.812 (±0.004) SVM: 0.843 (±0.003) BAG: 0.851 (±0.003) RF: 0.859 (±0.003) GBM: 0.867 (±0.003)

从结果可以看出:

  1. 所有模型都显著优于基线(75.2%)
  2. 集成方法普遍优于单一模型
  3. GBM表现最佳,达到约86.7%的准确率

实际建议:虽然GBM表现最好,但随机森林(RF)的准确率与之接近(85.9%),而训练速度更快。在计算资源有限的情况下,RF可能是更好的选择。

5. 模型优化与调参

5.1 梯度提升树(GBM)调优

GBM有多个关键参数可以优化:

  1. 学习率(learning_rate):控制每棵树的贡献程度
  2. 树的数量(n_estimators):集成中树的总数
  3. 最大深度(max_depth):单棵树的最大深度
  4. 子采样比例(subsample):训练每棵树使用的数据比例

使用网格搜索进行参数优化:

from sklearn.model_selection import GridSearchCV param_grid = { 'classifier__learning_rate': [0.01, 0.1, 0.2], 'classifier__n_estimators': [100, 200, 300], 'classifier__max_depth': [3, 5, 7], 'classifier__subsample': [0.8, 1.0] } gbm = GradientBoostingClassifier() pipeline = make_pipeline(gbm) search = GridSearchCV(pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1) search.fit(X, y) print(f'Best score: {search.best_score_:.3f}') print('Best params:', search.best_params_)

5.2 处理类别不平衡的专门技术

虽然GBM本身对类别不平衡有一定鲁棒性,但我们还可以尝试以下方法:

  1. 类别权重调整

    class_weight = {0: 1, 1: 3} # 给少数类更高权重 model = GradientBoostingClassifier(class_weight=class_weight)
  2. 过采样技术(如SMOTE)

    from imblearn.over_sampling import SMOTE from imblearn.pipeline import make_pipeline as make_imb_pipeline smote = SMOTE(sampling_strategy=0.5, random_state=42) pipeline = make_imb_pipeline(preprocessor, smote, model)
  3. 代价敏感学习

    • 使用代价敏感的GBM变体
    • 或在损失函数中引入不对称代价

经验分享:在实际项目中,我发现简单的类别权重调整(如少数类权重设为2-3)通常就能取得不错的效果,且实现简单。SMOTE等过采样技术虽然理论上更先进,但计算成本较高,且可能引入噪声。

6. 模型部署与预测

6.1 最终模型训练

确定最佳参数后,我们在全部训练数据上重新训练模型:

best_params = {'learning_rate': 0.1, 'max_depth': 5, 'n_estimators': 200, 'subsample': 0.8} final_model = GradientBoostingClassifier(**best_params) final_pipeline = make_pipeline(final_model) final_pipeline.fit(X, y)

6.2 新数据预测示例

假设有新样本需要进行预测:

import pandas as pd # 新样本数据(示例) new_data = pd.DataFrame([[ 45, 'Private', 200000, 'Masters', 14, 'Married-civ-spouse', 'Exec-managerial', 'Husband', 'White', 'Male', 5000, 0, 50, 'United-States' ]], columns=dataframe.columns[:-1]) # 预测 prob = final_pipeline.predict_proba(new_data)[0, 1] pred = final_pipeline.predict(new_data) print(f'Predicted probability: {prob:.3f}') print('Predicted class:', '>50K' if pred[0] == 1 else '<=50K')

6.3 模型解释与特征重要性

理解模型决策过程对于实际应用至关重要:

# 获取特征重要性 feature_importances = final_pipeline.named_steps['classifier'].feature_importances_ # 获取特征名称(考虑OneHotEncoder生成的列) cat_encoder = final_pipeline.named_steps['preprocessor'].named_transformers_['cat'] cat_features = cat_encoder.get_feature_names_out(input_features=cat_ix) all_features = num_ix.tolist() + cat_features.tolist() # 创建重要性DataFrame importance_df = pd.DataFrame({ 'feature': all_features, 'importance': feature_importances }).sort_values('importance', ascending=False) # 可视化前20个重要特征 importance_df.head(20).plot.barh(x='feature', y='importance') pyplot.show()

典型的重要特征可能包括:

  1. 年龄
  2. 教育年限
  3. 资本收益
  4. 每周工作时间
  5. 职业类型

7. 项目总结与经验分享

通过这个项目,我们系统地完成了从数据探索到模型部署的全流程。以下是一些关键经验:

  1. 数据质量至关重要

    • 原始数据中有约7.4%的缺失值
    • 不同特征需要不同的处理策略
    • 可视化分析帮助发现数据特性
  2. 模型选择考量

    • GBM表现最好(86.7%准确率)
    • 随机森林是很好的备选(85.9%)
    • 简单模型如决策树也有不错表现(81.2%)
  3. 不平衡处理心得

    • 75:25的不平衡程度不算极端
    • 直接使用GBM等集成方法通常足够
    • 更复杂的方法(如SMOTE)可能提升有限
  4. 实际应用建议

    • 关注业务需求决定优化方向(准确率 vs 召回率)
    • 模型解释性有时比绝对性能更重要
    • 考虑部署环境的计算限制

这个项目展示了如何处理一个真实世界的不平衡分类问题。虽然我们达到了86%以上的准确率,但仍有改进空间,比如:

  • 更精细的特征工程
  • 尝试深度学习模型
  • 集成多种方法

最终模型的选择应该综合考虑性能、复杂度和业务需求。希望这个案例能为处理类似的不平衡分类问题提供有价值的参考。

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

Office Custom UI Editor:快速打造专属办公界面的终极工具

Office Custom UI Editor&#xff1a;快速打造专属办公界面的终极工具 【免费下载链接】office-custom-ui-editor Standalone tool to edit custom UI part of Office open document file format 项目地址: https://gitcode.com/gh_mirrors/of/office-custom-ui-editor …

作者头像 李华
网站建设 2026/4/24 21:54:51

AutoJS进阶玩法:用手机搭建HTTP服务,实现自动化脚本的Web API化管理

AutoJS高阶开发&#xff1a;构建手机端HTTP服务网关实现脚本API化 你是否遇到过这样的困扰&#xff1f;手机里存了十几个AutoJS脚本——签到、爬数据、控制智能家居…每次都要手动点开对应脚本运行&#xff0c;既低效又难管理。想象一下&#xff0c;如果能像调用云服务API一样&…

作者头像 李华
网站建设 2026/4/24 21:41:18

避开这些坑!VisionPro多目标圆测量项目从调试到稳定的完整流程

VisionPro多目标圆测量实战&#xff1a;从参数调优到工业级稳定的避坑指南 在工业视觉检测领域&#xff0c;多目标圆的精确测量一直是看似简单却暗藏玄机的任务。当您面对数百个相似零件需要同时测量半径时&#xff0c;光照的微妙变化、材料的轻微形变、机械振动的干扰&#xf…

作者头像 李华
网站建设 2026/4/24 21:39:20

从选型到低功耗配置:芯海CS32F030/031实战避坑指南(附10个真实FAQ解析)

芯海CS32F030/031开发实战&#xff1a;选型决策与低功耗设计精要 在嵌入式系统开发领域&#xff0c;选择合适的MCU型号并规避设计陷阱往往决定着项目的成败。芯海科技的CS32F03X系列凭借其优异的性价比和丰富的外设资源&#xff0c;正成为越来越多硬件工程师的首选方案。然而&a…

作者头像 李华