【机器学习】逻辑回归

文章目录

  • 逻辑回归
    • 定义损失函数
    • 正则化
  • sklearn里面的逻辑回归
    • 多项式逻辑回归


逻辑回归

逻辑回归,是一种名为“回归”的线性分类器,其本质是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法。

线性回归是机器学习中最简单的的回归算法,它写作一个几乎人人熟悉的方程:

z = b + θ 1 x 1 + θ 2 x 2 + . . . + θ n x n = θ T X , ( θ 0 = b ) z = b+θ_1x_1+θ_2x_2+...+θ_nx_n=θ^TX,(θ_0=b) z=b+θ1x1+θ2x2+...+θnxn=θTX,(θ0=b)
θ被统称为模型的参数,其中 b b b被称为截距(intercept), θ 1 θ_1 θ1 ~ θ n θ_n θn 被称为系数(coefficient)。此时我们的z是连续的,所以是回归模型。

线性回归的任务,就是构造一个预测函数z来映射输入的特征矩阵x和标签值y的线性关系,而构造预测函数的核心就是找出模型的参数:θ系数和 b,著名的最小二乘法就是用来求解线性回归中参数的数学方法。

如果想要z是离散的,也就是标签是离散型变量,则需要再做一次函数转换 g ( z ) g(z) g(z),并且令 g ( z ) g(z) g(z)的值分布在(0,1)之间,且当 g ( z ) g(z) g(z)接近0时样本的标签为类别0,当 g ( z ) g(z) g(z)接近1时样本的标签为类别1,这样就得到了一个分类模型。而这个联系函数对于逻辑回归来说,就是Sigmoid函数:

g ( z ) = 1 1 + e − z = 1 1 + e − θ T X g(z) = \frac{1}{1+e^{-z}}=\frac{1}{1+e^{-θ^TX}} g(z)=1+ez1=1+eθTX1

在这里插入图片描述

Sigmoid函数是一个S型的函数,当自变量z趋近正无穷时,因变量g(z)趋近于1,而当z趋近负无穷时,g(z)趋近于0,它能够将任何实数映射到(0,1)区间,使其可用于将任意值函数转换为更适合二分类的函数。

二元逻辑回归的一般形式:
在这里插入图片描述

逻辑回归,可以理解维为由线性回归通过Sigmoid函数转换,使其预测值在[0,1]之间,达到二分类的效果。

为什么叫逻辑回归?何来的逻辑?
y ( x ) y(x) y(x)是逻辑回归返回的标签值,且取值在[0,1]之间,所以 y ( x ) y(x) y(x) 1 − y ( x ) 1-y(x) 1y(x)的和必然是1,如
果我们令 y ( x ) y(x) y(x) 除以 1 − y ( x ) 1-y(x) 1y(x)可以得到形似几率(odds)的 y ( x ) 1 − y ( x ) \frac{y(x)}{1-y(x)} 1y(x)y(x) ,在此基础上取对数,可以很容易就得到:
在这里插入图片描述
y(x)的形似几率取对数的本质其实就是我们的线性回归z,我们实际上是在对线性回归模型的预测结果取
对数几率来让其的结果无限逼近0和1。因此,其对应的模型被称为”对数几率回归“(logistic Regression),音译过来就是逻辑回归,这个名为“回归”却是用来做分类工作的分类器。

定义损失函数

定义损失函数非常重要,它能帮我们找到一组最佳的参数θ和偏置b,使得我们的模型能够更加准确的进行预测,即是说,能够衡量参数的模型拟合训练集时产生的信息损失的大小,并以此衡量参数的优劣,我们在求解参数时,追求损失函数最小,让模型在训练数据上的拟合效果最优。

二元逻辑回归的标签服从伯努利分布(即0-1分布):
在这里插入图片描述
我们可以将一个特征向量为x,参数为θ的模型中的一个样本i的预测情况表现为如下形式:

  • 样本i在由特征向量x和参数θ组成的预测函数中,样本标签被预测为1的概率为:在这里插入图片描述
  • 样本i在由特征向量x和参数θ组成的预测函数中,样本标签被预测为0的概率为:在这里插入图片描述
    P 1 P_1 P1被的值为1的时候,代表样本i的标签被预测为1,当 P 0 P_0 P0的值为1的时候,代表样本i的标签被预测为0。

