机器学习-Logistic回归

一、logistic回归基本概念

  1. 线性模型

        一般形式:

                             f(x)=w_{1}x_{1}+w_{2}x_{2}+...+w_{d}x_{d}+b

        其中x=(x1, x2, ..., xd)是由d维属性描述的样本,其中 xi x 在第 i 个属性上的取值。

  1.     2.Logistic回归
  •         Logistic回归是统计学习中的经典分类方法,属于对数线性模型,所以也被称为对数几率回归。虽然是叫做回归,但其实这是一种分类算法,Logistic回归是一种线性分类器,针对的是线性可分问题。利用logistic回归进行分类的主要思想是:根据现有的数据对分类边界线建立回归公式,以此进行分类。
    •         我们都知道使用线性模型可以进行回归学习,但若要做的是分类任务改如何处理?只需要找一个单调可微函数将分类任务的真实标记y与线性回归模型的预测值联系起来。考虑二分类任务,其输出标记y的取值为0和1,而线性回归模型产生的预测值是实值,于是需将实值z转换为0/1值。通过Sigmoid函数引入非线性因素,可以实现实值z转换为0/1值,处理二分类问题。

     2.1Sigmoid函数

                                y=\frac{1}{1+e^{-z}}        \Rightarrow       ln\frac{y}{1-y}=w^{T}x+b

        与单位阶跃函数的不连续相比Sigmoid函数则具有单调可微、任意阶可导的优点。

Sigmoid函数与单位阶跃函数比较:

  1. Sigmoid函数图像:
  2. y
  3. 二、logistic回归算法

  • 1.极大似然估计
    • 极大似然估计的方法步骤:

    • 确定待求解的未知参数,如均值、方差或特定分布函数的参数等;
    • 计算每个样本的概率密度为
    • 根据样本的概率密度累乘构造似然函数:
    • 通过似然函数最大化(求导为0),求解未知参数θ,为了降低计算难度,可采用对数加法替换概率乘法,通过导数为0/极大值来求解未知参数。

2.梯度上升法

        梯度上升法基本的思想是:要找到某函数的 最大值,最好的方法是沿着该函数的梯度方向探寻。如果梯度记为∇,则函数f(x,y)的梯度由 下式表示:

         梯度上升算法到达每个点后都会重新估计移动的方向。从P0开始,计算完该点的梯度,函数就根据梯度移动到下一点P1。在P1点,梯度再次被重新计算,并沿新的梯度方向移动到P2。如此循环迭代,直到满足停止条件。迭代的过程中,梯度算子总是保证我们能选取到最佳的移动方向。

3.梯度下降法

        梯度下降算法,它与上述的梯度上升算法是一样的,只是公式中的加法需要变成减法。梯度上升算法用来求函数的最大值,而梯度下降算法用来求函数的最小值。

三、算法实现

    代码实现:

#coding:utf-8
from numpy import *
import matplotlib.pyplot as plt
 
