logistic回归

一、介绍

逻辑回归算法属于监督学习的分类算法,用于解决二分类(0或1)问题
一篇很好的概念介绍https://zhuanlan.zhihu.com/p/28408516

1、sigmoid函数

逻辑回归引入sigmoid函数进行分类
\(g(x)=\frac{1}{1+e^{-x}}\)
当x为0时,值为0.5
当x减小时,值趋近0
当x增大时,值趋近1

def sigmoid(x):
    return 1 / (1 + exp(-x))

图如下

2、分类器

逻辑回归分类器即对每一个特征乘以一个回归系数,然后把所有的值相加,将和带入sigmoid函数中,通过阀值0.5分为两类

3、回归系数

通过最优化算法找出最佳回归系数——梯度上升法
梯度
\(\nabla f(x, y)={(\frac{\partial f}{\partial x}, \frac{\partial f}{\partial y})}\)
即总是指向函数值增长最快的方向,可以用来求函数最大值
设移动为a,那么梯度上升算法的迭代公式为
\(w=w+a\nabla f(w)\)
一直迭代,直至在某个条件下停止(如设定的误差范围)

二、训练算法

1、梯度上升找最佳系数

该处代码有数学推导结论,我当时看也是有点懵,找到两篇推导过程,但没看太懂
https://www.cnblogs.com/weiququ/p/9414746.html
https://zhuanlan.zhihu.com/p/28415991

# data为一个二维列表,每一行代表一条数据,每一列代表一个特征值,初始时第一个特征值初始为1
# label为每条数据对应的类别列表,用0,1区别
def gradAscent(data, label):
    dataMat = mat(data)
    label = mat(label).T  # 转为矩阵后转置便于矩阵乘
    m, n = shape(dataMat)
    a = 0.001  # a为步长参数
    w = ones((n, 1))  # 初始为一个有n行1列的值为1 的列向量,即回归系数初始化为1
    # 这里500为迭代次数的参数
    for i in range(500):
        error = label - sigmoid(dataMat * w)  # 计算与实际的相差的值
        w = w + a * dataMat.T * error  # 然后对该系数w用error不断调整
    return w

结果如下

数据集来自《机器学习实战第五章》
用到的画图函数如下

# w为最后得出的参数
def draw(data, label, w):
    import matplotlib.pyplot as plt
    dataArr = array(data)
    m, n = shape(dataArr)
    x1 = []
    y1 = []
    x2 = []
    y2 = []
    for i in range(m):
        if label[i] == 0:
            x1.append(dataArr[i, 1])
            y1.append(dataArr[i, 2])
        else:
            x2.append(dataArr[i, 1])
            y2.append(dataArr[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(x1, y1, s=30, c='red')
    ax.scatter(x2, y2, s=30, c='blue')
    # 画出最优的拟合直线
    x = arange(-3, 3, 0.1)
    y = (-w[0] - w[1] * x) / w[2]
    ax.plot(x, y)
    plt.show()

2、随机梯度上升找最佳系数

用于改进计算复杂度高的问题,每一次仅用一个样本来更新回归系数

def randGrad(data, label):
    dataArr = array(data)
    m, n = shape(dataArr)
    a = 0.01
    w = ones(n)
    for i in range(m):
        h = sigmoid(sum(dataArr[i] * w))
        error = label[i] - h
        w = w + a * dataArr[i] * error
    return w

结果如下

3、改进随机梯度上升找最佳系数

为了使系数能减少周期波动,快速收敛,每一次随机用一个样本来更新回归系数,且每次都调整步长参数a

def enRandGrad(data, label):
    dataArr = array(data)
    m, n = shape(dataArr)
    w = ones(n)
    # 150为迭代的次数参数
    for i in range(150):
        dataIndex = list(range(m))
        for j in range(m):
            a = 4 / (1 + i + j) + 0.01 # 调整步长参数a
            # 随机选取一个样本更新参数
            randIndex = int(random.uniform(0, len(dataIndex)))
            h = sigmoid(sum(dataArr[randIndex] * w))
            error = label[randIndex] - h
            w = w + a * dataArr[randIndex] * error
            del (dataIndex[randIndex])
    return w

结果如下

数据集里三个系数的变化如下

posted @ 2020-02-17 17:43  启林O_o  阅读(372)  评论(0编辑  收藏  举报