样本i的真实标签 y i y_i yi为1:

  • 如果 P 1 P_1 P1为1, P 0 P_0 P0为0,就代表样本i的标签被预测为1,与真实值一致。模型预测正确没有信息损失。
  • 如果 P 1 P_1 P1此时为0, P 0 P_0 P0为1,就代表样本i的标签被预测为0,与真实情况完全相反。预测错误有损失信息。
    同理真实值 y i y_i yi为0的情况,所以希望当 y i y_i yi为1的时候,我们希望 P 1 P_1 P1非常接近1,当 y i y_i yi为0的时候,我们希望 P 0 P_0 P0非常接近1,这样,模型的效果就很好,信息损失就很少。

将两种取值的概率整合,我们可以定义如下等式:
在这里插入图片描述
y i ^ 预测值 \hat{y_i}预测值 yi^预测值,当预测值与真实值一样时,上式是1的,表示预测真确,所以我们在追求 P ( y i ^ ∣ x i , θ ) P(\hat{y_i}|x_i,θ) P(yi^xi,θ)的最大值。这就将模型拟合中的“最小化损失”问题,转换成了对函数求解极值的问题。
P ( y i ^ ∣ x i , θ ) P(\hat{y_i}|x_i,θ) P(yi^xi,θ)是对单个样本i而言的函数,对一个训练集的m个样本来说,我们可以定义如下等式来表达所有样本在特征矩阵X和参数θ组成的预测函数中,预测出所有可能的 y ^ \hat{y} y^的概率P为:在这里插入图片描述
在这里插入图片描述这就是我们的交叉熵函数。为了数学上的便利以及更好地定义”损失”的含义,我们希望将极大值问题转换为极小值问题,因此我们对 log ⁡ P \log{P} logP取负,并且让参数θ作为函数的自变量,就得到了我们的损失函数:在这里插入图片描述这就是一个,基于逻辑回归的返回值 y θ ( x i ) y_θ(x_i) yθ(xi)的概率性质得出的损失函数。在这个函数上,我们只要追求最小值,就能让模型在训练数据上的拟合效果最好,损失最低。

正则化

正则化是用来防止模型过拟合的过程,常用的有L1正则化和L2正则化两种选项,分别通过在损失函数后加上参数向量 的L1范式和L2范式的倍数来实现。
这个增加的范式,被称为“正则项”,也被称为"惩罚项"。损失函数改变,基于损失函数的最优化来求解的参数取值必然改变,我们以此来调节模型拟合的程度。
在这里插入图片描述

L1范数:Loss function 加上 参数的绝对值之和,可以起到一个特征筛选的作用,使得某些参数直接为0。
L2范数:Loss function 加上 参数的绝对值平方之和,可以使Loss function更加平缓,防止出现过拟合,但只能使参数接近于0,不能为0,不能特征筛选。


sklearn里面的逻辑回归

  1. 类:linear_model.LogisticRegression
  2. 参数:
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  3. 属性

在这里插入图片描述

  1. 接口

在这里插入图片描述
参数很多,但只需要理解下面常用的即可:

  1. 正则化相关
参数说明
penalty可以输入"l1"或"l2"来指定使用哪一种正则化方式,不填写默认"l2"。
注意,若选择"l1"正则化,参数solver仅能够使用求解方式”liblinear"和"saga“,若使用“l2”正则化,参数solver中所有的求解方式都可以使用。
CC正则化强度的倒数,必须是一个大于0的浮点数,不填写默认1.0,即默认正则项与损失函数的比值是1:1。C越小,损失函数会越小,模型对损失函数的惩罚越重,正则化的效力越强,参数会逐渐被压缩得越来越小。

sklearn里面L1和L2的公式:
在这里插入图片描述
导入库:

from sklearn.linear_model import LogisticRegression as LR # 逻辑回归
from sklearn.datasets import load_breast_cancer # 乳腺癌数据集
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split # 划分测试集和训练集
from sklearn.metrics import accuracy_score  # 精确性,模型评估指标之一
data = load_breast_cancer() # 数据集
X = data.data # 特征
y = data.target # 标签lrl1 = LR(penalty="l1",solver="liblinear",C=0.5,max_iter=1000) # L1范数
lrl2 = LR(penalty="l2",solver="liblinear",C=0.5,max_iter=1000) # L2范数lrl1 = lrl1.fit(X,y) 
lrl2 = lrl2.fit(X,y)

通过coef_属性,查看每个特征所对应的参数:
在这里插入图片描述
在这里插入图片描述
L1和L2模型训练的效果比较:

