利用逻辑回归进行数据分类
1. 测试不同的逻辑函数
我们尝试使用两个具有不同决策边界的逻辑函数,通过比较成本来确定哪个函数的决策边界更优。这里使用两个例子:
p = 0.56 – 0.35 · x
(即
0.35 · x + 1 · p = 0.56
),这是我们的最佳猜测决策边界;另一个是任意选择的
x + p = 1
。显然,前者在区分普锐斯(Priuses)和宝马(BMWs)时是更好的分界线。
在源代码中,有一个
plot_line
函数可根据方程
ax + by = c
中的
a
、
b
和
c
值绘制直线。对于上述两个例子,
(a, b, c)
的值分别为
(0.35, 1, 0.56)
和
(1, 1, 1)
。我们可以使用以下代码将它们与汽车数据的散点图一起绘制:
plot_data(scaled_car_data)
plot_line(0.35,1,0.56)
plot_line(1,1,1)
对应的逻辑函数分别为
σ(0.35 · x + p – 0.56)
和
σ(x + p – 1)
,我们期望第一个函数相对于数据的成本更低。可以使用
logistic_cost
函数来验证:
>>> logistic_cost(0.35,1,0.56)
130.92490748700456
>>> logistic_cost(1,1,1)
135.56446830870456
正如预期的那样,直线
x + p = 1
是一个较差的决策边界,因此逻辑函数
σ(x + p – 1)
的成本较高。第一个函数
σ(0.35 · x + p – 0.56)
成本较低,拟合效果更好。但它是否是最佳拟合呢?接下来我们将通过梯度下降来寻找答案。
1.1 练习题解答
1.1.1 实现
plot_line(a,b,c)
函数
def plot_line(acoeff,bcoeff,ccoeff,**kwargs):
a,b,c = acoeff, bcoeff, ccoeff
if b == 0:
plt.plot([c/a,c/a],[0,1])
else:
def y(x):
return (c-a*x)/b
plt.plot([0,1],[y(0),y(1)],**kwargs)
1.1.2 写出
σ(ax + by – c)
的展开公式
已知
sigmoid
函数公式为:
[ \sigma(x) = \frac{1}{1 + e^{-x}} ]
则可推出:
[ \sigma(ax + by - c) = \frac{1}{1 + e^{c - ax - by}} ]
1.1.3 分析
k(x, y) = σ(x² + y² – 1)
的图像和决策边界
当
σ(x² + y² – 1) = 0.5
时,即
x² + y² – 1 = 0
,也就是
x² + y² = 1
,这是一个以原点为圆心,半径为 1 的圆。在圆内,
x² + y² < 1
,所以
σ(x² + y² – 1) < 0.5
;在圆外,
x² + y² > 1
,所以
σ(x² + y² – 1) > 0.5
。该函数的图像在远离原点的任何方向上趋近于 1,在圆内则减小到原点处的最小值约 0.27。
1.1.4 判断
σ(2x + y – 1)
和
σ(4x + 2y – 2)
是否为同一函数
这两个函数不是同一函数。因为
4x + 2y – 2
相对于
x
和
y
的增加速度更快,所以
σ(4x + 2y – 2)
的图像更陡峭。
1.2 总结
通过测试不同的逻辑函数,我们发现不同的决策边界会导致不同的成本,成本较低的函数拟合效果更好。同时,通过练习题的解答,我们对逻辑函数的实现和性质有了更深入的理解。
2. 寻找最佳逻辑函数
2.1 问题描述
现在我们面临一个简单的最小化问题,即找到使
logistic_cost
函数尽可能小的
a
、
b
和
c
值。这样,对应的函数
L(x, p) = σ(ax + bp – c)
将是对数据的最佳拟合。我们可以使用这个函数构建一个汽车分类器,将未知汽车的里程数
x
和价格
p
代入,如果
L(x, p) > 0.5
,则将其标记为宝马;否则,标记为普锐斯。
2.2 三维梯度下降
2.2.1 梯度计算
对于二维函数
f(x, y)
,在点
(x0, y0)
处的偏导数分别是关于
x
和
y
的导数,将这两个偏导数作为二维向量的分量,就得到了梯度:
def approx_gradient(f,x0,y0,dx=1e-6):
partial_x = approx_derivative(lambda x:f(x,y0),x0,dx=dx)
partial_y = approx_derivative(lambda y:f(x0,y),y0,dx=dx)
return (partial_x,partial_y)
对于三维函数
f(x, y, z)
,在点
(x0, y0, z0)
处有三个偏导数,将它们组合成一个三维向量,就得到了三维梯度:
def approx_gradient3(f,x0,y0,z0,dx=1e-6):
partial_x = approx_derivative(lambda x:f(x,y0,z0),x0,dx=dx)
partial_y = approx_derivative(lambda y:f(x0,y,z0),y0,dx=dx)
partial_z = approx_derivative(lambda z:f(x0,y0,z),z0,dx=dx)
return (partial_x,partial_y,partial_z)
2.2.2 三维梯度下降算法
def gradient_descent3(f,xstart,ystart,zstart,
tolerance=1e-6,max_steps=1000):
x = xstart
y = ystart
z = zstart
grad = approx_gradient3(f,x,y,z)
steps = 0
while length(grad) > tolerance and steps < max_steps:
x -= 0.01 * grad[0]
y -= 0.01 * grad[1]
z -= 0.01 * grad[2]
grad = approx_gradient3(f,x,y,z)
steps += 1
return x,y,z
将
logistic_cost
函数代入
gradient_descent3
函数,就可以找到使其最小化的输入。
2.3 使用梯度下降寻找最佳拟合
2.3.1 不同步数的结果
为了谨慎起见,我们可以先使用较小的
max_steps
值,如 100:
>>> gradient_descent3(logistic_cost,1,1,1,max_steps=100)
(0.21114493546399946, 5.04543972557848, 2.1260122558655405)
如果允许它执行 200 步:
>>> gradient_descent3(logistic_cost,1,1,1,max_steps=200)
(0.884571531298388, 6.657543188981642, 2.955057286988365)
这些结果是定义逻辑函数所需的参数,同时也是以
ax + bp = c
形式定义决策边界的参数。如果我们运行不同步数的梯度下降,并使用
plot_line
绘制相应的直线,可以看到决策边界逐渐收敛。
2.3.2 收敛结果
在 7000 到 8000 步之间,算法实际上收敛,即找到梯度长度小于
10^-6
的点:
>>> gradient_descent3(logistic_cost,1,1,1,max_steps=8000)
(3.7167003153580045, 11.422062409195114, 5.596878367305919)
我们可以将这个决策边界与之前的最佳猜测进行比较:
plot_data(scaled_car_data)
plot_line(0.35,1,0.56)
plot_line(3.7167003153580045, 11.422062409195114, 5.596878367305919)
这个决策边界与我们的猜测相差不大。逻辑回归的结果似乎将决策边界从我们的猜测略微向下移动,用一些误判为宝马的普锐斯(假阳性)换取了更多正确分类为宝马的车辆(真阳性)。
2.4 测试和理解最佳逻辑分类器
2.4.1 构建分类器
我们可以将
(a, b, c)
的值代入逻辑函数,然后使用它来创建一个汽车分类函数:
def best_logistic_classifier(x,p):
l = make_logistic(3.7167003153580045, 11.422062409195114,
5.596878367305919)
if l(x,p) > 0.5:
return 1
else:
return 0
2.4.2 测试分类器
将这个函数代入
test_classifier
函数,我们可以看到它在测试数据集上的准确率约为 80%:
>>> test_classifier(best_logistic_classifier,scaled_car_data)
0.8
2.4.3 分类器的特点
逻辑回归不仅仅是找到最优的决策边界。实际上,它会从整体上考虑数据集,找到在所有示例下最可能准确的模型。此外,我们的逻辑分类器还能给出每个分类点的确定性信息。与仅基于决策边界的分类器不同,逻辑分类器返回的 0 到 1 之间的值可以解释为汽车是宝马而非普锐斯的概率。这种确定性信息在实际应用中非常有价值。
2.5 练习题解答
2.5.1 修改
gradient_descent3
函数以打印总步数
def gradient_descent3(f,xstart,ystart,zstart,tolerance=1e-
6,max_steps=1000):
...
print(steps)
return x,y,z
运行
gradient_descent3(logistic_cost,1,1,1,max_steps=8000)
,打印的步数为 7244,这意味着算法在 7244 步时收敛。
2.5.2 实现任意维度的梯度计算和梯度下降
def partial_derivative(f,i,v,**kwargs):
def cross_section(x):
arg = [(vj if j != i else x) for j,vj in enumerate(v)]
return f(*arg)
return approx_derivative(cross_section, v[i], **kwargs)
def approx_gradient(f,v,dx=1e-6):
return [partial_derivative(f,i,v) for i in range(0,len(v))]
def gradient_descent(f,vstart,tolerance=1e-6,max_steps=1000):
v = vstart
grad = approx_gradient(f,v)
steps = 0
while length(grad) > tolerance and steps < max_steps:
v = [(vi - 0.01 * dvi) for vi,dvi in zip(v,grad)]
grad = approx_gradient(f,v)
steps += 1
return v
为了测试这个梯度下降函数,我们可以使用
sum_squares
函数:
def sum_squares(*v):
return sum([(x-1)**2 for x in v])
运行以下代码:
>>> v = [2,2,2,2,2]
>>> gradient_descent(sum_squares,v)
[1.0000002235452137,
1.0000002235452137,
1.0000002235452137,
1.0000002235452137,
1.0000002235452137]
结果表明梯度下降函数能够正确找到最小值。
2.5.3 尝试使用
simple_logistic_cost
函数进行梯度下降
使用
simple_logistic_cost
函数进行梯度下降时,算法似乎不会收敛。
a
、
b
和
c
的值会无限制地增加,尽管决策边界会稳定下来。这意味着梯度下降在探索越来越多的逻辑函数时,这些函数的方向保持不变,但变得无限陡峭。通过惩罚逻辑函数最确定的错误分类可以解决这个问题,而
logistic_cost
函数在这方面表现良好。
2.6 总结
通过梯度下降,我们找到了使
logistic_cost
函数最小化的参数,从而得到了最佳的逻辑分类器。这个分类器不仅能准确分类数据,还能提供分类的确定性信息。同时,通过练习题的解答,我们进一步扩展了梯度下降算法的应用范围。
3. 总结
3.1 分类任务概述
分类是一种机器学习任务,算法需要观察未标记的数据点并将其识别为某个类别的成员。在本文的例子中,我们根据二手车的里程数和价格数据编写了一个算法,将其分类为宝马 5 系或丰田普锐斯。
3.2 决策边界
在二维空间中,一种简单的分类方法是建立决策边界。决策边界是在数据所在的二维空间中绘制的一条边界,边界一侧的点被分类为一个类别,另一侧的点被分类为另一个类别。简单的决策边界可以是一条直线。
3.3 逻辑函数
如果决策边界线的形式为
ax + by = c
,那么
ax + by – c
在直线的一侧为正,另一侧为负。我们可以将这个值解释为数据点看起来像宝马的程度。正值表示数据点看起来像宝马,负值表示更像普锐斯。
通过将
sigmoid
函数与
ax + by – c
组合,我们得到一个新的函数
σ(ax + by – c)
,它也能衡量数据点看起来像宝马的程度,但只返回 0 到 1 之间的值。这种函数是二维逻辑函数。
3.4 分类器的确定性
逻辑分类器输出的 0 到 1 之间的值可以解释为它对数据点属于某个类别的信心程度。例如,返回值 0.51 和 0.99 都表示模型认为我们看到的是宝马,但后者的预测更有信心。
3.5 最佳拟合
使用适当的成本函数惩罚有信心的错误分类,我们可以使用梯度下降来找到最佳拟合的逻辑函数。这是根据数据集得到的最佳逻辑分类器。
3.6 展望
在未来的工作中,我们可以进一步探索逻辑回归在其他领域的应用,以及如何优化逻辑分类器的性能。同时,我们可以结合其他机器学习算法,提高分类的准确性和可靠性。
4. 关键技术点分析
4.1 逻辑函数与决策边界
逻辑函数在数据分类中起着核心作用,它通过 sigmoid 函数将线性函数映射到 0 到 1 的区间,从而为数据点属于某个类别的可能性提供了量化的度量。决策边界则是区分不同类别的分界线,其形式通常为线性方程
ax + by = c
。以下是它们之间的关系总结:
| 项目 | 描述 |
| ---- | ---- |
| 线性函数 |
ax + by - c
的正负决定了数据点相对于决策边界的位置,正表示倾向于一个类别,负表示倾向于另一个类别 |
| 逻辑函数 |
σ(ax + by - c)
将线性函数的输出映射到 0 到 1 的区间,输出值可解释为数据点属于某个类别的概率 |
| 决策边界 | 当
σ(ax + by - c) = 0.5
时,即
ax + by - c = 0
,对应的直线就是决策边界 |
4.2 梯度下降算法
梯度下降是一种优化算法,用于寻找函数的最小值。在逻辑回归中,我们使用梯度下降来最小化成本函数,从而找到最佳的逻辑函数参数。以下是梯度下降算法的关键步骤:
graph TD
A[初始化参数 x, y, z] --> B[计算梯度 grad]
B --> C{梯度长度 > 容差 且 步数 < 最大步数}
C -- 是 --> D[更新参数 x, y, z]
D --> B
C -- 否 --> E[返回参数 x, y, z]
具体代码实现如下:
def gradient_descent3(f,xstart,ystart,zstart,
tolerance=1e-6,max_steps=1000):
x = xstart
y = ystart
z = zstart
grad = approx_gradient3(f,x,y,z)
steps = 0
while length(grad) > tolerance and steps < max_steps:
x -= 0.01 * grad[0]
y -= 0.01 * grad[1]
z -= 0.01 * grad[2]
grad = approx_gradient3(f,x,y,z)
steps += 1
return x,y,z
4.3 成本函数的作用
成本函数用于衡量逻辑函数对数据的拟合程度。在逻辑回归中,我们希望找到使成本函数最小的参数,从而得到最佳的逻辑函数。成本函数的选择非常重要,它需要能够惩罚有信心的错误分类。例如,
logistic_cost
函数通过对错误分类进行适当的惩罚,使得梯度下降能够收敛到一个合理的解。而
simple_logistic_cost
函数由于没有对错误分类进行有效的惩罚,导致梯度下降无法收敛。
5. 应用场景与优势
5.1 应用场景
逻辑回归在许多领域都有广泛的应用,以下是一些常见的应用场景:
-
医疗诊断
:根据患者的症状和检查结果,预测疾病的发生概率,如判断肿瘤是良性还是恶性。
-
金融风险评估
:根据客户的信用记录、收入等信息,评估贷款违约的可能性。
-
市场营销
:根据客户的行为和特征,预测客户购买产品的概率,从而进行精准营销。
5.2 优势
逻辑回归作为一种经典的分类算法,具有以下优势:
-
简单易懂
:逻辑回归的原理和实现相对简单,易于理解和解释。
-
计算效率高
:梯度下降算法的计算复杂度较低,能够在较短的时间内得到结果。
-
可解释性强
:逻辑函数的参数可以解释为各个特征对分类结果的影响程度,有助于我们理解数据和模型。
6. 注意事项与改进方向
6.1 注意事项
在使用逻辑回归进行数据分类时,需要注意以下几点:
-
数据预处理
:数据的质量和特征的选择对模型的性能有很大影响。在进行逻辑回归之前,需要对数据进行清洗、标准化等预处理操作。
-
成本函数的选择
:不同的成本函数对模型的训练结果有不同的影响。需要根据具体的问题选择合适的成本函数。
-
梯度下降的参数设置
:梯度下降的步长、容差和最大步数等参数需要根据具体情况进行调整,以确保算法能够收敛到一个合理的解。
6.2 改进方向
为了提高逻辑回归的性能,可以考虑以下改进方向:
-
特征工程
:通过提取和选择更有价值的特征,提高模型的分类能力。
-
集成学习
:将逻辑回归与其他机器学习算法结合,如决策树、支持向量机等,提高分类的准确性和可靠性。
-
正则化
:使用正则化方法,如 L1 和 L2 正则化,防止模型过拟合。
7. 总结与展望
7.1 总结
本文介绍了利用逻辑回归进行数据分类的基本原理和方法。通过建立决策边界和使用逻辑函数,我们可以将数据点分类为不同的类别。使用梯度下降算法,我们可以找到最佳拟合的逻辑函数,从而得到一个准确的分类器。逻辑回归具有简单易懂、计算效率高和可解释性强等优点,在许多领域都有广泛的应用。
7.2 展望
随着机器学习技术的不断发展,逻辑回归也在不断改进和扩展。未来,我们可以进一步探索逻辑回归在深度学习、强化学习等领域的应用,以及如何将逻辑回归与其他算法结合,提高分类的性能和效率。同时,我们可以利用更多的数据和更复杂的模型,解决更具挑战性的分类问题。
超级会员免费看
2592

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



