前文介绍了基本的线性回归问题,尝试预测一系列连续值属性。现在我们将介绍的分类问题则关注离散值属性的预测。
在分类问题中,我们尝试预测的结果是否属于某一个类,最基础的就是二元的分类问题(例如预测垃圾邮件、恶性肿瘤),更为复杂的则是预测多元的分类问题。
一、分类问题
分类问题的样本与回归问题类似,由特征和目标构成,给定数据集:
{
(
x
(
i
)
,
y
(
i
)
)
,
i
=
1
,
2
,
.
.
.
,
m
}
\{(x^{(i)},y^{(i)}),i=1,2,...,m\}
{(x(i),y(i)),i=1,2,...,m}
x ( i ) x^{(i)} x(i) 代表第 i i i 个观察实例的 n + 1 n+1 n+1 维特征向量 ( x 0 ( i ) , . . . , x n ( i ) ) T (x_{0}^{(i)},...,x_{n}^{(i)})^T (x0(i),...,xn(i))T ; y ( i ) ∈ { 0 , 1 } y^{(i)} \in \{0,1\} y(i)∈{0,1} 代表第 i i i 个观察实例的目标变量,在这里有 0 或 1 两类结果。
即对于输入的自变量 x ( i ) x^{(i)} x(i) ,因变量 y ( i ) y^{(i)} y(i) 可能为 0 或 1。其中 0 表示负向类,1 表示正向类。
我们不对「正向」和「负向」加以特殊区分,但在实际应用中「正向」通常表示「具有我们要寻找的东西」,如垃圾邮件、恶性肿瘤等。
把线性回归算法应用到下图的数据集,用直线拟合结果,当预测值大于 0.5 时归为正向类,反之归为负向类。这看似合理,然而线性回归保留了
y
(
i
)
y^{(i)}
y(i) 太多的「信息量」。对于某些「反常样本」,我们可能预测出一个远大于 1 或者远小于 0 的结果。同理,这些「反常样本」用于拟合直线时也会对其造成一定偏移,以至于正常样本被归为错误类别。下图反常样本使得蓝线偏移。

如果我们要用线性回归算法来解决一个分类问题,对于分类, 取值为 0 或者1,但如果你使用的是线性回归,那么假设函数的输出值可能远大于 1,或者远小于0,即使所有训练样本的标签 都等于 0 或 1。尽管我们知道标签应该取值0 或者1,但是如果算法得到的值远大于1或者远小于0的话,就会感觉很奇怪。
逻辑回归算法的特点在于,算法的输出或者预测值一直介于0和1之间。顺便说以下,线性回归和逻辑回归都属于「广义线性模型」的特殊形式,线性模型都可用于回归问题的求解。但由于「逻辑函数」将结果映射到「伯努利分布」,因此逻辑回归更常用于分类问题。
二、假设表示
我们在线性回归的假设函数:
h
θ
(
x
)
=
θ
T
x
h_\theta(x)=\theta^Tx
hθ(x)=θTx ,其外套上 sigmoid 函数,构造逻辑回归的假设函数为:
h
θ
(
x
)
=
g
(
θ
T
x
)
=
1
1
+
e
−
θ
T
x
h_\theta(x)=g(\theta^Tx)=\frac{1}{1 + e^{-\theta^Tx}}
hθ(x)=g(θTx)=1+e−θTx1
所谓 sigmoid 函数(也即前面提到的逻辑函数),是一个介于 (0,1) 之间的单增 S 形函数:
g ( z ) = 1 1 + e − z g(z)=\frac{1}{1 + e^{-z}} g(z)=1+e−z1
也就是说,对于一个参数为 θ \theta θ 的逻辑回归模型,输入 x x x,得到 h θ ( x ) = 1 1 + e − θ T x h_\theta(x)=\frac{1}{1 + e^{-\theta^Tx}} hθ(x)=1+e−θTx1 的预测值。我们可以把这个输出值视为 x x x 这个样本对应的 y y y 等于 1 的概率,即 h θ ( x ) = P ( y = 1 ∣ x ; θ ) h_\theta(x)=P(y=1|x;\theta) hθ(x)=P(y=1∣x;θ) 。针对分类情形,我们可以认为如果概率 ⩾ 0.5 ⩾0.5 ⩾0.5,则分类为 1,否则分类为 0。例如如果对于给定的 x x x,通过已经确定的参数计算得出 h θ ( x ) = 0.7 h_\theta(x)=0.7 hθ(x)=0.7,则表示有 70% 的几率为正向类,相应地为负向类的几率为 1 − 0.7 = 0.3 1-0.7=0.3 1−0.7=0.3。
三、决策边界
根据 sigmoid 函数的性质,结合图形:
h
θ
(
x
)
≥
0.5
⟺
θ
T
X
≥
0
h_{\theta}(x) \geq 0.5 \Longleftrightarrow \theta^{T}X \geq 0
hθ(x)≥0.5⟺θTX≥0
所以只要 θ T X ≥ 0 \theta^{T}X \geq 0 θTX≥0 ,就会分类为 1,否则分类为 0;于是乎, θ T X = 0 \theta^{T}X = 0 θTX=0 解出的这条「线」被称作决策边界,它将整个空间划分成两块区域,各自属于一个分类。决策边界是假设函数的属性,不是数据集的属性,确定了参数 θ θ θ 也就确定了决策边界。
下面看两个二维情形的例子:

