机器学习笔记(3)逻辑回归

机器学习笔记(3)逻辑回归

在线性回归中我们需要预测的是连续的值,而在逻辑回归中我们需要预测的是离散值。虽然该算法中有“回归”二字,但是做的是分类的问题。

场景描述

线性回归有以下的应用场景,例如邮件的过滤,需要判断一封邮件是否是垃圾邮件。又或是肿瘤的诊断,需要判断肿瘤是良性或是恶性等等。

基本概念

应该如何构建一个分类算法呢?
先来看看将我们前面所学的线性回归直接应用到分类问题中会怎么样。
在肿瘤的例子中,我们选择肿瘤的大小这一特征来预测肿瘤是良性还是恶性。

我们这里定义 $y\in \left\{ 0,1 \right\}$ , 0 代表良性肿瘤,1 代表恶性肿瘤。
下图中我们有几个正例和反例,且我们已经根据样本拟合出了一条假设函数的直线。我们将输出的阈值设为0.5,当假设函数的输出值大于等于0.5时,我们预测 y = 1 ,当输出值小于0.5时我们预测 y = 0。
ml_11
根据这条直线我们可预测当肿瘤的size大于这一点(y=0.5时,直线上的点)时我们预测 y = 1,小于这一点时我们则预测 y = 0。这样看来这个假设函数可以很好的将正负样本区分开来,线性回归在分类的表现上似乎很不错,但是且慢,让我们看下面的例子:
ml_12
这里我们新增加了一个样本点,并且根据这个新的训练集拟合出了一个新的假设函数,该假设函数的图像如上方蓝色直线所示。从这条直线看来,分类的效果并不好,蓝色点左边的预测 y = 0,右边的预测为 y = 1 则它对相当一部分的样本点做出了错误的预测。
由此可见线性回归并不适合直接应用到分类的任务中。

逻辑回归模型

其实我们稍作修改就可以将线性回归应用到分类问题中。
我们需要给定一个新的假设函数,这个新的假设函数输出的值应该在0到1之间($0\leq h_\theta\leq1$)。下面我们给出新的假设函数的定义:
$$\Large h_\theta(x)=g(\Theta^Tx)$$
$$\huge\qquad\Downarrow \normalsize Z=\Theta X$$
$$\Large h_\theta(x)=g(Z)=\frac{1}{1+e^{-Z}}=\frac{1}{1+e^{-\Theta X}}$$
其中$g(Z) = \frac{1}{1+e^{-Z}}$是对数几率函数,它单调可微,是一种“Sigmoid 函数”它将Z值转化为一个接近 0 或 1 的 y 值,并且其输出值在 Z = 0 附近变化很陡。
注:Sigmoid 函数即形似 S 的函数,对率函数是 Sigmoid 函数最重要的代表
ml_13
假设函数的解释
$h_\theta(x)=$输入一个 x,给出 y = 1 的概率估计。
例:当 $x = \begin{bmatrix}x_0\\ x_1\end{bmatrix} = \begin{bmatrix}1\\ tumor\,size\end{bmatrix}$时,$h_\theta(x) =0.7$
我们可以说,有70%的概率肿瘤是恶性的。

决策边界

ml_13

从上面 Sigmoid 函数的图像可以看出,当我们将假设函数的阈值设为 0.5 时,Z的值在 0 处便成为了一个分界点。
当$h_\theta \geq0.5$ , 我们预测 y = 1
当$h_\theta <0.5$ , 我们预测 y = 0

当$Z \geq 0$ , 我们预测 y = 1
当$Z < 0$ , 我们预测 y = 0

假设我们有一个如下图所示的一个训练集

ml_14

