sklearn-逻辑回归-概述

sklearn-逻辑回归-概述

逻辑回归的本质

是一个返回对数几率的,在线新数据上表现优异的分类器,主要被应用在金融领域。其数据目的是求解能够让模型对数据拟合程度最高的参数θ的值,以此构建预测函数y(x),然后将特征矩阵输入预测函数来计算出逻辑回归的结果y

虽然逻辑回归通常被用于处理二分类问题,但逻辑回归也可以做多分类。

为什么要用逻辑回归

逻辑回归对线性关系的拟合效果非常好

特征与标签之间的线性关系极强的数据,比如金融领域中的信用卡欺诈、评分卡制作;电商中的营销预测等等相关的数据,都是逻辑回归的强项。虽然现在有了梯度提升树GDBT,比逻辑回顾效果更好,也被许多数据咨询公司启用,但逻辑回归的金融领域,尤其在银行业中的统治地位不可动摇,毕竟银行业在上个世纪就已经使用逻辑回归这种统计方法了。

相对的,逻辑回归在非线性数据的效果很多时候比瞎猜还不如,所以如果已知数据之间的联系是非线性的,千万不要迷信逻辑回归

逻辑回归计算更快

对于线性数据,逻辑回归的拟合和计算都非常快,计算效率优于SVM和随机森林,在大型数据上尤其能够看得出区别

逻辑回归返回的分类结果是以小数形式呈现的类概率数字

逻辑回归返回的分类结果不是固定的0和1,而是以小数形式呈现的类概率数字,可以把逻辑回归返回的结果当成连续型数据来利用。比如在评分卡制作时,我们不仅需要判断客户是否会违约,还需要给出确定的“信用分”,这个信用分的计算就需要使用类概率计算出的对数几率,而决策树和随机森林这样的分类器,可以产出分类结果,却无法帮助我们计算分数

抗噪能力强

福布斯杂志在讨论逻辑回归的优点时,甚至有着“技术上来说,最佳模型的AUC面积低于0.8时,逻辑回归非常明显优于树模型”的说法,并且,逻辑回归在小数据集上表现更好,在大型的数据集上,树模型有着更好的表现。

逻辑回归相关的类

逻辑回归相关的类说明
linear_model.LogisticRegression逻辑回归分类器,又叫最大熵分类器
linear_model.LogisticRegressionCV带交叉验证的逻辑回归分类器
linear_model.logistic_regression_path是用来计算 Logistic 回归模型以获得正则化参数的列表,不是用来做回归的
linear_model.SGDClassifier利用梯度下降求解的线性分类器(SVM,逻辑回归等等)
linear_model.SGDRegressor利用梯度下降最小化正则化后的损失函数的线性回归模型
metrics.log_loss对数损失,又称逻辑损失或交叉熵损失,是逻辑回归专用的一种损失
在sklearn0.21版本被移除的类说明
linear_model.RandomizedLogisticRegression随机的逻辑回归
其他会涉及的类说明
metrics.confusion_matrix混淆矩阵,模型评估指标之一
metrics.roc_auc_scoreROC曲线,模型评估指标之一
metrics.accuracy_score精确性,模型评估指标之一

linear_model.LogisticRegression

class sklearn.linear_model.LogisticRegression(penalty='l2', dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='lbfgs', max_iter=100, multi_class='auto', verbose=0, warm_start=False, n_jobs=None, l1_ratio=None)

二元逻辑回归的损失函数

为什么用损失函数

建模是追求模型在测试集上的表现最优,因此模型的评估指标往往是用来衡量模型在测试集上的表现,但是逻辑回归有着基于训练数据求解参数θ的需求,并且希望训练出来的模型能够尽可能地拟合训练数据,即模型在训练集上的预测准确率越接近100%越好。
因此,使用“损失函数”这个评估指标,来衡量参数为θ的模型拟合训练集时产生的信息损失的大小,并以此衡量参数θ的优劣。
如果一组参数建模后,模型在训练集上表现良好,我们就说模型拟合过程中的损失很小,损失函数的值很小,拟合充分,这一组参数就优秀。相反,如果模型在训练集上表现糟糕,损失函数的值就会很大,模型就训练不足,效果很差。
即是说,我们在求解参数θ时,追求损失函数最小,让模型在训练数据上的拟合效果最优,即预测准确率尽量靠近100%。

没有“求解参数”需求的模型没有损失函数,比如KNN,决策树

重要参数 penalty & C
正则化

正则化是用来防止模型过拟合的过程。常用的有 L1 正则化和 L2 正则化两种选项,分别通过在损失函数后面加上参数向量 θ 的 L1 范式和 L2 范式的倍数来实现。这个增加的范式,被称为“正则项”,也被称为“惩罚项”。

损失函数的改变,基于损失函数的最优化来求解的参数取值必然会改变,以此来调节模型拟合的程度。其中 L1 范式表现为每个参数的绝对值之和, L2 范式表现为参数向量中的每个参数的平方和的开方值。公式如图1所示:

图1:
在这里插入图片描述

  • j(θ) 是损失函数
  • C 是用来控制正则化程度的超参数
  • n 是方程中特征的总数,也是方程中参数的总数
  • j 代表每个参数,j 要 >=1 , 是因为参数向量 θ 中,第一个参数时 θ0, 是截距,它通常不参与正则化
参数 penalty

可以输入"l1"或"l2"来指定使用哪一种正则化方式,默认 “l2”
若选择"l1"正则化,参数 solver 仅能够使用求解方式 “liblinear"和"saga”,若选择"l2"正则化,参数solver中所有的求解方式都可以使用

参数 C

