- 一、什么是逻辑回归?
- 二、逻辑回归简单理论
- 2.1 概念
- 2.2 Sigmoid 函数
- 2.3 Logistic 回归的类型
- 2.4 线性回归和逻辑回归区别
- 三、案例实现
- 3.1 数据集描述
- 3.2 模型建立
- 3.3 混淆矩阵评估理论
- 3.4 混淆矩阵评估
- 四、ROC曲线和AUC
- 4.1 ROC曲线
- 4.2 AUC
- 4.3 为什么使用ROC曲线?
- 4.4 案例实现
- 五、逻辑回归的优缺点
- 六、参考
分类技术是机器学习和数据挖掘应用的重要组成部分。数据科学中大约 70% 的问题是分类问题。有很多可用的分类问题,但逻辑回归很常见,是解决二元分类问题的有用回归方法。另一类分类是多项分类,它处理目标变量中存在多个类的问题。例如,IRIS 数据集是一个非常著名的多类分类示例。其他示例是分类文章/博客/文档类别。
逻辑回归可用于各种分类问题,例如垃圾邮件检测。糖尿病预测,如果给定的客户将购买特定产品或他们是否会搅动另一个竞争对手,用户是否会点击给定的广告链接,还有更多示例。
逻辑回归是用于二分类的最简单和最常用的机器学习算法之一。它易于实现,可用作任何二元分类问题的基线。它的基本基本概念在深度学习中也具有建设性。逻辑回归描述和估计一个因二元变量和自变量之间的关系。
性回归的位置如上图所示,它属于机器学习 – 监督学习 – 分类 – 逻辑回归。
逻辑回归(Logistic Regression)主要解决二分类问题,用来表示某件事情发生的可能性。
例如:
一封邮件是垃圾邮件的可能性(是、不是) 你购买一件商品的可能性(买、不买) 广告被点击的可能性(点、不点)
二、逻辑回归简单理论 2.1 概念逻辑回归是一种用于预测二元类的统计方法。结果或目标变量本质上是二分法的。二分法意味着只有两个可能的类别。例如,它可以用于癌症检测问题,是否有可能为癌症,它计算事件发生的概率。
我们先来看下线性回归方程:y=c+x1m1+x2m2+x3m3…+XnXn,其中,y 是因变量,x1、x2 … 和 Xn 是解释变量。
再来看一个Sigmoid函数: 对线性回归应用 Sigmoid 函数则为(对数几率函数是一个常用的替代函数):
简化一下:
于是有:
我们将 y 视为 x 为正例的概率,则 1-y 为 x 为其反例的概率。两者的比值称为几率(odds),指该事件发生与不发生的概率比值,若事件发生的概率为 p。则对数几率:
将 y 视为类后验概率估计,重写公式有:
也就是说,输出 Y=1 的对数几率是由输入 x 的线性函数表示的模型,这就是逻辑回归模型。当
的值越接近正无穷,
概率值也就越接近 1。因此逻辑回归的思路是,先拟合决策边界(不局限于线性,还可以是多项式),再建立这个边界与分类的概率联系,从而得到了二分类情况下的概率。
通过上述推导我们可以看到 Logistic 回归实际上是使用线性回归模型的预测值逼近分类任务真实标记的对数几率,其优点有:
- 直接对分类的概率建模,无需实现假设数据分布,从而避免了假设分布不准确带来的问题(区别于生成式模型);
- 不仅可预测出类别,还能得到该预测的概率,这对一些利用概率辅助决策的任务很有帮助
- 对数几率函数是任意阶可导的凸函数,有许多数值优化算法都可以求出最优解。
举一个癌症诊断的例子,根据肿瘤大小判断是否患有癌症。如下图所示,诊断结果只有两个。1:有癌症;0:没癌症。 如果用线性回归表示:
这么大的肿瘤,那必须是癌症啊,所以输出 y 还是 1。但是如果按照上面的线性回归方程带入x=2,y小于0.5,而得出结果不是癌症,这样的结果就不对了,因此这种情况就不能用线性回归。
sigmoid 函数,也称为逻辑函数,给出一个“S”形曲线,它可以取任何实数值并将其映射为 0 和 1 之间的值。如果曲线变为正无穷大,则预测的 y 将变为 1,如果曲线趋于负无穷大,预测的 y 将变为 0。如果 sigmoid 函数的输出大于 0.5,我们可以将结果分类为 1 或 YES,如果小于 0.5,我们可以将其分类为 0 或不。输出不能例如:如果输出为 0.75,我们可以用概率表示:患者患癌症的几率为 75%。
我们来绘制sigmoid函数: 代码如下:
import matplotlib.pyplot as plt
import numpy as np
def sigmoid(x):
# 直接返回sigmoid函数
return 1. / (1. + np.exp(-x))
def plot_sigmoid():
# param:起点,终点,间距
x = np.arange(-10, 10, 0.2)
y = sigmoid(x)
plt.plot(x, y)
plt.show()
if __name__ == '__main__':
plot_sigmoid()
绘制结果:
- 二元逻辑回归:目标变量只有两种可能的结果,例如垃圾邮件或非垃圾邮件、癌症或非癌症。
- 多项式逻辑回归:目标变量具有三个或更多的名义类别,例如预测葡萄酒的类型。
- 序数逻辑回归:目标变量具有三个或更多序数类别,例如从 1 到 5 的餐厅或产品评级。
最常见得为二元逻辑回归。
2.4 线性回归和逻辑回归区别线性回归为您提供连续输出,但逻辑回归提供恒定输出。连续输出的一个例子是房价和股票价格。离散输出的示例是预测患者是否患有癌症,预测客户是否会流失。线性回归使用普通最小二乘法 (OLS) 估计,而逻辑回归使用最大似然估计 (MLE) 方法估计。
根据上图可知,功能上区别:
- 线性回归主要功能是拟合数据。
- 逻辑回归主要功能是区分数据,找到决策边界。
代价函数区别(了解即可)
- 线性回归的代价函数常用平方误差函数。
- 逻辑回归的代价函数常用交叉熵。
参数优化的方法都是常用梯度下降。
三、案例实现 3.1 数据集描述该数据集最初来自美国国家糖尿病、消化和肾脏疾病研究所。数据集的目的是根据数据集中包含的某些诊断测量值,诊断性地预测患者是否患有糖尿病。从更大的数据库中选择这些实例受到了一些限制。特别是,这里的所有患者都是至少 21 岁的皮马印第安血统的女性。
数据集由几个医学预测变量和一个目标变量组成Outcome。预测变量包括患者的怀孕次数、BMI、胰岛素水平、年龄等。
第一步:导入数据
import pandas as pd
pima = pd.read_csv("diabetes.csv")
pima
如下:
第二步:选自变量和因变量
X = pima.drop('Outcome',axis=1)# 特征
y = pima.Outcome # 目标变量
X
如下:
第三步:拆分数据。让我们使用函数 train_test_split() 拆分数据集。需要传递 3 个参数 features、target 和 test_set size。此外,可以使用 random_state 随机选择记录。
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=100)
在这里,数据集以 75:25 的比例分为两部分。这意味着 75% 的数据将用于模型训练,25% 用于模型测。如图:
第四步: 创建模型,训练模型,使用模型预测。导入 Logistic 回归模块并使用 LogisticRegression() 函数创建一个 Logistic 回归分类器对象。然后,使用 fit() 在训练集上拟合你的模型,并使用 predict() 在测试集上执行预测。
# 导入模型
from sklearn.linear_model import LogisticRegression
# 初始化模型,使用默认参数
logreg = LogisticRegression()
# 用数据训练模型
logreg.fit(X_train,y_train)
# 使用模型预测
y_pred=logreg.predict(X_test)
y_pred
如下:
在此之前,先了解下混淆矩阵,用图形表示如下: 假定为1表示正类, 0表示负类,说明如下:
- True Positive(TP):真正类。样本的真实类别是正类,并且模型识别的结果也是正类。类别实际为1,被分为1
- False Negative(FN):假负类。样本的真实类别是正类,但是模型将其识别为负类。类别实际为1,被分为0。
- False Positive(FP):假正类。样本的真实类别是负类,但是模型将其识别为正类。类别实际为0,被分为1。
- True Negative(TN):真负类。样本的真实类别是负类,并且模型将其识别为负类。 类别实际为0,被分为0。
从混淆矩阵得到分类指标: Accuracy(精确率),Precision(正确率或者准确率),Recall(召回率),Specificity(特异性),Sensitivity(灵敏度)。
指标计算方法如下:
- 样例总数 = TP + FP + TN + FN
- 精确率(Accuracy):精确率是最常用的分类性能指标。可以用来表示模型的精度,即模型识别正确的个数/样本的总个数。一般情况下,模型的精度越高,说明模型的效果越好。计算:Accuracy = (TP+TN)/(TP+FN+FP+TN)
- 正确率或者准确率(Precision):又称为查准率,表示在模型识别为正类的样本中,真正为正类的样本所占的比例。一般情况下,查准率越高,说明模型的效果越好。计算:Precision = TP/(TP+FP)
- 召回率(Recall):又称为查全率,召回率表现出在实际正样本中,分类器能预测出多少。计算:Recall(召回率) = Sensitivity(敏感指标,True Positive Rate,TPR)= 查全率。表示的是,模型正确识别出为正类的样本的数量占总的正类样本数量的比值。一般情况下,Recall越高,说明有更多的正类样本被模型预测正确,模型的效果越好。计算:Recall = TP/(TP+FN)
- 一般来说,查准率高时,查全率旺旺偏低;二查全率高时,查准率往往偏低。
- F1_Score:它被定义为正确率和召回率的调和平均数。在 β=1 的情况,F1-Score的值是从0到1的,1是最好,0是最差。
- 灵敏度(Sensitivity) = TP/(TP+FN)。灵敏度和召回率是一模一样的,只是名字换了而已。
- FPR(False Positive Rate)= FP /(FP + TN),即负类数据被分为正类的比例
- TPR(True Positive Rate)= TP /(TP + FN),即正类数据被分为正类的比例
因此我们知道,计算Precision,Recall,Specificity等只是计算某一分类的特性,而Accuracy和F1-Score是判断分类模型总体的标准
精确率(Accuracy)和正确率(Precision)的区别:Accuracy,不管是哪个类别,只要预测正确,其数量都放在分子上,而分母是全部数据量,说明这个精确率是对全部数据的判断。而正确率在分类中对应的是某个类别,分子是预测该类别正确的数量,分母是预测为该类别的全部的数量。或者说,Accuracy是对分类器整体上的精确率的评价,Precision是分类器预测为某一个类别的精确的评价。
3.4 混淆矩阵评估第五步:使用混淆矩阵进行模型评估。
from sklearn import metrics
cnf_matrix = metrics.confusion_matrix(y_test, y_pred)
cnf_matrix
输出为:
array([[107, 20],
[ 29, 36]], dtype=int64)
在这里,可以看到数组对象形式的混淆矩阵。这个矩阵的维度是 2*2,因为这个模型是二分类的。您有两个类 0 和 1。对角线值表示准确的预测,而非对角线元素是不准确的预测。107和36是正确预测,20和29是错误预测。
第六步:使用热图可视化混淆矩阵
# 使用热图可视化混淆矩阵
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
class_names=[0,1] # 两个类
fig, ax = plt.subplots()
tick_marks = np.arange(len(class_names))
plt.xticks(tick_marks, class_names)
plt.yticks(tick_marks, class_names)
# 热力图
sns.heatmap(pd.DataFrame(cnf_matrix), annot=True, cmap="YlGnBu" ,fmt='g')
ax.xaxis.set_label_position("top")
plt.tight_layout()
plt.title('Confusion matrix', y=1.1)
plt.ylabel('Actual label')
plt.xlabel('Predicted label')
如图: 第七步(必须):用混淆矩阵评估指标。让我们使用模型评估指标(如准确率、精度和召回率)来评估模型。
print("Accuracy:",metrics.accuracy_score(y_test, y_pred))
print("Precision:",metrics.precision_score(y_test, y_pred))
print("Recall:",metrics.recall_score(y_test, y_pred))
如下:
Accuracy: 0.7447916666666666
Precision: 0.6428571428571429
Recall: 0.5538461538461539
说明:
- 你得到了74%的分类率,说明模型还可以啦,一般吧。
- 关于精确,即你的模型有多精确。在预测案例中,当你的逻辑回归模型预测患者将患糖尿病时,患者有 64% 的可能性。
- 召回率:如果测试集中有糖尿病患者,并且你的逻辑回归模型可以在 55% 的可能性内识别出它。
ROC曲线如下: 对于样本数据,我们使用分类器对其进行分类,分类器会给出每个数据为正例的概率,我们可以针对此来设定一个阈值,当某个sample被判断为正例的概率大于这个阈值时,认为该sample为正例,小于则为负例,然后通过计算我们就可以得到一个(TPR , FPR)对,即图像上的一个点,我们通过不断调整这个阈值,就得到若干个点,从而画出一条曲线。
我们可以看出,当这个阈值越大时,越多的样本被分为负例,而这些样本中其实也有正例的存在。这样一来,TPR下降(正例数据被分为负例了),FPR下降(负类数据更不会被分为正例,但是影响要比TPR小,所以斜率呈上升趋势)。阈值越小时,越多的样本被分为正例,而这些样本中可能包含是正例,却被分为负例的样本以及是负例却被分为正例的样本,这样一来TPR上升(更多的正例样本被分为正例),FPR上升(更多的负例样本被分为正例,影响更大,所以斜率呈下降趋势)。
4.2 AUCAUC,(Area Under Curve),被定义为ROC曲线下的面积,显然这个面积小于1,又因为ROC曲线一般都处于y=x这条直线的上方,所以AUC一般在0.5到1之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。
从AUC判断分类器(预测模型)优劣的标准:
- AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
- 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
- AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
- AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测(预测是对的,实际就去认为是对的)。
ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。下图是ROC曲线和Precision-Recall曲线的对比: 在上图中,(a)和©为ROC曲线,(b)和(d)为Precision-Recall曲线。(a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,©和(d)是将测试集中负样本的数量增加到原来的10倍后,分类器的结果。可以明显的看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。
第八步:还是评估,使用ROC曲线来评估。 特征 (ROC) 曲线是真阳性率与假阳性率的关系图。它显示了敏感性和特异性之间的权衡。
y_pred_proba = logreg.predict_proba(X_test)[::,1]
fpr, tpr, _ = metrics.roc_curve(y_test, y_pred_proba)
auc = metrics.roc_auc_score(y_test, y_pred_proba)
plt.plot(fpr,tpr,label="data 1, auc="+str(auc))
plt.legend(loc=4)
plt.show()
如图: 得到 AUC 得分为 0.77。AUC 分数 1 代表完美的分类器,0.5 代表毫无价值的分类器。
优点:
- 实现简单,广泛的应用于工业问题上;
- 分类时计算量非常小,速度很快,存储资源低;
- 便利的观测样本概率分数;
- 对逻辑回归而言,多重共线性并不是问题,它可以结合L2正则化来解
- 它不需要缩放功能。逻辑回归提供了观察的概率分数。
缺点:
- 当特征空间很大时,逻辑回归的性能不是很好;
- 容易欠拟合,一般准确度不太高
- 不能很好地处理大量多类特征或变量;
- 只能处理两分类问题(在此基础上衍生出来的softmax可以用于多分类),且必须线性可分;
- 对于非线性特征,需要进行转换
https://zhwhong.cn/2017/04/14/ROC-AUC-Precision-Recall-analysis/ https://www.plob.org/article/12476.html