我们有了以下的假设函数,并已经拟合出了参数$\Theta$
$$\Large h_\theta(x)=g(\theta_0+\theta_1x_1+\theta_2x_2)$$
$$\Huge\Downarrow\normalsize \Theta=\begin{bmatrix} -3 \\ 1 \\ 1 \end{bmatrix}$$
$$\Large h_\theta(x)=g(-3+x_1+x_2)$$
那么,我们可以预测
当 $-3+x_1+x_2\geq0$时, y = 1
当 $-3+x_1+x_2<0 $时, y = 0
这里可以看出$x_1+x_2=3$ 可以作为预测的分界线,接着我们在图中做出关于$x_1,x_2$的图像,即图中红色的线。我们将这个线称为“决策边界”
ml_15
假设函数的不同,得到的决策边界也不尽相同。当假设函数变得复杂时,我们也可以得到非线性的决策边界。
比如下面的例子
ml_16

$$\Large h_\theta(x)=g(\theta_0+\theta_1x_1+\theta_2x_2+\theta_3x_1^2+\theta_4x_2^2)$$
$$\huge\Downarrow\normalsize \Theta =\begin{bmatrix}-1 \\ 0 \\ 0 \\ 1 \\ 1 \end{bmatrix}$$
$$\Large h_\theta(x)=g(-1+x_1^2+x_2^2)$$
我们可以得到决策边界 $x_1^2+x_2^2=1$
ml_17
当假设函数更复杂的话,我们可以得到更加有趣的决策边界:
ml_18

需要注意的是,决策边界不是训练集的属性,而是假设函数本身及其参数的属性。只要给定了参数向量$\Theta$,决策边界就决定了。
我们不是用训练集来定义决策边界,而是用训练集来拟合参数$\Theta$

代价函数

既然我们有了假设函数,那么我们就需要通过代价函数拟合出参数$\Theta$的值。
我们再来回顾一下线性回归的大家函数,并对其的表示方法做一些改进:
$$\Large J(\Theta)=\frac{1}{2m}\sum_{i=1}^{m}{({h_\Theta}({x}^{(i)})-{y}^{(i)})}^{2}$$
$$\Huge\Downarrow$$
$$\Large J(\Theta)=\frac{1}{m}\sum_{i=1}^{m}\underbrace{\frac{1}{2}{({h_\Theta}({x}^{(i)})-{y}^{(i)})}^{2}}$$
$$\qquad\qquad\qquad\qquad\Huge\Downarrow$$
$$\Large cost(h_\theta(x),y) = \frac{1}{2}{({h_\Theta}({x}^{(i)})-{y}^{(i)})}^{2}$$

如果直接将假设函数带入到这个代价函数中的话,即令
$\Large h_\theta(x)=\frac{1}{1+e^{-\Theta X}}$
我们将会得到一个非凸优化问题。而这并不是我们想看到的。
所以我们需要一个新的代价函数。

