前言

逻辑回归就是解决二分类问题的利器

逻辑回归

逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法,虽然名字中带有回归,但是它与回归之间有一定的联系。由于算法的简单和高效,在实际中应用非常广泛。

逻辑回归的特点

1、通过公式计算,能够得出样本对应目标值的概率值
2、逻辑回归仍然会有过拟合问题;也有自己的权重值;也有自己的损失函数(ps:虽说与线性回归原理相同,但是由于是分类问题,损失函数不一样,所以其损失函数只能通过梯度下降求解)。
3、逻辑回归预测的概率为样本中占少数的类别的概率,此时此类别为正例。(这样是方便模型构建,如果预测为样本多数类别的概率,那么参与计算的数据就会更多)

逻辑回归的原理

想知道其原理,我们需要明白逻辑回归中的输入值是什么

输入

mark

逻辑回归的输入值其实是我们上文线性回归中的输出

激活函数

sigmoid函数

mark

  • 回归的结果输入到sigmoid函数当中
  • 输出结果:[0, 1]区间中的一个概率值,默认为0.5为阈值

mark

逻辑回归最终的分类是通过属于某个类别的概率值来判断是否属于某个类别,并且这个类别默认标记为1(正例),另外的一个类别会标记为0(反例)。(方便损失计算)

输出结果解释:假设有两个类别A,B,并且假设我们的概率值为属于A(1)这个类别的概率值。现在有一个样本的输入到逻辑回归输出结果0.6,那么这个概率值超过0.5,意味着我们训练或者预测的结果就是A(1)类别。那么反之,如果得出结果为0.3那么,训练或者预测结果就为B(0)类别。

我们之前的线性回归的预测结果的误差是用均方误差来衡量的

而对于逻辑回归的,我们是使用对数似然损失来衡量这个损失

我们可以通过这样一张图来体现逻辑回归的误差

mark

损失

逻辑回归的损失,称之为对数似然损失,公式如下:

  • 分开类别:

mark

我们可以通过log函数图像来理解这个公式

mark

完整的损失公式为

mark

我们将上图的数据带入数据就差不多可以理解这个意义了

mark

log§, P值越大,结果越小

优化

而我们优化也是使用梯度下降优化算法

去减少损失函数的值

这样去更新逻辑回归前面对应算法的权重参数

提升原本属于1类别的概率,降低原本是0类别的概率。

逻辑回归API介绍

sklearn.linear_model.LogisticRegression(solver=‘liblinear’, penalty=‘l2’, C = 1.0)

  • solver可选参数:{‘liblinear’, ‘sag’, ‘saga’,‘newton-cg’, ‘lbfgs’},
    • 默认: ‘liblinear’;用于优化问题的算法。
    • 对于小数据集来说,“liblinear”是个不错的选择,而“sag”和’saga’对于大型数据集会更快。
    • 对于多类问题,只有’newton-cg’, ‘sag’, 'saga’和’lbfgs’可以处理多项损失;“liblinear”仅限于“one-versus-rest”分类。
  • penalty:正则化的种类
  • C:正则化力度

LogisticRegression方法相当于 SGDClassifier(loss=“log”, penalty=" "),SGDClassifier实现了一个普通的随机梯度下降学习。而使用LogisticRegression(实现了SAG)

案例:癌症分类预测-良/恶性乳腺癌肿瘤预测

数据描述

(1)699条样本,共11列数据,第一列用语检索的id,后9列分别是与肿瘤

相关的医学特征,最后一列表示肿瘤类型的数值。

(2)包含16个缺失值,用”?”标出。

原始数据的下载地址:https://archive.ics.uci.edu/dataset/17/breast+cancer+wisconsin+diagnostic

我这里是下载了数据放在本地来运行

案例分析

  1. 获取数据

  2. 基本数据处理

    2.1缺失值处理

    2.2确定特征值,目标值

    2.3分割数据

  3. 特征工程(标准化)

  4. 机器学习(逻辑回归)

  5. 模型评估

代码示例:

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import pandas as pd
import numpy as np


names = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape',
'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin',
'Normal Nucleoli', 'Mitoses', 'Class']
data=pd.read_csv('./data/breast-cancer-wisconsin.data',names=names)

