扫码查看

逻辑回归(Logistic Regression)

首先要明确一点,逻辑回归不仅仅可以处理回归问题,也可以处理分类问题。

线性回归的问题

当我们遇到如下数据的时候,可以用线性回归很好的进行拟合。

但是线性回归对离群点(outliers)很敏感,如我们加入一个离群点,就会做出如下拟合。这样的拟合会让正常的数据点的预测变得不准确。

这样我们就需要一个非线性的函数来拟合。于是伟大的科学家就选择了sigmoid函数。为什么要选择sigmoid函数?

Sigmoid函数

Sigmoid函数形式如下:
\[g(z) = \frac{1}{1+e^{-z}}\]
函数图如下:

可见sigmoid函数将 $(-\infty,+\infty) \(的值映射到\)(0,1)$区间内,在二分类问题中,我们可以认为若预测值小于0.5,则其分类为0,若预测值大于0.5,则其分类为1。

当然具体问题具体分析,当我们预测病人癌症患病概率时,若预测值为0.49,表明该病人有0.49的可能性患癌,我们可以适当调整阈值,比如\(x=0.3\)等,这些都是后话。

Sigmoid的导数

在这里不得不提一下它的导数,因为在逻辑回归中,计算梯度下降必然要计算其导数。sigmoid函数优秀的性质可以让我们很方便的计算其导数。
\[\begin{align}\frac{\mathrm{d}g(z)}{\mathrm{d}z} &= \frac{-1}{(1+e^{-z})^2}·(-e^{-z})\\&= \frac{1}{1+e^{-z}}·(1-\frac{1}{1+e^{-z}})\\&= g(z)(1-g(z))\end{align}\]

\(h_\theta (x)\)

自然而然地,我们可以假设:
\[h_\theta (x) = \frac{1}{1+e^{-\theta^T x}}\]
其中:
\[\theta = \left<\theta_1,\theta_2,...,\theta_n\right>\\x = {x^1,x^2,...,x^m}\]
这里\(x^1\)代表的是第一个数据,包括n个特征值\({x_1,x_2,...,x_n}\)和1个label。

逻辑回归

下面我们开始进行逻辑回归的一次运算。

数据我们使用的时sklearn库中的癌症预测数据,通过cancer.DESCR可以看到该数据集有569个实例,每个数据包括10个特征和1个标签以表示是否患病。

from sklearn import datasets

cancer = datasets.load_breast_cancer()
data = cancer.data
target = cancer.target
print(cancer.DESCR)

根据线性回归的计算过程,我们不难总结出逻辑回归的几个步骤:

  1. 随机初始化\(\theta\)
  2. 找到合适的损失函数
  3. 通过梯度下降法迭代找出使损失函数最小的\(\theta\)值。

1.随机初始化\(\theta\)

通过python函数来实现,没什么好说的。

2.找到合适的损失函数

不同于线性回归,在处理二分类问题中,我们有两个目标值0和1,而我们预测出的却是在$(-\infty,+\infty) $之间的离散值,我们需要达到两点:

1.在预测为正例时,我们希望预测值越靠近1,损失函数越小。
\[J(\theta) =-log(h_\theta (x))\]

2.在预测为反时,我们希望预测值越靠近0,损失函数越小。
\[J(\theta) = -log(1-h_\theta (x))\]

将二者结合,我们得到:

\[J(\theta) = \frac{1}{m}\sum_{i=1}^m\left(-y·log(h_\theta (x))-(1-y)·log(1-h_\theta (x))\right)\]

3.通过梯度下降法迭代找出使损失函数最小的\(\theta\)

又到了我们最喜欢的公式推导环节,令:
\[z = \theta x = \theta_0x_0+\theta_1x_1+...\\h_\theta(x)=g(z)\]
注意这里\(x_1\)代表一个向量,由所有实例的第1个特征值组成\(x_1^0,x_1^1,x_1^2...\)

先来计算\(h_\theta(x^i)\)对第\(j\)个参数的偏导(根据上面的sigmoid导数和链式法则可以推出):
\[\begin{align}\frac{\partial h_\theta(x^i)}{\partial \theta_j}&= \frac{\partial g(z^i)}{\partial z^i}·\frac{\partial z^i}{\partial \theta_j}\\&= h_\theta(x^i)·(1-h_\theta(x^i))·\frac{\partial z^i}{\partial \theta_j}\\&= h_\theta(x^i)·(1-h_\theta(x^i))·x_j^i\end{align}\]

然后:

$$
\begin{align}
J(\theta) &= \frac{1}{m}\sum_{i=1}^m\left(-y^i·log(h_\theta (x^i))-(1-y^i)·log(1-h_\theta (x^i))\right)\
\frac{\partial J(\theta)}{\partial \theta_i} &= \frac{1}{m}\sum_{i=1}^m\left(\frac{-y^i}{h_\theta (x^i)}·\frac{\partial h_\theta(x^i)}{\partial \theta_j}-\frac{(1-y^i)}{1-h_\theta (x^i)}·\frac{\partial(1- h_\theta(x^i))}{\partial \theta_j}\right)\
&= \frac{1}{m}\sum_{i=1}^m(x_j^i·(h_\theta (x^i)-y^i))(利用之前推导的式子)

\end{align}
$$

用矩阵描述

因为在计算机处理时,经常用Numpy等进行矩阵上的计算,所以我想用矩阵来描述一下。

定义矩阵:
\[\begin{align}X &= \{X^0,X^1,...X^m\}(共m个数据,shape:m*n)\\X^i&=\{X^i_0,X^i_1,...X^i_n\}(每个数据n个特征值,shape:1*n)\\Y &= \{Y^0,Y^1,...Y^m\}(每个数据的label,shape:1*m)\\\theta&= \{ \theta_0,\theta_1...\theta_n \}(需要优化的参数,shape:1*m)\end{align}\]
上述定义中, \(Y\)以及\(\theta\)有些特殊,在sklearn中读出的标签值(data.target)的维度实际上为(m,),如下图,含义是他是一个有569个元素的list,而不是一个矩阵。

通常我习惯用reshape函数处理成m*1维的矩阵。

target.reshape(-1, 1)

\(\theta\)为了与target保持一致,我也如此初始化(仅为个人习惯):

theta = np.ones(data.shape[1])

下面开始推导:

参考

逻辑回归代价函数及其梯度下降公式推导

逻辑回归中如何应用梯度下降算法与损失函数

12-13 23:32
查看更多