机器学习47:逻辑回归--进阶篇

摘要

本文深入介绍了二分类模型的评估方法与逻辑回归的进阶应用。文章首先讲解了混淆矩阵、精确率、召回率、F1-score等评估指标,并通过代码示例对比了不同模型的性能差异。随后阐述了ROC曲线与AUC指标的原理及其在类别不平衡场景下的优势。最后通过电信客户流失案例,展示了从数据预处理(独热编码)、可视化分析到模型训练与评估的完整流程。

Abstract

This article delves into evaluation methods for binary classification models and advanced applications of logistic regression. It first explains evaluation metrics including confusion matrix, precision, recall, and F1-score, comparing different models through code examples. It then describes the principles of ROC curves and AUC, along with their advantages in imbalanced classification scenarios. Finally, it demonstrates a complete workflow from data preprocessing (one-hot encoding) and visualization analysis to model training and evaluation through a telecom customer churn case.

一.分类问题评估

接上篇内容,最后提到只靠预测准确率是不能够满足各种场景需求的。所以下面开始对深入讲解混淆矩阵、精确率、召回率、F1-score等评估指标进行了解。

1.混淆矩阵

混淆矩阵中四个值分别是:TP(真正例)------实际为正例且预测为正例;TN(真负例)------实际为负例且预测为负例;FP(假正例)------实际为负例但预测为正例(误报);FN(假负例)------实际为正例但预测为负例(漏报)。其中TP和TN表示预测正确,FP和FN表示预测错误。混淆矩阵具体如下表:

2.精确率(Precision)

精确率是指在所有被模型预测为正例的样本中,实际为正例的比例,计算公式为 TP / (TP + FP)。它衡量的是模型"预测为正例的结果"有多准,关注的是不误报。例如在垃圾邮件检测中,高精确率意味着被判定为垃圾邮件的邮件里,真正是垃圾邮件的占比很高,正常邮件被误判的情况很少。

例如有10个样本,有6个垃圾邮件,4个正常邮件,这里以垃圾邮件为正例(则可知TP:6, FN:0,FP:3,TN=1)。在模型A中如果预测对了6个垃圾邮件,1个正常邮件,则模型A精确率则为6/(6+3)=66.7%。

3.召回率(Recall)

召回率是指在所有实际为正例的样本中,被模型正确预测为正例的比例,计算公式为 TP / (TP + FN)。它衡量的是模型"找出正例"的能力有多强,关注的是不漏报。例如在癌症筛查中,高召回率意味着绝大多数真正的癌症患者都被模型识别出来了,漏诊(把病人误判为健康)的情况很少,即使可能伴随一些误报(把健康人误判为病人)。

同样的以精确率中的邮件为例,则模型A召回率为6/(6+0)=100%。

4.F1-score

F1-score是精确率和召回率的调和平均数,计算公式为 2 × (精确率 × 召回率) / (精确率 + 召回率)。它综合了精确率和召回率两者的表现,当这两个指标需要同时兼顾时(比如在类别不平衡的数据集中,单一指标容易失真),F1-score能提供一个更平衡、更全面的评价。它的取值范围在0到1之间,值越高说明模型越稳健,既不容易漏报(高召回率),也不容易误报(高精确率)。

则以以精确率中的邮件为例,则模型A的F1-score为2*0.667*1/(0.667+1)=80%。

5.代码实现

下面是对于上述四个属性进行简单的代码实现:

python 复制代码
# 需求:已知有10个样本,6个垃圾邮件(正例),4个正常邮件
# 模型A预测结果为:预测对了3个垃圾邮件,预测对了4个正常邮件
# 模型B预测结果为:预测对了6个垃圾邮件,预测对了1个正常邮件
# 根据上述数据,搭建 混淆矩阵,并分别计算模型A和模型B的准确率、召回率、F1值

# 导包
import pandas as pd
from sklearn.metrics import confusion_matrix,precision_score,recall_score,f1_score   # 混淆矩阵,精确率,召回率,F1值

