- 1. 从线性回归到逻辑回归
- 2. 二元逻辑回归的模型
- 3. 二元逻辑回归的损失函数
- 4. 二元逻辑回归的损失函数的优化方法
- 5. 二元逻辑回归的正则化
- 6. 二元逻辑回归的推广:多元逻辑回归
- 7.小结
- 8. python 代码
- 参考
逻辑回归是一个分类算法,它可以处理二元分类以及多元分类。虽然它名字里面有“回归”两个字,却不是一个回归算法。那为什么有“回归”这个误导性的词呢 ?个人认为,虽然逻辑回归是分类模型,但是它的原理里面却残留着回归模型的影子。
1. 从线性回归到逻辑回归
线性回归的模型是求出输出特征向量Y和输入样本矩阵X之间的线性关系系数 $θ$,满足 $\mathbf{Y = X\theta}$ 。此时我们的Y是连续的,所以是回归模型。如果我们想要Y是离散的话,怎么办呢?一个可以想到的办法是,我们对于这个Y再做一次函数转换,变为 $g(Y)$。如果我们令 $g(Y)$ 的值在某个实数区间的时候是类别 A,在另一个实数区间的时候是类别 B,以此类推,就得到了一个分类模型。如果结果的类别只有两种,那么就是一个二元分类模型了。逻辑回归的出发点就是从这来的。
2. 二元逻辑回归的模型
对线性回归的结果做一个在函数 g 上的转换,可以变化为逻辑回归。这个函数 g 在逻辑回归中我们一般取为 sigmoid
函数,形式如下:
它有一个非常好的性质,即当z趋于正无穷时,$g(z)$ 趋于1,而当z趋于负无穷时,$g(z)$ 趋于0,这非常适合于我们的分类概率模型。另外,它还有一个很好的导数性质:
\[g^{'}(z) = g(z)(1-g(z))\]这个通过函数对 $g(z)$ 求导很容易得到,后面我们会用到这个式子。
如果我们令 $g(z)$ 中的 $z$ 为:$z=xθ$,这样就得到了二元逻辑回归模型的一般形式:
\[h_{\theta}(x) = \frac{1}{1+e^{-x\theta}}\]其中x为样本输入,$h_{\theta}(x)$ 为模型输出,可以理解为某一分类的概率大小。而 $θ$ 为分类模型的要求出的模型参数。对于模型输出 $h_{\theta}(x)$ ,我们让它和我们的二元样本输出y(假设为0和1)有这样的对应关系,如果 $h_{\theta}(x) >0.5$ ,即 $x\theta > 0$ , 则 y 为1。如果 $h_{\theta}(x) < 0.5$ ,即 $x\theta < 0$ , 则 y 为 0。y=0.5 是临界情况,此时 $x\theta = 0$ 为, 从逻辑回归模型本身无法确定分类。
$h_{\theta}(x)$ 的值越小,而分类为 0 的的概率越高,反之,值越大的话分类为1的的概率越高。如果靠近临界点,则分类准确率会下降。
此处我们也可以将模型写成矩阵模式:
\[h_{\theta}(X) = \frac{1}{1+e^{-X\theta}}\]其中 $h_{\theta}(X)$ 为模型输出,为 $m \times 1$的维度。X为样本特征矩阵,为$m \times n$的维度。$θ$ 为分类的模型系数,为$m \times 1$的向量。
3. 二元逻辑回归的损失函数
线性回归的损失函数,由于线性回归是连续的,所以可以使用模型误差的的平方和来定义损失函数。但是逻辑回归不是连续的,自然线性回归损失函数定义的经验就用不上了。不过我们可以用最大似然法来推导出我们的损失函数。
我们知道,按照第二节二元逻辑回归的定义,假设我们的样本输出是0或者1两类。那么我们有:
我们知道,按照第二节二元逻辑回归的定义,假设我们的样本输出是0或者1两类。那么我们有:
\[P(y=1|x,\theta ) = h_{\theta}(x)\] \[P(y=0|x,\theta ) = 1- h_{\theta}(x)\]把这两个式子写成一个式子,就是:
\(P(y|x,\theta ) = h_{\theta}(x)^y(1-h_{\theta}(x))^{1-y}\) 其中y的取值只能是0或者1。
得到了 y 的概率分布函数表达式,我们就可以用似然函数最大化来求解我们需要的模型系数 $θ$ 。
为了方便求解,这里我们用对数似然函数最大化,对数似然函数取反即为我们的损失函数 $J(\theta)$ 。其中:似然函数的代数表达式为:
\[L(\theta) = \prod\limits_{i=1}^{m}(h_{\theta}(x^{(i)}))^{y^{(i)}}(1-h_{\theta}(x^{(i)}))^{1-y^{(i)}}\]其中m为样本的个数。
对似然函数对数化取反的表达式,即损失函数表达式为:
\[J(\theta) = -lnL(\theta) = -\sum\limits_{i=1}^{m}(y^{(i)}log(h_{\theta}(x^{(i)}))+ (1-y^{(i)})log(1-h_{\theta}(x^{(i)})))\]损失函数用矩阵法表达更加简洁:
\[J(\theta) = -Y^Tlogh_{\theta}(X) - (E-Y)^T log(E-h_{\theta}(X))\]其中$E$ 为全 1 向量。
4. 二元逻辑回归的损失函数的优化方法
对于二元逻辑回归的损失函数极小化,有比较多的方法,最常见的有梯度下降法,坐标轴下降法,等牛顿法等。这里推导出梯度下降法中 $θ$ 每次迭代的公式。由于代数法推导比较的繁琐,我习惯于用矩阵法来做损失函数的优化过程,这里给出矩阵法推导二元逻辑回归梯度的过程。
对于 $J(\theta) = -Y^T logh_{\theta}(X) - (E-Y)^T log(E-h_{\theta}(X))$ ,我们用 $J(\theta)$ 对 $θ$ 向量求导可得:
\[\begin{equation*} \begin{split} \frac{\partial}{\partial\theta}J(\theta) = &X^T[\frac{1}{h_{\theta}(X)}\odot h_{\theta}(X)\odot (E-h_{\theta}(X))\odot (-Y)] +\\ &X^T[\frac{1}{E-h_{\theta}(X)}\odot h_{\theta}(X)\odot (E-h_{\theta}(X))\odot (E-Y)] \end{split} \end{equation*}\]这一步我们用到了向量求导的链式法则,和下面三个基础求导公式的矩阵形式:
\[\frac{\partial}{\partial x}logx = 1/x\] \[\frac{\partial}{\partial z}g(z) = g(z)(1-g(z)) (g(z)为sigmoid函数)\] \[\frac{\partial x\theta}{\partial \theta} = x\]对于刚才的求导公式我们进行化简可得:
\[\frac{\partial}{\partial\theta}J(\theta) = X^T(h_{\theta}(X) - Y )\]从而在梯度下降法中每一步向量 $θ$ 的迭代公式如下:
\[\theta = \theta - \alpha X^T(h_{\theta}(X) - Y )\]其中,$α$ 为梯度下降法的步长。
实践中,我们一般不用操心优化方法,大部分机器学习库都内置了各种逻辑回归的优化方法,不过了解至少一种优化方法还是有必要的。
5. 二元逻辑回归的正则化
逻辑回归也会面临过拟合问题,所以我们也要考虑正则化。常见的有 L1 正则化和 L2 正则化。
逻辑回归的 L1 正则化的损失函数表达式如下,相比普通的逻辑回归损失函数,增加了 L1 的范数做作为惩罚,超参数 $α$ 作为惩罚系数,调节惩罚项的大小。
-
二元逻辑回归的 L1 正则化损失函数表达式如下:
\[J(\theta) = -Y^T\bullet logh_{\theta}(X) - (E-Y)^T\bullet log(E-h_{\theta}(X)) +\alpha ||\theta||_1\]其中 $||\theta||_1$ 为 $θ$ 的L1范数。
逻辑回归的 L1 正则化损失函数的优化方法常用的有坐标轴下降法和最小角回归法。
-
二元逻辑回归的L2正则化损失函数表达式如下:
其中 $||\theta||_2$ 为 $θ$ 的L2范数。
逻辑回归的L2正则化损失函数的优化方法和普通的逻辑回归类似。
6. 二元逻辑回归的推广:多元逻辑回归
逻辑回归的模型和损失函数都局限于二元逻辑回归,实际上二元逻辑回归的模型和损失函数很容易推广到多元逻辑回归。比如总是认为某种类型为正值,其余为 0 值,这种方法为最常用的 one-vs-rest,简称OvR.
另一种多元逻辑回归的方法是 Many-vs-Many(MvM),它会选择一部分类别的样本和另一部分类别的样本来做逻辑回归二分类。最常用的是 One-Vs-One(OvO)。OvO是 MvM 的特例。每次我们选择两类样本来做二元逻辑回归。
这里只介绍多元逻辑回归的 softmax
回归的一种特例推导:
首先回顾下二元逻辑回归。
\[P(y=1|x,\theta ) = h_{\theta}(x) = \frac{1}{1+e^{-x\theta}} = \frac{e^{x\theta}}{1+e^{x\theta}}\] \[P(y=0|x,\theta ) = 1- h_{\theta}(x) = \frac{1}{1+e^{x\theta}}\]其中 y 只能取到 0 和 1 。则有:
\[ln\frac{P(y=1|x,\theta )}{P(y=0|x,\theta)} = x\theta\]如果我们要推广到多元逻辑回归,则模型要稍微做下扩展。
我们假设是K元分类模型,即样本输出y的取值为1,2,。。。,K。
根据二元逻辑回归的经验,我们有:
\[ln\frac{P(y=1|x,\theta )}{P(y=K|x,\theta)} = x\theta_1\] \[ln\frac{P(y=2|x,\theta )}{P(y=K|x,\theta)} = x\theta_2\] \[....\] \[ln\frac{P(y=K-1|x,\theta )}{P(y=K|x,\theta)} = x\theta_{K-1}\]加上概率之和为1的方程如下:
\(\sum\limits_{i=1}^{K}P(y=i|x,\theta ) = 1\) 从而得到K个方程,里面有K个逻辑回归的概率分布。
解出这个K元一次方程组,得到K元逻辑回归的概率分布如下:
\[P(y=k|x,\theta ) = e^{x\theta_k} \bigg/ 1+\sum\limits_{t=1}^{K-1}e^{x\theta_t} \qquad k = 1,2,...K-1\] \[P(y=K|x,\theta ) = 1 \bigg/ 1+\sum\limits_{t=1}^{K-1}e^{x\theta_t}\]
多元逻辑回归的损失函数推导以及优化方法和二元逻辑回归类似,
7.小结
逻辑回归尤其是二元逻辑回归是非常常见的模型,训练速度很快,虽然使用起来没有支持向量机(SVM)那么占主流,但是解决普通的分类问题是足够了,训练速度也比起SVM要快不少。
8. python 代码
将数据分类 (二分类)
import matplotlib.pyplot as plt
import numpy as np
# 加载数据
def load_file(filename):
file = open(filename)
x = list()
y = list()
for line in file.readlines():
line = line.strip().split()
x.append([1, float(line[0]), float(line[1])])
y.append(float(line[-1]))
xmat = np.mat(x)
ymat = np.mat(y).T
file.close()
return xmat, ymat
def w_calc(xmat, ymat, alpha=0.001, max_iter=100001):
'''
:param xmat: 样本
:param ymat: 样本标签
:param alpha: 学习率
:param max_iter: 最大迭代次数
:return: 系数矩阵
'''
# 初始化W 系数矩阵 三行一列
W = np.mat(np.random.randn(3, 1))
# 更新 W
for i in range(max_iter):
# sigmoid 函数
H = 1 / (1 + np.exp((-xmat * W)))
# 损失函数求偏导后的结果
dw = xmat.T * (H - ymat)
W -= alpha * dw
return W
xmat, ymat = load_file('test.txt')
# 系数矩阵
W = w_calc(xmat, ymat)
w0 = W[0, 0]
w1 = W[1, 0]
w2 = W[2, 0]
plotx1 = np.arange(2, 6, 0.01)
plotx2 = -(w0 + w1 * plotx1) / w2
# 得到的分类线
plt.plot(plotx1, plotx2)
# .A 将矩阵转化为 array 的形式
plt.scatter(xmat[:, 1][ymat == 0].A, xmat[:, 2][ymat == 0].A)
plt.scatter(xmat[:, 1][ymat == 1].A, xmat[:, 2][ymat == 1].A)
plt.show()
结果: