逻辑回归模型和Python代码实现

news2024/11/15 12:31:35

文章目录

  • 逻辑回归原理
    • sigmoid函数
    • 优化建模
  • 代码实现
    • 自编代码
    • sklearn代码
  • 代码测试
    • 原理测试
    • 交叉验证

逻辑回归原理

此前介绍的线性回归基本模型和增加了正则项的优化模型都只能用来预测连续值(标签值是多少),如果想要应用于分类问题(标签值是1还是0),就还需要进一步操作,即本文即将介绍的逻辑回归,其本质是预测标签值是1和0的概率分别为多少。

由于连续值的取值范围为 ( − ∞ , + ∞ ) (-\infty, +\infty) (,+),而概率值的取值范围是 ( 0 , 1 ) (0, 1) (0,1),所以需要将线性回归模型得到的连续值做一次转换,压缩到 ( 0 , 1 ) (0, 1) (0,1)中。

sigmoid函数

在逻辑回归模型中,将连续值压缩的方式是使用sigmoid函数,其表达式为
f ( x ) = 1 1 + e − x f(x)=\frac{1}{1+e^{-x}} f(x)=1+ex1
sigmoid函数的图形如下,显然 f ( x ) f(x) f(x)的范围是 ( 0 , 1 ) (0, 1) (0,1)

图形实线的Python代码为

import matplotlib.pyplot as plt
import numpy as np
import math


# sigmoid函数
def sigmoid(x):
    return 1 / (1 + math.exp(-x))
    

def plot_sigmoid():
    
    # 构造x和y数据
    x = np.linspace(-6, 6, 100)
    y = []
    for i in x:
        y.append(sigmoid(i))
    
    # 绘制基本数据
    plt.figure(figsize=(5, 5))
    plt.plot(x, y)
    
    # 将y轴移至坐标原点,并去除右侧实线
    ax = plt.gca()
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data', 0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['right'].set_color('none')
    
    # 增加坐标标签
    plt.xlabel('x', loc='right')
    plt.ylabel('f(x)', loc='top', rotation=0)


if __name__ == '__main__':
    # 绘制sigmoid曲线
    plot_sigmoid()

除了以上的图示,我们还可以从数学角度来推演:针对样本的预测值 y ^ \hat{y} y^,其线性回归表达式为
y ^ = w 1 ∗ x 1 + w 2 ∗ x 2 + . . . + w n ∗ x n + b \hat{y}=w_1*x_1+w_2*x_2+...+w_n*x_n+b y^=w1x1+w2x2+...+wnxn+b
y ^ \hat{y} y^的范围是 ( − ∞ , + ∞ ) (-\infty, +\infty) (,+),那么指数函数 e y ^ e^{\hat{y}} ey^的范围是 ( 0 , + ∞ ) (0, +\infty) (0,+),构造如下的表达式
e y ^ e y ^ + 1 \frac{e^{\hat{y}}}{e^{\hat{y}}+1} ey^+1ey^
显然,上式的范围即为 ( 0 , 1 ) (0, 1) (0,1),而对上式的分子和分母同时除以 e y ^ e^{\hat{y}} ey^,得到
1 1 + e − y ^ \frac{1}{1+e^{-\hat{y}}} 1+ey^1
以上即为sigmoid函数。

到了这里,其实就出现了一个问题:逻辑回归为什么要使用sigmoid函数?是否可以使用其他函数替代?
我在网上找了很久,但并没有找到让我折服的解释,其中一篇算是说的比较全的了,放在这里以作参考。

优化建模

基于以上分析,我们可以做出以下定义:针对任意一个样本,其分类结果为1的概率为
f = 1 1 + e − y ^ f=\frac{1}{1+e^{-\hat{y}}} f=1+ey^1
其中, y ^ = w 1 ∗ x 1 + w 2 ∗ x 2 + . . . + w n ∗ x n + b \hat{y}=w_1*x_1+w_2*x_2+...+w_n*x_n+b y^=w1x1+w2x2+...+wnxn+b

该样本被分类为0的概率即为
g = 1 − 1 1 + e − y ^ g=1-\frac{1}{1+e^{-\hat{y}}} g=11+ey^1
分子和分母同时乘以 e y ^ e^{\hat{y}} ey^,得到
g = 1 1 + e y ^ g=\frac{1}{1+e^{\hat{y}}} g=1+ey^1
对于该样本来说,要让分类模型准确,那么,如果真实标签 y y y为1,则应该让 f f f最大化;反之,应该让 g g g最大化。
因此,对于整个训练集来说,可以建立优化模型为:寻找最佳的 w 1 , w 2 , . . . , w n , b w_1, w_2,...,w_n,b w1,w2,...,wn,b,使得如下表达式最大化
F ∗ G F*G FG
其中, F F F为所有真实标签为1的样本对应的 f f f函数的连乘; G G G为所有真实标签为0的样本对应的 g g g函数的连乘。
事实上,此即为,概率论中的最大似然函数,不过名称不重要,重要的是对建模过程的理解。

