zoukankan      html  css  js  c++  java
  • 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、回归系数

    通过最优化算法找出最佳回归系数——梯度上升法
    梯度
    ( abla f(x, y)={(frac{partial f}{partial x}, frac{partial f}{partial y})})
    即总是指向函数值增长最快的方向,可以用来求函数最大值
    设移动为a,那么梯度上升算法的迭代公式为
    (w=w+a abla 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
    

    结果如下

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

  • 相关阅读:
    OAuth
    PHP获取客户端的真实IP
    负载均衡----实现配置篇(Nginx)
    在线时间戳转换
    使用curl进行模拟登录
    定时任务
    Matplotlib使用教程
    CentOS7.X安装PHP
    Python虚拟环境的搭建与使用
    CentOS7.X安装openssl
  • 原文地址:https://www.cnblogs.com/Qi-Lin/p/12322774.html
Copyright © 2011-2022 走看看