赞
踩
逻辑回归中,因变量取值是一个二元分布,模型学习 E [ y ∣ x ; θ ] E [y | x; \theta] E[y∣x;θ], 给定自变量和超参数后,得到因变量的期望,并基于期望来处理预测分类。
LR模型中,
log
p
1
−
p
=
θ
T
x
\log \frac{p}{1-p}=\theta^{\mathrm{T}} x
log1−pp=θTx
其中, p 是预测输入为正样本的概率。
定义 事件的几率(odds)为,该事件发生的概率与该事件不发生的概率的比值
p
1
−
p
\frac{p}{1-p}
1−pp.
逻辑斯谛回归与线性回归的区别与相同点
逻辑斯谛回归是线性回归在分类问题的推广,使用sigmoid函数作为 link 函数。逻辑回归可以看作广义线性模型在因变量服从二元分布是的一个特殊情况。
线性回归使用最小二乘法进行参数估计,逻辑斯谛回归使用极大似然法,最大化预测属于实际的概率。其实,最小二乘法是在自变量x 与超参数 θ \theta θ 确定,因变量y服从正态分布的假设下,使用极大似然估计的一个化简。
LR和SVM(线性核)的联系与区别
LR和SVM的不同
1、损失函数的不同
LR是cross entropy(对数似然损失函数),SVM的损失函数是最大化间隔距离(合页损失);
2、SVM不能产生概率,LR可以产生概率;
LR 拟合的是概率分布。
3、SVM自带结构风险最小化,LR则是经验风险最小化
在假设空间、损失函数和训练集确定的情况下,经验风险最小化即最小化损失函数;
结构最小化是为了防止过拟合,在经验风险的基础上加上表示模型复杂度的正则项。
4、LR和SVM在实际应用的区别
根据经验来看,对于小规模数据集,SVM的效果要好于LR,但是大数据中,SVM的计算复杂度受到限制,而LR因为训练简单,可以在线训练,所以经常会被大量采用。
n 是特征数量, m是样本数:
(1)如果 n 相对于 m 很大,(比如,n=1万, m = 10-1000) 使用LR算法或者 不带核的SVM;
(2) 如果 n 很小,m的数量适中(比如, n = 1-1000, m = 10-10000)
使用带有核函数的SVM算法
(3)如果n 很小, m很大, (n = 1-1000, m = 50000+)
增加更多的feature,使用LR或者不带核函数的SVM。
LR和不带核的SVM类似。
5、SVM的处理方法是只考虑support vectors,也就是和分类最相关的少数点,去学习分类器。
而逻辑回归通过非线性映射,大大减小了离分类平面较远的点的权重,相对提升了与分类最相关的数据点的权重。
逻辑斯蒂回归是假设因变量服从伯努利分布。
也就是说,经过sigmoid函数,将 x 映射为
ϕ
\phi
ϕ 后,x与y的概率分布仍然是指数分布簇,即模型仍是广义线性模型。
LR模型定义:
线性二分类模型:
f
(
x
)
=
θ
T
x
f(x)=\theta^{T} x
f(x)=θTx
其中,
f
(
x
)
=
0
f(x)=0
f(x)=0是决策平面。
逻辑回归决策函数是将此线性二分类嵌套一个sigmoid函数:
h
θ
(
x
)
=
sigmoid
(
f
(
x
)
)
=
1
1
+
e
−
θ
T
x
h_{\theta}(x)=\operatorname{sigmoid}(f(x))=\frac{1}{1+e^{-\theta^{T} x}}
hθ(x)=sigmoid(f(x))=1+e−θTx1
该式子取值在0~1,它的含义是,二分类中,类别y 为正类(即1)的概率。
(为什么
h
θ
(
x
)
h_{\theta}(x)
hθ(x)可以看做是正类的概率?
因为,在线性二分类中,
θ
T
x
>
0
\theta^{T} x>0
θTx>0属于正类,因此,这里
h
θ
(
x
)
>
0.5
h_{\theta}(x)>0.5
hθ(x)>0.5属于正类。
h
θ
(
x
)
h_{\theta}(x)
hθ(x)取值又在0~1之间,因此,在二分类中,把
h
θ
(
x
)
h_{\theta}(x)
hθ(x)当作正类的概率没问题。
这里,有点本末倒置,因为构建LogisticRegression时,就是引入概率 p 来解释 y,通过 log[ p/(1-p)]=y
来进行连接 p 和 y 的关系。
)
因此,在二分类中,
P
(
Y
=
1
∣
x
)
=
exp
(
θ
T
x
)
1
+
exp
(
θ
T
x
)
P
(
Y
=
0
∣
x
)
=
1
1
+
exp
(
θ
T
x
)
P(Y=1 | x)=\frac{\exp (\theta^{T} x)}{1+\exp (\theta^{T} x)}\\ P(Y=0 | x)=\frac{1}{1+\exp (\theta^{T} x)}
P(Y=1∣x)=1+exp(θTx)exp(θTx)P(Y=0∣x)=1+exp(θTx)1
其中,
θ
T
x
=
w
⋅
x
+
b
\theta^{T} x = w \cdot x+b
θTx=w⋅x+b
此外, 如果取Y的取值为{+1, -1 }; 最终梯度计算会不一样。
最大似然函数:
L
(
θ
)
=
p
(
y
^
∣
X
;
θ
)
=
∏
i
=
1
m
p
(
y
(
i
)
∣
x
(
i
)
;
θ
)
=
∏
i
=
1
m
(
h
θ
(
x
(
i
)
)
)
y
(
i
)
(
1
−
h
θ
(
x
(
i
)
)
)
(
1
−
y
(
i
)
)
(这里也体现了LR满足伯努利分布。)
令损失函数为负对数似然函数:
loss
(
θ
)
=
−
log
(
L
(
θ
)
)
=
−
{
∑
i
=
1
m
y
(
i
)
log
(
h
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
h
(
x
(
i
)
)
)
}
\operatorname{loss}(\theta)=-\log (L(\theta))=- \left\{ \sum_{i=1}^{m} y^{(i)} \log \left(h\left(x^{(i)}\right)\right) + \left(1-y^{(i)}\right) \log \left(1-h\left(x^{(i)}\right)\right) \right\}
loss(θ)=−log(L(θ))=−{i=1∑my(i)log(h(x(i)))+(1−y(i))log(1−h(x(i)))}
化简得到:
l
o
s
s
(
θ
)
=
−
∑
i
=
1
m
[
(
y
−
1
)
θ
T
x
−
l
o
g
(
1
+
e
−
θ
T
x
)
]
=
−
∑
i
=
1
m
[
y
θ
T
x
−
l
o
g
(
1
+
e
θ
T
x
)
]
loss(\theta) = - \sum_{i=1}^{m} [ (y-1)\theta^Tx - log(1+e^{-\theta^Tx})]\\ = - \sum_{i=1}^{m} [ y\theta^Tx - log(1+e^{\theta^Tx})]
loss(θ)=−i=1∑m[(y−1)θTx−log(1+e−θTx)]=−i=1∑m[yθTx−log(1+eθTx)]
对
l
o
s
s
(
θ
)
loss(\theta)
loss(θ) 求极小值。
∂ ∂ θ J ( θ ) = − ∑ i = 1 m ( y ( i ) − h θ ( x ( i ) ) ) ⋅ x i \frac{\partial}{\partial \theta} J(\theta) = -\sum_{i=1}^{m}\left(y^{(i) }-h_{\theta}\left(x^{(i)}\right)\right) \cdot x_{i} ∂θ∂J(θ)=−i=1∑m(y(i)−hθ(x(i)))⋅xi
这也是梯度下降法计算的参数梯度。
参数更新:
沿着负梯度方向进行更新。
w
←
w
−
α
⋅
∂
∂
w
J
(
w
,
b
)
w \leftarrow w-\alpha \cdot \frac{\partial}{\partial w} J(w,b)
w←w−α⋅∂w∂J(w,b)
b
←
b
−
α
⋅
∂
∂
b
J
(
w
,
b
)
b \leftarrow b-\alpha \cdot \frac{\partial}{\partial b} J(w,b)
b←b−α⋅∂b∂J(w,b)
假如有y 有K类,使用多项逻辑回归(softmax regression)来分类。
p
(
x
=
k
)
=
e
w
k
⋅
x
∑
i
=
1
K
e
w
k
⋅
x
p(x = k) = \frac{e^{w_k\cdot x} } {\sum_{i = 1}^{K}{e^{w_k\cdot x}}}
p(x=k)=∑i=1Kewk⋅xewk⋅x
损失函数:
L
o
s
s
(
w
)
=
∑
i
=
1
N
∑
j
=
1
k
[
s
i
g
n
(
y
i
=
c
)
l
o
g
(
P
(
Y
=
c
∣
x
)
]
Loss( w ) = \sum\limits_{i = 1}^{N} \sum\limits_{j = 1}^{k} [ sign(y_i = c) log(P(Y = c | x) ]
Loss(w)=i=1∑Nj=1∑k[sign(yi=c)log(P(Y=c∣x)]
或者采用 one-vs-rest 方法,构建 K-1 个逻辑斯蒂回归模型。
1.减少特征数量;
2.正则化
损失函数:
L
o
s
s
(
w
)
=
−
1
N
∑
i
=
1
N
[
y
i
l
o
g
(
P
(
Y
=
1
∣
x
)
+
(
1
−
y
i
)
l
o
g
(
P
(
Y
=
0
∣
x
)
]
+
λ
2
∗
N
∑
j
=
1
N
θ
j
2
=
−
1
N
∑
i
=
1
N
[
y
i
(
w
x
+
b
)
−
l
o
g
(
1
+
l
o
g
(
1
+
e
w
x
+
b
)
]
+
λ
2
∗
N
∑
j
=
1
N
θ
j
2
Loss( w ) = -\frac{1}{N}\sum\limits_{i = 1}^{N} [y_i log(P(Y = 1 | x) + (1 - y_i) log( P( Y = 0 | x )] + \frac{\lambda}{2*N}\sum_{j = 1}^{N} {\theta_j^2 }\\ = -\frac{1}{N} \sum\limits_{i = 1}^{N} [y_i (wx + b) - log(1 + log( 1 + e ^{wx + b})] + \frac{\lambda}{2*N}\sum_{j = 1}^{N} {\theta_j^2 }
Loss(w)=−N1i=1∑N[yilog(P(Y=1∣x)+(1−yi)log(P(Y=0∣x)]+2∗Nλj=1∑Nθj2=−N1i=1∑N[yi(wx+b)−log(1+log(1+ewx+b)]+2∗Nλj=1∑Nθj2
λ
\lambda
λ为正则化系数。
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=‘lbfgs’, max_iter=100, multi_class=‘auto’, verbose=0, warm_start=False, n_jobs=None, l1_ratio=None)
在sklearn 中, 可以设置 超参数C(正则项惩罚系数的倒数)
L1,L2惩罚项的区别
L1容易使得LR系数 w 更加稀疏;
L2 相当于weight decay,目标函数变为凸函数,梯度下降法和L-BFGS都能收敛到全局最优解。
正则化项实际上是给了模型一个先验知识,L2正则相当于添加了一个均值为0,协方差为 1/λ 的高斯分布先验。
LogisticRegression二分类的python实现,由于LogisticRegression没有解释解,使用梯度下降法进行求解。
注:以下参数更新部分代码未必正确。
import sklearn.datasets as datasets import numpy as np from sklearn.linear_model import LogisticRegression as LR class LogisticRegression(): def __init__(self,alpha=0.01,epochs=3): self.W = None self.b = None self.alpha = alpha self.epochs = epochs def fit(self,X,y): # 设定种子 np.random.seed(10) self.W = np.random.normal(size=(X.shape[1])) self.b = 0 for epoch in range(self.epochs): if epoch%50 == 0: print("epoch",epoch) w_derivate = np.zeros_like(self.W) b_derivate = 0 for i in range(len(y)): # 这里是加上负梯度 w_derivate += (y[i] - 1/(1+np.exp(-np.dot(X[i],self.W.T)-self.b)))*X[i] b_derivate += (y[i] - 1/(1+np.exp(-np.dot(X[i],self.W.T)-self.b))) # ?这里没必要就行求平均值,把向量转变成了标量! self.W = self.W + self.alpha*np.mean(w_derivate,axis=0) self.b = self.b + self.alpha*np.mean(b_derivate) return self def predict(self,X): p_1 = 1/(1 + np.exp(-np.dot(X,self.W) - self.b)) return np.where(p_1>0.5, 1, 0) def accuracy(pred, true): count = 0 for i in range(len(pred)): if(pred[i] == true[i]): count += 1 return count/len(pred) def normalize(x): return (x - np.min(x))/(np.max(x) - np.min(x)) if __name__ == "__main__": # input datasets digits = datasets.load_breast_cancer() X = digits.data y = digits.target # 归一化 X_norm = normalize(X) X_train = X_norm[:int(len(X_norm)*0.8)] X_test = X_norm[int(len(X_norm)*0.8):] y_train = y[:int(len(X_norm)*0.8)] y_test = y[int(len(X_norm)*0.8):] # model 1 lr = LogisticRegression(epochs=500,alpha=0.03) lr.fit(X_train,y_train) y_pred = lr.predict(X_test) # 评估准确率 acc = accuracy(y_pred, y_test) print("acc", acc) # model 2 clf_lr = LR() clf_lr.fit(X_train, y_train) y_pred2 = clf_lr.predict(X_test) print("acc2", accuracy(y_pred2, y_test))
运行结果:
acc 0.9473684210526315
acc2 0.9298245614035088
可以看到自己写的LR模型比sklearn里边实现的效果更好,原因,可能是我们设定的超参数(如alpha,epoch)更加适合这个小数据集吧。
2020-10-16更新:
以上的LR模型代码实现应该是有点问题的,如果按照理论,应该是:
class LogisticRegression(): def __init__(self,alpha=0.01,epochs=3): self.W = None self.b = None self.alpha = alpha self.epochs = epochs def fit(self,X,y): # 设定种子 np.random.seed(10) self.W = np.random.normal(size=(X.shape[1])) self.b = 0 for epoch in range(self.epochs): loss = 0.0 if epoch%100 == 0: print("epoch",epoch) w_derivate = np.zeros_like(self.W) b_derivate = 0 for i in range(len(y)): # 这里是加上负梯度 w_derivate += (y[i] - 1/(1+np.exp(-np.dot(X[i],self.W.T)-self.b)))*X[i] b_derivate += (y[i] - 1/(1+np.exp(-np.dot(X[i],self.W.T)-self.b))) loss += (y[i]*(np.dot(X[i],self.W.T)+self.b) - 1/(1+np.exp(-np.dot(X[i],self.W.T)-self.b))) loss /= len(y) loss *= -1 if epoch % 100 == 0: print("loss", loss) #print("w", w_derivate) w_derivate /= len(y) b_derivate /= len(y) self.W = self.W + self.alpha*w_derivate self.b = self.b + self.alpha*b_derivate return self def predict(self,X): p_1 = 1/(1 + np.exp(-np.dot(X,self.W) - self.b)) return np.where(p_1>0.5, 1, 0)
同样的数据集,使用1000 epochs, 0.1的学习率:
epoch 0 loss 0.4458747565746601 epoch 100 loss 0.46556179062935027 epoch 200 loss 0.43805751597460546 epoch 300 loss 0.40752544455838813 epoch 400 loss 0.3775484524293621 epoch 500 loss 0.3486239389088694 epoch 600 loss 0.32095136138793146 epoch 700 loss 0.2946335832030799 epoch 800 loss 0.2697025483110918 epoch 900 loss 0.2461376580506989 acc 0.9210526315789473 # my implement acc2 0.9298245614035088 # sklearn LR model
从损失看,这个实现应该是准确的。之前实现,把参数更新量求平均值变成一个标量的方式应该是错误的,只是这种平滑的方式居然给模型学习带来意想不到的效果,所以,上述的实现就不覆盖了。
LR特征离散化原因:
1.离散特征容易增加和减少特征,快速迭代模型;
2.稀疏向量内积乘法运算速度更快,计算易于存储、扩展;
3.离散特征对异常值不敏感,鲁棒性强;
4.简化了逻辑斯蒂模型,降低模型过拟合。
5.离散化的特征方便进行特征交叉,使得模型的表达能力更强。
把高度相关的特征去掉原因:
使得模型的可解释性更强;提高训练速度。
如果模型很多特征高度相关,损失函数本身收敛了,参数仍然没有收敛,训练时间变长。
避免局部极小方法:
1.以多组不同参数值进行初始化;
2.使用随机梯度下降,加入随机的因素。
特征系数绝对值能认为是特征重要性吗?
1.特征系数绝对值越大,对分类效果的影响越显著,但不能认为特征系数更大的特征更重要。
2.改变变量尺度会改变系数绝对值;
3.特征相关,系数可以认为从一个特征转移到另一个特征;
逻辑斯谛回归需要标准化?
理论上不需要,因为特征尺寸发生改变,并不影响到最优决策面;但是,为了加快模型的收敛速度,一般也进行标准化。
但是,像Lasso回归,岭回归,是需要对数据进行标准化的,因为在输入的缩放比例下不是等变的。
特征维度很高,对LR模型造成的影响
特征多,很可能噪声维度灾难,也就是数据稀疏,LR模型容易欠拟合,效果会下降。
最近开通了个公众号,主要分享推荐系统,风控等算法相关的内容,感兴趣的伙伴可以关注下。
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。