逻辑回归的代价函数
$$ \Large cost(h_\theta) =\left\{ \begin{aligned} -log(h_\theta(x)) \qquad y=1 \\ -log(1-h_\theta(x)) \qquad y=0 \end{aligned} \right. $$
为了更加直观的了解逻辑回归的代价函数我们将其的图像画出:
当 y = 1 时,从下图中可看出,
若$h_\theta(x)=1$ , cost = 0
若$h_\theta(x)=0$ , cost -> $\infty$
也就是说,当真值为 1 时,而我们很肯定的预测它为 0 ,那么我们就使用很大的代价来“惩罚”这个算法

ml_19

当 y = 0 时,从下图中可看出,
若$h_\theta(x)=0$ , cost = 0
若$h_\theta(x)=1$ , cost -> $\infty$

同样的,当真值为 0 时,而我们很肯定的预测它为 1 ,那么我们就使用很大的代价来“惩罚”这个算法
ml_20

这样我们就了解了这个代价函数的作用,当这个表示方法并不方便,我们需要根据 y 的值来决定使用哪个表达式。其实我们将其写进一个表达式中:
$$\Large cost(h_\theta(x),y)=-ylog(h_\theta(x))-(1-y)log(1-h_\theta(x))$$
可以验证,这个表达式和原来的表达式是等价的。

我们写出代价函数的完整表达式
$$\Large J(\theta) = \frac{1}{m}cost(h_\theta(x),y)
$$
$$\Huge \Downarrow$$
$$\Large J(\theta) = -\frac{1}{m}y^{(i)}log(h_\theta(x^{(i)}))-(1-y^{(i)})log(1-h_\theta(x^{(i)}))
$$

梯度下降

直接给出梯度下降的公式
$$\Large repeat\left\{\Theta_j = \Theta_j-\alpha\sum_{i=1}^m(h_\theta(x^{(i)}-y^{(i)}))x_j^{(i)} \right\}$$
这里仍需要同时更新所有的$\Theta_j$
认真的读者可以发现,这个梯度下降的公式和线性回归的公式是一样的,但实际上它们并不相同,因为此处的假设函数的定义已经改变了。

优化算法

除了梯度下降法之外还需许多别的算法可以用来拟合参数,比如说

  • Conjugate gradient
  • BFGS
  • L-BFGS

这些算法相比于梯度下降法有如下优点

  • 无需选择血虚率
  • 比梯度下降法更快

不可避免的也有缺点

  • 更加复杂难懂

这些算法内有一个智能内循环,称之为线搜索算法,它可以自动尝试不同的学习率,并自动选择一个好的学习率,甚至可以为每次迭代选择不同的学习率。

因为这些算法较复杂,在不了解其细节的情况下使用,可能会使模型的调试更加不透明一些,但在处理大规模的机器学习问题时,仍倾向于使用这些算法,而不是梯度下降算法。

多分类问题

上面我们讲的都是二元分类问题,有时我们还会遇到多分元类的问题。
如:

  • 邮件分类问题,学习,工作,家庭,朋友等等
  • 病情诊断,健康 感冒 发烧等
  • 天气预测晴天,多云,下雨,下雪等

    ml_21

如图所示,我们的训练集中有三种类别的样本。我们可以为每一种类别构建一个分类器来实现多元分类。

首先我们创建一个新的训练集,将三角形设为正类,其它两类设为负类,根据这个训练集构建一个分类器。其余两类如此构建各自的分类器。

这样我们对每一种类别都有了各自的分类器,当输入新的 X 时,我们用所有的分类器对其进行预测,输出概率最高的一个($max\, h(\theta^i(x)$)),便是最终的结果。

绘图代码

最后放上一点绘图的代码

绘制 Sigmoid 函数

1
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
#创建画布
fig = plt.figure(figsize=(5, 5))
#使用axisartist.Subplot方法创建一个绘图区对象ax
ax = axisartist.Subplot(fig, 111)
#将绘图区对象添加到画布中
fig.add_axes(ax)

# 通过set_visible方法设置绘图区所有坐标轴隐藏
ax.axis[:].set_visible(False)
# ax.new_floating_axis代表添加新的坐标轴
ax.axis["x"] = ax.new_floating_axis(0,0)
# 给x坐标轴加上箭头
ax.axis["x"].set_axisline_style("->", size = 1.0)
# 添加y坐标轴,且加上箭头
ax.axis["y"] = ax.new_floating_axis(1,0)
ax.axis["y"].set_axisline_style("-|>", size = 1.0)
# 设置x、y轴上刻度显示方向
ax.axis["x"].set_axis_direction("top")
ax.axis["y"].set_axis_direction("right")
# 设置x、y轴标签
ax.axis["x"].label.set_text("Z")
ax.axis["y"].label.set_text("g ( Z )")


# 设置坐标轴范围和标签
plt.xlim(-10,10)
plt.ylim(0,1)
plt.ylabel("Z")
# plt.ylabel("g(Z)")

z = np.linspace(-10,10,1000)
g = 1.0/(1+pow(math.e,-z))
plt.plot(z,g)

代价函数的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# cost() = -log(h(x))
fig = plt.figure()
x = np.linspace(0.0001,1,100)
y = -(np.log(x))
plt.xlabel("h(x)")

plt.xlim(0,1)
plt.ylim(0,10)

plt.plot(x,y)
plt.show()

# cost() = -log(1- h(x))
fig = plt.figure()
x = np.linspace(0,1,1000)
y = -(np.log(1-x))
plt.xlabel("h(x)")

plt.xlim(0,1)
plt.ylim(0,10)

plt.plot(x,y)
plt.show()

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×