SS00015.algorithm——|Arithmetic&Machine.v15|——|Machine:监督学习算法.v13|

本文介绍了如何使用Scikit-Learn库在Python中实现逻辑回归,这是监督学习算法的一种,广泛应用于机器学习和人工智能领域。
摘要由CSDN通过智能技术生成
一、逻辑回归的Scikit-Learn实现
### --- 逻辑回归的Scikit-Learn实现

~~~     # 参数详解
class sklearn.linear_model.LogisticRegression (penalty=’l2’, dual=False, tol=0.0001,
C=1.0,fifit_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)
~~~     # 正则化参数:penalty
~~~     LogisticRegression默认就带了正则化项。
~~~     penalty参数可选择的值为"1"和"2",分别对应L1的正则化和L2的正则化,默认是L2的正则化。

~~~     在调参时如果我们主要的目的只是为了解决过拟合,一般penalty选择L2正则化就够了。
~~~     但是如果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化。
~~~     另外,如果模型的特征非常多,我们希望一些不重要的特征系数归零,
~~~     从而让模型系数稀疏化的话,也可以使用L1正则化。
~~~     penalty参数的选择会影响我们损失函数优化算法的选择。
~~~     即参数solver的选择,如果是L2正则化,
~~~     那么4种可选的算法 ('newton-cg','Ibfgs','liblinear','sag'} 都可以选择。
~~~     但是如果penalty是L1正则化的话,就只能选择 ‘liblinear'了。
~~~     这是因为L1正则化的损失函数不是连续可导的,而 {‘newton-cg’,'Ibfgs,'sag'}
~~~     这三种优化算法时都需要损失函数的一阶或者二阶连续导数。而 ’liblinear' 并没有这个依赖。

~~~     而两种正则化下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.shape
lrl1 = LR(penalty="l1",solver="liblinear",C=0.5,max_iter=1000)
#逻辑回归的重要属性coef_,查看每个特征所对应的参数
lrl2 = LR(penalty="l2",solver="liblinear",C=0.5,max_iter=1000)
lrl1 = lrl1.fit(X,y)
lrl1.coef_
(lrl1.coef_ != 0).sum(axis=1)
lrl2 = lrl2.fit(X,y)
lrl2.coef_
~~~     可以看见,当我们选择L1正则化的时候,许多特征的参数都被设置为了0,
~~~     这些特征在真正建模的时候,就不会出现在我们的模型当中了,
~~~     而L2正则化则是对所有的特征都给出了参数。
~~~     究竟哪个正则化的效果更好呢?还是都差不多?

l1 = []
l2 = []
l1test = []
l2test = []
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)
lrl2 = LR(penalty="l2",solver="liblinear",C=i,max_iter=1000)
lrl1 = lrl1.fit(Xtrain,Ytrain)
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,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试试看。
### --- 算法优化参数:solver

~~~     # solver参数决定了我们对逻辑回归损失函数的优化方法,有4种算法可以选择,分别是∶
~~~     liblinear∶使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
~~~     Ibfgs∶拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
~~~     newton-cg∶也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
~~~     sag∶即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅用一部分的样本来计算梯度,适合于样本数据多的时候。
~~~     从上面面的描述可以看出,newton-cg,
~~~     Ibfgs和sag这三种优化算法时都需要损失函数的一阶或者二阶连续导数,
~~~     因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
~~~     同时,sag每次仅使用了部分样本进行梯度迭代,所以当样本量少的时候不要选择它,
~~~     而如果样本量非常大,比如大于10万,sag是第一选择。
~~~     但是sag不能用于L1正则化,所以当你有大量的样本,又需要L1正则化的话就要自己做取舍了。
~~~     要么通过对样本采样来降低样本量量,要么回到L2正则化。

~~~     从上面的描述,大家可能觉得,既然newton-cg,Ibfgs和sag这么多限制,
~~~     如果不是大样本,我们选择liblinear不就行了吗?因为liblinear也有自己的弱点!
~~~     我们知道,逻辑回归有二元逻辑回归和多元逻辑回归。
~~~     对于多元逻辑回归常见的有one-vs-rest(OvR)和many-vs-many(MvM)两种,
~~~     而MvM一般比OvR分类相对准确一些。liblinear只支持OVR,不支持MVM,
~~~     这样如果我们需要相对精确的多元逻辑回归时就不的先择liblinear了。
~~~     也意味着如果我们需要相对精确的多元逻辑回归不能位用L1正则化了。
### --- 梯度下降:重要参数max_iter

