# 让模型看的更准更稳,正则优化
回到逻辑回归
w1x1+w2x2+w0=0
是一条直线,用于区分坐标系中两类点的,区分圆圈与三角形
是要让值落在0~1
之间
现在让(w1
,w2
)取(1
,1
),得出直线x1+x2=0
如下图所示
那么2x1+2x2=0
与-x1-x2=0
也是这条直线
awx=0
只要a!=0
,那么a
取任何值,直线都是等价的
那么既然一条直线中有无数个w
的存在,那么为什么只能取一个w
值呢?
这么众多的w
中,有何好坏呢?
x1+x2=0
这条直线,w向量
是怎么表示的(与直线呈90°),为法向量
,那么一条直线有无数条法向量
,反过来也是法向量
,如下图所示
x=(x1,x2)
也是向量,那么wx
相乘就是它们的内积
,内积
什么时候大于0
,什么时候小于0
?
θ
是w与x
向量的夹角
θ
在-90°~90°
之间,则wx>0
,反之,则wx>0
从向量中,再次证明了分割线
分割线的一边是大于0
,另一边是小于0
,以上通过法向量解释了一遍
那么w=(1,1)
与w=(-1,-1)
,有什么区别?
答:最终结果的两类分,刚好把类别颠倒了
w=(-1,-1)的部分>0
,它的对立面则<0
那么下图所示中:
f1(x):x为正的概率
f2(x):x为负的概率
f1(x)+f2(x)=1
推导为1
:
对于同一条直线 有无数个w
的方式进行表达
对于w
预测硬币的正面概率
那么-W
就是预测硬币反面的概率
比如,有个分类器模型,正确率为30%
,预测的w=(1,2)
,但是明天你就要交活了,这时只要将w
取-w
,即w=(-1,-2)
,那么正确率就为70%
那么以上是w
取负的情况,那么w
成倍的增加会发生什么情况呢?
当w->-w,w0->-w0 则 f(x)-> 1-f(x)
,分类器并没有变化,只是所得分类正好相反,原先输入的是圆圈的概率,变为了三角的概率
那么当w->10w w0->10w0
时,这条直线没有改变,变化的地方有哪些呢?
若w
成倍的增加,那么-(wx+w0)
会成倍的增加,最终导致f(x)
的取值会发生变化,虽然不影响分类,但是会影响概率的取值,那么来分析一下取值会发生什么变化?
通过曲线分析,若是同一个x
下的w
成倍增加时,那么f(x)
会更趋近于0
或者1
(两极分化更厉害),会让取值变得很硬,w
越大,取值越趋近于0
或者1
,这样不好,分类结果特别硬
当w=1 p1=0.6 p2=0.4
当w=100 p1->1 p2->0
,这样分类结果很硬,没有中间的过渡区分度
所以得出结论,当直线没有变化时,w
变小,会比较好
第二种解释:
如果w1
很大,那么x1
的细微的抖动,将会使最终结果变化很大,因为w1
将这个w1x1
这个信号放大了
从这个角度来说,也是希望w
变小,越好
第三种解释:
比如x1的信号
是真实的身高,x1的噪声
是测量误差,其中噪声
是随机产生的,值可大可小,满足正态分布
x1=信号+噪声
由上,每个x都能拆成信号与噪声
就能写成:
假如,这些特征相对较多时,那么当w
成倍增加时,会将信号与噪声同时放大,但是由于信息冗余,当维度过多时,信号中的后面的维度会跟前面的维度大概率会冗余,比如10维->7维
,但是噪声不冗余,还是10维
所以虽然信号与噪声同时放大,但是噪声是很独立的,没有冗余,所以噪声会增加的更多,w
越大,性噪比会越来越小
结论:在不改变直线的前提,w
越小越好
第四种解释:
机器学习模型,为的就是在测试集上表现好
把这个分解为两种目标
- 在训练集上表现好:就是让损失函数(KL)最小
- 训练集与测试集差别小
如何做到训练集与测试集差别小呢?
不考虑分类效果,单纯让它们差别小有什么办法?
答:随机猜,不管什么集(忽视数据),全靠蒙,这样就很接近
那么当w
变为什么值,f(x)
值随机蒙呢?
答:w=0,那么x不管是什么(忽视数据),f(x)=0.5
,由此可见,w=0
时,训练集与测试集差别最小,那么w=0
也是w
极端小的一种情况,从而证明当w
变小时,训练集与测试集差别变小
在推理:
KL
损失函数越小让训练集表现越好
||W||
测试集与训练集差异小
是个系数,调节
KL
与||W||
的比例,是侧重于KL
,还是侧重于差异
若是
0
,则退化为最初学习逻辑回归时,完全不考虑测试集与训练集的差异,只考虑训练集的情况
若趋近于正无穷时,那么完全不考虑训练集的效果,只考虑测试集与训练集的差异
一般来说训练集种数据量越大,越接近全量数据,那么考虑差异性就会降低,越小;数据量越小,那么考虑差异性就会提升,
越大
如果已经找到了w
进行正确分类,把w
扩大了2倍,损失函数(KL
)会更小
其中损失函数就是让f
在正确分类下越来越硬,让f
更趋向于1
或者0
比如:找到了一个w=(1,2)
能够正确分类了,此时把它放大十倍,w=(10,20)
,那么KL损失函数值
会更小
因为KL损失函数就是该点概率到1或者0的距离值,当w变大,导致f更趋向于1或者0,从而使该距离变小
那么当我们单纯只拿这个KL来训练时,会导致训练的w
越来越大,最终导致w
值溢出
w->无穷
使用sklearn
做逻辑回归时,它的损失函数就是这样的
已经帮你自带上了这一项,因为不带这一项
w
根本学不出来,会导致溢出,这一项用来限制w
的长度
所以这两项会互相牵制
,彼此成就
一般来说:
正则项的作用:
- 从机器角度考虑:抑制
w
在分类正确情况下,按比例无限增大 - 减少测试集和训练集的差异性
- 破坏训练集的效果
第一种:L2正则
第二种:L1正则
一般没人用L3、L4
正则,一般L1、L2
就到头了
相当于一个衡量三角形的斜边L2
一个衡量三角形的直角边L1
这个正则项,不光用在逻辑回归,也用在线性回归
如果是L2正则
时,叫做岭回归
L1
和L2
正则有什么区别?
关联到之前所学MSE
中使用方差与绝对值
L1正则
比如w1x1+w2x2=0
是条直线,两维特征,x1
是身高,x2
是体重,x1
这个维度重要,x2
这个维度次要
那么使用L1正则
时,会将w2=0
,将w1
减少的小一些,这样影响最小
比如,向量w1=(3,2)
非要减少2个长度时,会趋向于w1=(3,0)
,把最差的维度趋向0
,要比把每个维度都减少要好,既然一定要牺牲分类效果了,就是w1
要变小时,那么就先把最差维度的牺牲掉,这样对分类效果影响最少
模型如何判断x1
与x2
哪个重要?
答:这个涉及统计学,模型会看每个x
的分布情况,从而做出判断
比如:在训练集中,模型发现对于真实结果为1
的所有样本中,x2
没有x1
集中,那么x2
相对x1
就是次要的
L2正则
分析:当w
变小,KL
变大
比如:单纯只看w1
减少时,KL
与L2
的变化情况,对于KL
增加是比较稳定的,线性的,每次相对稳定的增加a
,但是对于L2
变化则是当w1
减少到一定程度后,趋于平缓,收益变小,也就是说当w1
降到一定程度后,就不再下降了,转移到w2
或者其他维度了
下表所示
W1变化 | KL变化 | L2变化 |
---|---|---|
5~4 | a | 25-16=9 |
4~3 | a | 16-9=7 |
3~2 | a | 9-4=5 |
结论
使用L2正则
:w
各维度普遍变小
使用L1正则
:牺牲最不重要的维度
代码中使用L1
或L2
正则
# -*- encoding:utf-8 -*-
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from numpy import shape
from sklearn import metrics
import numpy as np
def read_data(path):
with open(path) as f :
lines=f.readlines()
lines=[eval(line.strip()) for line in lines]
X,y=zip(*lines)
X=np.array(X)
y=np.array(y)
return X,y
X_train,y_train=read_data("train_data")
X_test,y_test=read_data("test_data")
def train_model(reg):
print reg
model = LogisticRegression(penalty=reg)
model.fit(X_train, y_train)
print "w", model.coef_
#print (model.intercept_)
y_pred_train = model.predict(X_train)
y_pred_test = model.predict(X_test)
e_train=metrics.mean_squared_error(y_train, y_pred_train)
e_test=metrics.mean_squared_error(y_test, y_pred_test)
'''
print "训练集MSE:{}".format(e_train)
print "测试集MSE:{}".format(e_test)
print "训练测试差异{}".format(e_test-e_train)
print
'''
#train_model(reg="None")
train_model(reg="l1")
train_model(reg="l2")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
执行结果
从上图看出,使用L1
正则,w
有很多项变为0
,从而达到降维的效果
代码中不指定penalty
(惩罚)项时,默认是L2
正则
那么要是需求上要求降维时,不能想当然的把权重小的直接拿掉,因为存在信息冗余的问题,应该使用L1
正则降维,因为如下图所示,将w1变为0
,但是w3变为0.6
一般情况下使用L1
正则居多,因为不但能起到降维效果,也能提高泛化能力
模型最终想要的是:测试集效果好
而使用机器学习,首先保证训练集效果好,然后再使得训练集和测试集差异小,
其中训练集效果好就是我们的损失函数小,
训练集和测试集差异小就是说模型的推广、泛化能力强
L2
正则:数学完美,实际很少用到,或者没有降维需求时,可以使用L2
正则
等高线
指的是地形图
上高度相等的相邻各点所连成的闭合曲线。把地面上海拔高度相同的点连成的闭合曲线,并垂直投影
到一个水平面上,并按比例缩绘在图纸上,就得到等高线。等高线也可以看作是不同海拔高度的水平面与实际地面的交线,所以等高线是闭合曲线。在等高线上标注的数字为该等高线的海拔。
特征
1、位于同一等高线上的地面点,海拔高度相同。但海拔高度相同的点不一定位于同一条等高线上。(如上图140m的等高线)
2、在同一幅图内,除了陡崖以外,不同高程的等高线不能相交。
3、在图廓
内相邻等高线的高差一般是相同的,因此地面坡度
与等高线之间的等高线平距
成反比,等高线平距愈小,等高线排列越密,说明地面坡度越大;等高线平距愈大,等高线排列越稀,则说明地面坡度愈小。
4、等高线是一条闭合的曲线,如果不能在同一幅内闭合,则必在相邻或者其他图幅内闭合。
5、等高线经过山脊
或山谷
时改变方向,因此,山脊线或者山谷线应垂直于等高线转折点处的切线,即等高线与山脊线或者山谷线正交。
只考虑两维的情况下
下图中的等高线图:
圆圈线上的点代表:w1,w2
等高线的高度代表:那一点上的w1,w2
的KL
距离
当w
一直变小,KL
距离变大,越来越高
由于x1
比x2
的数据量级大,当w
变小时,w1
变化小一定数值,要比w2
对于KL
贡献大,也就是w1
变化时,等高线会变陡
所以当x1
量级大于x2
的时候,我们希望学习的时候w1
变化慢一点,而w2
变化快一点
损失函数:
KL
对w
求导:
分为两种情况:
y=1
有a
个样本
y=0
有b
个样本
公式转化为:
当x1
数据量大时,导数变大,w1
变化的快,
当x2
数据量小时,导数变小,w2
变大的慢;因为导数是反应变化率
在通过梯度下降法求证:
通过分析公式:x1
大,则w1
变化大,x2
小,则w2
变化小
但是上面理想情况等高线的分析:当x1
量级大于x2
的时候,我们希望学习的时候w1
变化慢一点,而w2
变化快一点,而实际情况则是x1
大,则w1
变化大,x2
小,则w2
变化小
也就是说实际的梯度下降过程中是有问题的,那么有什么办法解决呢?
分析造成上述问题的本质原因是x1
与x2
的数据量级不一致
,造成理想与实际的差异大
那么我们把数据量级变一致就行了,就是归一
如何归一呢?
有很多样本(x1
,x2
),先来看一维
取很多样本中的x1
里面最大值max1
,最小值min1
,将x1
代入如下公式:
这样x1
的取值范围就在0~1
之间,这样便将数据量级变为一致了
但是这样做是有问题的
脏数据或者是噪声,影响会很大
比如:月薪,有1w,2w,3w,突然来个首富,1000w
那么通过上面公式取值方法:那么月薪1w、2w、3w的就挤在一起了,没有差异了,信息损失了,区分度下降
所以一般不用上面的方法
x1
围绕均值
左右分布,当x1
的数据量很大时,均方差
变大
上面对x
向量的这种特殊处理,在机器学习中叫做对输入样本的正规化,对输入数据做预处理,可以使模型学习的更好
那么对输入数据进行预处理会改变最终的学习结果吗?
理论上说:预处理是不会对最终理想结果进行改变的
但是实际上输入数据正规化后,让学习加速,在同样的时间内,比如只训练一个小时,得出的改善的结果,因为理论上的结果需要花费很久的时间去学习才能够学到,所以正规化是非常有必要的,能够加快学习速度
正规化如何加快学习速度呢?
正规化之前,由于w1
梯度下降步幅大于w2
,就会如下图所示,来回反复震荡,才最终走到圆心处
正规化后,之前椭圆线趋近于圆线,w1
与w2
的幅度是一样的,那么w
很快就能下降到圆心处
损失函数:
y=1
有n
个样本
y=0
有m
个样本
KL
对w
求导:
当f
趋近于1
时,那么加号前面的趋近于0
,说明正样本已经基本学完了,开始学习负样本的了
那么就能把情况简化一下:
当x1
是身高,x2
是体重时,那么都是大于0
的数值
那么看这个式子,
f
是0~1
之间的数,并且x1
与x2
都是大于的数那么,w
则只能变小,越来越小
推理出:
w1
与w2
只能同时增加或者同时减少,因为x1
与x2
是大于0
的
假如输入数据已经正规化了,那么等高线也接近于圆形了
如果w1
与w2
只能同增或者同减
那么w
的移动范围只能是1(同增)、3(同减)象限内
既然只能是往1或者3走,那么圆心处是学习的最优点,现在w
在右下方处,不能朝着2象限走,只能绕远路,先1象限一大步,然后3象限退一步,导致学习慢
造成这一问题的根本原因就是x1
与x2
同号
上述问题如何解决呢?
将x1
待入下面公式:
该公式就保证了x1
就有正有负了
这种方式也叫做特征转换
,将采集的自然信号,经过转换,不会增加信息、也不减少信息,但是可让学习加速
演示代码:使用方差与均值
from sklearn import preprocessing
import numpy as np
X = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]])
scaler = preprocessing.StandardScaler().fit(X)
print "mean",scaler.mean_
print "scale",scaler.scale_
print scaler.transform(X)
2
3
4
5
6
7
8
9
10
总结:
输入数据向量x
,经过逻辑回归LR模型
,输出y
(0~1
)之间的概率值
模型
就是通过逻辑函数
不断调整w
交叉熵损失函数=KL距离
除了损失函数
以外,还有L1
与L2
正则,提升泛化能力
还要对输入数据进行标准化(让数据可正可负)及正规化(让数据量级归一均衡),提升学习速度
评价指标:
- 正确率
- 准确率和召回率
- Roc曲线 Auc值 真实反应正样本中预测分值大于负样本中预测分值的组合数