网站12栅格系统怎么做,黄冈网站建设营销,餐饮行业做网站的好处,大学做兼职英语作文网站学习笔记来自#xff1a;
所用的库和版本大家参考#xff1a;
Python 3.7.1Scikit-learn 0.20.1 Numpy 1.15.4, Pandas 0.23.4, Matplotlib 3.0.2, SciPy 1.1.0
1 概述
1.1 名为“回归”的分类器
在过去的四周中#xff0c;我们接触了不少带“回归”二字的算法#xf…学习笔记来自
所用的库和版本大家参考
Python 3.7.1Scikit-learn 0.20.1 Numpy 1.15.4, Pandas 0.23.4, Matplotlib 3.0.2, SciPy 1.1.0
1 概述
1.1 名为“回归”的分类器
在过去的四周中我们接触了不少带“回归”二字的算法回归树随机森林的回归无一例外他们都是区别于分类算法们用来处理和预测连续型标签的算法。然而逻辑回归是一种名为“回归”的线性分类器其本质是由线性回归变化而来的一种广泛使用于分类问题中的广义回归算法。要理解逻辑回归从何而来得要先理解线性回归。线性回归是机器学习中最简单的的回归算法它写作一个几乎人人熟悉的方程 通过函数z线性回归使用输入的特征矩阵X来输出一组连续型的标签值y_pred以完成各种预测连续型变量的任务 (比如预测产品销量预测股价等等)。那如果我们的标签是离散型变量尤其是如果是满足0-1分布的离散型变量我们要怎么办呢?我们可以通过引入联系函数(link function)将线性回归方程z变换为g(z)并且令g(z)的值 分布在(0,1)之间且当g(z)接近0时样本的标签为类别0当g(z)接近1时样本的标签为类别1这样就得到了一个分类模型。而这个联系函数对于逻辑回归来说就是Sigmoid函数: 面试高危问题Sigmoid函数的公式和性质 不难发现g(z)的形似几率取对数的本质其实就是我们的线性回归z我们实际上是在对线性回归模型的预测结果取对数几率来让其的结果无限逼近0和1。因此其对应的模型被称为”对数几率回归“(logistic Regression)也就是我们的逻辑回归这个名为“回归”却是用来做分类工作的分类器。
思考g(z)代表了样本为某一类标签的概率吗 1.2 为什么需要逻辑回归
线性回归对数据的要求很严格比如标签必须满足正态分布特征之间的多重共线性需要消除等等而现实中很多真实情景的数据无法满足这些要求因此线性回归在很多现实情境的应用效果有限。逻辑回归是由线性回归变化而来因此它对数据也有一些要求而我们之前已经学过了强大的分类模型决策树和随机森林它们的分类效力很强并且不需要对数据做任何预处理。
何况逻辑回归的原理其实并不简单。一个人要理解逻辑回归必须要有一定的数学基础必须理解损失函数正则化梯度下降海森矩阵等等这些复杂的概念才能够对逻辑回归进行调优。其涉及到的数学理念不比支持向量机少多少。况且要计算概率朴素贝叶斯可以计算出真正意义上的概率要进行分类机器学习中能够完成二分类功能的模型简直多如牛毛。因此在数据挖掘人工智能所涉及到的医疗教育人脸识别语音识别这些领域逻辑回归没有太多的出场机会。
甚至在我们的各种机器学习经典书目中周志华的《机器学习》400页仅有一页纸是关于逻辑回归的(还是一页 数学公式)《数据挖掘导论》和《Python数据科学手册》中完全没有逻辑回归相关的内容sklearn中对比各种 分类器的效应也不带逻辑回归玩可见业界地位。
但是无论机器学习领域如何折腾逻辑回归依然是一个受工业商业热爱使用广泛的模型因为它有着不可替代 的优点:
逻辑回归对线性关系的拟合效果好到丧心病狂特征与标签之间的线性关系极强的数据比如金融领域中的信用卡欺诈评分卡制作电商中的营销预测等等相关的数据都是逻辑回归的强项。虽然现在有了梯度提升树GDBT比逻辑回归效果更好也被许多数据咨询公司启用但逻辑回归在金融领域尤其是银行业中的统治地位依然不可动摇(相对的逻辑回归在非线性数据的效果很多时候比瞎猜还不如所以如果你已经知道数据之间的联系是非线性的千万不要迷信逻辑回归)逻辑回归计算快:对于线性数据逻辑回归的拟合和计算都非常快计算效率优于SVM和随机森林亲测表 示在大型数据上尤其能够看得出区别逻辑回归返回的分类结果不是固定的01而是以小数形式呈现的类概率数字:我们因此可以把逻辑回归返回的结果当成连续型数据来利用。比如在评分卡制作时我们不仅需要判断客户是否会违约还需要给出确定的”信用分“而这个信用分的计算就需要使用类概率计算出的对数几率而决策树和随机森林这样的分类器可以产出分类结果却无法帮助我们计算分数(当然在sklearn中决策树也可以产生概率使用接口predict_proba调用就好但一般来说正常的决策树没有这个功能)。
另外逻辑回归还有抗噪能力强的优点。福布斯杂志在讨论逻辑回归的优点时甚至有着“技术上来说最佳模型的AUC面积低于0.8时逻辑回归非常明显优于树模型”的说法。并且逻辑回归在小数据集上表现更好在大型的数据集上树模型有着更好的表现。 由此我们已经了解了逻辑回归的本质它是一个返回对数几率的在线性数据上表现优异的分类器它主要被应 用在金融领域。其数学目的是求解能够让模型最优化的参数的值并基于参数和特征矩阵计算出逻辑回归的结果 y(x)。注意:虽然我们熟悉的逻辑回归通常被用于处理二分类问题但逻辑回归也可以做多分类。
1.3 sklearn中的逻辑回归 2 linear_model.LogisticRegression 2.1 二元逻辑回归的损失函数
在学习决策树和随机森林时我们曾经提到过两种模型表现:在训练集上的表现和在测试集上的表现。我们建模是追求模型在测试集上的表现最优因此模型的评估指标往往是用来衡量模型在测试集上的表现的。然而逻辑回归有着基于训练数据求解参数的需求并且希望训练出来的模型能够尽可能地拟合训练数据即模型在训练集上的预测准确率越靠近100%越好。
因此我们使用”损失函数“这个评估指标来衡量参数的优劣即这一组参数能否使模型在训练集上表现优异。如果用一组参数建模后模型在训练集上表现良好那我们就说模型表现的规律与训练集数据的规律一致拟合过程中的损失很小损失函数的值很小这一组参数就优秀相反如果模型在训练集上表现糟糕损失函数就会很大模型就训练不足效果较差这一组参数也就比较差。即是说我们在求解参数时追求损失函数最小让模型在训练数据上的拟合效果最优即预测准确率尽量靠近100%。
关键概念损失函数 逻辑回归的损失函数是由最大似然法来推导出来的具体结果可以写作: 由于我们追求损失函数的最小值让模型在训练集上表现最优可能会引发另一个问题:
如果模型在训练集上表示优秀却在测试集上表现糟糕模型就会过拟合。虽然逻辑回归和线性回归是天生欠拟合的模型但我们还是需要控制过拟合的技术来帮助我们调整模型对逻辑回归中过拟合的控制通过正则化来实现。
2.2 正则化重要参数penalty C
正则化是用来防止模型过拟合的过程常用的有L1正则化和L2正则化两种选项分别通过在损失函数后加上参数向量的L1范式和L2范式的倍数来实现。这个增加的范式被称为“正则项”也被称为惩罚项。
损失函数改变基于损失函数的最优化来求解的参数取值必然改变我们以此来调节模型拟合的程度。其中L1范数表现为参数向量中的每个参数的绝对值之和L2范数表现为参数向量中的每个参数的平方和的开方值。 L1正则化和L2正则化虽然都可以控制过拟合但它们的效果并不相同。当正则化强度逐渐增大即C逐渐变小 参数的取值会逐渐变小但L1正则化会将参数压缩为0L2正则化只会让参数尽量小不会取到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_scoredata load_breast_cancer()
X data.data
y data.targetdata.data.shapelrl1 LR(penaltyl1,solverliblinear,C0.5,max_iter1000)
lrl2 LR(penaltyl2,solverliblinear,C0.5,max_iter1000)#逻辑回归的重要属性coef_查看每个特征所对应的参数
lrl1 lrl1.fit(X,y)
lrl1.coef_(lrl1.coef_ ! 0).sum(axis1)lrl2 lrl2.fit(X,y)
lrl2.coef_可以看见当我们选择L1正则化的时候许多特征的参数都被设置为了0这些特征在真正建模的时候就不会出现在我们的模型当中了而L2正则化则是对所有的特征都给出了参数。
究竟哪个正则化的效果更好呢?还是都差不多?
l1 []
l2 []
l1test []
l2test []Xtrain, Xtest, Ytrain, Ytest train_test_split(X,y,test_size0.3,random_state420)for i in np.linspace(0.05,1,19):lrl1 LR(penaltyl1,solverliblinear,Ci,max_iter1000) lrl2 LR(penaltyl2,solverliblinear,Ci,max_iter1000)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],labellabel[i])
plt.legend(loc4) #图例的位置在哪里?4表示右下角
plt.show()可见至少在我们的乳腺癌数据集下两种正则化的结果区别不大。但随着C的逐渐变大正则化的强度越来越小模型在训练集和测试集上的表现都呈上升趋势直到C0.8左右训练集上的表现依然在走高但模型在未知数据集上的表现开始下跌这时候就是出现了过拟合。我们可以认为C设定为0.9会比较好。在实际使用时基本就默认使用l2正则化如果感觉到模型的效果不好那就换L1试试看。 2.2 梯度下降重要参数max_iter
之前提到过逻辑回归的数学目的是求解能够让模型最优化的参数的值即求解能够让损失函数最小化的的值 而这个求解过程对于二元逻辑回归来说有多种方法可以选择最常见的有梯度下降法(Gradient Descent)坐标轴下降法(Coordinate Descent)牛顿法(Newton-Raphson method)等每种方法都涉及复杂的数学原理但 这些计算在执行的任务其实是类似的。 现在我在这个图像上随机放一个小球当我松手这个小球就会顺着这个华丽的平面滚落直到滚到深蓝色的区域——损失函数的最低点。但是小球不能够一次性滚动到最低处它的能量不足所以每次最多只能走距离G。 为了严格监控这个小球的行为我要求小球每次只能走0.05 * G并且我要记下它每次走动的方向直到它滚到图像上的最低点。
现在我松手来看小球如何运动: 可以看见小球从高处滑落最终停在深蓝色的区域中的某个点上而这个点就是我们在现有状况下可以获得的图像的最低点。有了这个图像的最低点的数值我们就可以计算出这个点所对应的参数向量了。 2.3 二元回归与多元回归重要参数solver multi_class 之前我们对逻辑回归的讨论都是针对二分类的逻辑回归展开其实sklearn提供了多种可以使用逻辑回归处理多分类问题的选项。比如说我们可以把某种分类类型都看作1其余的分类类型都为0值和数据预处理中的二值化的思维类似这种方法被称为一对多(One-vs-rest)简称OvR在sklearn中表示为ovr。又或者我们可以把好几个分类类型划为1剩下的几个分类类型划为O值这是一种多对多(Many-vs-Many)的方法简称MvM在sklearn中表示为Multinominal。每种方式都配合L1或L2正则项来使用。
在sklearn中我们使用参数multi_class来告诉模型我们的预测标签是什么样的类型。
multi_class
输入ovr , multinomial, auto来告知模型我们要处理的分类问题的类型。默认是ovr。
ovr:表示分类问题是二分类或让模型使用一对多的形式来处理多分类问题。
multinomial:表示处理多分类问题这种输入在参数solver是liblinear时不可用。
auto:表示会根据数据的分类情况和其他参数来确定模型要处理的分类问题的类型。比如说如果数据是二分类或者solver的取值为liblinearauto会默认选择ovr。反之则会选择nultinomial。
注意:默认值将在0.22版本中从ovr更改为auto。
我们之前提到的梯度下降法只是求解逻辑回归参数的一种方法并且我们只讲解了求解二分类变量的参数时的各种原理。sklearn为我们提供了多种选择让我们可以使用不同的求解器来计算逻辑回归。求解器的选择由参数solver控制共有五种选择。其中“liblinear”是二分类专用也是现在的默认求解器。 2.4 逻辑回归中的特征选择
当特征的数量很多的时候我们出于业务考虑也出于计算量的考虑希望对逻辑回归进行特征选择来降维。比如在判断一个人是否会患乳腺癌的时候医生如果看5~8个指标来确诊会比需要看30个指标来确诊容易得多。
业务选择
说到降维和特征选择首先要想到的是利用自己的业务能力进行选择肉眼可见明显和标签有关的特征就是需要留下的。当然如果我们并不了解业务或者有成千上万的特征那我们也可以使用算法来帮助我们。或者可以让算法先帮助我们筛选过一遍特征然后在少量的特征中我们再根据业务常识来选择更少量的特征。
PCA和SVD一般不用
说到降维我们首先想到的是之前提过的高效降维算法PCA和SVD遗憾的是这两种方法大多数时候不适用于逻辑回归。逻辑回归是由线性回归演变而来线性回归的一个核心目的是通过求解参数来探究特征X与标签y之间的关系而逻辑回归也传承了这个性质我们常常希望通过逻辑回归的结果来判断什么样的特征与分类结果相关因此我们希望保留特征的原貌。PCA和SVD的降维结果是不可解释的因此一旦降维后我们就无法解释特征和标签之间的关系了。当然在不需要探究特征与标签之间关系的线性数据上降维算法PCA和SVD也是可以使用的。
统计方法可以使用但不是非常必要
既然降维算法不能使用我们要用的就是特征选择方法。逻辑回归对数据的要求低于线性回归由于我们不是使用最小二乘法来求解所以逻辑回归对数据的总体分布和方差没有要求也不需要排除特征之间的共线性但如果我们确实希望使用一些统计方法比如方差卡方互信息等方法来做特征选择也并没有问题。过滤法中所有的方法都可以用在逻辑回归上。
在一些博客中有这样的观点多重共线性会影响线性模型的效果。对于线性回归来说多重共线性会影响比较大所以我们需要使用方差过滤和方差膨胀因子VIF(variance inflation factor)来消除共线性。但是对于逻辑回归其实不是非常必要甚至有时候我们还需要多一些相互关联的特征来增强模型的表现。当然如果我们无法通过其他方式提升模型表现并且你感觉到模型中的共线性影响了模型效果那懂得统计学的你可以试试看用VIF消除共线性的方法遗憾的是现在sklearn中并没有提供VIF的功能。
轻松一刻R vs Python统计学 vs 机器学习
统计学的思路是一种“先验”的思路不管做什么都要先”检验“先”满足条件“事后也要各种”检验“以确保各种数学假设被满足不然的话理论上就无法得出好结果。而机器学习是一种”后验“的思路不管三七二十一先让模型跑一跑效果不好再想办法如果模型效果好不在意什么共线性残差不满足正态分布没有哑变量之类的细节模型效果好大过天
高效的嵌入法embedded
但是更有效的方法毫无疑问会是我们的embedded嵌入法。我们已经说明了由于L1正则化会使得部分特征对应的参数为0因此L1正则化可以用来做特征选择结合嵌入法的模块SelectFromModel我们可以很容易就筛选出让模型十分高效的特征。注意此时我们的目的是尽量保留原数据上的信息让模型在降维后的数据上的拟合效果保持优秀因此我们不考虑训练集测试集的问题把所有的数据都放入模型进行降维。
#导库
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 cross_val_score
from sklearn.feature_selection import SelectFromModeldata load_breast_cancer() # 乳腺癌数据的实例化
data.data.shapeLR_ LR(solver“liblinear”,C0.8,random_state420)
cross_val_score(LR_,data.data,data.target,cv10).mean()#对数据进行降维
# 参数threshold(相当于特征重要性阈值)
# 参数norm_order选择范式L1还是L2
# norm_order1说明使用的是L1范式模型会删除在L1范式下面无效的特征
X_embedded SelectFromModel(LR_,norm_order1).fit_transform(data.data,data.target)
X_embedded.shapedata.target.shapecross_val_score(LR_,X_embedded,data.target,cv10).mean()看看结果特征数量被减小到个位数并且模型的效果却没有下降太多如果我们要求不高在这里其实就可以停下了。但是能否让模型的拟合效果更好呢在这里我们有两种调整方式
1)调节SelectFromModel这个类中的参数threshold 这是嵌入法的阈值表示删除所有参数的绝对值低于这个阈值的特征。现在threshold默认为None所以SelectFromModel只根据L1正则化的结果来选择了特征即选择了所有L1正则化后参数不为0的特征。我们此时只要调整threshold的值画出threshold的学习曲线就可以观察不同的threshold下模型的效果如何变化。
一旦调整threshold就不是在使用L1正则化选择特征而是使用模型的属性.coef_中生成的各个特征的系数来选择。coef_虽然返回的是特征的系数但是系数的大小和决策树中的feature_importances_以及降维算法中的可解释性方差explained_vairance_概念相似其实都是衡量特征的重要程度和贡献度的因此SelectFromModel中的参数threshold可以设置为coef_的阈值即可以剔除系数小于threshold中输入的数字的所有特征。
然而这种方法其实是比较无效的大家可以用学习曲线来跑一跑当threshold越来越大被删除的特征越来越多模型的效果也越来越差模型效果最好的情况下需要保证有17个以上的特征。实际上我画了细化的学习曲线如果要保证模型的效果比降维前更好我们需要保留25个特征这对于现实情况来说是一种无效的降维需要30个指标来判断病情和需要25个指标来判断病情对医生来说区别不大。
2)调逻辑回归的类LR_通过画C的学习曲线来实现好用
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression as LR # 逻辑回归
from sklearn.model_selection import cross_val_score # 交叉验证
from sklearn.datasets import load_breast_cancer # 乳腺癌数据集
from sklearn.feature_selection import SelectFromModel # 嵌入法特征选择data load_breast_cancer()x data.data
y data.targetLR_ LR(solverliblinear, C0.2, random_state500)
print(cross_val_score(LR_, x, y, cv10).mean())fullx []
fsx []c np.arange(0.01, 10.01, 0.5)for i in c:LR_ LR(solverliblinear, Ci, random_state500)# 使用没用嵌入法降维的xfullx.append(cross_val_score(LR_, x, y, cv10).mean())# 使用嵌入法降维x_embedded SelectFromModel(LR_, norm_order1).fit_transform(x, y)fsx.append(cross_val_score(LR_, x_embedded, y, cv10).mean())# 得出最高的评分及相应的C值
print(max(fsx), c[fsx.index(max(fsx))])plt.figure(figsize[20, 5])
plt.plot(c, fullx, labelfull)
plt.plot(c, fsx, labelfeature selection)
plt.legend()
plt.show() 得出最高的评分及相应的C值 这样我们就实现了在特征选择的前提下保持模型拟合的高效现在如果有一位医生可以来为我们指点迷津看看剩下的这些特征中有哪些是对针对病情来说特别重要的也许我们还可以继续降维。当然除了嵌入法系数累加法或者包装法也是可以使用的。
比较麻烦的系数累加法
系数累加法的原理非常简单。coef_虽然返回的是特征的系数但是系数的大小和决策树中的feature_importances_以及降维算法中的可解释性方差explained_vairance_概念相似其实都是衡量特征的重要程度和贡献度的。在PCA中我们通过绘制累积可解释方差贡献率曲线来选择超参数在逻辑回归中我们可以使用系数coef_来这样做。
并且我们选择特征个数的逻辑也是类似的找出曲线由锐利变平滑的转折点转折点之前被累加的特征都是我们需要的转折点之后的我们都不需要。不过这种方法相对比较麻烦因为我们要先对特征系数进行从大到小的排序还要确保我们知道排序后的每个系数对应的原始特征的位置才能够正确找出那些重要的特征。如果要使用这样的方法不如直接使用嵌入法来得方便。
简单快速的包装法
相对的包装法可以直接设定我们需要的特征个数逻辑回归在现实中运用时可能会有”需要5~8个变量”这种需求包装法此时就非常方便了。不过逻辑回归的包装法的使用和其他算法一样并不具有特别之处因此在这里就不在赘述包装法具体参考03期特征选择中的包装法。
2.5 样本不平衡与参数class_weight
样本不平衡是指在一组数据集中标签的一类天生占有很大的比例或误分类的代价很高即我们想要捕捉出某种特定的分类的时候的状况。
什么情况下误分类的代价很高?例如我们现在要对潜在犯罪者和普通人进行分类如果没有能够识别出潜在犯罪者那么这些人就可能去危害社会造成犯罪识别失败的代价会非常高但如果我们将普通人错误地识别成了潜在犯罪者代价却相对较小。所以我们宁愿将普通人分类为潜在犯罪者后再人工甄别但是却不愿将潜在犯罪者分类为普通人有种宁愿错杀不能放过的感觉。
再比如说在银行要判断一个新客户是否会违约通常不违约的人vs违约的人会是99: 1的比例真正违约的人其实是非常少的。这种分类状况下即便模型什么也不做全把所有人都当成不会违约的人正确率也能有99%,这使得模型评估指标变得毫无意义根本无法达到我们的“要识别出会违约的人的建模目的。
因此我们要使用参数class_weight对样本标签进行一定的均衡给少量的标签更多的权重让模型更偏向少数类向捕获少数类的方向建模。该参数默认None此模式表示自动给与数据集中的所有标签相同的权重即自动11。当误分类的代价很高的时候我们使用”balanced“模式我们只是希望对标签进行均衡的时候什么都不填就可以解决样本不均衡问题。
但是sklearn当中的参数class_weight变幻莫测大家用模型跑一跑就会发现我们很难去找出这个参数引导的模 型趋势或者画出学习曲线来评估参数的效果因此可以说是非常难用。我们有着处理样本不均衡的各种方法其中主流的是采样法是通过重复样本的方式来平衡标签可以进行上采样增加少数类的样本比如SMOTE 或者下采样减少多数类的样本。对于逻辑回归来说上采样是最好的办法。在案例中会给大家详细来讲如何在逻辑回归中使用上采样。