ClassificationModeling ClassificationModeling

构建用于分类预测和分类的二元和多类分类模型

预测建模 0 次安装 0 次浏览 更新于 3/3/2026

name: 分类建模 description: 使用逻辑回归、决策树和集成方法构建二元和多类分类模型,用于分类预测和分类

分类建模

概览

分类建模预测分类目标值,根据输入特征将观察结果分配到离散类别或类别中。

使用场景

  • 预测二元结果,如客户流失、贷款违约或电子邮件垃圾邮件
  • 将项目分类到多个类别,如产品类型或情感
  • 构建信用评分模型或风险评估系统
  • 从患者数据中识别疾病诊断或医疗条件
  • 预测客户购买可能性或对营销的响应
  • 在生产系统中检测欺诈、异常或质量缺陷

分类类型

  • 二元分类: 两个类别(是/否,成功/失败)
  • 多类: 超过两个类别
  • 多标签: 每个观察结果有多个类别

常用算法

  • 逻辑回归: 线性分类
  • 决策树: 基于规则的非线性
  • 随机森林: 决策树集成
  • 梯度提升: 顺序树构建
  • SVM: 支持向量机
  • 朴素贝叶斯: 概率分类器

关键指标

  • 准确率: 正确的总体预测
  • 精确度: 真正例 / (真正例 + 假正例)
  • 召回率: 真正例 / (真正例 + 假负例)
  • F1-Score: 精确度/召回率的调和平均数
  • AUC-ROC: 接收者操作特征曲线下的面积

Python实现

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.metrics import (
    confusion_matrix, classification_report, roc_auc_score, roc_curve,
    precision_recall_curve, f1_score, accuracy_score
)
import seaborn as sns

# 生成样本二元分类数据
np.random.seed(42)
from sklearn.datasets import make_classification

X, y = make_classification(
    n_samples=1000, n_features=20, n_informative=10,
    n_redundant=5, random_state=42
)

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 逻辑回归
lr_model = LogisticRegression(max_iter=1000)
lr_model.fit(X_train_scaled, y_train)
y_pred_lr = lr_model.predict(X_test_scaled)
y_proba_lr = lr_model.predict_proba(X_test_scaled)[:, 1]

print("逻辑回归:")
print(classification_report(y_test, y_pred_lr))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_lr):.4f}
")

# 决策树
dt_model = DecisionTreeClassifier(max_depth=10, random_state=42)
dt_model.fit(X_train, y_train)
y_pred_dt = dt_model.predict(X_test)
y_proba_dt = dt_model.predict_proba(X_test)[:, 1]

print("决策树:")
print(classification_report(y_test, y_pred_dt))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_dt):.4f}
")

# 随机森林
rf_model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
rf_model.fit(X_train, y_train)
y_pred_rf = rf_model.predict(X_test)
y_proba_rf = rf_model.predict_proba(X_test)[:, 1]

print("随机森林:")
print(classification_report(y_test, y_pred_rf))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_rf):.4f}
")

# 梯度提升
gb_model = GradientBoostingClassifier(n_estimators=100, max_depth=5, random_state=42)
gb_model.fit(X_train, y_train)
y_pred_gb = gb_model.predict(X_test)
y_proba_gb = gb_model.predict_proba(X_test)[:, 1]

print("梯度提升:")
print(classification_report(y_test, y_pred_gb))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_gb):.4f}
")

# 混淆矩阵
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

models = [
    (y_pred_lr, '逻辑回归'),
    (y_pred_dt, '决策树'),
    (y_pred_rf, '随机森林'),
    (y_pred_gb, '梯度提升'),
]

for idx, (y_pred, title) in enumerate(models):
    cm = confusion_matrix(y_test, y_pred)
    ax = axes[idx // 2, idx % 2]
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=ax)
    ax.set_title(title)
    ax.set_ylabel('真实标签')
    ax.set_xlabel('预测标签')

plt.tight_layout()
plt.show()

# ROC曲线
plt.figure(figsize=(10, 8))

probas = [
    (y_proba_lr, '逻辑回归'),
    (y_proba_dt, '决策树'),
    (y_proba_rf, '随机森林'),
    (y_proba_gb, '梯度提升'),
]