以上定义的问题是一个无约束优化问题,可以使用很多优化算法求解,例如梯度类算法等。

代码实现

自编代码

接下来看一下,如何编写代码实现对权重系数 w w w和截距 b b b的优化计算。

以下代码中,使用的是forge数据集。该数据集有2维特征,所以待优化的变量有三个: w 1 , w 2 , b w_1, w_2, b w1,w2,b。values实现了对连乘的计算,同时在外侧增加了log函数,以此解决因为values本身数值过小而导致提前收敛的风险。优化方法使用的是scipy.optimize命令。

from scipy import optimize


# 自编代码,带优化函数
def f(t):

    # 【数据集1】forge
    X, y = forge()

    values = 0

    for i in range(len(y)):
        # 去log,否则数值太小,无法优化
        if y[i] == 1:
            values -= math.log(1 / (1 + math.exp(-t[0] * X[i, 0] - t[1] * X[i, 1] - t[2])))
        if y[i] == 0:
            values -= math.log(1 / (1 + math.exp(t[0] * X[i, 0] + t[1] * X[i, 1] + t[2])))

    return values


# self代码优化权重系数和截距
def logreg_by_self():

    res = optimize.minimize(f, [0, 0, 0], method='BFGS')
    print('coef_by_self: {}, intercept_by_self: {}'.format(res.x[0:2], res.x[2]))

sklearn代码

如果调用工具包,可以直接使用sklearn.linear_model中的LogisticRegression即可。

from sklearn.linear_model import LogisticRegression

# sklearn优化权重系数和截距
def logreg_by_sklearn():
    # 【数据集1】forge
    X, y = forge()

    logreg = LogisticRegression(penalty='none', solver="lbfgs")
    logreg.fit(X, y)
    print('coef_by_sklearn: {}, intercept_by_sklearn: {}'.format(logreg.coef_, logreg.intercept_))

代码测试

原理测试

首先校验自编代码的准确性,调用以上两个函数,对比各自得到的权重系数和截距值

if __name__ == '__main__':

    # 对比self和sklearn计算结果
    logreg_by_self()
    logreg_by_sklearn()

代码输出结果如下所示。显然,两个方法得到的权重系数和截距是一致的,由此验证了原理和代码的正确性。

coef_by_self: [1.28004377 4.13686808], intercept_by_self: -21.37174954243782
coef_by_sklearn: [[1.28004046 4.13685915]], intercept_by_sklearn: [-21.37170026]

交叉验证

事实上,逻辑回归模型中也可以使用交叉验证的策略,进一步提升算法的性能指标。以下代码针对cancer数据集,使用交叉验证的方式,得到了最佳的正则化系数C。

import numpy as np
from sklearn.linear_model import LogisticRegression, LogisticRegressionCV
from sklearn.model_selection import train_test_split


# sklearn代码实现逻辑回归
def logreg_cv_by_sklearn(X, y):
    # 数据集拆分
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

    # 构造不同的Cs值,logregCV交叉验证得到最佳C
    Cs = np.logspace(-5, 2, 20)
    # 默认solver是lbfgs,会提示未收敛,故修改为liblinear
    logregCV = LogisticRegressionCV(Cs=Cs, cv=5, solver="liblinear")
    logregCV.fit(X_train, y_train)
    print('Logreg_best_C: {}'.format(logregCV.C_))

    # 使用最佳C重新训练
    logreg = LogisticRegression(C=logregCV.C_[0], solver="liblinear")
    logreg.fit(X_train, y_train)

    print('Training set score: {}'.format(logreg.score(X_train, y_train)))
    print('Test set score: {}'.format(logreg.score(X_test, y_test)))


if __name__ == '__main__':

    # 【数据集3】cancer,用于实现交叉验证
    cancer_data, X_arr, y_arr = breast_cancer()
    # sklearn代码实现交叉验证
    logreg_cv_by_sklearn(X_arr, y_arr)

运行以上的程序,可以得到如下结果。

Logreg_best_C: [100.]
Training set score: 0.9741784037558685
Test set score: 0.965034965034965

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/59944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出 文章目录 回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出预测效果基本介绍模型结构程序设计参考资料致谢预测效果 基本介绍 GRU神经网络是LSTM神经网络的一种变体,LSTM 神经网 络是在RNN的基础上发展起来的。RNN是一…

Python学习----网络编程

网络:网络就是实现资源共享和信息传递的虚拟平台,我们可以编写基于网络通信的程序。比如socket编程,web开发 Socket编程 Socket是程序之间通信的一个工具,好比显示生活中的电话,你知道了对方的电话号码之后&#xff…

RabbitMQ进阶

可以结合着狂神的RabbitMQ的笔记来进行学习 狂神说RabbitMQ笔记 RabbitMQ高级特性 消息可靠性投递 保证我发出的消息可以到达中间件,避免在传输的过程中发生丢失的情况。 这两个可靠性传输方式分别是负责不同的阶段,confirm是负责保证从生产者到队列…

