1. Python imbalanced-learn库是什么?
imbalanced-learn(imblearn)是一个专门处理不平衡数据集的Python库。它是scikit-learn的扩展库,提供了多种重采样技术来处理分类问题中的类别不平衡问题。该库提供了以下主要功能:
- 过采样技术:如SMOTE(合成少数类过采样技术)、ADASYN(自适应合成采样)等
- 欠采样技术:如随机欠采样、Tomek Links、NearMiss等
- 结合过采样和欠采样的混合技术
- 集成学习方法:将重采样技术与分类器结合
imbalanced-learn遵循scikit-learn的API设计,使其能够轻松集成到机器学习工作流程中,包括在Pipeline中使用。
2. AI领域,imbalanced-learn作用?
在AI和机器学习领域,imbalanced-learn解决了一个关键问题:不平衡数据集处理。这一功能十分重要,原因如下:
-
提高少数类预测性能:在许多实际应用中(如欺诈检测、医疗诊断、异常检测),关注的目标类通常是数据集中的少数类。标准机器学习算法在不平衡数据上往往偏向多数类,导致对少数类的预测性能差。
-
适应不同领域需求:
- 医疗AI:疾病诊断数据通常高度不平衡
- 金融科技:欺诈交易在所有交易中占比很小
- 网络安全:恶意行为检测中正常行为占大多数
- 故障预测:设备故障事件通常很少见
- 自然语言处理:特定类别的文本可能非常罕见
-
定制评估指标:该库支持特定于不平衡学习的评估指标,如精确率-召回率曲线、ROC曲线等
-
与深度学习集成:可以在深度学习预处理阶段用于平衡训练数据
-
优化决策阈值:提供了工具来调整分类决策阈值,这对不平衡数据的性能评估至关重要
imbalanced-learn使AI系统能够更公平、更准确地处理现实世界中固有的不平衡数据分布,从而改善对少数类别样本的识别能力,这在许多关键应用中尤为重要。
3. 欠采样处理在客户流失预测中的应用
需求分析
背景
某电信公司面临客户流失问题。公司拥有大量客户数据,包括服务使用情况、账单信息和客户服务互动等。公司希望建立一个预测模型来识别可能流失的客户,从而采取针对性措施挽留这些客户。
挑战
数据集中流失客户(正类)只占总体的15%,而非流失客户(负类)占85%。这种不平衡会导致标准机器学习模型倾向于预测大多数类,忽视少数类,而公司更关心的恰恰是少数类(即可能流失的客户)。
目标
- 建立能准确识别潜在流失客户的分类模型
- 解决数据不平衡问题,特别是通过欠采样技术
- 评估不同欠采样方法的效果
- 为业务部门提供可解释的模型和建议
代码构建思路
- 数据探索与预处理:
- 加载数据并理解特征
- 处理缺失值和异常值
- 特征工程和编码
- 处理数据不平衡:
- 使用imbalanced-learn库实现多种欠采样技术
- 比较随机欠采样、Tomek Links、NearMiss等方法
- 模型构建与评估:
- 训练多个分类模型(如随机森林、XGBoost)
- 使用适合不平衡数据的评估指标(如AUC、F1分数、召回率)
- 实现交叉验证确保模型稳定性
- 结果比较与解释:
- 比较不同欠采样技术的效果
- 提取特征重要性进行业务解释
- 模型部署建议
完整实现
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 机器学习库
from sklearn.model_selection import train_test_split, cross_val_score, StratifiedKFold
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc, precision_recall_curve
from sklearn.feature_selection import SelectFromModel
from xgboost import XGBClassifier
# 导入不平衡学习库
from imblearn.under_sampling import RandomUnderSampler, TomekLinks, NearMiss
from imblearn.pipeline import Pipeline as ImbPipeline
# 结果可视化
import matplotlib.pyplot as plt
import seaborn as sns
# 设置随机种子以确保结果可复现
np.random.seed(42)
# 1. 数据加载与探索
print("1. 数据加载与初步探索")
# 加载电信客户流失数据集
# 此数据集包含电信公司的客户信息及其是否已流失的标记
df = pd.read_csv('https://raw.githubusercontent.com/IBM/telco-customer-churn-on-icp4d/master/data/Telco-Customer-Churn.csv')
# 显示数据集基本信息
print(f"数据集形状: {
df.shape}")
print("\n数据集前5行:")
print(df.head())
# 检查数据类型和缺失值
print("\n数据类型和缺失值统计:")
print(df.info())
print("\n缺失值统计:")
print(df.isnull().sum())
# 目标变量分布 - 检查流失率
print("\n客户流失情况统计:")
print(df['Churn'].value_counts())
print(df['Churn'].value_counts(normalize=True) * 100)
# 2. 数据预处理
print("\n2. 数据预处理")
# 将目标变量转换为二进制值
df['Churn'] = df['Churn'].map({
'Yes': 1, 'No': 0})
# 删除不相关的列
df = df.drop(['customerID'], axis=1)
# 处理TotalCharges列(可能包含空格字符)
df['TotalCharges'] = pd.to_numeric(df['TotalCharges'], errors='coerce')
df['TotalCharges'].fillna(df['MonthlyCharges'] * df[