logistic回归常用于处理线性二分类问题,其模型满足如下的条件概率分布:
p ( Y = 1 ∣ x ) = e x p ( w x + b ) 1 + e x p ( w x + b ) p(Y=1|x)=\dfrac{exp(wx+b)}{1+exp(wx+b)} p(Y=1∣x)=1+exp(wx+b)exp(wx+b) 记作 π ( x ) \pi(x) π(x)
p ( Y = 0 ∣ x ) = 1 1 + e x p ( w x + b ) p(Y=0|x)=\dfrac{1}{1+exp(wx+b)} p(Y=0∣x)=1+exp(wx+b)1
此处x是输入,可以是一维也可以是多维, w ∈ R n w\in R^n w∈Rn 且 b ∈ R b\in R b∈R,w为权值向量,b为偏置,参数空间为 w = ( w ( 1 ) , w ( 2 ) , . . . , w ( n ) , b ) T w = (w^{(1)},w^{(2)},...,w^{(n)},b)^T w=(w(1),w(2),...,w(n),b)T.
对logistic回归模型做学习时,对于给定的训练集可以用极大似然法估计模型参数。写出似然函数, ∏ [ π ( x i ) ] y i [ 1 − π ( x i ) ] 1 − y i \prod [\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i} ∏[π(xi)]yi[1−π(xi)]1−yi,对其取对数得到对数似然函数L(W) = ∑ [ y i l o g π ( x i ) + ( 1 − y i ) l o g ( 1 − π ( x i ) ) ] \sum[y_ilog\pi(x_i)+(1-y_i)log(1-\pi(x_i))] ∑[yilogπ(xi)+(1−yi)log(1−π(xi))] ,接下来对L(W)求极大值,得到w估计值。
一般地,将 -L(W) 设为损失函数并用梯度下降法或者拟牛顿法求取参数。
f ( x ) = 1 1 + e − x f(x) = \dfrac{1}{1+e^{-x}} f(x)=1+e−x1
函数的定义域为 ( − ∞ , ∞ ) (-\infty,\infty) (−∞,∞),值域为 ( 0 , 1 ) (0,1) (0,1) 且在0.5处呈中心对称,函数在定义域内连续光滑且处处可导,其导数为: f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) f'(x) = f(x)(1-f(x)) f′(x)=f(x)(1−f(x))
sigmoid函数在中心附近增长最快,两端增速缓慢,其密度函数与分布函数图为:
一方面,sigmoid函数满足LR的需求:1.取值范围在(0,1)范围内;2.对于一个事件发生情况,50%是分水岭,选择函数应该在0.5中心对称;从这两个条件来看,sigmoid函数满足相关性质;
进一步地,对于一个有效分类器,响应值(WX内积)越大,代表数据属于正类的可能性越大,反之,属于反类的可能性越大,这需要有一个函数能将WX映射到条件概率 P ( Y = 1 ∣ x , w ) P(Y=1|x,w) P(Y=1∣x,w)中去,而sigmoid函数可以实现此函数的功能。
满足LR条件的映射函数不止sigmoid,为什么选Sigmoid函数而不选择其他函数?
这可以利用最大熵去解释。根据最大熵原理:从满足约束条件的模型中选择熵最大的模型,而根据熵的性质,x服从均匀分布时的熵最大;
假定目标 Y ∣ X Y|X Y∣X 服从伯努利分布,则最大熵模型为:
− ∑ v = 1 k ∑ i = 1 m [ π ( x ( i ) ) v l o g ( π ( x ( i ) ) v ) ] -\displaystyle\sum_{v=1}^k\displaystyle\sum_{i=1}^m[{\pi(x(i))}_vlog(\pi(x(i))_v)] −v=1∑ki=1∑m[π(x(i))vlog(π(x(i))v)] (*)
其中 π ( x ) v \pi(x)_v π(x)v 表示 分类至v的概率,即 p ( Y = v ∣ x ) p(Y=v|x) p(Y=v∣x)的值,x(i) 表示第i个样本输入值,此外, π ( ) \pi() π()满足:
π ( x ) v ⩾ 0 \pi(x)_v \geqslant 0 π(x)v⩾0
∑ v = 1 k π ( x ) v = 1 \displaystyle\sum_{v=1}^k \pi(x)_v = 1 v=1∑kπ(x)v=1
∑ i = 1 m π ( x ( i ) ) u x ( i ) j = ∑ i = 1 m A ( u , y ( i ) ) x ( i ) j \displaystyle\sum_{i=1}^m \pi(x(i))_ux(i)_j = \displaystyle\sum_{i=1}^m A(u,y(i))x(i)_j i=1∑mπ(x(i))ux(i)j=i=1∑mA(u,y(i))x(i)j
前两个式子保证 π ( x ) v \pi(x)_v π(x)v 存在概率属性,第三个等式表示 π ( x ) v \pi(x)_v π(x)v 要尽量贴合真实标签的分布,其中A(u,v)其实就是0 -1 变量,表示u和v是否相等。
由于这里的模型是一个带约束条件的极大值模型,所以利用拉格朗日乘数法求解 π ( ) \pi() π()函数的形式,使得(*)式达到最大,最后求得 π ( ) \pi() π()的形式为sigmoid函数(详细推理见参考资料(2),或参考李航的统计学习方法之最大熵模型)。
LR损失函数是一个log距离(交叉熵),为何不用均方差距离?
由上述公式可看出,从某种程度看LR的损失函数是一种交叉熵,用于衡量预测值( π ( x i ) \pi (x_i) π(xi))与实际值 y i y_i yi 之间的关系。
1、 用均方差距离表示的损失函数为 loss = ∑ [ y i ( 1 − π ( x i ) ) 2 + ( 1 − y i ) ( 0 − π ( x i ) ) 2 ] \sum [y_i(1-\pi(x_i))^2+(1-y_i)(0-\pi(x_i))^2] ∑[yi(1−π(xi))2+(1−yi)(0−π(xi))2] ,其loss 取值范围在[0,1]之间,损失函数的区分度不明显,最后训练出的模型容易出现较多“极端”预估错误的情况,而log距离存在明显的区分度,当 y = 1 , π = 1 y=1,\pi=1 y=1,π=1 时误差为0,当 π \pi π不为1时,loss 随着 π \pi π的变小而变大,由于取了负对数, π \pi π在取值属于[0,1]范围内变化时,loss的变化范围是 [ 0 , ∞ ] [0,\infty] [0,∞];
2、均方差距离是一个非凸函数,无法收敛到全局最优点;而对数似然函数是一个凸函数,可通过梯度下降算法或拟牛顿法求得全局最优点;
3、均方误差的偏导值在输出概率为0,1时非常小,这可能会造成模型在刚开始训练时,梯度近乎消失。
LR损失函数加正则项
LR模型是一个简单的线性模型,为防止模型过拟合,可以在LR损失函数后面加入正则项,正则项可分为两种,即L1正则和L2正则,其实际作用是对损失函数中的某些参数做一些限制。L1正则项其实是在原损失函数中加入权值向量中各个元素的绝对值之和(即权值向量的一范数,也称作哈曼顿距离);L2正则项其实是在原损失函数中加入权值向量中各个元素的平方和的平方根(即权值向量的二范数,也称为欧氏距离)
LR什么情况下需要归一化?
当LR的损失函数内不包含正则项时,不做归一化不会影响最终的结果,但是若损失函数包含正则项时,其对特征尺度伸缩是敏感的,故需要加正则项。
LR模型常用于处理线性问题,那是否可以处理非线性问题呢?
经查阅资料发现LR可以用于处理非线性问题,但是要运用到核技巧,但是核技巧的运用一般都是隐式的,也就是找不到显示的把低维数据映射到高维的函数,而只能计算高维空间中数据的点积,在这种情况下,LR的 W T X + b W^TX+b WTX+b得改成 ∑ a i ⟨ x i , x ⟩ + b \sum{a_i\lang x_i,x\rang +b} ∑ai⟨xi,x⟩+b 的形式,原模型只需存储w和b,而现模型需记录各 a i , x i a_i,x_i ai,xi等,存储量就变大了。相应的,对比接下来要讲的SVM,也需要用核技巧才能解决非线性问题,但SVM的模型参数仅与支持向量有关,即仅当 a i a_i ai非0时才需要存储相应的 x i x_i xi,所以在非线性可分时,用SVM处理的情况较多。
另一种提法是对输入特征做处理,例如特征离散化、组合特征等,对特征做处理后将原先的非线性问题转化为线性问题后再做模型拟合。
听过一个提法:运用LR时对特征做离散化
为什么做特征离散化?
经查阅,在工业操作中,常将连续值离散化为一系列0,1特征后再投入训练,这有几点优势:1.稀疏向量做内积运算速度快,便与存储;2.离散化后的特征对异常数据有很强的鲁棒性;3.单变量离散化为N个变量后,每个变量有单独的权重,相当于为模型引入非线性,提升模型的表达能力;4.离散特征做特征价差后可进一步引入变量;5.离散特征后模型会更加稳定;简而言之:计算简便,优化模型,增强泛化能力。
如何做特征离散化?
基于卡方的离散化方法:将数值特征的每个不同值看做一个区间,对相邻区间计算卡方统计量,大于阈值就合并,否则就停止
基于熵的离散化方法:使用合并(或分裂)的方法计算前后信息增益变化值,若差值超过阈值,则合并(或分裂)直至收敛。
什么情况下做特征离散化比较有意义?
对于LR模型来说,做特征离散化是有意义的,一方面,是因为LR模型是个参数模型,一般参数模型对于参数是有一个分布假设的,经离散化处理后的特征更容易满足这种分布假设,另一方面,LR模型更适合用于处理稀疏数据和海量特征。
利用 sklearn 库的LogisticRegression函数去拟合模型。
sklearn.linear_model.LogisticRegression()
LogisticRegression(penalty=‘l2’,dual=False,tol=1e-4,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)
简要介绍 LogisticRegression 的参数:
参数 | 含义 |
---|---|
penalty | 字符串类型:’l1’ or ‘l2’,默认:’l2’,正则项 |
dual | 布尔型,默认:False。当样本数>特征数时,dual=False,用于liblinear解决器中L2正则化 |
tol | 浮点型,默认:1e-4;迭代终止判断的误差范围 |
C | 浮点型,默认:1.0;其值等于正则化强度的倒数,为正的浮点数。数值越小表示正则化越强 |
fit_intercept | 布尔型,默认:True;指定是否应该向决策函数添加常量(即偏差或截距) |
random_state | 整型,默认None;当“solver”==“sag”或“liblinear”时使用。在变换数据时使用的伪随机数生成器的种子。如果是整数, random_state为随机数生成器使用的种子;若为RandomState实例,则random_state为随机数生成器;如果没有,随机数生成器就是’ np.random '使用的RandomState实例 |
intercept_scaling | 浮点型,默认为1;仅仅当solver是”liblinear”时有用 |
class_weight | 默认为None;与“{class_label: weight}”形式中的类相关联的权重。如果不给,则所有的类的权重都应该是1 |
solver | {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’},默认: ‘liblinear’;用于优化问题的算法。对于小数据集来说,“liblinear”是个不错的选择,而“sag”和’saga’对于大型数据集会更快。对于多类问题,只有’newton-cg’, ‘sag’, 'saga’和’lbfgs’可以处理多项损失;“liblinear”仅限于“one-versus-rest”分类。 |
max_iter | 最大迭代次数,整型,默认是100 |
multi_class | 字符串型,{ovr’, ‘multinomial’},默认:‘ovr’;如果选择的选项是“ovr”,那么一个二进制问题适合于每个标签,否则损失最小化就是整个概率分布的多项式损失。对liblinear solver无效。 |
verbose | 整型,默认是0;对于liblinear和lbfgs solver,verbose可以设为任意正数 |
warm_start | 布尔型,默认为False;当设置为True时,重用前一个调用的解决方案以适合初始化。否则,只擦除前一个解决方案。对liblinear解码器无效 |
n_jobs | 整型,默认是1;如果multi_class=‘ovr’ ,则为在类上并行时使用的CPU核数。无论是否指定了multi_class,当将’ solver ’ '设置为’liblinear’时,将忽略此参数。如果给定值为-1,则使用所有核。 |
solver优化方法补充:
liblinear:利用坐标轴下降法迭代优化函数
lbfgs:拟牛顿法的一种,利用损失函数的海塞矩阵迭代损失函数
newton-cg:牛顿法的一种
sag:随机平均梯度下降,梯度下降法的变种,是一种线性收敛算法,这个速度远比SGD快
注:newton-cg, lbfgs和sag这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
multi_class:
‘ovr’: 无论多少元逻辑回归均看作二元
‘multinomial’: 利用交叉熵损失函数
penalty调参方法
1、如果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化。
2.如果模型的特征非常多,我们希望一些不重要的特征系数归零,从而让模型系数稀疏化的话,也可以使用L1正则化
首先读取上一期处理好的数据特征:TF-IDF
import pickle
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
## 路径
tf_idf_path = 'D:/NLP_datasets/daguan/'
data_path = 'D:/NLP_datasets/daguan/new_data/'
model_path = 'D:/NLP_datasets/daguan/model'
res_path = 'D:/NLP_datasets/daguan/result'
## 读取tf-idf特征
print('读取特征')
tf_idf = open(tf_idf_path+'data_w_tfidf.pkl','rb')
# data = (x_train,y_train,x_test) #当时存储的数据模式
x_train,y_train,x_test = pickle.load(tf_idf)
trainData,testData,trainTag,testTag = train_test_split(x_train,y_train,test_size=0.3,random_state=25)
接下来利用LogisticRegression函数训练模型,调试参数;利用trainData和trainTag训练模型,用验证集检测模型效果
lr = LogisticRegression()
lr.fit(trainData,trainTag)
print('验证集正确率:',lr.score(testData,testTag))
print('训练集正确率:',lr.score(trainData,trainTag))
out
一开始未设置任何参数时,训练集的正确率为0.91且验证集为0.61,这表明模型发生过拟合,所以需要调节参数,修正模型。
# C表示正则化强度的倒数
lr = LogisticRegression(C=150,dual=True)
lr.fit(trainData,trainTag)
print('验证集正确率:',lr.score(testData,testTag))
print('训练集正确率:',lr.score(trainData,trainTag))
out
调参后模型效果有变好,但还是存在过拟合的嫌疑;该模型的F1值为:
接下来保存训练好的模型,并对测试集特征做预测,将结果保存好。
## 保存结果
import pandas as pd
df_result = pd.DataFrame({'id':range(5000),'class':y_test})
df_result.to_csv(res_path + 'LR(default)_data_w_tfidf.csv',index=False)
## 保存模型
from sklearn.externals import joblib
joblib.dump(lr, model_path + "LR(150)_data_w_tfidf.m")
SVM是一种二分类算法,其基本思想是找出在特征空间上间隔最大的‘’线性‘’分类器,SVM的学习策略是使间隔最大化。
定义函数间隔和几何间隔
函数间隔的几何含义是预测点距离超平面的最小距离,并且值为负时表示分类错误,所以函数间隔可表示分类的正确性和确信度;而几何间隔是在函数间隔基础上做了规范化处理,是的间隔值的大小有绝对意义。
最大化几何间隔
支持向量机的基本思想是求解能够正确划分训练数据集并且几何间隔最大的分离超平面,通俗来说,就是找一平面能最好的划分现有数据集的同时尽可能将数据分得最开(对最难分的实例点也有足够大的确信度将其分开)。
对于线性可分数据,采用硬间隔最大化对数据做划分
其模型即为上述讨论的基本模型:
min α 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j x i T x j − ∑ i = 1 N α i \displaystyle\min_{\alpha}\dfrac{1}{2}\displaystyle\sum_{i=1}^N{\displaystyle\sum_{j=1}^N}{\alpha_i\alpha_jy_iy_jx_i^Tx_j}-\displaystyle\sum_{i=1}^N\alpha_i αmin21i=1∑Nj=1∑NαiαjyiyjxiTxj−i=1∑Nαi
s.t. ∑ i = 1 N α i y i = 0 , α i ⩾ 0 , i = 1 , 2 , . . . , N \displaystyle\sum_{i=1}^N\alpha_iy_i=0, \alpha_i\geqslant 0,i=1,2,...,N i=1∑Nαiyi=0,αi⩾0,i=1,2,...,N
对于近似线性可分数据,利用软间隔最大化做划分
min w , b , ξ 1 2 ∥ w ∥ 2 + C ∑ i = 1 N ξ i \displaystyle\min_{w,b,\xi} {\dfrac{1}{2}\lVert w \lVert ^2+C\displaystyle\sum_{i=1}^N\xi_i} w,b,ξmin21∥w∥2+Ci=1∑Nξi
s.t.
y i ( w ⋅ x i + b ) ⩾ 1 − ξ i , i = 1 , 2 , . . . , N y_i(w\cdot x_i+b)\geqslant 1-\xi_i,{ i=1,2,...,N} yi(w⋅xi+b)⩾1−ξi,i=1,2,...,N
ξ i ⩾ 0 , i = 1 , 2 , . . . , N \xi_i\geqslant0,i=1,2,...,N ξi⩾0,i=1,2,...,N
上述模型为线性SVM的原问题,按SVM算法推导流程可得到对偶问题的模型为:
min α 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j x i T x j − ∑ i = 1 N α i \displaystyle\min_{\alpha}\dfrac{1}{2}\displaystyle\sum_{i=1}^N{\displaystyle\sum_{j=1}^N}{\alpha_i\alpha_jy_iy_jx_i^Tx_j}-\displaystyle\sum_{i=1}^N\alpha_i αmin21i=1∑Nj=1∑NαiαjyiyjxiTxj−i=1∑Nαi
s.t. ∑ i = 1 N α i y i = 0 , 0 ⩽ α i ⩽ C , i = 1 , 2 , . . . , N \displaystyle\sum_{i=1}^N\alpha_iy_i=0,0\leqslant \alpha_i\leqslant C,i=1,2,...,N i=1∑Nαiyi=0,0⩽αi⩽C,i=1,2,...,N
对于线性不可分数据,采用核技巧和软间隔最大化对模型做划分
核函数 | 表达式 | 特点 |
---|---|---|
多项式核 | K ( x , z ) = ( x ⋅ z + 1 ) p K(x,z)=(x\cdot z+1)^p K(x,z)=(x⋅z+1)p | 参数多,计算复杂 |
高斯核 | K ( x , z ) = e x p ( − ∥ x − z ∥ 2 2 σ 2 ) K(x,z)=exp(-\dfrac{\lVert x-z\lVert^2}{2\sigma ^2} ) K(x,z)=exp(−2σ2∥x−z∥2) | 应用广,对大小样本均由较好地性能 |
支持向量
在线性可分情况下,训练集的样本点中与分离超平面距离最近的样本点的实例称为支持向量,即满足 y i ( w ⋅ x i + b ) − 1 = 0 y_i(w\cdot x_i+b)-1=0 yi(w⋅xi+b)−1=0 的向量。
KKT条件
对于对偶问题 max α , β : α i ⩾ 0 θ D ( α , β ) = max α , β : α i ⩾ 0 min x L ( x , α , β ) \displaystyle\max_{\alpha,\beta :\alpha_i\geqslant 0} \theta_D(\alpha,\beta)=\displaystyle\max_{\alpha,\beta :\alpha_i\geqslant 0}{\displaystyle\min_{x}L(x,\alpha,\beta)} α,β:αi⩾0maxθD(α,β)=α,β:αi⩾0maxxminL(x,α,β)
s.t. α i ⩾ 0 , i = 1 , 2 , . . . , k \alpha_i\geqslant0,i=1,2,...,k αi⩾0,i=1,2,...,k,的KKT条件是
x ∗ , α ∗ , β ∗ x^*,\alpha^*,\beta^* x∗,α∗,β∗是对偶问题和原始问题的解。
拟采用 sklearn.svm 的 LinearSVC模型训练
1、LinearSVC使用的是平方hinge loss,SVC使用的是绝对值hinge loss
2、LinearSVC使用的是One-vs-All(也成One-vs-Rest)的优化方法,而SVC使用的是One-vs-One
3、对于多分类问题,如果分类的数量是N,则LinearSVC适合N模型,而SVC适合N(N-1)/2模型
4、对于二分类问题一般只有其中一个合适,具体问题具体对待
5、LinearSVC基于liblinear,罚函数是对截矩进行惩罚;SVC基于libsvm,罚函数不是对截矩进行惩罚
6、我们知道SVM解决问题时,问题是分为线性可分和线性不可分问题的,liblinear对线性可分问题做了优化,故在大量数据上收敛速度比libsvm快
Sklearn.svm.LinearSVC(penalty=’l2’, loss=’squared_hinge’, dual=True, tol=0.0001, C=1.0, multi_class=’ovr’,fit_intercept=True, intercept_scaling=1, class_weight=None, verbose=0, random_state=None, max_iter=1000)
其参数类似于LogsticRgression的参数,故不赘述,具体可参考:link
from sklearn import svm
svm1 = svm.LinearSVC()
svm1.fit(trainData,trainTag)
print('验证集正确率:',svm1.score(testData,testTag))
print('训练集正确率:',svm1.score(trainData,trainTag))
print('F1值:',F1(testTag,predict,average='micro'))
out
未调参数的拟合结果要优于LR模型,但仍存在过拟合的风险,尝试调节参数提高模型的正确率。
最后用所有的训练数据训练模型,预测测试集,保存预测值及模型
svm1 = svm.LinearSVC(C=10,dual=False)
svm1.fit(x_train,y_train)
## 保存模型
joblib.dump(svm1, model_path + "SVM(c10)_data_w_tfidf.m")
## 保存预测数据
y_test = svm1.predict(x_test)
df_result = pd.DataFrame({'id':range(5000),'class':y_test})
df_result.to_csv(res_path + 'SVM(c10)_data_w_tfidf.csv',index=False)
1)lr的损失函数
2 )最大熵解释为何用sigmoid函数
3)损失函数中正则化项L1和L2的理解
4)逻辑斯蒂回归能否解决非线性分类问题?
5)逻辑回归LR的特征为什么要先离散化
6)特征离散化方法
7)常用特征离散化方法
8)SVM标准问题推导
9)LogisticRegression调参小结
10)Sklearn库中Logistic Regression函数各个参数总结
11)SVC和LinearSVC的区别