对于上述样本点的分布,用一条直线即可划分空间,对应的假设函数为
h
θ
(
x
)
=
g
(
θ
0
+
θ
1
x
1
+
θ
2
x
2
)
h_{\theta}(x) = g(\theta_0+\theta_1x_1+\theta_2x_2)
hθ(x)=g(θ0+θ1x1+θ2x2)。例子中的决策边界是
−
3
+
x
1
+
x
2
=
0
-3+x_1+x_2 = 0
−3+x1+x2=0 所对应的直线。

而对于这种分布,我们必须选择二维曲线来划分空间,即使用多项式特征来确定曲线的参数,对应的假设函数为 h θ ( x ) = g ( θ 0 + θ 1 x 1 + θ 2 x 2 + θ 3 x 3 2 + θ 4 x 4 2 ) h_{\theta}(x) = g(\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}+\theta_3x_{3}^{2}+\theta_{4}x_{4}^{2}) hθ(x)=g(θ0+θ1x1+θ2x2+θ3x32+θ4x42) 。当然,我们也可以用更复杂的多项式曲线来划分更复杂的分布。例子中的决策边界是 − 31 + x 1 2 + x 2 2 = 0 -31+x_1^2+x_2^2 = 0 −31+x12+x22=0 所对应的曲线。
四、代价函数
对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将
h
θ
(
x
)
=
1
1
+
e
−
θ
T
x
h_\theta(x)=\frac{1}{1 + e^{-\theta^Tx}}
hθ(x)=1+e−θTx1 带入到这样定义了的代价函数中时,我们得到的代价函数将是一个非凸函数,如下图。

