SMOTE实战:用Python轻松搞定数据不平衡问题(附完整代码)

发布时间:2026/6/29 6:08:55

SMOTE实战:用Python轻松搞定数据不平衡问题(附完整代码) SMOTE实战用Python轻松搞定数据不平衡问题附完整代码在机器学习项目中数据不平衡问题就像一位不请自来的客人——它总是悄无声息地出现却能让你的模型表现大打折扣。想象一下你正在构建一个信用卡欺诈检测系统但欺诈交易只占总样本的0.1%。这种情况下即使模型把所有交易都预测为正常也能达到99.9%的准确率——这显然不是我们想要的结果。SMOTE合成少数类过采样技术正是为解决这类问题而生。不同于简单的复制少数类样本SMOTE通过智能地生成新样本在保持数据分布特性的同时有效平衡数据集。本文将带你从零开始用Python的imbalanced-learn库实现完整的SMOTE流程包括数据可视化、参数调优和实战技巧。1. 环境准备与数据加载工欲善其事必先利其器。我们需要准备以下工具包import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import make_classification from imblearn.over_sampling import SMOTE from collections import Counter为了演示效果我们创建一个高度不平衡的模拟数据集# 生成不平衡数据集 X, y make_classification(n_classes2, class_sep2, weights[0.9, 0.1], n_informative3, n_redundant1, flip_y0, n_features20, n_clusters_per_class1, n_samples1000, random_state42)查看类别分布print(f原始数据分布: {Counter(y)}) # 输出: Counter({0: 900, 1: 100})可视化展示plt.figure(figsize(10,6)) sns.countplot(xy) plt.title(类别分布直方图, fontsize15) plt.xlabel(类别, fontsize12) plt.ylabel(数量, fontsize12) plt.show()2. SMOTE基础实现SMOTE的核心思想是在少数类样本的特征空间邻居之间生成新样本。具体实现仅需几行代码# 初始化SMOTE sm SMOTE(random_state42) # 应用SMOTE X_res, y_res sm.fit_resample(X, y) # 查看新分布 print(f过采样后分布: {Counter(y_res)}) # 输出: Counter({0: 900, 1: 900})可视化对比plt.figure(figsize(12,5)) plt.subplot(1,2,1) sns.scatterplot(xX[:,0], yX[:,1], huey) plt.title(原始数据分布) plt.subplot(1,2,2) sns.scatterplot(xX_res[:,0], yX_res[:,1], huey_res) plt.title(SMOTE处理后分布) plt.tight_layout() plt.show()关键参数说明参数默认值说明sampling_strategyauto重采样后的少数类比例k_neighbors5生成新样本时考虑的邻居数random_stateNone随机种子3. 高级调优技巧3.1 控制采样比例有时我们不需要完全1:1的平衡可以通过sampling_strategy参数控制# 只将少数类增加到多数类的50% sm SMOTE(sampling_strategy0.5, random_state42) X_res, y_res sm.fit_resample(X, y) print(f50%平衡后分布: {Counter(y_res)}) # 输出: Counter({0: 900, 1: 450})3.2 结合欠采样SMOTE常与随机欠采样结合使用SMOTEENNfrom imblearn.combine import SMOTEENN smote_enn SMOTEENN(random_state42) X_res, y_res smote_enn.fit_resample(X, y) print(fSMOTEENN处理后分布: {Counter(y_res)})3.3 处理高维数据对于高维数据可先使用PCA降维再应用SMOTEfrom sklearn.decomposition import PCA pca PCA(n_components5) X_pca pca.fit_transform(X) sm SMOTE(random_state42) X_res, y_res sm.fit_resample(X_pca, y)4. 实战案例信用卡欺诈检测让我们用真实场景演示完整流程。首先加载Kaggle信用卡欺诈数据集df pd.read_csv(creditcard.csv) X df.drop(Class, axis1) y df[Class] print(f欺诈比例: {sum(y)/len(y)*100:.4f}%) # 输出: 欺诈比例: 0.1727%处理流程数据标准化from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_scaled scaler.fit_transform(X)应用SMOTEsm SMOTE(random_state42) X_res, y_res sm.fit_resample(X_scaled, y)模型训练与评估from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report X_train, X_test, y_train, y_test train_test_split( X_res, y_res, test_size0.3, random_state42) model RandomForestClassifier(random_state42) model.fit(X_train, y_train) y_pred model.predict(X_test) print(classification_report(y_test, y_pred))常见报错解决方案MemoryError减小数据集规模或使用SMOTE的ratio参数ValueError: Expected n_neighbors n_samples减少k_neighbors值NaN values detected先处理缺失值再应用SMOTE5. 替代方案与进阶技巧当SMOTE效果不佳时可以考虑以下替代方案ADASYN根据样本密度自适应生成新样本from imblearn.over_sampling import ADASYN ada ADASYN(random_state42) X_res, y_res ada.fit_resample(X, y)BorderlineSMOTE专注于边界样本from imblearn.over_sampling import BorderlineSMOTE bsmote BorderlineSMOTE(random_state42) X_res, y_res bsmote.fit_resample(X, y)评估指标选择建议场景推荐指标欺诈检测召回率医学诊断F1分数客户流失精确率在实际项目中我发现结合多种采样技术往往能取得更好效果。例如可以先使用SMOTE增加少数类样本再用Tomek Links清理边界噪声。这种组合策略在我的一个客户流失预测项目中将F1分数从0.62提升到了0.78。

相关新闻