Logistic回归

项目代码

Logistic回归

假设有一堆数据点,用一条直线对这些点进行拟合(该条直线成为最佳拟合直线),这个拟合过程就称为回归。
利用Logistic回归进行分类的思想:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的回归源于最佳拟合,表示要找到最佳拟合参数集。

利用Logistic回归如何分类

假设在二分类情况下,我们希望有某个函数在接受所有输入之后可以预测出类别(即可以输出0或1,表示不同类别)。这种函数称为海维赛德阶跃函数(或者称为单位阶跃函数)。然而海维赛德阶跃函数在跳跃点上从0瞬间跳跃到1,这个瞬间跳跃过程有时很难处理。因此需要一个更好的函数,这就是这节用到的sigmoid函数,其数学表达式为:
s i g m o i d ( z ) = 1 1 + e − z sigmoid(z)=\frac{1}{1+e^{-z}} sigmoid(z)=1+ez1
下图是sigmoid函数在不同坐标尺度下的曲线图:
在这里插入图片描述
z = 0 z=0 z=0时, s i g m o i d ( z ) = 1 2 sigmoid(z)=\frac{1}{2} sigmoid(z)=21;随着 z z z的增大, s i g m o i d ( z ) sigmoid(z) sigmoid(z)函数值逼近1;随着 z z z的减小, s i g m o i d ( z ) sigmoid(z) sigmoid(z)函数值逼近0。在坐标尺度比较大的情况下, s i g m o i d ( z ) sigmoid(z) sigmoid(z)函数很像一个阶跃函数。
因此,为实现Logistic回归分类器,我们可以在每个特征上都乘一个回归系数,然后把所有结果值相加后带入 s i g m o i d ( z ) sigmoid(z) sigmoid(z)函数,任何大于0.5的数据被分为类别1,小于0.5的被归入类别0。
Python代码实现 s i g m o i d 函 数 sigmoid函数 sigmoid:

def sigmoid(inX):
    return 1 / (1 + np.exp(-inX))

确定了分类器的函数形式之后,怎么确定最佳回归系数???

利用优化算法确定最佳回归系数

s i g m o i d sigmoid sigmoid函数的输入记为 z z z,则:
z = w 0 x 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n + z=w_0x_0+w_1x_1+w_2x_2+...+w_nx_n+ z=w0x0+w1x1+w2x2+...+wnxn+
采用向量形式可以写为: z = w T x z=w^Tx z=wTx,其中向量 w w w就是我们需要找的最佳回归系数。
那么怎么求出最佳回归系数 w w w呢???

梯度上升法求 w w w

梯度上升法的思想:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。如果梯度记为 ∇ \nabla ,则函数 f ( x , y ) f(x,y) f(x,y)的梯度可以表示为:
∇ f ( x , y ) = ⟮ δ f ( x , y ) δ y δ f ( x , y ) δ x ⟯ \nabla f(x,y)=\lgroup^\frac{\delta f(x,y)}{\delta x} _\frac{\delta f(x,y)}{\delta y}\rgroup f(x,y)=δyδf(x,y)δxδf(x,y)
这个公式意味着沿 x x x的方向移动 δ f ( x , y ) δ x \frac{\delta f(x,y)}{\delta x} δxδf(x,y),沿 y y y的方向移动 δ f ( x , y ) δ y \frac{\delta f(x,y)}{\delta y} δyδf(x,y),函数 f ( x , y ) f(x,y) f(x,y)要在待计算的点上有定义并且可微。如图(图来自机器学习实战一书):
在这里插入图片描述
从图中可以看出梯度算子总是指向函数值增长最快的方向,移动量的大小称为步长 α \alpha α。则梯度的迭代公式可以表示为:
w : = w w:=w w:=w + + + α \alpha α ∇ \nabla w _w w f ( w ) f(w) f(w)
该公式在达到某个停止条件之前一直迭代执行,例如迭代次数达到某个指定值或算法达到某个可以允许的误差范围。
在这里插入图片描述
图片来自机器学习实战一书。
梯度上升法的伪代码如下:

'''
1. 初始化回归系数w
2. for N次数:
3.     计算整个数据集的梯度gradient
4.     使用w = w + alpha*gradient更新回归系数
5.     返回回归系数
'''

python代码实现:

def grad_ascent(x_train, y_train, learning_rate=0.001, epochs=500):
    x_mat = np.matrix(x_train)
    y_mat = np.matrix(y_train).transpose()
    rows, cols = x_mat.shape
    args = np.ones((cols + 1, 1))
    add_1 = np.ones((rows,))
    x_mat = np.column_stack((x_mat, add_1))
    for k in range(epochs):
        y_pre = sigmoid(x_mat * args)
        loss = y_mat - y_pre
        args = args + learning_rate * x_mat.transpose() * loss
    w = args[:-1]
    b = np.array(args[-1])
    return w, b

画出决策边界的代码:

def plot_best_fit(x_train, y_train, weight, bias):
    import matplotlib.pyplot as plt
    rows = x_train.shape[0]
    x0 = []; x1 = []; y0 = []; y1 = []
    for i in range(rows):
        if y_train[i] == 0:
            x0.append(x_train[i, 0])
            y0.append(x_train[i, 1])
        else:
            x1.append(x_train[i, 0])
            y1.append(x_train[i, 1])
    ax = plt.subplot(111)
    ax.scatter(x0, y0, s=30, c='r')
    ax.scatter(x1, y1, s=30, c='g')
    x = np.arange(-3, 3, 0.1)
    y = (-bias - weight[0] * x) / weight[1]
    ax.plot(x, y.transpose())
    plt.xlabel('X1')
    plt.ylabel('Y1')
    plt.show()
    ```
加载数据集的代码:

```python
def read_data(data_path):
    data = np.loadtxt(data_path)
    return data[:, :-1], data[:, -1]

结果:
在这里插入图片描述

随机梯度上升法

梯度上升法在每次更新回归系数时都需要遍历整个数据集,该方法处理100个左右的数据还可以,但如果有数亿的样本和上万的特征,该方法的计算复杂度太高。因此将该算法改为以此仅用一个样本点更新回归系数,该方法称为随机梯度上升算法,伪代码和实现代码及结果如图(图来自机器学习实战一书):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
该方法的结果并非最佳拟合,这是因为上一个实现是在整个数据集上迭代500次才得到。判断一个优化算法优劣的可靠方法是看它是否收敛,也就是说参数是否达到稳定值。因此需要对随机梯度算法进行改进,代码如下:

def stoc_grad_ascent(x_train, y_train, learning_rate=0.01, epochs=500):
    rows, cols = x_train.shape
    args = np.ones((cols + 1, ))
    add_1 = np.ones((rows,))
    x_train = np.column_stack((x_train, add_1))
    for j in range(epochs):
        data_index = np.arange(rows)
        for i in range(rows):
            learning_rate = 4/(j+i+1)+0.01
            # learning_rate = learning_rate*0.95
            rand_index = int(np.random.uniform(0,len(data_index)))
            y_pre = sigmoid(sum(x_train[rand_index] * args))
            loss = y_train[rand_index] - y_pre
            args = args + learning_rate * x_train[rand_index] * loss
            np.delete(data_index, rand_index)
    w = args[:-1]
    b = args[-1]
    return w, b

改进之处:1) 每次迭代调整 α \alpha α值;2) 通过随机取样更新回归系数。
其结果如图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值