# 1定义变量,记录样本数据
y_train = ['垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '正常', '正常', '正常', '正常']

# 2.定义变量,记录模型A的预测结果
y_pre_a = ['垃圾', '垃圾', '垃圾', '正常', '正常', '正常', '正常', '正常', '正常', '正常']

# 3.定义变量,记录模型B的预测结果
y_pre_b = ['垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '垃圾', '正常']

# 4.用标签标记 正例,反例
label = ['垃圾', '正常']
df_label = ['垃圾(正例)', '正常(反例)']
# 5.对于真实值y_train,和模型A的预测结果y_pre_a,进行混淆矩阵
cm_a = confusion_matrix(y_train, y_pre_a, labels=label)

# 6.将上述结果转成Dataframe
df_A = pd.DataFrame(cm_a, index=df_label, columns=df_label)
print(f'混淆矩阵A:\n{df_A}')

# 7.对于真实值y_train,和模型B的预测结果y_pre_b,进行混淆矩阵
cm_b = confusion_matrix(y_train, y_pre_b, labels=label)

# 8.将上述结果转成Dataframe
df_B = pd.DataFrame(cm_b, index=df_label, columns=df_label)
print(f'混淆矩阵B:\n{df_B}')

# 9.计算模型A的准确率、召回率、F1值
print(f'模型A的准确率:{precision_score(y_train, y_pre_a, pos_label="垃圾")}')     # 参数1:真实值,参数2:预测结果,参数3:正例标签
print(f'模型A的召回率:{recall_score(y_train, y_pre_a, pos_label="垃圾")}')
print(f'模型A的F1值:{f1_score(y_train, y_pre_a, pos_label="垃圾")}')

# 10.计算模型B的准确率、召回率、F1值
print(f'模型B的准确率:{precision_score(y_train, y_pre_b, pos_label="垃圾")}')
print(f'模型B的召回率:{recall_score(y_train, y_pre_b, pos_label="垃圾")}')
print(f'模型B的F1值:{f1_score(y_train, y_pre_b, pos_label="垃圾")}')

得到的结果如下:

混淆矩阵A:

垃圾(正例) 正常(反例)

垃圾(正例) 3 3

正常(反例) 0 4

混淆矩阵B:

垃圾(正例) 正常(反例)

垃圾(正例) 6 0

正常(反例) 3 1

模型A的准确率:1.0

模型A的召回率:0.5

模型A的F1值:0.6666666666666666

模型B的准确率:0.6666666666666666

模型B的召回率:1.0

模型B的F1值:0.8

二.ROC曲线与AUC指标

在了解前,首先看上图中的x,y坐标,其中TPR(真正率)是指正样本中被预测为正样本的概率,FPR(假正率)是指负样本中被预测为正样本的概率。

1.ROC曲线(Receiver Operating Characteristic Curve)

ROC曲线是评估二分类模型性能的重要工具。它以假正率FPR为横轴,真正率TPR为纵轴,通过绘制不同分类阈值下模型的表现,直观反映模型的分类能力。

2. 曲线下面积(AUC,Area Under the Curve)

AUC是指ROC曲线下的面积,它量化了二分类模型将正样本排在负样本前面的能力。AUC的取值范围在0.5到1之间:0.5表示模型完全没有区分能力(等同于随机猜测),1.0表示模型能完美区分所有正负样本。通常情况下,AUC值越大,模型的分类性能越好。与传统准确率不同,AUC对类别不平衡不敏感,因此当数据集中正负样本数量差异较大时,AUC是比准确率更可靠的评估指标。

三.电信客户流失案例

案例需求:

已知:用户个人,通话,上网等信息。

需求:通过分析特征属性确定客户流失原因,以及哪些因素可能导致用户流失。建立预测模型来判断用户是否流失,并提出用户流失预警策略。

首先是进行导包:

python 复制代码
# 导包
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# 混杂度矩阵,准确度,精确度,召回率,F1值,分类报告
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score,classification_report

其次是对于数据进行导入并经行预处理:

python 复制代码
def data_preprocess():
   # 读取数据集
   churn_df = pd.read_csv('./data/churn.csv')
   # 将Churn和gender的数据类型转换成数值型
   # 用到独热编码
   churn_df = pd.get_dummies(churn_df, columns=['Churn', 'gender'])
   churn_df.drop(['Churn_No', 'gender_Male'], axis=1, inplace=True)  # 也可在创建独热编码时括号中添加drop_first=True
   # 修改数据列名
   churn_df.rename(columns={'Churn_Yes': 'flag'}, inplace=True)
   # churn_df.info()
   return churn_df

得到结果如下:

再对于这个数据进行可视化:

python 复制代码
def data_visualize():
   # 获取处理后的数据集
   churn_df = data_preprocess()
   # 绘制数据可视化
   # 参1:数据集,参2:x轴数据(月度会员),参数3:分组数据
   sns.countplot(data=churn_df, x='Contract_Month', hue='flag')
   plt.show()

结果如下:

最后经行模型训练:

python 复制代码
def logistic_regression():
   # 获取处理后的数据集
   churn_df = data_preprocess()
   # 提取特征和标签
   # x的特征列:月度会员,其他网络,电子支付
   x = churn_df[['Contract_Month','internet_other','PaymentElectronic']]
   y = churn_df['flag']    # False-不流失 True-流失
   # 划分训练集和测试集
   x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
   # 特征工程
   # 模型训练
   # 创建模型
   estimator = LogisticRegression()
   # 训练
   estimator.fit(x_train, y_train)
   # 模型预测
   y_pre = estimator.predict(x_test)
   print(f'预测值:{y_pre}')
   # 模型评估
   print(f'准确度:{estimator.score(x_test, y_test)}')  # 预测前
   print(f'准确度:{accuracy_score(y_test, y_pre)}')  # 预测后
   print(f'精确度:{precision_score(y_test, y_pre)}')
   print(f'召回率:{recall_score(y_test, y_pre)}')
   print(f'F1值:{f1_score(y_test, y_pre)}')
   # 分类报告
   # macro avg:宏平均,即不考虑样本权重,直接计算所有类别的准确度,然后求平均,适用于数据均衡的情况
   # weighted avg:加权平均,即考虑样本权重,将所有类别的准确度乘以样本权重,然后求平均,适用于数据不平衡的情况
   print(f'分类报告:{classification_report(y_test, y_pre)}')

得到结果如下:

预测值:False False False ... False False False

准确度:0.7693399574166075

准确度:0.7693399574166075

精确度:0.5892116182572614

召回率:0.3858695652173913

F1值:0.4663382594417077

|--------------|-----------|--------|----------|---------|
| 分类报告 | precision | recall | f1-score | support |
| False | 0.81 | 0.90 | 0.85 | 1041 |
| True | 0.59 | 0.39 | 0.47 | 368 |
| accuracy | | | 0.77 | 1409 |
| macro avg | 0.70 | 0.65 | 0.66 | 1409 |
| weighted avg | 0.75 | 0.77 | 0.75 | 1409 |

总结

本文系统讲解了二分类模型的评估体系与逻辑回归的实践应用。混淆矩阵提供了TP、TN、FP、FN四个基础维度;精确率关注"预测为正例中有多少是对的",召回率关注"真实正例中有多少被找出",F1-score则综合平衡两者。ROC曲线与AUC指标对类别不平衡不敏感,是比准确率更可靠的评估工具。通过电信客户流失案例,演示了独热编码处理类别特征、特征筛选、模型训练及分类报告输出的完整流程,为处理实际二分类问题提供了实践参考。