引言
在机器学习中,逻辑回归是一种用于二分类问题的线性回归的扩展。逻辑回归的成本函数是用来评估模型预测结果与实际结果之间差异的函数
文章目录
- 引言
- 一、成本函数在逻辑回归中的形式
- 1.1 成本函数的具体形式
- 1.1.1 对于单个训练样本
- 二、逻辑回归的成本函数实现
- 2.1 导入第三方库
- 2.2 数据集
- 2.3 成本函数
- 2.4 代码描述
- 2.5 示例
- 2.6 总结
一、成本函数在逻辑回归中的形式
逻辑回归的成本函数是交叉熵损失(Cross-Entropy Loss)的一种形式,它由两部分组成:正例的损失和负例的损失
1.1 成本函数的具体形式
1.1.1 对于单个训练样本
损失(loss)函数定义为:
loss
(
y
,
y
^
)
=
−
y
log
(
y
^
)
−
(
1
−
y
)
log
(
1
−
y
^
)
\text{loss}(y, \hat{y}) = -y \log(\hat{y}) - (1 - y) \log(1 - \hat{y})
loss(y,y^)=−ylog(y^)−(1−y)log(1−y^)
其中:
- y y y是真实的标签值,取值为 0 或 1。
- y ^ \hat{y} y^是模型预测的概率,即 y ^ = P ( y = 1 ∣ x ; θ ) \hat{y} = P(y = 1 | x; \theta) y^=P(y=1∣x;θ),这是通过逻辑函数(logistic function)计算得出的。
逻辑函数(也称为sigmoid函数)定义为:
y
^
=
σ
(
z
)
=
1
1
+
e
−
z
\hat{y} = \sigma(z) = \frac{1}{1 + e^{-z}}
y^=σ(z)=1+e−z1
其中:
- z z z是线性回归的输出,即 z = θ T x + b z = \theta^T x + b z=θTx+b, θ \theta θ是权重参数, b b b是偏置项
将上述损失函数应用于整个训练集,得到成本函数(Cost Function):
J
(
θ
)
=
1
m
∑
i
=
1
m
loss
(
y
(
i
)
,
y
^
(
i
)
)
J(\theta) = \frac{1}{m} \sum_{i=1}^{m} \text{loss}(y^{(i)}, \hat{y}^{(i)})
J(θ)=m1i=1∑mloss(y(i),y^(i))
其中:
- m m m是训练样本的数量, y ( i ) y^{(i)} y(i)和 y ^ ( i ) \hat{y}^{(i)} y^(i)分别是第 i i i个样本的真实标签和预测概率
- 成本函数 J ( θ ) J(\theta) J(θ)的目的是通过最小化这个函数来找到最佳的参数 θ \theta θ,使得模型在训练数据上的预测误差最小
- 在逻辑回归中,通常使用梯度下降(Gradient Descent)或其变体来最小化成本函数
二、逻辑回归的成本函数实现
2.1 导入第三方库
import numpy as np
%matplotlib widget
import matplotlib.pyplot as plt
from lab_utils_common import plot_data, sigmoid, dlc
plt.style.use('./deeplearning.mplstyle')
2.2 数据集
我们从决策边界实验中使用的数据集开始
X_train = np.array([[0.5, 1.5], [1,1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]]) #(m,n)
y_train = np.array([0, 0, 0, 1, 1, 1]) #(m,)
我们将使用一个辅助函数来绘制这些数据。标签为𝑦=1的数据点用红色十字表示,而标签为𝑦=0的数据点用蓝色圆圈表示
fig,ax = plt.subplots(1,1,figsize=(4,4))
plot_data(X_train, y_train, ax)
# 设置两个轴的范围为0-4
ax.axis([0, 4, 0, 3.5])
ax.set_ylabel('$x_1$', fontsize=12)
ax.set_xlabel('$x_0$', fontsize=12)
plt.show()
输出结果:
2.3 成本函数
在之前的实验中,开发了逻辑损失函数。回忆一下,损失是针对一个示例定义的。在这里,将组合损失以形成成本,其中包括所有示例。
对于逻辑回归,成本函数的形式为:
J
(
w
,
b
)
=
1
m
∑
i
=
0
m
−
1
[
l
o
s
s
(
f
w
,
b
(
x
(
i
)
)
,
y
(
i
)
)
]
(1)
J(\mathbf{w},b) = \frac{1}{m} \sum_{i=0}^{m-1} \left[ loss(f_{\mathbf{w},b}(\mathbf{x}^{(i)}), y^{(i)}) \right] \tag{1}
J(w,b)=m1i=0∑m−1[loss(fw,b(x(i)),y(i))](1)
其中:
l
o
s
s
(
f
w
,
b
(
x
(
i
)
)
,
y
(
i
)
)
=
−
y
(
i
)
log
(
f
w
,
b
(
x
(
i
)
)
)
−
(
1
−
y
(
i
)
)
log
(
1
−
f
w
,
b
(
x
(
i
)
)
)
(2)
loss(f_{\mathbf{w},b}(\mathbf{x}^{(i)}), y^{(i)}) = -y^{(i)} \log\left(f_{\mathbf{w},b}\left( \mathbf{x}^{(i)} \right) \right) - \left( 1 - y^{(i)}\right) \log \left( 1 - f_{\mathbf{w},b}\left( \mathbf{x}^{(i)} \right) \right) \tag{2}
loss(fw,b(x(i)),y(i))=−y(i)log(fw,b(x(i)))−(1−y(i))log(1−fw,b(x(i)))(2)
其中m是数据集中的训练示例数量,且:
f
w
,
b
(
x
(
i
)
)
=
g
(
z
(
i
)
)
z
(
i
)
=
w
⋅
x
(
i
)
+
b
g
(
z
(
i
)
)
=
1
1
+
e
−
z
(
i
)
\begin{align} f_{\mathbf{w},b}(\mathbf{x^{(i)}}) &= g(z^{(i)})\tag{3} \\ z^{(i)} &= \mathbf{w} \cdot \mathbf{x}^{(i)}+ b\tag{4} \\ g(z^{(i)}) &= \frac{1}{1+e^{-z^{(i)}}}\tag{5} \end{align}
fw,b(x(i))z(i)g(z(i))=g(z(i))=w⋅x(i)+b=1+e−z(i)1(3)(4)(5)
2.4 代码描述
compute_cost_logistic
算法遍历所有示例,计算每个示例的损失并求和
注意,变量X和y不是标量值,而是形状为(𝑚,𝑛)和(𝑚,)的矩阵,其中𝑛是特征数量,𝑚是训练示例的数量
def compute_cost_logistic(X, y, w, b):
"""
计算成本
参数:
X (ndarray (m,n)): 数据,m个示例,每个示例有n个特征
y (ndarray (m,)) : 目标值
w (ndarray (n,)) : 模型参数
b (scalar) : 模型参数
返回:
cost (scalar): 成本
"""
m = X.shape[0]
cost = 0.0
for i in range(m):
z_i = np.dot(X[i],w) + b
f_wb_i = sigmoid(z_i)
cost += -y[i]*np.log(f_wb_i) - (1-y[i])*np.log(1-f_wb_i)
cost = cost / m
return cost
使用下面的单元格检查成本函数的实现。
w_tmp = np.array([1,1])
b_tmp = -3
print(compute_cost_logistic(X_train, y_train, w_tmp, b_tmp))
预期输出:0.3668667864055175
输出结果:
2.5 示例
现在,让我们看看不同的𝑤值下成本函数的输出
在之前的实验中,绘制了𝑏=−3,𝑤0=1,𝑤1=1的决策边界。也就是说,使用了w = np.array([-3,1,1])
假设您想看看𝑏=−4,𝑤0=1,𝑤1=1,或者w = np.array([-4,1,1])是否提供了更好的模型。
首先,让我们为这两个不同的𝑏值绘制决策边界,看看哪个更适合数据。
对于𝑏=−3,𝑤0=1,𝑤1=1,我们将绘制−3+𝑥0+𝑥1=0(以蓝色显示)
对于𝑏=−4,𝑤0=1,𝑤1=1,我们将绘制−4+𝑥0+𝑥1=0(以品红色显示)
# 导入matplotlib库并绘图
import matplotlib.pyplot as plt
# 选择0到6之间的值
x0 = np.arange(0,6)
# 绘制两个决策边界
x1 = 3 - x0
x1_other = 4 - x0
fig,ax = plt.subplots(1, 1, figsize=(4,4))
# 绘制决策边界
ax.plot(x0,x1, c=dlc["dlblue"], label="$b$=-3")
ax.plot(x0,x1_other, c=dlc["dlmagenta"], label="$b$=-4")
ax.axis([0, 4, 0, 4])
# 绘制原始数据
plot_data(X_train,y_train,ax)
ax.axis([0, 4, 0, 4])
ax.set_ylabel('$x_1$', fontsize=12)
ax.set_xlabel('$x_0$', fontsize=12)
plt.legend(loc="upper right")
plt.title("决策边界")
plt.show()
输出结果:
从这张图中可以看出,w = np.array([-4,1,1])
对于训练数据来说是一个更差的模型,让我们看看成本函数的实现是否反映了这一点
w_array1 = np.array([1,1])
b_1 = -3
w_array2 = np.array([1,1])
b_2 = -4
print("当b = -3时的成本: ", compute_cost_logistic(X_train, y_train, w_array1, b_1))
print("当b = -4时的成本: ", compute_cost_logistic(X_train, y_train, w_array2, b_2))
预期输出:
当b = -3时的成本: 0.3668667864055175
当b = -4时的成本: 0.5036808636748461
输出结果:
可以看到,成本函数的行为符合预期,w = np.array([-4,1,1])
的成本确实高于w = np.array([-3,1,1])
的成本
2.6 总结
- 如图所示,检查并使用了逻辑回归的成本函数