《菜菜的机器学习 sklearn 课堂》逻辑回归,java 教程百度云最新版
虽然我们熟悉的逻辑回归通常被用于处理二分类问题,但逻辑回归也可以做多分类。
| 逻辑回归相关的类 | 说明 |
| --- | --- |
| linear_model.LogisticRegression | 逻辑回归分类器(又叫 logit 回归,最大熵分类器) |
| 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_score | ROC 曲线,模型评估指标之一 |
| 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='warn',
max_iter=100,
multi_class='warn',
verbose=0,
warm_start=False,
n_jobs=None
)
损失函数的概念与解惑
在学习决策树和随机森林时,我们曾经提到过两种模型表现:
在训练集上的表现
在测试集上的表现
我们建模是追求模型在测试集上的表现最优,因此模型的评估指标往往是用来衡量模型在测试集上的表现的。
然而,逻辑回归有着基于训练数据求解参数 θ \theta θ的需求,并且希望训练出来的模型能够尽可能地拟合训练数据,即模型在训练集上的预测准确率越靠近 100%越好。
因此,我们使用"损失函数"这个评估指标,来衡量参数为θ的模型拟合训练集时产生的信息损失的大小,并以此衡量参数θ的优劣。如果用一组参数建模后,
模型在训练集上表现良好
那我们就说模型拟合过程中的损失很小,损失函数的值很小,这一组参数就优秀
模型在训练集上表现糟糕
损失函数就会很大,模型就训练不足,效果较差,这一组参数也就比较差
即是说,我们在求解参数 θ \theta θ时,追求损失函数最小,让模型在训练数据上的拟合效果最优,即预测准确率尽量靠近 100%。
关键概念:损失函数
衡量参数 θ \theta θ的优劣的评估指标,用来求解最优参数的工具
损失函数小,模型在训练集上表现优异,拟合充分,参数优秀
损失函数大,模型在训练集上表现差劲,拟合不足,参数糟糕
我们追求:能够让损失函数最小化的参数组合
注意:没有"求解参数"需求的模型没有损失函数,比如 KNN,决策树
逻辑回归的损失函数是由极大似然估计推导出来的,具体结果可以写作:
J ( θ ) = ? ∑ i = 1 m ( y i ? l o g ( y θ ( x i ) ) + ( 1 ? y i ) ? l o g ( 1 ? y θ ( x i ) ) ) ) J(\theta) = - \sum _{i=1} ^m (y_i * log(y_\theta(x_i)) + (1-y_i) * log(1-y_\theta(x_i)))) J(θ)=?i=1∑m?(yi??log(yθ?(xi?))+(1?yi?)?log(1?yθ?(xi?))))
其中, θ \theta θ表示求解出来的一组参数,m 是样本的个数, y i y_i yi?是样本 i 上真实的标签, y θ ( x i ) y_\theta(x_i) yθ?(xi?)是样本 i 上,基于参数 θ \theta θ计算出来的逻辑回归返回值, x i x_i xi?是样本 i 各个特征的取值。我们的目标就是求解出使 J ( θ ) J(\theta) J(θ)最小的 θ \theta θ取值。
注意,在逻辑回归的本质函数 y(x)里,特征矩阵 x 是自变量,参数是 θ \theta θ。但在损失函数中,参数 θ \theta θ是损失函数的自变量,x 和 y 都是已知的特征矩阵和标签,相当于是损失函数的参数。不同的函数中,自变量和参数各有不同,因此大家需要在数学计算中,尤其是求导的时候避免混淆。
由于我们追求损失函数的最小值,让模型在训练集上表现最优,可能会引发另一个问题:如果模型在训练集上表示优秀,却在测试集上表现糟糕,模型就会过拟合。虽然逻辑回归和线性回归是天生欠拟合的模型,但我们还是需要控制过拟合的技术来帮助我们调整模型,对逻辑回归中过拟合的控制,通过正则化来实现。
正则化(L1、L2)
正则化是用来防止模型过拟合的过程,常用的有 L1 正则化和 L2 正则化两种选项,分别通过在损失函数后加上参数向量 θ \theta θ的 L1 范式和 L2 范式的倍数来实现,这个增加的范式,被称为"正则项",也被称为"惩罚项"。
损失函数改变,基于损失函数的最优化来求解的参数取值必然改变,我们以此来调节模型拟合的程度
L1 范式表现为参数向量中的每个参数的绝对值之和
J ( θ ) L 1 = C ? J ( θ ) + ∑ j = 1 n ∣ θ j ∣ ( j ≥ 1 ) J(\theta)_{L1} = C * J(\theta) + \sum_{j=1}^{n} |\theta_j | (j \ge 1) J(θ)L1?=C?J(θ)+j=1∑n?∣θj?∣(j≥1)
L2 范数表现为参数向量中的每个参数的平方和的开方值。
J ( θ ) L 2 = C ? J ( θ ) + ∑ j = 1 n ( θ j ) 2 ( j ≥ 1 ) J(\theta)_{L2} = C * J(\theta) + \sqrt{\sum_{j=1}^n(\theta_j)^2}(j \ge 1) J(θ)L2?=C?J(θ)+j=1∑n?(θj?)2 ?(j≥1)
J ( θ ) J(\theta) J(θ) - 损失函数
C - 用来控制正则化程度的超参数
n - 方程中特征的总数,也是方程中参数的总数
j - 每个参数
在这里 j 要大于等于 1,因为我们的参数向量 θ \theta θ中,第一个参数是 θ 0 \theta_0 θ0?是截距,它通常不参与正则化。
在许多书籍和博客中,大家可能也会见到如下的写法:
其实和我们上面的式子的本质是一模一样的。不过在大多数教材和博客中,常数项是乘以正则项,通过调控正则项来调节对模型的惩罚。而 sklearn 当中,常数项 C 是在损失函数的前面,通过调控损失函数本身的大小,来调节对模型的惩罚。
参数:
penalty
可以输入"l1"
或 "l2"
来指定使用哪一种正则化方式,不填写默认 "l2"
若选择"l1"
正则化,参数solver
仅能够使用求解方式"liblinear"
和"saga"
若使用"l2"
正则化,参数solver
中所有的求解方式都可以使用
C
C 是正则化强度的倒数,必须是一个大于 0 的浮点数,不填写默认 1.0,即默认正则项与损失函数的比值是 1:1。C 越小,损失函数会越小,模型对损失函数的惩罚越重,正则化的效力越强,参数会逐渐被压缩得越来越小。
L1 正则化和 L2 正则化虽然都可以控制过拟合,但它们的效果并不相同。当正则化强度逐渐增大(即 C 逐渐变小),参数 θ \theta θ的取值会逐渐变小:
L1 正则化会将参数压缩为 0
L2 正则化只会让参数尽量小,不会取到 0
在 L1 正则化在逐渐加强的过程中,携带信息量小的
、对模型贡献不大的特征的参数,会比携带大量信息的、对模型有巨大贡献的特征的参数更快地变成 0,所以 L1 正则化本质是一个特征选择的过程,掌管了参数的“稀疏性”。L1 正则化越强,参数向量中就越多的参数为 0,参数就越稀疏,选出来的特征就越少,以此来防止过拟合。因此,如果特征量很大,数据维度很高,我们会倾向于使用 L1 正则化。由于 L1 正则化的这个性质,逻辑回归的特征选择可以由 Embedded 嵌入法来完成。
相对的,L2 正则化在加强的过程中,会尽量让每个特征对模型都有一些小的贡献,但携带信息少,对模型贡献不大的特征的参数会非常接近于 0。通常来说,如果我们的主要目的只是为了防止过拟合,选择 L2 正则化就足够了。但是如果选择 L2 正则化后还是过拟合,模型在未知数据集上的效果表现很差,就可以考虑 L1 正则化。
两种正则化下 C 的取值,都可以通过学习曲线来进行调整。
建立两个逻辑回归,L1 正则化和 L2 正则化的差别就一目了然了:
导库
from sklearn.linear_model import LogisticRegression as LR
from sklearn.datasets import load_breast_cancer # 乳腺癌数据
import numpy as np # 画图
import matplotlib.pyplot as plt # 画图
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
data = load_breast_cancer() # 读取乳腺癌数据
X = data.data
y = data.target
data.data.shape #569 个样本,30 个特征
lrl1 = LR(penalty="l1",solver="liblinear",C=0.5,max_iter=1000) #l1 范式正则化
lrl2 = LR(penalty="l2",solver="liblinear",C=0.5,max_iter=1000) #l2 范式正则化
#逻辑回归的重要属性 coef_(θ),查看每个特征所对应的参数
lrl1 = lrl1.fit(X,y)
lrl1.coef_ # l1 正则化会让参数为 0
(lrl1.coef_ != 0).sum(axis=1)
lrl2 = lrl2.fit(X,y)
lrl2.coef_ # l2 正则化不会让参数为 0
可以看见,当我们选择 L1 正则化的时候,许多特征的参数都被设置为了 0,这些特征在真正建模的时候,就不会出现在我们的模型当中了,而 L2 正则化则是对所有的特征都给出了参数。
究竟哪个正则化的效果更好呢?还是都差不多?
np.linspace(0.05, 1, 19) #从 0.05 开始到 1,取出 19 个数字
l1 = []
l2 = []
l1test = []
l2test = []
30%数据用于测试,70%用于训练,420 是随便输的数
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)
画图
for i in np.linspace(0.05,1,19):
lrl1 = LR(penalty="l1",solver="liblinear",C=i,max_iter=1000) # l1 正则化
lrl2 = LR(penalty="l2",solver="liblinear",C=i,max_iter=1000) # l2 正则化
lrl1 = lrl1.fit(Xtrain,Ytrain)
l1.append(accuracy_score(lrl1.predict(Xtrain),Ytrain))
l1test.append(accuracy_score(lrl1.predict(Xtest),Ytest)) # lrl1.score(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,1,19),graph[i],color[i],label=label[i])
plt.legend(loc=4) #标签名的位置在哪里? 4 表示:右下角
plt.show()
可见,至少在我们的乳腺癌数据集下,两种正则化的结果区别不大。但随着 C 的逐渐变大,正则化的强度越来越小,模型在训练集和测试集上的表现都呈上升趋势,直到 C=0.8 左右,训练集上的表现依然在走高,但模型在未知数据集上的表现开始下跌,这时候就是出现了过拟合。我们可以认为,C 设定为 0.8 会比较好。
实际使用时,基本就默认使用 l2 正则化,如果感觉到模型的效果不好,那就换 L1 试试看。
=====================================================================
评论