l1 = []
l2 = []
l1test = []
l2test = []
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)
for i in np.linspace(0.05,1,19):lrl1 = LR(penalty="l1",solver="liblinear",C=i,max_iter=1000)lrl2 = LR(penalty="l2",solver="liblinear",C=i,max_iter=1000)lrl1 = lrl1.fit(Xtrain,Ytrain)l1.append(accuracy_score(lrl1.predict(Xtrain),Ytrain))l1test.append(accuracy_score(lrl1.predict(Xtest),Ytest))lrl2 = lrl2.fit(Xtrain,Ytrain)l2.append(accuracy_score(lrl2.predict(Xtrain),Ytrain))l2test.append(accuracy_score(lrl2.predict(Xtest),Ytest))
graph = [l1,l2,l1test,l2test]
color = ["green","black","lightgreen","gray"]
label = ["L1","L2","L1test","L2test"]
plt.figure(figsize=(6,6))
for i in range(len(graph)):plt.plot(np.linspace(0.05,1,19),graph[i],color[i],label=label[i])
plt.legend(loc=4) #图例的位置在哪里?4表示,右下角
plt.show()

在这里插入图片描述两种正则化的结果区别不大。但随着C的逐渐变大,正则化的强度越来越小,模型在训练集和测试集上的表现都呈上升趋势,直到C=0.8左右,训练集上的表现依然在走高,但模型在未知数据集上的表现开始下跌,这时候就是出现了过拟合。我们可以认为,C设定为0.8会比较好。在实际使用时,基本
就默认使用l2正则化,如果感觉到模型的效果不好,那就换L1试试看。

  1. 重要参数max_iter:最大的迭代次数【进行梯度下降找最小值的迭代次数】
    参数max_iter最大迭代次数来代替步长(lreaning rate),帮助我们控制模型的迭代速度并适时地让模型停下。max_iter越大,代表步长越小,模型迭代时间越长,反之,则代表步长设置很大,模型迭代时间很短。
    在这里插入图片描述

来看看乳腺癌数据集下,max_iter的学习曲线:

循环迭代次数

l2 = []
l2test = []
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)
for i in np.arange(1,201,10):lrl2 = LR(penalty="l2",solver="liblinear",C=0.9,max_iter=i)lrl2 = lrl2.fit(Xtrain,Ytrain)l2.append(accuracy_score(lrl2.predict(Xtrain),Ytrain))l2test.append(accuracy_score(lrl2.predict(Xtest),Ytest))

在这里插入图片描述

画出迭代次数与准确率的图

graph = [l2,l2test]
color = ["black","gray"]
label = ["L2","L2test"]plt.figure(figsize=(20,5))
for i in range(len(graph)):plt.plot(np.arange(1,201,10),graph[i],color[i],label=label[i])plt.legend(loc=4)
plt.xticks(np.arange(1,201,10))
plt.show()

在这里插入图片描述

#我们可以使用属性.n_iter_来调用本次求解中真正实现的迭代次数
lr = LR(penalty="l2",solver="liblinear",C=0.9,max_iter=300).fit(Xtrain,Ytrain)
lr.n_iter_

最大的迭代次数,并不是说就会迭代这么多次,如果梯度下降找到了局部最优点就会停止:
在这里插入图片描述

  1. 重要参数solver & multi_class :【二元回归与多元回归】

上面都是针对二分类的逻辑回归展开,其实sklearn提供了多种可以使用逻辑回归处理多分类问题的选项。比如说,我们可以把某种分类类型都看作1,其余的分类类型都为0值,和”数据预处理“中的二值化的思维类似,这种方法被称为"一对多"(One-vs-rest),简称OvR,在sklearn中表示为“ovr"。又或者,我们可以把好几个分类类型划为1,剩下的几个分类类型划为0值,这是一种”多对多“(Many-vs-Many)的方法,简称MvM,在sklearn中表示为"Multinominal"。每种方式都配合L1或L2正则项来使用。

在sklearn中,我们使用参数multi_class来告诉模型,我们的预测标签是什么样的类型。

  • auto”:表示会根据数据的分类情况和其他参数来确定模型要处理的分类问题的类型。比如说,如果数据是二分类,或者solver的取值为"liblinear",“auto"会默认选择"ovr”。反之,则会选择"nultinomial"。【默认】
  • ovr”:表示分类问题是二分类,或让模型使用"一对多"的形式来处理多分类问题。
  • multinomial’:表示处理多分类问题,这种输入在参数solver是’liblinear’时不可用

在这里插入图片描述
multinomialovr的区别:【鸢尾花数据集】

from sklearn.datasets import load_iris
iris = load_iris()
for multi_class in ('multinomial', 'ovr'):clf = LR(solver='sag', max_iter=200, random_state=42,multi_class=multi_class).fit(iris.data, iris.target)
#打印两种multi_class模式下的训练分数
#%的用法,用%来代替打印的字符串中,想由变量替换的部分。%.3f表示,保留三位小数的浮点数。%s表示,字符串。
#字符串后的%后使用元祖来容纳变量,字符串中有几个%,元祖中就需要有几个变量print("training score : %.3f (%s)" % (clf.score(iris.data, iris.target), multi_class))