C正则化强度的倒数,必须是一个大于0的浮点数,默认1.0,即默认正则项与损失函数的比值是 1:1

C越小,损失函数会越小,模型对损失函数的惩罚越重,正则化的效力越强,参数 θ 会逐渐被压缩的越来越小

乳腺癌数据集下看两种正则化的结果

L1 和 L2 正则化虽然都可以控制过拟合,但他们效果并不相同。当正则化强度逐渐增大(即C逐渐变小), 参数 θ 的取值会逐渐变小,但 L1 正则化会将参数压缩为0, L2正则化只会让参数尽量小,不会取到0,所以有说法称 L1 正则化掌控"稀疏性"(一个矩阵或者一个列表中,0的个数越多,就越稀疏),L2 正则化会比较稠密

在 L1 正则化在逐渐加强的过程中,携带信息量小的、对模型贡献不大的特征的参数,会比携带大量信息的、对模型有巨大贡献的特征的参数更快地变为0,所以 L1 正则化本质是一个特征选择的过程,掌管了参数的“稀疏性”。L1 正则化越强,参数向量中越多的参数为0,参数就越稀疏,选出来的特征就越少,以此来防止过拟合。因此,如果特征量很大,数据维度很高,我们会倾向使用L1正则化。由于 L1 正则化的这个性质,逻辑回归的特征选择可以由 Embedded 嵌入法来完成。

在 L2 正则化加强的过程中,会尽量让每个特征对模型都有一些小的贡献,所以携带信息少,对模型贡献不大的特征的参数会非常接近于0.

一般来说,如果我们的目的只是为了防止过拟合,选择 L2 正则化就够了,但如果选择了 L2 正则化后,模型在未知数据集上的效果表现很差,就可以考虑 L1 正则化。

两种正则化 C 的取值,都可以通过学习曲线来进行调整,代码如下所示:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression as LR
# load_breast_cancer 为乳腺癌数据集
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 将数据集实例化
data = load_breast_cancer()
X = data.data
y = data.target

# 查看数据集X的组成,结果如图2所示,为569行数据,30列特征
X.shape

# 建立两个逻辑回归的模型 lrl1 和 lrl2
lrl1 = LR(penalty="l1", solver="liblinear", C=0.5, max_iter=1000)
lrl2 = LR(penalty="l2", solver="liblinear", C=0.5, max_iter=1000)

# l1 正则化下训练模型
lrl1 = lrl1.fit(X, y)

# 逻辑回归的重要属性 coef_,查看每个特征所对应的参数,结果如图3所示
lrl1.coef_

# 查看参数不为 0 的特征个数,打印结果为10,对应图3不为0的个数
(lrl1.coef_ != 0).sum(axis=1)

# l2 正则化下训练模型
lrl2 = lrl2.fit(X, y)
# 查看参数不为 0 的特征个数,打印结果为30,对应数据集的列数30,可见 L2 正则化会让参数越来越小但不会为0
(lrl2.coef_ != 0).sum(axis=1)

# 因为逻辑回归有着要把训练的准确率提高到100%的目标,因此训练的数据也要保存下来,即l1,l1test
l1 = []
l2 = []
l1test = []
l2test = []

# 区分训练集和测试集,X为特征矩阵,y代表标签,test_size为测试集占比
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size = 0.3, random_state = 420)

# 画 C的学习曲线,看模型的效果是怎样的,让C的值在0.05到1之间遍历,随机取从小到大的19个数
for i in np.linspace(0.05, 2, 19):
    lrl1 = LR(penalty="l1", solver="liblinear", C=i, max_iter=1000)
    lrl2 = LR(penalty="l2", solver="liblinear", C=i, max_iter=1000)
    lrl1 = lrl1.fit(Xtrain, Ytrain)
    # lrl1.predic t(Xtrain)代表模型在训练过后,对于输入的特征矩阵的Xtrain的预测值y
    # accuracy_score 是精确性函数,计算准确率,看看训练后的模型预测和现实测差距到底是多少,第2个参数代表标签值y,即现实数据
    l1.append(accuracy_score(lrl1.predict(Xtrain), Ytrain))
    l1test.append(accuracy_score(lrl1.predict(Xtest), Ytest))
    
    lrl2 = lrl2.fit(Xtrain, Ytrain)
    l2.append(accuracy_score(lrl2.predict(Xtrain), Ytrain))
    l2test.append(accuracy_score(lrl2.predict(Xtest), Ytest))

graph = [l1, l2, l1test, l2test]
color = ["green", "black", "lightgreen", "gray"]
label = ["L1", "L2", "L1test", "L2test"]

# 创建画布
plt.figure(figsize=(6,6))
for i in range(len(graph)):
    plt.plot(np.linspace(0.05, 2, 19), graph[i], color[i], label=label[i])
# 图例的位置在哪里,0:最佳位置(有时会覆盖曲线),1:右上角 2:左上角 3:左下角 4:右下角
plt.legend(loc=4) 
# 打印画布,结果如 图4 所示
plt.show()

图2:
在这里插入图片描述
图3:
在这里插入图片描述
图4:
在这里插入图片描述

结论

在乳腺癌数据集下,两种正则化的区别不大,随着C的逐渐变大,正则化的强度越来越小,模型在训练集和测试集上的表现都呈上升趋势,直到 C = 0.8 左右,训练集上的表现依然在走高,但模型在未知数据集上的表现开始下跌,这时候就是出现了过拟合。我们可以认为,C设定为0.8或者0.9会比较好。在实际使用中,基本就默认使用 L2 正则化,如果感到 L2 正则化模型的效果不好,就换 L1 试试看。

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值