~~~     逻辑回归的数学目的是求解能够让模型最优化,拟合程度最好的参数W的值,
~~~     即求解能够让损失函数J(w)最小化的W值。
~~~     对于二元逻辑回归来说,有多种方法可以用来求解参数W,
~~~     最常见的有梯度下降法(Gradient Descent),坐标下降法(Coordinate Descent),
~~~     牛顿法(Newton-Raphson method)等,其中又以梯度下降法最为著名。
~~~     每种方法都涉及复杂的数学原理,但这些计算在执行的任务其实是类似的。
~~~     来看看乳腺癌数据集下,max_iter的学习曲线∶
l2 = []
l2test = []
Xtrain, Xtest, Ytrain, Ytest =
train_test_split(X,y,test_size=0.3,random_state=420)
for i in np.arange(1,201,10):
lrl2 = LR(penalty="l2",solver="liblinear",C=0.9,max_iter=i)
lrl2 = lrl2.fit(Xtrain,Ytrain)
l2.append(accuracy_score(lrl2.predict(Xtrain),Ytrain))
l2test.append(accuracy_score(lrl2.predict(Xtest),Ytest))
graph = [l2,l2test]
color = ["black","gray"]
label = ["L2","L2test"]
plt.figure(figsize=(20,5))
for i in range(len(graph)):
plt.plot(np.arange(1,201,10),graph[i],color[i],label=label[i])
plt.legend(loc=4)
plt.xticks(np.arange(1,201,10))
plt.show()
#我们可以使⽤属性.n_iter_来调⽤本次求解中真正实现的迭代次数
lr = LR(penalty="l2",solver="liblinear",C=0.9,max_iter=300).fit(Xtrain,Ytrain)
lr.n_iter_
~~~     当max_iter中限制的步数已经走完了,逻辑回归却还没有找到损失函数的最小值,
~~~     参数w的值还没有被收敛,sklearn就会弹出下面的红色警告
~~~     当参数solver="liblinear"∶
~~~     当参数solver="sag"∶
~~~     虽然写法看起来略有不同,但其实都是一个含义,
~~~     这是在提醒我们:参数没有收敛,请增大max_iter中输入的数字。
~~~     但我们不一定要听sklearn的。max_iter很大,意味着步长小,模型运行得会更加缓慢。然
~~~     我们在梯度下降中追求的是损失函数的最小值,
~~~     但这也可能意味着我们的模型会过拟合(在训练集上表现得太好,在测试集上却不一定),
~~~     因此,如果在max iter报红条的情况下,
~~~     模型的训练和预测效果都已经不错了,那我们就不需要再增大max_iter中的数目了,
~~~     毕竟一切都以模型的预测效果为基准 一只要最终的预测效果好,运行又快,那就一切都好,无所谓是否报红色警告了。
### --- 分类方式选参数

~~~     multi_class参数决定了我们分类方式的选择,有ovr和multinomial两个值可以选择,默认是ovr。
~~~     ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。
~~~     如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。 
~~~     OvR的思想很简单,无论你是多少元逻辑回归,我们都可以看做二元逻辑回归。
~~~     具体做法是,对于第K 类的分类决策,我们把所有第K类的样本作为正例,
~~~     除了第K类样本以外的所有样本都作为负例,然后在上面做二元逻辑回归,
~~~     得到第K类的分类模型。其他类的分类模型获得以此类推。
~~~     # 生成三个假的数据集:
~~~     # 定义一个函数:
~~~     处理过的数据集就是⼆分类问题,通过逻辑回归可能得到⿊线区分不同类别。
~~~     同理,
~~~     定义函数:
~~~     处理过的数据集就是二分类问题,通过逻辑回归可能得到黑线区分不同类别。
~~~     同理,
~~~     当需要预测新的数据的类别时,使用如下公式∶
~~~     使用不同的函数去预测输入X,分别计算不同Y^的值,然后取其中的最大值。
~~~     哪个类别对应的 越大,就认为 属于哪个类。

~~~     而MvM则相对复杂,这里举MvM的特例one-vs-one(OvO)作讲解。
~~~     如果模型有T类,我们每次在所有的T类样本里面选择两类样本出来,
~~~     不妨记为T1类和T2类,把所有的输出为T1和T2的样本放在一起,
~~~     把T1作为正例,T2作为负例,进行二元逻辑回归,得到模型参数。
~~~     我们一共需要T(T-1)/2次分类。
~~~     从上面的描述可以看出OvR相对简单,
~~~     但分类效果相对略差(这里指大多数样本分布情况,某些样本分布下OvR可能更好)。
~~~     而MvM分类相对精确,但是分类速度没有OvR快。

~~~     如果选择了ovr,则4种损失函数的优化方法liblinear,newton-cg,bfgs和sag都可以选择。
~~~     但是如果选择了multinomial,则只能选择newton-g,Ibfgs和sag了。
~~~     这里使用鸢尾花多分类数据集进行演示∶
from sklearn.linear_model import LogisticRegression as LR
from sklearn.datasets import load_iris
iris = load_iris()
for multi_class in ('multinomial', 'ovr'):
clf = LR(solver='sag', max_iter=100, random_state=42,
multi_class=multi_class).fit(iris.data,iris.target)
#打印两种multi_class模式下的训练分数
#%的⽤法,⽤%来代替打印的字符串中,想由变量替换的部分。%.3f表示,保留三位⼩数的浮点数。%s表示,
字符串。
#字符串后的%后使⽤元祖来容纳变量,字符串中有⼏个%,元组中就需要有⼏个变量
print("training score : %.3f (%s)" % (clf.score(iris.data,
iris.target),multi_class))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yanqi_vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值