在这里插入图片描述

多项式逻辑回归

上文逻辑回归是在平面上找一条直线,用这条直线来分割所有样本对应的分类。

在这里插入图片描述从图片中可以看得,一条直线不可能将红蓝点完全分隔开,可以采用多项式,不使用直线来分割,尽可能的提高分类的准确率。

多项式实现:

from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
#专门产生多项式的,并且多项式包含的是相互影响的特征集。
from sklearn.preprocessing import PolynomialFeatures
from sklearn.model_selection import train_test_split#增加多项式预处理
def polynomial_model(degree=1,**kwarg):polynomial_features = PolynomialFeatures(degree=degree,include_bias=False)logistic_regression = LogisticRegression(solver='liblinear',**kwarg)#solver的默认参数是'lbfgs',只支持L2,要改成'liblinear',L1,L2都能支持pipeline = Pipeline([("polynomial_features",polynomial_features),("logistic_regression",logistic_regression)])return pipelineX_train, X_test, y_train, y_test = train_test_split(data_X, data_y, random_state=666)
#增加二阶多项式特征,创建并训练模型
model=polynomial_model(degree=2,penalty='l1',max_iter=1000)#使用L1范式作为正则项,进行稀疏化
model.fit(X_train,y_train)#训练模型
# 结果可视化
plot_decision_boundary(model, axis=[0, 100, 0, 100])
plt.scatter(data_X[data_y == 0, 0], data_X[data_y == 0, 1], color='red')
plt.scatter(data_X[data_y == 1, 0], data_X[data_y == 1, 1], color='blue')
plt.xlabel('成绩1')
plt.ylabel('成绩2')
plt.title('两门课程成绩与是否录取的关系')
plt.show()

在这里插入图片描述从图片中可以看到采用多项式之后,基本能够完全分隔开红蓝两类,至少准确率要比之前的高。


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

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

相关文章

vuex报错[vuex] getters should be function but “getters.doublecount“ in

vuex.esm.js:135 uncaught error: [vuex] getters should be function but “getters.doublecount” in module “user” is 1. 出现这个报错是因为在使用vuex的moulds时 index.js中已经创建了一个vue实例new Vuex.Store,然后在模块文件中又创建了一个,就…

Can We Edit Multimodal Large Language Models?

本文是LLM系列文章,针对《Can We Edit Multimodal Large Language Models?》的翻译。 我们可以编辑多模态大型语言模型吗? 摘要1 引言2 相关工作3 编辑多模态LLM4 实验5 结论 摘要 本文主要研究多模态大语言模型(Multimodal Large Language Models, mllm)的编辑…

单片机TDL的功能、应用与技术特点 | 百能云芯

在现代电子领域中,单片机(Microcontroller)是一种至关重要的电子元件,广泛应用于各种应用中。TDL(Time Division Multiplexing,时分多路复用)是一种数据传输技术,结合单片机的应用&a…

【精华系列】跟着Token学习数据挖掘-1

Hello,大家好!这里是Token的博客,欢迎您的到来 今天整理的笔记时数据挖掘方向的基础入门,了解数据分析使用的一些基础的Python库,为后面的数据处理做好准备 01-数据分析工具介绍 准备:Python的安装、平台搭…

二叉树的创建和遍历

之前我们在学习二叉树的遍历的时候都是先手动创建出一个二叉树,然后再前中后序的遍历, 但实际中,是给你一个数组里面存的数,然后把他以(前中后)的遍历储存创建为一个二叉树 思路: 想要创建二叉树…

数据结构之顺序表的模拟实现