[附源码]Python计算机毕业设计Django抗疫医疗用品销售平台

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

2023年江苏省职业院校技能大赛中职赛项规程样题

2023年江苏省职业院校技能大赛中职赛项规程 一、赛项名称 赛项编号:JSZ202335 赛项名称:网络安全 赛项组别:学生组、教师组 赛项归属专业大类:信息技术类 竞赛目的 贯彻落实《国家职业教育改革实施方案》《关于推动现代职业教…

设计模式——观察者模式

动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖…

非零基础自学Golang 2 开发环境 2.1 Go 的安装

非零基础自学Golang 学习文档地址:https://www.topgoer.cn/ 本文仅用于学习记录,不存在任何商业用途,如侵删【已联系过文档作者】 文章目录非零基础自学Golang2 开发环境2.1 Go 的安装2.1.1 下载地址2.1.2 Go 的安装2.1.3 安装检查2 开发环境…

TypeScript22(Rollup构建TS项目 webpack构建TS项目)

Rollup构建TS项目 安装依赖: 1.全局安装rollup: npm install rollup-g 2.安装TypeScript: npm install typescript -D 3.安装TypeScript 转换器: npm install rollup-plugin-typescript2 -D 4.安装代码压缩插件&#xff1a…

项目:金融行业反欺诈模型

当今以互联网、移动终端等为代表的技术力量正深刻地影响着金融支付市场,信息化、网络化、无线终端等技术的应用,使金融机构特别是银行业的经营发生了天翻地覆的变化,传统的银行柜台和网点业务,正渐渐被电子化交易所替代&#xff0…

[附源码]计算机毕业设计基于SpringBoot的黄河文化科普网站

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Golang开发变量声明命名惯例

《Go语言精进之路》第二、三章部分内容学习记录笔记。 1.基本原则 Golang开发中,可遵守简单且一致的命名原则,力求命名精简、易懂和一致。 package声明 Golang的package声明以小写形式的单个词进行命名: shopservice、utils、logs、tcc、l…

08_openstack之nova节点扩容

目录 一、环境准备 二、扩容节点配置 三、部署扩容节点 1、编辑answer.ini文件 2、执行安装 一、环境准备 部署openstack私有云环境:02_openstack私有云部署_桂安俊kylinOS的博客-CSDN博客 上述环境只部署了nova1节点,现将未部署的nova2节点作为扩…

1. Nginx 基本功能配置

Nginx 目录信息 图 为 windows 版本的。 进入Nginx的主目录我们可以看到这些文件夹 client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp 其中这几个文件夹在刚安装后是没有的,主要用来存放运行过程中的临时文件 client_body_t…

20221104英语学习

今日单词: portable adj.轻便的,便携的;手提式的 beautiful adj.美丽的, 风和日丽的, 出色的 hunter n.猎人, 狩猎者, (猎食其他动物的)猎兽, 搜集某种东西的人 circle n.圆, 圈, 圆形, 圆圈 style n.样式, 风格,…

Unity 算法 之 点集中计算绘制 凸包 的简单整理

Unity 算法 之 点集中计算绘制 凸包 的简单整理 目录 Unity 算法 之 点集中计算绘制 凸包 的简单整理 一、简单介绍 二、Graham扫描法 第一种说明: 第二种说明: 三、代码(第二种说明) 四、参考文献 一、简单介绍 算法&…

工作上的三个境界:能做,能做好,能持续做好

某天,技术岗A员工抬杠管理岗B员工的工作:你的工作啊,实习生都能做,你的价值太小了........一顿DISS。 这样的场景,似曾相识否?这是职场中常见的一类人“杠精”的表现。 做技术的,往往认为管理…

MySQL8.0 OCP最新版1Z0-908认证考试题库整理-006

原题 Choose the best answer.You are having performance issues with MySQL instances. Those servers are monitored withMySQL Enterprise Monitor.Using Query Analyzer, where do you begin to look for problem queries?A) Sort the "Exec" column and check…

什么是物联网?如何保护物联网iot安全性

物联网iot:物联网(IoT)将生活中事物以网络进行连接,彼此交换信息。整个世界借由设备连接成一体。 对于消费者而言,这意味着您可以在大洋彼岸远程调节家中的恒温器。但是对企业而言,物联网不仅创造了连接客户和合作伙伴…

BBR 公平收敛

BBR 的公平收敛来自于两点: ProbeBW 状态加速比收敛:带宽越大,加速比越小。ProbeRTT 状态 RTT 收敛:inflight 越大,越容易让 inflight 小的测到 minrtt 而避免进入 ProbeRTT,inflight 越小,测量…

用Python代码自己写Python代码,竟如此简单

用Python代码自己写Python代码,竟如此简单 Python作为一门功能强大且使用灵活的编程语言,可以应用于各种领域,具有“无所不能”的特质。 Python甚至可以代替人,自己写Python代码。而且很简单,只需学会Python的基础知…