机器学习——Logistic回归

目录

前言:

Logistic回归简介

前期引入

线性模型与回归

 最小二乘与参数求解

回归的基本思想

Sigmod函数

Logistic回归

分类问题  

极大似然法 

梯度下降

数据分类

代码实现

数据准备

代码实现:

总结


前言:

        Logistic回归是一种十分常见的分类模型,是的严格来说这是一个分类模型,之所以叫做回归也是由于历史原因。不同于线性回归中对于参数的推导,我们在这里运用的方式不再是最小二乘法,而是极大似然估计。

Logistic回归简介

        逻辑斯谛回归(logistic regression)是统计学习中的经典分类方法,属于对数线性模型,所以也被称为对数几率回归。这里要注意,虽然带有回归的字眼,但是该模型是一种分类算法,逻辑斯谛回归是一种线性分类器,针对的是线性可分问题。利用logistic回归进行分类的主要思想是:根据现有的数据对分类边界线建立回归公式,以此进行分类。这里的“回归”一词源于最佳拟合,表示要找到最佳拟合参数集,因此,logistic训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化方法

前期引入

线性模型与回归

线性模型一般形式:

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

向量形式可记为:

           f ( x )= wT x + b

其中w=(w1, w2, ..., wd)为待求解系数

我们可以根据样本来拟出一条直线,如下:

给定数据集 D={(x1, y1), (x2, y2), ..., (xm, ym)}

其中xi=(xi1, xi2, ..., xid), yi ∈R

线性回归(linear regression)目的:

学习一个线性模型以尽可能准确地 预测实值输出标记:

 最小二乘与参数求解

线性回归目标:

参数/模型估计:最小二乘法(least square method)

考虑xi是一维数据,设其回归值𝑓(𝑥𝑖)f(x_i)实际观察 𝑦𝑖y_i 之间存在的误差 𝑒𝑖〖 e〗_i,则学习的目标为:

最小化均方误差:

分别对wb求导,可得:

得到解析/闭合(closed-form)解:

回归的基本思想

根据训练数据和分类边界线方程(方程参数未知),得到最佳拟合参数集,从而实现数据的分类。通常,Logistic回归适用于二值型输出分类,即二分类,也就是分类结果只有两种情况:是与否,发生与不发生等。

Sigmod函数

既然,Logistic回归的输出只有两种情况,那么我们有必要引入一种函数,该函数只有两种输出,0或者1。有人可能会想到单位阶跃函数,没错,确实可以,但是考虑到单位阶跃函数是分段函数,其在x=0处的跳变不方便用代码处理。故此,我们介绍另外一种函数——Sigmod函数。其实,从数学的角度上讲,这也是一种阶跃函数。

Sigmoid函数也叫Logistic函数,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来做二分类。

其基本图形如下:

当x=0时,Sigmod(0)的值为0.5。为了实现分类器,我们将每个样本的每个特征值乘以相应的回归系数,然后求和,并带入Sigmod函数。当结果大于0.5时,该样本被归为1类;当结果小于0.5时,该样本归为0类。这样我们就实现了Logistic的二分类。所以,Logistic分类,也是一种概率估计,即样本有多大的概率被划分为某一类。

Logistic回归

分类问题  

线性模型可以衍生出一般形式:

g(∙)称为联系函数(link function),该函数一般为单调可微函数。

对数线性回归是 g(∙)=ln(∙) 时广义/多维线性模型的特例。

预测值与输出标记

寻找函数将分类标记与线性回归模型输出联系起来。

单位阶跃函数:

 

