Sklearn实现逻辑回归
方法与参数
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='liblinear', max_iter=100,
multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)
penalty='l2'
: 字符串‘l1’或‘l2’,默认‘l2’。- 用来指定惩罚的基准(正则化参数)。只有‘l2’支持‘newton-cg’、‘sag’和‘lbfgs’这三种算法。
- 如果选择‘l2’,solver参数可以选择‘liblinear’、‘newton-cg’、‘sag’和‘lbfgs’这四种算法;如果选择‘l1’的话就只能用‘liblinear’算法。
dual=False
: 对偶或者原始方法。Dual只适用于正则化相为l2的‘liblinear’的情况,通常样本数大于特征数的情况下,默认为False。C=1.0
: C为正则化系数λ的倒数,必须为正数,默认为1。和SVM中的C一样,值越小,代表正则化越强。fit_intercept=True
: 是否存在截距,默认存在。intercept_scaling=1
: 仅在正则化项为‘liblinear’,且fit_intercept设置为True时有用。solver='liblinear'
: solver参数决定了我们对逻辑回归损失函数的优化方法,有四种算法可以选择。- a) liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
- b) lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
- c) newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
- d) sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候。
从上面的描述可以看出,newton-cg、lbfgs和sag这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
同时,sag每次仅仅使用了部分样本进行梯度迭代,所以当样本量少的时候不要选择它,而如果样本量非常大,比如大于10万,sag是第一选择。但是sag不能用于L1正则化,所以当你有大量的样本,又需要L1正则化的话就要自己做取舍了。要么通过对样本采样来降低样本量,要么回到L2正则化。
但是liblinear也有自己的弱点!我们知道,逻辑回归有二元逻辑回归和多元逻辑回归。对于多元逻辑回归常见的有one-vs-rest(OvR)和many-vs-many(MvM)两种。而MvM一般比OvR分类相对准确一些。而liblinear只支持OvR,不支持MvM,这样如果我们需要相对精确的多元逻辑回归时,就不能选择liblinear了。也意味着如果我们需要相对精确的多元逻辑回归不能使用L1正则化了。
总结:
正则化 算法 适用场景 L1 liblinear liblinear适用于小数据集;如果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化;如果模型的特征非常多,希望一些不重要的特征系数归零,从而让模型系数稀疏化的话,也可以使用L1正则化。 L2 liblinear libniear只支持多元逻辑回归的OvR,不支持MvM,但MVM相对精确。 L2 lbfgs/newton-cg/sag 较大数据集,支持one-vs-rest(OvR)和many-vs-many(MvM)两种多元逻辑回归。 L2 sag 如果样本量非常大,比如大于10万,sag是第一选择;但不能用于L1正则化。
-
multi_class='ovr'
: 分类方式。官网有个对比两种分类方式的例子:链接地址。- ovr即one-vs-rest(OvR),multinomial是many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。
- ovr不论是几元回归,都当成二元回归来处理。mvm从从多个类中每次选两个类进行二元回归。如果总共有T类,需要T(T-1)/2次分类。
- OvR相对简单,但分类效果相对略差(大多数样本分布情况)。而MvM分类相对精确,但是分类速度没有OvR快。
- 如果选择了ovr,则4种损失函数的优化方法liblinear,newton-cg,lbfgs和sag都可以选择。但是如果选择了multinomial,则只能选择newton-cg, lbfgs和sag了。
-
class_weight=None
: 类型权重参数。用于标示分类模型中各种类型的权重。默认不输入,即所有的分类的权重一样。- 选择‘balanced’自动根据y值计算类型权重。
- 自己设置权重,格式:
{class_label: weight}
。例如0,1分类的er'yuan二元模型,设置class_weight={0:0.9, 1:0.1}
,这样类型0的权重为90%,而类型1的权重为10%。
-
random_state=None
: 随机数种子,默认为无。仅在正则化优化算法为sag,liblinear时有用。 -
max_iter=100
: 算法收敛的最大迭代次数。 -
tol=0.0001
: 迭代终止判据的误差范围。 -
verbose=0
: 日志冗长度int:冗长度;0:不输出训练过程;1:偶尔输出; >1:对每个子模型都输出 -
warm_start=False
: 是否热启动,如果是,则下一次训练是以追加树的形式进行(重新使用上一次的调用作为初始化)。布尔型,默认False。 -
n_jobs=1
: 并行数,int:个数;-1:跟CPU核数一致;1:默认值。
LogisticRegression类的常用方法
-
fit(X, y, sample_weight=None)
- 拟合模型,用来训练LR分类器,其中X是训练样本,y是对应的标记向量
- 返回对象,self。
-
fit_transform(X, y=None, **fit_params)
- fit与transform的结合,先fit后transform。返回
X_new
:numpy矩阵。
- fit与transform的结合,先fit后transform。返回
-
predict(X)
- 用来预测样本,也就是分类,X是测试集。返回array。
-
predict_proba(X)
- 输出分类概率。返回每种类别的概率,按照分类类别顺序给出。如果是多分类问题,multi_class="multinomial",则会给出样本对于每种类别的概率。
- 返回array-like。
-
score(X, y, sample_weight=None)
- 返回给定测试集合的平均准确率(mean accuracy),浮点型数值。
- 对于多个分类返回,则返回每个类别的准确率组成的哈希矩阵。
示例
参考官网的例子,对鸢尾花数据进行逻辑回归。画图参考。
import numpy as np from sklearn import linear_model, datasets from sklearn.cross_validation import train_test_split # 1.加载数据 iris = datasets.load_iris() X = iris.data[:, :2] # 使用前两个特征 Y = iris.target #np.unique(Y) # out: array([0, 1, 2]) # 2.拆分测试集、训练集。 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0) # 设置随机数种子,以便比较结果。 # 3.标准化特征值 from sklearn.preprocessing import StandardScaler sc = StandardScaler() sc.fit(X_train) X_train_std = sc.transform(X_train) X_test_std = sc.transform(X_test) # 4. 训练逻辑回归模型 logreg = linear_model.LogisticRegression(C=1e5) logreg.fit(X_train, Y_train) # 5. 预测 prepro = logreg.predict_proba(X_test_std) acc = logreg.score(X_test_std,Y_test)
因为这里数据量小,结果准确率只有0.7。嘛,只是小小的示范一下怎么使用sklearn的逻辑回归方法。在训练模型之前,可以优化一下模型参数,用GridSearchCV()
函数。
参考文章:
- Logistic Regression 模型简介,美团技术,简单易懂。
- 逻辑回归模型(Logistic Regression, LR)基础
- 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)
- 对线性回归,logistic回归和一般回归的认识,斯坦福大学机器学习课程的笔记。
- 【机器学习算法系列之二】浅析Logistic Regression
- 逻辑回归算法的原理及实现(LR),用Excel实现的。
作者:ChZ_CC
链接:https://www.jianshu.com/p/e51e92a01a9c
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
之前在逻辑回归原理小结这篇文章中,对逻辑回归的原理做了小结。这里接着对scikit-learn中逻辑回归类库的我的使用经验做一个总结。重点讲述调参中要注意的事项。
1. 概述
在scikit-learn中,与逻辑回归有关的主要是这3个类。LogisticRegression, LogisticRegressionCV 和logistic_regression_path。其中LogisticRegression和LogisticRegressionCV的主要区别是LogisticRegressionCV使用了交叉验证来选择正则化系数C。而LogisticRegression需要自己每次指定一个正则化系数。除了交叉验证,以及选择正则化系数C以外, LogisticRegression和LogisticRegressionCV的使用方法基本相同。
logistic_regression_path类则比较特殊,它拟合数据后,不能直接来做预测,只能为拟合数据选择合适逻辑回归的系数和正则化系数。主要是用在模型选择的时候。一般情况用不到这个类,所以后面不再讲述logistic_regression_path类。
此外,scikit-learn里面有个容易让人误解的类RandomizedLogisticRegression,虽然名字里有逻辑回归的词,但是主要是用L1正则化的逻辑回归来做特征选择的,属于维度规约的算法类,不属于我们常说的分类算法的范畴。
后面的讲解主要围绕LogisticRegression和LogisticRegressionCV中的重要参数的选择来来展开,这些参数的意义在这两个类中都是一样的。
2. 正则化选择参数:penalty
LogisticRegression和LogisticRegressionCV默认就带了正则化项。penalty参数可选择的值为"l1"和"l2".分别对应L1的正则化和L2的正则化,默认是L2的正则化。
在调参时如果我们主要的目的只是为了解决过拟合,一般penalty选择L2正则化就够了。但是如果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化。另外,如果模型的特征非常多,我们希望一些不重要的特征系数归零,从而让模型系数稀疏化的话,也可以使用L1正则化。
penalty参数的选择会影响我们损失函数优化算法的选择。即参数solver的选择,如果是L2正则化,那么4种可选的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以选择。但是如果penalty是L1正则化的话,就只能选择‘liblinear’了。这是因为L1正则化的损失函数不是连续可导的,而{‘newton-cg’, ‘lbfgs’,‘sag’}这三种优化算法时都需要损失函数的一阶或者二阶连续导数。而‘liblinear’并没有这个依赖。
具体使用了这4个算法有什么不同以及有什么影响我们下一节讲。
3. 优化算法选择参数:solver
solver参数决定了我们对逻辑回归损失函数的优化方法,有4种算法可以选择,分别是:
a) liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
b) lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
c) newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
d) sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候。
从上面的描述可以看出,newton-cg, lbfgs和sag这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
同时,sag每次仅仅使用了部分样本进行梯度迭代,所以当样本量少的时候不要选择它,而如果样本量非常大,比如大于10万,sag是第一选择。但是sag不能用于L1正则化,所以当你有大量的样本,又需要L1正则化的话就要自己做取舍了。要么通过对样本采样来降低样本量,要么回到L2正则化。
从上面的描述,大家可能觉得,既然newton-cg, lbfgs和sag这么多限制,如果不是大样本,我们选择liblinear不就行了嘛!错,因为liblinear也有自己的弱点!我们知道,逻辑回归有二元逻辑回归和多元逻辑回归。对于多元逻辑回归常见的有one-vs-rest(OvR)和many-vs-many(MvM)两种。而MvM一般比OvR分类相对准确一些。郁闷的是liblinear只支持OvR,不支持MvM,这样如果我们需要相对精确的多元逻辑回归时,就不能选择liblinear了。也意味着如果我们需要相对精确的多元逻辑回归不能使用L1正则化了。
具体OvR和MvM有什么不同我们下一节讲。
4. 分类方式选择参数:multi_class
multi_class参数决定了我们分类方式的选择,有 ovr和multinomial两个值可以选择,默认是 ovr。
ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。
OvR的思想很简单,无论你是多少元逻辑回归,我们都可以看做二元逻辑回归。具体做法是,对于第K类的分类决策,我们把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为负例,然后在上面做二元逻辑回归,得到第K类的分类模型。其他类的分类模型获得以此类推。
而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, lbfgs和sag都可以选择。但是如果选择了multinomial,则只能选择newton-cg, lbfgs和sag了。
5. 类型权重参数: class_weight
class_weight参数用于标示分类模型中各种类型的权重,可以不输入,即不考虑权重,或者说所有类型的权重一样。如果选择输入的话,可以选择balanced让类库自己计算类型权重,或者我们自己输入各个类型的权重,比如对于0,1的二元模型,我们可以定义class_weight={0:0.9, 1:0.1},这样类型0的权重为90%,而类型1的权重为10%。
如果class_weight选择balanced,那么类库会根据训练样本量来计算权重。某种类型样本量越多,则权重越低,样本量越少,则权重越高。
那么class_weight有什么作用呢?在分类模型中,我们经常会遇到两类问题:
第一种是误分类的代价很高。比如对合法用户和非法用户进行分类,将非法用户分类为合法用户的代价很高,我们宁愿将合法用户分类为非法用户,这时可以人工再甄别,但是却不愿将非法用户分类为合法用户。这时,我们可以适当提高非法用户的权重。
第二种是样本是高度失衡的,比如我们有合法用户和非法用户的二元样本数据10000条,里面合法用户有9995条,非法用户只有5条,如果我们不考虑权重,则我们可以将所有的测试集都预测为合法用户,这样预测准确率理论上有99.95%,但是却没有任何意义。这时,我们可以选择balanced,让类库自动提高非法用户样本的权重。
提高了某种分类的权重,相比不考虑权重,会有更多的样本分类划分到高权重的类别,从而可以解决上面两类问题。
当然,对于第二种样本失衡的情况,我们还可以考虑用下一节讲到的样本权重参数: sample_weight,而不使用class_weight。sample_weight在下一节讲。
6. 样本权重参数: sample_weight
上一节我们提到了样本不失衡的问题,由于样本不平衡,导致样本不是总体样本的无偏估计,从而可能导致我们的模型预测能力下降。遇到这种情况,我们可以通过调节样本权重来尝试解决这个问题。调节样本权重的方法有两种,第一种是在class_weight使用balanced。第二种是在调用fit函数时,通过sample_weight来自己调节每个样本权重。
在scikit-learn做逻辑回归时,如果上面两种方法都用到了,那么样本的真正权重是class_weight*sample_weight.
以上就是scikit-learn中逻辑回归类库调参的一个小结,还有些参数比如正则化参数C(交叉验证就是 Cs),迭代次数max_iter等,由于和其它的算法类库并没有特别不同,这里不多累述了。
(欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com)
如果这篇文章帮助到了你,你可以请作者喝一杯咖啡