49、利用逻辑回归进行数据分类

利用逻辑回归进行数据分类

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 展望

随着机器学习技术的不断发展,逻辑回归也在不断改进和扩展。未来,我们可以进一步探索逻辑回归在深度学习、强化学习等领域的应用,以及如何将逻辑回归与其他算法结合,提高分类的性能和效率。同时,我们可以利用更多的数据和更复杂的模型,解决更具挑战性的分类问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值