for y_proba, label in probas:
    fpr, tpr, _ = roc_curve(y_test, y_proba)
    auc = roc_auc_score(y_test, y_proba)
    plt.plot(fpr, tpr, label=f'{label} (AUC={auc:.4f})')

plt.plot([0, 1], [0, 1], 'k--', label='随机分类器')
plt.xlabel('假正例率')
plt.ylabel('真正例率')
plt.title('ROC曲线比较')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 精确度-召回率曲线
plt.figure(figsize=(10, 8))

for y_proba, label in probas:
    precision, recall, _ = precision_recall_curve(y_test, y_proba)
    f1 = f1_score(y_test, (y_proba > 0.5).astype(int))
    plt.plot(recall, precision, label=f'{label} (F1={f1:.4f})')

plt.xlabel('召回率')
plt.ylabel('精确度')
plt.title('精确度-召回率曲线')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 特征重要性
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 基于树的特征重要性
feature_importance_rf = pd.Series(
    rf_model.feature_importances_, index=range(X.shape[1])
).sort_values(ascending=False)

axes[0].barh(range(10), feature_importance_rf.values[:10])
axes[0].set_yticks(range(10))
axes[0].set_yticklabels([f'特征 {i}' for i in feature_importance_rf.index[:10]])
axes[0].set_title('随机森林 - 前10个特征')
axes[0].set_xlabel('重要性')

# 逻辑回归系数
lr_coef = pd.Series(lr_model.coef_[0], index=range(X.shape[1])).abs().sort_values(ascending=False)
axes[1].barh(range(10), lr_coef.values[:10])
axes[1].set_yticks(range(10))
axes[1].set_yticklabels([f'特征 {i}' for i in lr_coef.index[:10]])
axes[1].set_title('逻辑回归 - 前10个特征(绝对系数值)')
axes[1].set_xlabel('绝对系数')

plt.tight_layout()
plt.show()

# 模型比较
results = pd.DataFrame({
    '模型': ['逻辑回归', '决策树', '随机森林', '梯度提升'],
    '准确率': [
        accuracy_score(y_test, y_pred_lr),
        accuracy_score(y_test, y_pred_dt),
        accuracy_score(y_test, y_pred_rf),
        accuracy_score(y_test, y_pred_gb),
    ],
    'AUC-ROC': [
        roc_auc_score(y_test, y_proba_lr),
        roc_auc_score(y_test, y_proba_dt),
        roc_auc_score(y_test, y_proba_rf),
        roc_auc_score(y_test, y_proba_gb),
    ],
    'F1-Score': [
        f1_score(y_test, y_pred_lr),
        f1_score(y_test, y_pred_dt),
        f1_score(y_test, y_pred_rf),
        f1_score(y_test, y_pred_gb),
    ]
})

print("模型比较:")
print(results)

# 交叉验证
cv_scores = cross_val_score(
    RandomForestClassifier(n_estimators=100, random_state=42),
    X_train, y_train, cv=5, scoring='roc_auc'
)
print(f"
交叉验证AUC分数: {cv_scores}")
print(f"平均CV AUC: {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")

# 概率校准
from sklearn.calibration import calibration_curve

prob_true, prob_pred = calibration_curve(y_test, y_proba_rf, n_bins=10)

plt.figure(figsize=(8, 6))
plt.plot(prob_pred, prob_true, 'o-', label='随机森林')
plt.plot([0, 1], [0, 1], 'k--', label='完美校准')
plt.xlabel('平均预测概率')
plt.ylabel('正例比例')
plt.title('校准曲线')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

类不平衡处理

  • 过采样: 增加少数类样本
  • 欠采样: 减少多数类样本
  • SMOTE: 合成少数过采样
  • 类别权重: 对错误分类少数类进行惩罚

阈值选择

  • 默认 (0.5): 等同误分类成本
  • 自定义阈值: 基于业务需求
  • 最优: 最大化F1分数或AUC

交付物

  • 分类指标(准确率、精确度、召回率、F1)
  • 所有模型的混淆矩阵
  • ROC和精确度-召回率曲线
  • 特征重要性分析
  • 模型比较表
  • 最佳模型推荐
  • 概率校准图