class func:
    def loadDataSet(self):
        dataMat = []
        labelMat = []
        fr = open('testSet.txt')
        for line in fr.readlines():
            # 矩阵的格式【标签,X1,X2】
            lineArr = line.strip().split()
 
            #插入X1,X2,以及初始化的回归系数(权重),全部设为1.0
            dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])
 
            #插入标签,
            #必须转换成int类型,因为只有两类
            labelMat.append(int(lineArr[2]))
 
 
        return dataMat,labelMat
 
    # 使用sigmoid函数进行分类
    def sigmoid(self,inX):
        return 1.0/(1+exp(-inX))
 
    #普通梯度上升
    #使用梯度上升算法进行优化,找到最佳优化系数
    #dataMatIn是训练集,三维矩阵,(-0.017612	14.053064	0)
    #classLabels是类别标签,数值型行向量,需要转置为列向量,取值是0,1
    def gradAscent(self,dataMatIn,classLabels):
        dataMatrix = mat(dataMatIn) #转换为Numpy矩阵数据类型
        labelMat = mat(classLabels).transpose() #转置矩阵,便于加权相乘
        m,n = shape(dataMatrix) #得到矩阵的行列数,便于设定权重向量的维度
 
        alpha = 0.001
        maxCycles = 500
        weights = ones((n,1))  #返回一个被1填满的 n * 1 矩阵,作为初始化权重
        for k in range(maxCycles):
            h = self.sigmoid(dataMatrix*weights)
            erro = (labelMat - h)   #labelMat是使用当前回归系数得到的的标签,labelMat是训练集的标签,取值是0,1
            weights = weights + alpha * dataMatrix.transpose( ) * erro  #根据使用当前权重计算的值与初始值的误差,更改weight,
                                                                        #按照误差的方向调整回归系数
        return weights
 
    #随机梯度上升
 
    def stocGradAscent0(dataMatrix, classLabels):
        m, n = shape(dataMatrix)
        alpha = 0.01
        weights = ones(n)
        for i in range(m):
            h = sigmoid(sum(dataMatrix[i] * weights))
            error = classLabels[i] - h
            weights = weights + alpha * error * dataMatrix[i]
         return weights
 
 
    def plotBestFit(self,wei):
        weights = wei.getA()
        dataMat,labelMat = self.loadDataSet()
        dataArr = array(dataMat)
        n = shape(dataMat)[0]
        xcord1 = []
        ycord1 = []
        xcord2 = []
        ycord2 = []
 
        #根据标签不同分为两种颜色画图,易于分辨
        for i in range(n):
            if int(labelMat[i]) == 1:
                xcord1.append(dataArr[i,1])
                ycord1.append(dataArr[i,2])
            else :
                xcord2.append(dataArr[i, 1])
                ycord2.append(dataArr[i, 2])
 
        fig = plt.figure()
        ax = fig.add_subplot(111) #将画布分为一行一列的画布,并从第一块开始画
        ax.scatter(xcord1,ycord1,s=30,c='red',marker = 's') #scatter散开
        ax.scatter(xcord2,ycord2,s=30,c='green')
        x = arange(-3.0,3.0,1)
        y = (-weights[0]-weights[1]*x)/weights[2]
        ax.plot(x,y)
        plt.xlabel('x1')
        plt.ylabel('x2')
        plt.show()
 
 
 
 
if __name__=="__main__":
    #普通梯度上升
    logRegres = func()
    dataArr,labelMat = logRegres.loadDataSet()
    weights = logRegres.gradAscent(dataArr,labelMat)
    logRegres.plotBestFit(weights)
 
 
    #随机梯度上升
    logRegres = func()
    dataArr,labelMat = logRegres.loadDataSet()
    weights =stocGradAscent0(array(dataArr),labelMat)
    plotBestFit(weights)

结果展示:

分析:我们使用普通梯度上升法来实现,普通梯度上升在每次更新回归系数时都需要遍历整个数据集,复杂度会较高,但是准确率也会比较好。而另一种随机梯度上升算法则是一次仅用一个样本点更新回归系数,拟合效果没有普通梯度上升算法好,这是因为所用于实验的数据太少,准确率会比较低。

四、总结

        通过上述原理的说明,我们知道了机器学习Logistic回归算法的概念以及如何通过Logistic回归来处理模型,还有这回归函数的的含义,并且我们通过获取数据集之后对数据进行预处理,再通过对数据集进行Logistic回归算法之后,对模型进行创建、训练与评估之后,得出最后的预测结果。我们也可以知道Logistic回归算法具有很好的数学原理。而且在数据量很小的时候我们可以通过普通梯度算法来解决问题,首先复杂度不高,且准确度好,数据量很大的时候我们可以通过随机梯度上升算法来计算,以此来减小函数的复杂度。通过学习我们也知道了 Logistic 回归原理简单,模型清晰,操作高效,背后的概率的推导过程经得住推敲,在研究中,通常以 Logistic 回归模型作为基准,再尝试使用更复杂的算法,可以在大数据场景中使用。但同时也存在容易欠拟合,精度不高的问题。

        

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值