# 2.基本数据处理
# 2.1 缺失值处理
data = data.replace(to_replace="?", value=np.NaN)
data = data.dropna()
# 2.2 确定特征值,目标值
x = data.iloc[:, 1:10]
x.head()
y = data["Class"]
y.head()
# 2.3 分割数据
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)

# 3.特征工程(标准化)
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

# 4.机器学习(逻辑回归)
estimator = LogisticRegression()
estimator.fit(x_train, y_train)

# 5.模型评估
y_predict = estimator.predict(x_test)
y_predict
estimator.score(x_test, y_test)
print("准确率 \n",score)

运行结果:

准确率 
0.9854014598540146

但是在逻辑回归中,我们并不是重点关注预测的准确率

而是关注在所有的样本当中,癌症患者有没有被全部预测(检测)出来

分类评估方法

在说召回率和精确率还有准确率之前,我们需要了解一下混淆矩阵这个东西

在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)

大概是这样的

mark

  • 精确率:预测结果为正例样本中真实为正例的比例

mark

等于TP/(TP+FP)

  • 召回率:真实为正例的样本中预测结果为正例的比例

mark

等于 TP/(TP+FN)

  • 准确率:分对的样本数占所有的样本数的比例

    等于TP+TN)/(TP+TN+FN+FP)

  • F1-score:反映了模型的稳健型

    mark

这里只是大概写一下这些是什么,详细介绍可以看这篇博客:https://blog.csdn.net/qq_36653505/article/details/82709281

分类评估API

  • sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None )
    • y_true:真实目标值
    • y_pred:估计器预测目标值
    • labels:指定类别对应的数字
    • target_names:目标类别名称
    • return:每个类别精确率与召回率

我们可以在上文的案例中添加这个API看看效果

from sklearn.metrics import classification_report
......

ret=classification_report(y_test,y_pre)
print(ret)
ret=classification_report(y_test,y_pre,labels=(2,4),target_names=("良性","恶性"))
print(ret)

这个两个的运行结果如下

注:support指的是样本

第一个为:

`precision    recall  f1-score   support

2 0.99 0.99 0.99 89
4 0.98 0.98 0.98 48

accuracy 0.99 137
macro avg 0.98 0.98 0.98 137
weighted avg 0.99 0.99 0.99 137

第二个为:

  precision    recall  f1-score   support

良性 0.99 0.99 0.99 89
恶性 0.98 0.98 0.98 48

accuracy 0.99 137
macro avg 0.98 0.98 0.98 137
weighted avg 0.99 0.99 0.99 137

第二种显示的效果明显好与第一种

但是对于样本不均衡的评估我们就需要使用roc曲线和auc指标来评估了

ROC曲线与AUC指标

TPR与FPR

  • TPR = TP / (TP + FN)
    • 所有真实类别为1的样本中,预测类别为1的比例
  • FPR = FP / (FP + TN)
    • 所有真实类别为0的样本中,预测类别为1的比例

ROC曲线

  • ROC曲线的横轴就是FPRate,纵轴就是TPRate,当二者相等时,表示的意义则是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5

mark

AUC指标

  • AUC的概率意义是随机取一对正负样本,正样本得分大于负样本的概率
  • AUC的最小值为0.5,最大值为1,取值越高越好
  • AUC=1,完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。
  • 0.5<AUC<1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。

最终AUC的范围在[0.5, 1]之间,并且越接近1越好

AUC计算API

  • from sklearn.metrics import roc_auc_score
    • sklearn.metrics.roc_auc_score(y_true, y_score)
      • 计算ROC曲线面积,即AUC值
      • y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
      • y_score:预测得分,可以是正类的估计概率、置信值或者分类器方法的返回值

我们在之前案例代码中添加这个API的使用看看效果

from sklearn.metrics import roc_auc_score
......
y_test=np.where(y_test>3,1,0)
roc_score=roc_auc_score(y_test,y_pre)
print(roc_score)

因为y_true这个参数必须是0或者1,所以我们需要转化y_test中的值

在上面的案例中,如果y_test为2是良性,4为恶性

而我们的正例一般是取样本量少的为正例,所以在本个案例中,我们是取恶性为正例,所以在对于y_test进行0和1的转换时,大于3的转换为1,小于3的转换为0

运行结果为

0.9839653558052434

本文完