现在,我们的任务就是从训练集中拟合逻辑回归的参数 θ θ θ。仍然采用代价函数的思想——找到使代价最小的参数即可。
广义上来讲,代价函数是这样的一个函数:
J
(
θ
)
=
1
m
∑
i
=
1
m
C
o
s
t
(
h
θ
(
x
(
i
)
)
,
y
(
i
)
)
J(\theta) = \frac{1}{m} \sum_{i=1}^{m} Cost (h_\theta(x^{(i)}) , y^{(i)})
J(θ)=m1i=1∑mCost(hθ(x(i)),y(i))
也就是说用每个数据的估计值 h θ ( x ( i ) ) h_{\theta}(x^{(i)}) hθ(x(i)) 和真实值 y ( i ) y^{(i)} y(i) 计算一个代价 C o s t ( h θ ( x ( i ) ) , y ( i ) ) Cost (h_\theta(x^{(i)}) , y^{(i)}) Cost(hθ(x(i)),y(i)) ,比如线性回归中这个代价就是二者差值的平方。
理论上来说,我们也可以对逻辑回归模型沿用平方误差的定义,但当我们将 h θ ( x ) = 1 1 + e − θ T x h_\theta(x)=\frac{1}{1 + e^{-\theta^Tx}} hθ(x)=1+e−θTx1 代入到这样的代价函数中时,我们得到的将是一个非凸函数。这意味着空间中会有许多局部最小值,使得梯度下降法难以寻找到全局最小值。
因此我们重新定义逻辑回归的代价函数:
C
o
s
t
(
h
θ
(
x
)
,
y
)
=
{
−
ln
(
h
θ
(
x
)
)
y
=
1
−
ln
(
1
−
h
θ
(
x
)
)
y
=
0
Cost (h_\theta(x) , y) = \begin{cases} -\ln (h_{\theta}(x)) & y=1 \\ -\ln (1-h_{\theta}(x)) & y=0 \end{cases}
Cost(hθ(x),y)={−ln(hθ(x))−ln(1−hθ(x))y=1y=0
绘制出的曲线大致呈这样:

观察曲线,发现当 y = 1 y=1 y=1(样本的真实值为 1)时,预测值 $h_{\theta}(x) $ 越接近 1 则代价越小,越接近 0 则代价趋于无穷。譬如在肿瘤分类中,将实际为恶性的肿瘤以百分之百的概率预测为良性,带来的后果将不可估量。
与此同时,注意到代价函数也可以简写为:
C
o
s
t
(
h
θ
(
x
)
,
y
)
=
−
[
y
ln
(
h
θ
(
x
)
)
+
(
1
−
y
)
ln
(
1
−
h
θ
(
x
)
)
]
Cost (h_\theta(x) , y) = -[y\ln(h_\theta(x)) + (1-y)\ln(1-h_\theta(x))]
Cost(hθ(x),y)=−[yln(hθ(x))+(1−y)ln(1−hθ(x))]
它还有另外一个名称——二元交叉熵代价函数(BCE)。
五、代价函数的数学推导
首先明确什么是一个好的代价函数——当参数 θ θ θ 使得 J ( θ ) J(\theta) J(θ) 取最小值时,这个 θ θ θ 也能使模型拟合效果最好。这时我们回忆起 最大似然估计 的思想:当参数 θ θ θ 使得 L ( θ ) L(\theta) L(θ) 取最大值时,这个 θ θ θ 也能使得事件组最容易发生!
前文已经提到,我们用概率解释预测值
P
(
y
=
k
)
=
{
p
k
=
1
1
−
p
k
=
0
P(y = k) = \begin{cases} p & k = 1 \\ 1 - p & k = 0 \end{cases}
P(y=k)={p1−pk=1k=0
利用「伯努利分布公式」故:
P
(
y
=
k
)
=
[
h
θ
(
x
)
]
k
[
1
−
h
θ
(
x
)
]
1
−
k
,
k
∈
{
0
,
1
}
P(y = k) = \left[ h_\theta(x) \right]^k \left[ 1 - h_\theta(x) \right]^{1 - k}, \quad k \in \{0, 1\}
P(y=k)=[hθ(x)]k[1−hθ(x)]1−k,k∈{0,1}
而对于数据集
{
(
x
(
i
)
,
y
(
i
)
)
,
i
=
1
,
2
,
⋯
,
m
}
\left\{ (x^{(i)}, y^{(i)}), \, i = 1, 2, \cdots, m \right\}
{(x(i),y(i)),i=1,2,⋯,m} 下,将其视为已发生的一个事件组,则似然函数为:
L
(
θ
)
=
∏
i
=
1
m
P
(
y
=
y
(
i
)
)
=
∏
i
=
1
m
[
h
θ
(
x
(
i
)
)
]
y
(
i
)
[
1
−
h
θ
(
x
(
i
)
)
]
1
−
y
(
i
)
L(\theta) = \prod_{i=1}^m P\left( y = y^{(i)} \right) = \prod_{i=1}^m \left[ h_\theta \left( x^{(i)} \right) \right]^{y^{(i)}} \left[ 1 - h_\theta \left( x^{(i)} \right) \right]^{1 - y^{(i)}}
L(θ)=i=1∏mP(y=y(i))=i=1∏m[hθ(x(i))]y(i)[1−hθ(x(i))]1−y(i)
取对数得到:
ln
L
(
θ
)
=
∑
i
=
1
m
{
y
(
i
)
ln
[
h
θ
(
x
(
i
)
)
]
+
(
1
−
y
(
i
)
)
ln
[
1
−
h
θ
(
x
(
i
)
)
]
}
\ln L(\theta) = \sum_{i=1}^m \left\{ y^{(i)} \ln \left[ h_\theta \left( x^{(i)} \right) \right] + \left( 1 - y^{(i)} \right) \ln \left[ 1 - h_\theta \left( x^{(i)} \right) \right] \right\}
lnL(θ)=i=1∑m{y(i)ln[hθ(x(i))]+(1−y(i))ln[1−hθ(x(i))]}
注意到,最大似然估计法的目标是找到
L
(
θ
)
L(\theta)
L(θ) 或
ln
L
(
θ
)
\ln L(\theta)
lnL(θ) 的最大值,而逻辑回归的目标是找到
J
(
θ
)
J(\theta)
J(θ) 的最小值,所以自然的,我们将
ln
L
(
θ
)
\ln L(\theta)
lnL(θ) 取反来定义
J
(
θ
)
J(\theta)
J(θ) :
J
(
θ
)
=
−
1
m
ln
L
(
θ
)
=
−
1
m
∑
i
=
1
m
[
y
(
i
)
ln
(
h
θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
ln
(
1
−
h
θ
(
x
(
i
)
)
)
]
\begin{aligned} J(\theta) &= -\frac{1}{m} \ln L(\theta) \\ &= -\frac{1}{m} \sum_{i=1}^m \left[ y^{(i)} \ln \left( h_\theta \left( x^{(i)} \right) \right) + \left( 1 - y^{(i)} \right) \ln \left( 1 - h_\theta \left( x^{(i)} \right) \right) \right] \end{aligned}
J(θ)=−m1lnL(θ)=−m1i=1∑m[y(i)ln(hθ(x(i)))+(1−y(i))ln(1−hθ(x(i)))]
其中 1 m \frac{1}{m} m1 对要求的 θ θ θ 没有影响,仅是取一下平均罢了。
可以证明上述代价函数 J ( θ ) J(\theta) J(θ) 会是一个凸函数,并且没有局部最优值。凸性分析的内容不在本讲的范围,但是可以证明我们所选的代价函数会给我们带来一个凸优化问题。
六、梯度下降和高级优化
既然是凸函数,那么现在我们就可以进行梯度下降求解
arg
min
θ
J
(
θ
)
\arg \min_{\theta} J(\theta)
argminθJ(θ) ,利用 sigmoid 函数的对数性质
log
σ
(
z
)
=
−
log
(
1
+
e
−
z
)
\log \sigma(z) = -\log(1 + e^{-z})
logσ(z)=−log(1+e−z) 和
log
(
1
−
σ
(
z
)
)
=
−
log
(
1
+
e
z
)
\log(1 - \sigma(z)) = -\log(1 + e^{z})
log(1−σ(z))=−log(1+ez) 求偏导,我们先计算:
∂
∂
θ
Cost
(
h
θ
(
x
)
,
y
)
=
∂
∂
θ
[
−
y
ln
(
h
θ
(
x
)
)
−
(
1
−
y
)
ln
(
1
−
h
θ
(
x
)
)
]
=
∂
∂
θ
[
y
ln
(
1
+
e
−
θ
T
x
)
+
(
1
−
y
)
ln
(
1
+
e
θ
T
x
)
]
=
−
y
x
e
−
θ
T
x
1
+
e
−
θ
T
x
+
(
1
−
y
)
x
e
θ
T
x
1
+
e
θ
T
x
=
−
y
x
+
(
1
−
y
)
x
e
θ
T
x
1
+
e
θ
T
x
=
(
−
y
+
1
1
+
e
−
θ
T
x
)
x
=
(
h
θ
(
x
)
−
y
)
x
\begin{aligned} \frac{\partial}{\partial \theta} \text{Cost} \left( h_\theta (x), y \right) &= \frac{\partial}{\partial \theta} \left[ -y \ln \left( h_\theta (x) \right) - (1 - y) \ln \left( 1 - h_\theta (x) \right) \right] \\ &= \frac{\partial}{\partial \theta} \left[ y \ln \left( 1 + e^{-\theta^T x} \right) + (1 - y) \ln \left( 1 + e^{\theta^T x} \right) \right] \\ &= \frac{ -y x e^{-\theta^T x} }{ 1 + e^{-\theta^T x} } + \frac{ (1 - y) x e^{\theta^T x} }{ 1 + e^{\theta^T x} } \\ &= \frac{ -y x + (1 - y) x e^{\theta^T x} }{ 1 + e^{\theta^T x} } \\ &= \left( -y + \frac{1}{ 1 + e^{-\theta^T x} } \right) x \\ &= \left( h_\theta (x) - y \right) x \end{aligned}
∂θ∂Cost(hθ(x),y)=∂θ∂[−yln(hθ(x))−(1−y)ln(1−hθ(x))]=∂θ∂[yln(1+e−θTx)+(1−y)ln(1+eθTx)]=1+e−θTx−yxe−θTx+1+eθTx(1−y)xeθTx=1+eθTx−yx+(1−y)xeθTx=(−y+1+e−θTx1)x=(hθ(x)−y)x
于是乎,
∂
J
∂
θ
=
1
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
(
i
)
\frac{\partial J}{\partial \theta} = \frac{1}{m} \sum_{i=1}^m \left( h_\theta \left( x^{(i)} \right) - y^{(i)} \right) x^{(i)}
∂θ∂J=m1i=1∑m(hθ(x(i))−y(i))x(i)
没错,这个偏导的形式和线性回归完全相同!不同的只是
h
θ
(
x
)
=
g
(
θ
T
X
)
h_\theta (x) = g \left( \theta^T X \right)
hθ(x)=g(θTX) 的定义——多了一层 sigmoid 函数,正是因此,我们不能使用正规方程直接给出解析解,而必须使用梯度下降等方法。
θ
:
=
θ
−
α
⋅
∂
J
∂
θ
\theta := \theta - \alpha \cdot \frac{\partial J}{\partial \theta}
θ:=θ−α⋅∂θ∂J
现在我们对其使用梯度下降即可。另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。
除了梯度下降法,还有很多算法可以用来求解这个最优值:共轭梯度法(Conjugate Gradient)、局部优化法(BFGS)、有限内存局部优化法(LBFGS)等。
这些算法通常不需要手动选择学习率 α \alpha α ,而是使用一个智能的内循环(线性搜索算法)来选择一个较好的 α \alpha α ,甚至能为每次迭代选择不同的 α \alpha α 。因此他们有着更优越的常数和时间复杂度,在大型机器学习项目中更加适用。
七、代码实现
下面以 Coursera 上的二分类数据集 ex2data1.txt 为例,首先看一下数据的分布:
import numpy as np
import matplotlib.pyplot as plt
# load data, data.shape = (100, 3)
data = np.loadtxt('ex2data1.txt', delimiter=',')
(m, n) = data.shape
X = data[:, :-1]
y = data[:, -1]
# preview data
pos = np.where(y == 1)[0]
neg = np.where(y == 0)[0] # 返回索引
plt.scatter(X[pos, 0], X[pos, 1], marker="o", c='c')
plt.scatter(X[neg, 0], X[neg, 1], marker="x", c='r')
plt.xlabel('Exam 1 score')
plt.ylabel('Exam 2 score')
plt.show()

看起来用直线即可划分数据。
此外,注意到如果每次都用
n
p
.
s
u
m
(
)
np.sum()
np.sum() 计算
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
j
(
i
)
\sum_{i=1}^m \left( h_\theta \left( x^{(i)} \right) - y^{(i)} \right) x_j^{(i)}
∑i=1m(hθ(x(i))−y(i))xj(i) 耗时较大,因此将求和化成矩阵形式:
θ
:
=
θ
−
α
1
m
X
T
(
g
(
X
θ
)
−
y
)
\theta := \theta - \alpha \frac{1}{m} X^T \left( g(X\theta) - y \right)
θ:=θ−αm1XT(g(Xθ)−y)
实现逻辑回归如下,矩阵化后运行时间可缩短一半:
import numpy as np
import matplotlib.pyplot as plt
# load data, data.shape = (100, 3)
data = np.loadtxt('ex2data1.txt', delimiter=',')
(m, n) = data.shape
X = data[:, :-1]
y = data[:, -1]
# normalization
X = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1)
X = np.c_[np.ones(m), X] # 增加一列 1
# parameters
alpha = 0.01
num_iters = 10000
theta = np.zeros(n)
def sigmoid(z):
g = np.zeros(z.size)
g = 1 / (1 + np.exp(-z))
return g
# Gradient Descent
for _ in range(0, num_iters):
error = sigmoid(X @ theta) - y # error.shape = (100, )
theta -= (alpha / m) * (X.T @ error) # X.T.shape = (2, 100)
# plot decision boundary
pos = np.where(y == 1)[0]
neg = np.where(y == 0)[0]
plt.scatter(X[pos, 1], X[pos, 2], marker="o", c='c')
plt.scatter(X[neg, 1], X[neg, 2], marker="x", c='r')
x_plot = np.array([np.min(X[:, 1]), np.max(X[:, 1])])
y_plot = (-1 / theta[2]) * (theta[1] * x_plot + theta[0])
plt.plot(x_plot, y_plot)
plt.show()
得到的
(
θ
0
,
θ
1
,
θ
2
)
(\theta_0, \theta_1, \theta_2)
(θ0,θ1,θ2) 结果是:
[
1.2677
,
3.0555
,
2.8289
]
[1.2677, 3.0555, 2.8289]
[1.2677,3.0555,2.8289],绘制出决策边界的图像为:

八、多类别分类:一对多
在实际情形中,我们还会使用逻辑回归来解决多元的分类问题。多分类的数据集和二分类相似,区别在于目标变量
y
(
i
)
y^{(i)}
y(i)在这里不仅有 0 或 1 两类结果,还可以取 2、3 等更多的数字。

对于接下来要介绍的方法,标签数字的顺序、取法,都不会影响最终的结果。但在某些分类模型中,数值可能具有实际意义,这时候使用独热码(One-Hot)或许是更好的选择。
对于 N 分类问题,我们可以将其转化为 N 个二分类问题——只需创建 N 个「伪训练集」,每个训练集中仅包含一个类作为正向类,其他 N-1 个类均视为负向类。

接下来就可以训练 N 个标准的逻辑回归分类器,将其记为:
h
θ
(
i
)
(
x
)
=
P
(
y
=
i
∣
x
;
θ
)
,
i
=
(
1
,
2
,
⋯
,
N
)
h_\theta^{(i)} (x) = P(y = i \mid x; \theta), \quad i = (1, 2, \cdots, N)
hθ(i)(x)=P(y=i∣x;θ),i=(1,2,⋯,N)
显然,每个分类器的输出都可以视为「属于某类」的概率,在预测时,我们只需要运行一遍所有分类器,然后取其最大值作为预测结果即可。

302

被折叠的 条评论
为什么被折叠?