💕"世事犹如书籍,一页页被翻过去。人要向前看,少翻历史旧账。"💕 作者:Mylvzi 文章主要内容:数据结构之顺序表的模拟实现 /*** Created with IntelliJ IDEA.* Description:* User: 绿字* Date:…

Python —— 特殊场景处理(鼠标、键盘操作文件上传)

1、鼠标操作 1、概述 使用Selenium的ActionChains类来模拟鼠标操作,导入模块如下: # 导入模块 from selenium.webdriver.common.action_chains import ActionChains 通过ActionChains对象可以发起鼠标左键、右键、移动鼠标等操作,最后使用…

计算机视觉:池化层的作用是什么?

本文重点 在深度学习中,卷积神经网络(CNN)是一种非常强大的模型,广泛应用于图像识别、目标检测、自然语言处理等领域。而池化层作为CNN中的一个关键步骤,扮演着优化神经网络、提升深度学习性能的重要角色。本文将深入探讨池化层的作用及其重要性,帮助读者更好地理解和应…

linux进程间通讯--信号量

1.认识信号量 方便理解:信号量就是一个计数器。当它大于0能用,小于等于0,用不了,这个值自己给。 2.特点: 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。信号量基于操作系统的 PV 操作&am…

英特尔 SGX 技术概述

目录 介绍概述指示结构Memory安全区页面缓存Enclave Page Cache (EPC)安全区页面缓存映射Enclave Page Cache Map (EPCM) Memory ManagementStructures页面信息Page Information (PAGEINFO)安全信息Security Information (SECINFO)分页加密元数据Paging …

大型公共建筑能耗监测与信息管理系统研究及产品选型

摘要:文章通过阐述大型公共建筑能耗现状,突出大型公共建筑实施节能监管的必要性,并在系统总结运用技术手段实施建筑能耗监测的基础上,介绍了江苏省建筑能耗监测系统研究过程中的技术创新和应用情况。 关键词:公共建筑…

Python 环境构建最佳实践:联合使用 Mamba + Conda + PIP

此前,我们单独介绍过 PIP 和 Conda,在后续的实际应用中,还是遇到了不少 Python 环境构建的问题,特别是在 Windows 系统上,最突出的表现是:虽然PIP的包依赖解析和下载都很快,但在 Windows 上经常会因为缺失底层依赖的程序库(例如某些dll文件)而导致 Python 程序启动时报…

【数据挖掘】数据挖掘、关联分析、分类预测、决策树、聚类、类神经网络与罗吉斯回归

目录 一、简介二、关于数据挖掘的经典故事和案例2.1 正在影响中国管理的10大技术2.2 从数字中能够得到什么?2.3 一个网络流传的笑话(转述)2.4 啤酒与尿布2.5 网上书店关联销售的案例2.6 数据挖掘在企业中的应用2.7 交叉销售 三、数据挖掘入门3.1 什么激发了数据挖掘…

深度丨券商如何落地基于客户旅程编排的陪伴式服务?

金融行业的本质是服务行业。现阶段,传统券商为客户提供的通道服务高度依赖于证监会颁发的牌照,难以通过差异化的服务给客户提供价值。而伴随着引流开户成本高企,流量红利消失,金融行业步入存量竞争的时代,券商必须通过…

# 鸿蒙ArkTS Api9 AES ECB 加密

鸿蒙ArkTS Api9 AES ECB 加密 由于鸿蒙ArkTS是javascript编写的,因此总是感觉会被抓包破解了,不过这个问题通过提了个工单问了一下,目前鸿蒙编译完成之后的包是无法获取到其内部代码的。因此就能够放心的把加密的密钥给扔在里边了。 所以研究…

DAY 1 QT 创建QQ界面

#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//创建一个窗口,改变窗口标签名和窗口标签图标this -> resize(640,500);//设置窗口界面大小this -> setWindowTitle("QQ登录");//设置窗口标题this -> s…

文件传输软件的挑战与发展趋势

无论是在教育、医疗、金融、媒体、政府等行业,还是在个人生活和工作中,文件传输软件都有着广泛的应用价值和意义。然而,随着信息技术的发展和数据量的增长,文件传输软件也面临着一些挑战和问题,同时也有着一些发展趋势…

weapp-tailwindcss for uni-app 样式条件编译语法插件

weapp-tailwindcss for uni-app 样式条件编译语法插件 版本需求 2.10.0 weapp-tailwindcss for uni-app 样式条件编译语法插件 这是什么玩意?如何使用 tailwind.config.js 注册postcss 插件注册 uni-app vite vue3uni-app vue2 配置完成 配置项 这是什么玩意? 在 uni-app …

如何在小程序中设置页面显示的文字

不同商家,对于小程序有不同的要求。所以,小程序应该支持商家在后台灵活配置小程序各个页面的文字显示。下面具体介绍如何显示各个页面的文字。 朋友圈分享图文字:会显示在朋友圈海报顶部 升级会员提示:对于普通会员,在…

Ansible定义命令行、主机/主机组、playbook等变量,注册变量和vars_prompt的用法示例

目录 一.Ansible定义变量 1.用途 2.定义规则 3.变量优先级 二.命令行定义变量 三.定义主机和主机组变量 1.主机变量 (1)内置主机变量 (2)简单示例 2.主机组变量 四.定义playbook变量 1.通过vars表示定义变量&#xff…