单位阶跃函数缺点
不连续
替代函数 —— 逻辑斯蒂函数( logistic/sigmoid function
单调可微、任意阶可导

 

 所以:逻辑回归是拟合“ysigmoid函数”

运用 Sigmoid 函数:
对数几率( log odds
样本作为正例的相对可能性的对数

极大似然法 

对数几率:
而:
因此有:
极大似然法( maximum likelihood)
给定数据集
最大化样本属于其真实标记的概率
等同于最大化对数似然函数

转化为最大化逻辑斯蒂似然函数求解

记: 

可简写为:

梯度下降

 

数据分类

给定数据样本:

分类:

代码实现

数据准备

将数据放在testSet.txt里面:

数据集内容如下:

以上只展示一部分数据。

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
from numpy import *
import matplotlib.pyplot as plt
 
#从文件中加载数据:特征X,标签label
def loadDataSet():
    dataMatrix=[]
    dataLabel=[]
    #这里给出了python 中读取文件的简便方式
    f=open('testSet.txt')
    for line in f.readlines():
        #print(line)
        lineList=line.strip().split()
        dataMatrix.append([1,float(lineList[0]),float(lineList[1])])
        dataLabel.append(int(lineList[2]))
    #for i in range(len(dataMatrix)):
    #   print(dataMatrix[i])
    #print(dataLabel)
    #print(mat(dataLabel).transpose())
    matLabel=mat(dataLabel).transpose()
    return dataMatrix,matLabel
 
#logistic回归使用了sigmoid函数
def sigmoid(inX):
    return 1/(1+exp(-inX))
 
#函数中涉及如何将list转化成矩阵的操作:mat()
#同时还含有矩阵的转置操作:transpose()
#还有list和array的shape函数
#在处理矩阵乘法时,要注意的便是维数是否对应
 
#graAscent函数实现了梯度上升法,隐含了复杂的数学推理
#梯度上升算法,每次参数迭代时都需要遍历整个数据集
def graAscent(dataMatrix,matLabel):
    m,n=shape(dataMatrix)
    matMatrix=mat(dataMatrix)
 
    w=ones((n,1))
    alpha=0.001
    num=500
    for i in range(num):
        error=sigmoid(matMatrix*w)-matLabel
        w=w-alpha*matMatrix.transpose()*error
    return w
 
 
#随机梯度上升算法的实现,对于数据量较多的情况下计算量小,但分类效果差
#每次参数迭代时通过一个数据进行运算
def stocGraAscent(dataMatrix,matLabel):
    m,n=shape(dataMatrix)
    matMatrix=mat(dataMatrix)
 
    w=ones((n,1))
    alpha=0.001
    num=20  #这里的这个迭代次数对于分类效果影响很大,很小时分类效果很差  
    for i in range(num):
        for j in range(m):
            error=sigmoid(matMatrix[j]*w)-matLabel[j]
            w=w-alpha*matMatrix[j].transpose()*error        
    return w
 
def stocGraAscent1(dataMatrix,matLabel):
    m,n=shape(dataMatrix)
    matMatrix=mat(dataMatrix)
 
    w=ones((n,1))
    num=200  #这里的这个迭代次数对于分类效果影响很大,很小时分类效果很差
    setIndex=set([])
    for i in range(num):
        for j in range(m):
            alpha=4/(1+i+j)+0.01
 
            dataIndex=random.randint(0,100)
            while dataIndex in setIndex:
                setIndex.add(dataIndex)
                dataIndex=random.randint(0,100)
            error=sigmoid(matMatrix[dataIndex]*w)-matLabel[dataIndex]
            w=w-alpha*matMatrix[dataIndex].transpose()*error    
    return w
 
#绘制图像
def draw(weight):
    x0List=[];y0List=[];
    x1List=[];y1List=[];
    f=open('testSet.txt','r')
    for line in f.readlines():
        lineList=line.strip().split()
        if lineList[2]=='0':
            x0List.append(float(lineList[0]))
            y0List.append(float(lineList[1]))
        else:
            x1List.append(float(lineList[0]))
            y1List.append(float(lineList[1]))
 
    fig=plt.figure()
    ax=fig.add_subplot(111)
    ax.scatter(x0List,y0List,s=10,c='red')
    ax.scatter(x1List,y1List,s=10,c='green')
 
    xList=[];yList=[]
    x=arange(-3,3,0.1)
    for i in arange(len(x)):
        xList.append(x[i])
 
    y=(-weight[0]-weight[1]*x)/weight[2]
    for j in arange(y.shape[1]):
        yList.append(y[0,j])
 
    ax.plot(xList,yList)
    plt.xlabel('x1');plt.ylabel('x2')
    plt.show()
 
 
if __name__ == '__main__':
    dataMatrix,matLabel=loadDataSet()
    #weight=graAscent(dataMatrix,matLabel)
    weight=stocGraAscent1(dataMatrix,matLabel)
    print(weight)
    draw(weight)

运行结果:

总结

Logistic回归是一种常用的分类算法,适用于二分类问题。通过对数据进行训练,可以得到一个分类边界,将数据分为两个类别。

在这个实验中,我们使用了两种方法来实现Logistic回归:梯度上升算法和随机梯度上升算法。梯度上升算法每次迭代都需要遍历整个数据集,计算量较大;而随机梯度上升算法每次迭代只需要随机选取一个样本进行计算,计算量较小。同时,随机梯度上升算法还引入了学习率的概念,使得每次迭代的步长不固定,可以更好地适应数据。

在实验过程中,我们加载了一个数据集,并使用训练数据来训练模型。训练过程中,我们根据模型的预测结果和实际标签之间的误差来更新模型参数,使得模型的预测结果更加准确。最终,得到了一个分类边界,并使用绘图函数将分类结果可视化。

总结起来,Logistic回归是一种简单而有效的分类算法,在处理二分类问题时具有较好的效果。通过实验,我们可以了解到不同的算法对分类结果的影响,并选择合适的方法来解决实际问题。

以下为Logistic回归的优缺点:

优点:

  1. 实现简单:Logistic回归是一个相对简单的分类算法,易于理解和实现。
  2. 计算代价低:相比其他复杂的分类算法,Logistic回归的计算代价较低,训练速度较快。
  3. 输出结果易于理解:Logistic回归输出的结果可以被解释为概率,而不仅仅是类别标签,这使得结果更易于理解。

缺点:

  1. 只能处理二分类问题:Logistic回归只能解决二分类问题,对于多分类问题需要进行改进或者组合其他算法。
  2. 对特征工程敏感:Logistic回归对输入特征的线性关系假设比较严格,如果特征之间的关系不是线性的,可能会导致分类效果不佳。
  3. 容易欠拟合:当特征之间的关系较为复杂时,Logistic回归可能会出现欠拟合的情况,分类效果不佳。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值