【机器学习】(基础篇六) —— 数据集的划分和过拟合问题

数据集的划分

训练集和测试集

在机器学习中,数据集通常会被划分为训练集(Training Set)和测试集(Test Set),有时还会包括一个验证集(Validation Set)。这样的划分是为了能够更好地评估模型的性能,并防止过拟合。

训练集

  • 训练集用于构建模型。这是模型学习数据特征和模式的主要来源。模型通过最小化训练集上的损失函数来学习参数。

测试集

  • 测试集用于评估模型的泛化能力,即模型在未见过的新数据上的表现。这是非常重要的,因为我们的目标通常是使模型能够在未知数据上做出准确预测,而不仅仅是记忆训练数据。
  • 测试集应该独立于训练集,模型在训练过程中不应该接触到测试集的数据。

验证集(可选):

  • 验证集用于在训练过程中调整模型的超参数,比如学习率、正则化参数等。它帮助我们选择最佳模型版本,但不应用于最终评估模型性能,因为模型已经“看到”了这部分数据。

留出法

最常用的划分方法,将数据分成两部分:一个训练集,一个测试集,数据集的划分比例没有固定标准,常见的是70%训练集、15%验证集和15%测试集,或者是80%训练集和20%测试集,具体取决于数据量大小和项目需求。

我们之前的例子中都是使用这种方法划分训练集和测试集,在sklearn中,使用model_selection中的train_test_split就可以非常快速地实现数据集的划分,在使用这个方法时注意,传入的x和y都应该是ndarray(nump数组)类型,如果是使用pandas进行读取和处理数据,记得转换格式。

k折交叉验证

将数据集划分为k个等大小子集,并重复k次保持验证。每次使用其中一个k子集作为测试集,将其他k-1子集放在一起形成训练集。然后计算所有k次试验的平均误差。这种方法的优点是,如何划分数据无关紧要。每一个数据点在一个测试集中精确地出现一次,并且在一个训练集中有k-1次。结果估计的方差随着k的增加而减小。该方法的缺点是训练算法必须从头开始重新运行k次,这意味着需要k倍的计算量来进行评估。

同样在sklean中,已经为我们提供了k折交叉验证的实现函数,是model_selection 的KFold方法

【示例】使用sklearn实现对鸢尾花数据集逻辑回归模型的k折交叉验证

import numpy as np
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score# 加载数据集
data = load_iris()
X = data.data
y = data.target# 创建K折交叉验证对象
kf = KFold(n_splits=5)# 进行K折交叉验证
accuracies = []
for train_index, test_index in kf.split(X):X_train, X_test = X[train_index], X[test_index]y_train, y_test = y[train_index], y[test_index]model = LogisticRegression()model.fit(X_train, y_train)predictions = model.predict(X_test)accuracy = accuracy_score(y_test, predictions)accuracies.append(accuracy)# 输出平均准确性
mean_accuracy = np.mean(accuracies)
print(f"Mean accuracy: {mean_accuracy}")

输出结果:Mean accuracy: 0.9266666666666665

留一法交叉验证:k折交叉验证的特殊情况,其中k=n,

n为样本个数。使用一个样本作为验证集,其余样本作为训练集。重复此步骤,以便将样本中的每个观察结果作为验证数据使用一次。如果数据较多计算量会很大

数据集划分方法的选择:大数据集用留出法,小数据集用交叉验证

过拟合

  • 训练误差:指模型在其训练数据上的表现情况。具体来说,它是模型预测输出与训练数据的真实输出之间的差异度量。通常情况下,训练误差较低意味着模型能够很好地拟合训练数据中的模式。

  • 泛化误差:指模型在未见过的数据上的表现情况。这是模型实际应用时最重要的性能指标,因为它衡量了模型对新数据的预测能力。理想情况下,泛化误差应该尽可能低,这意味着模型不仅能够很好地拟合训练数据,而且还能很好地处理未知数据。

泛化是指一个模型能够很好地处理新的未知数据,而不仅仅是训练数据。如果模型训练得太好,它可以很好地拟合训练数据中的随机波动或噪声,但在新的数据上无法准确地预测。

在这里插入图片描述

机器学习中更经常遇到过拟合问题,让我们来详细看一下如何解决过拟合问题

  • 选择合适的模型复杂度:使用更复杂的模型可以减少训练误差,但同时也增加了过拟合的风险。使用较简单的模型可以降低过拟合的风险,但也可能导致欠拟合。因此,需要选择一个合适的模型复杂度。
  • 正则化技术:如L1、L2正则化可以帮助控制模型复杂度,防止过拟合。
  • 交叉验证:使用交叉验证等技术来评估模型的泛化能力,帮助调整模型的参数。
  • 数据增强:通过增加训练数据的多样性来提高模型的泛化能力。
  • 早停法(Early Stopping):在训练过程中,如果验证集上的性能不再改善,则停止训练,以避免过拟合。

在选择完合适的模型之后,我们最常用的方法就是利用正则化来消除过拟合。

偏差和方差

偏差和方差的概念和过拟合欠拟合息息相关。

偏差(Bias):用所有可能的训练集训练出所有的模型输出的平均值与真实模型输出值之间的差异

方差(Variance):不同的训练集训练出的模型输出值之间的差异

在这里插入图片描述

确定模型是否有偏差或方差:

如果你的模型在训练集上表现得很好,但在测试集上表现得差得多,那么它就面临高方差问题。

另一方面,如果你的模型在训练数据集和测试数据集上都表现不佳,那么它就存在高偏差。

一般而言,偏差和方差存在冲突:训练不足时,学习器拟合能力不强,偏差主导;随着训练程度加深,学习器拟合能力增强,方差主导;训练充足后,拟合能力强,方差主导

在这里插入图片描述

正则化

正则化是一种常用的防止过拟合的技术,它通过在损失函数中加入一个额外的项来限制模型参数的大小,从而避免模型变得过于复杂。在scikit-learn(简称sklearn)中,可以通过设置正则化参数来轻松地应用正则化。下面是如何使用正则化来解决过拟合问题的具体步骤:

主要有两种类型的正则化:

  • L1正则化(Lasso Regression):L1正则化倾向于产生稀疏解,使得一些特征的系数变为0,从而实现特征选择。L1是指所有参数的绝对值之和

    L o s s = Original Loss + λ ∑ i = 1 n ∣ w i ∣ \mathrm{Loss}=\text{Original Loss}+\lambda\sum_{i=1}^n|w_i| Loss=Original Loss+λi=1nwi

  • L2正则化(Ridge Regression):L2正则化使得所有特征都有非零系数,但这些系数的大小受到限制,从而防止过拟合。L2是指所有参数的平方和

    L o s s = Original Loss + λ ∑ i = 1 n w i 2 \mathrm{Loss}=\text{Original Loss}+\lambda\sum_{i=1}^nw_i^2 Loss=Original Loss+λi=1nwi2

正则化强度由一个超参数控制,通常标记为alpha(对于线性模型)或C(对于支持向量机等其他模型)。较大的alpha值意味着更强的正则化,较小的alpha值意味着较弱的正则化。

下面的两个模型套索回归和岭回归分别使用L1和L2正则化

套索回归

Lasso回归(Least Absolute Shrinkage and Selection Operator,最小绝对收缩和选择算子)是一种正则化

线性回归方法,由Robert Tibshirani于1996年提出,旨在解决多重共线性问题、变量选择以及防止过拟合

在Lasso回归中,目标函数在线性回归的基础上加上一个L1正则项(所有参数的绝对值之和),变为:

min ⁡ β 1 2 n ∑ i = 1 n ( y i − β 0 − ∑ j = 1 p β j x i j ) 2 + λ ∑ j = 1 p ∣ β j ∣ \begin{aligned}\min_\beta\frac{1}{2n}\sum_{i=1}^n(y_i-\beta_0-\sum_{j=1}^p\beta_jx_{ij})^2+\lambda\sum_{j=1}^p|\beta_j|\end{aligned} βmin2n1i=1n(yiβ0j=1pβjxij)2+λj=1pβj

Lasso回归的特点:

  • 特征选择:由于L1惩罚项的作用,Lasso回归会将一些不重要的特征的系数压缩至零,从而实现特征选择。
  • 稀疏解:Lasso回归产生的解是稀疏的,即大多数特征的权重会被设为零,这有助于解释和理解模型。
  • 正则化:通过调节 λ 参数,可以控制模型的复杂度。当 λ=0时,回归就退化为普通的线性回归。当 λ 很大时,所有参数都会被压缩至零。
  • 防止过拟合:由于包含了正则化项,Lasso回归在面对多重共线性或数据维度很高的情况下,比普通的线性回归更不容易过拟合。
  • 计算复杂性:虽然Lasso回归的优化问题是非光滑的(因为L1惩罚项是非光滑的),但可以通过坐标下降、最小角度回归(LARS)等算法高效地求解。

【代码示例】使用sklearn实现Lasso回归

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error# 设置随机数种子以便结果可复现
np.random.seed(0)# 使用make_regression生成数据集
X, y = make_regression(n_samples=100, n_features=1, noise=10)# 将数据分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)# 创建Lasso回归模型实例
lasso = Lasso(alpha=0.1)# 拟合模型
lasso.fit(X_train, y_train)# 预测测试集
y_pred = lasso.predict(X_test)# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")# 可视化
plt.scatter(X_test, y_test, color='blue', label='Actual data')
plt.plot(X_test, y_pred, color='red', linewidth=2, label='Lasso regression')
plt.legend()
plt.title('Lasso Regression')
plt.xlabel('Feature')
plt.ylabel('Target')
plt.show()

运行结果:

在这里插入图片描述

岭回归

岭回归(Ridge Regression)是一种用于解决多重共线性问题以及防止过拟合的线性模型技术。它通过对最小二乘估计加上一个正则化项来修正模型参数的估计,从而减小了某些极端情况下的系数估计值,提高了模型的稳定性和泛化能力。岭回归的求解步骤如下:

  1. 模型形式: 岭回归的目标函数是在最小二乘损失函数的基础上加入L2范数惩罚项(所有参数的平方和):

    L ( a ) = 1 2 N ∑ i = 1 N ( y i − ( a 0 + a 1 x i 1 + a 2 x i 2 + ⋯ + a p x i p ) ) 2 + λ ∑ j = 1 p a j 2 L(a)=\frac1{2N}\sum_{i=1}^N(y_i-(a_0+a_1x_{i1}+a_2x_{i2}+\cdots+a_px_{ip}))^2+\lambda\sum_{j=1}^pa_j^2 L(a)=2N1i=1N(yi(a0+a1xi1+a2xi2++apxip))2+λj=1paj2

    也可写为为 Minimize β ∣ ∣ y − X β ∣ ∣ 2 2 + λ ∣ ∣ β ∣ ∣ 2 2 \text{Minimize}_\beta||y-X\beta||_2^2+\lambda||\beta||_2^2 Minimizeβ∣∣y22+λ∣∣β22

    其中,y 是因变量向量,X 是包含所有特征(包括截距项)的设计矩阵,β 是回归系数向量,而 λ 是正则化强度参数,控制着模型对复杂度的惩罚程度。

  2. 选择正则化参数 λ

    • 交叉验证(多次实验):通过分割训练数据集为若干子集并计算不同 λ 下的交叉验证误差,选择使得验证误差最小的那个 λ。
    • 通过轮廓线(L-curve)、网格搜索或其他启发式方法寻找最优的 λ 值。

通过梯度下降法或其变种(如随机梯度下降、小批量梯度下降等)来计算参数。对于每个参数计算梯度,然后进行参数更新,达到满意的状态。

这里用的是批量梯度下降法,如果使用随机梯度下降或小批量梯度下降,只需将全体样本N替换为随机选取的一个或一小批样本即可。

岭回归主要适用于过拟合严重或各变量之间存在多重共线性的情况,它可以解决特征数量比样本量多的问题,另外,岭回归作为一种缩减算法可以判断哪些特征重要或者不重要,有点类似于降维,缩减算法可以看作是对一个模型增加偏差的同时减少方差。但是岭回归方程的R2会稍低于普通回归分析,但回归系数的显著性往往明显高于普通回归。

【代码示例】python实现岭回归

# 岭回归
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge# 数据
data=[
[0.07,3.12],[0.41,3.82],[0.99,4.55],[0.73,4.25],[0.98,4.56],
[0.55,3.92],[0.34,3.53],[0.03,3.15],[0.13,3.11],[0.13,3.15],
[0.31,3.47],[0.65,4.12],[0.73,4.28],[0.23,3.48],[0.96,4.65],
[0.62,3.95],[0.36,3.51],[0.15,3.12],[0.63,4.09],[0.23,3.46],
[0.08,3.22],[0.06,3.19],[0.92,4.63],[0.71,4.29],[0.01,3.08],
[0.34,3.45],[0.04,3.16],[0.21,3.36],[0.61,3.99],[0.54,3.89] ]
dataMat = np.array(data) # 将列表转换为二维矩阵
# 生成x和y
x = dataMat[:,0:1]
y = dataMat[:,1]
model = Ridge(alpha=0.5) # alpha为参数更新时的学习率
model.fit(x,y)
print("系数矩阵:",model.coef_)
print("线性回归模型:\n",model)
predicted = model.predict(x)
plt.scatter(x,y,marker='o')
plt.plot(x,predicted,color = 'r')
plt.xlabel('x')
plt.ylabel('y')
plt.show

运行结果:

系数矩阵: [1.40203058]
线性回归模型:Ridge(alpha=0.5)

在这里插入图片描述

【代码示例】使用交叉验证得到最佳的学习率alpha

# 岭回归交叉验证
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import RidgeCV# 数据
data=[
[0.07,3.12],[0.41,3.82],[0.99,4.55],[0.73,4.25],[0.98,4.56],
[0.55,3.92],[0.34,3.53],[0.03,3.15],[0.13,3.11],[0.13,3.15],
[0.31,3.47],[0.65,4.12],[0.73,4.28],[0.23,3.48],[0.96,4.65],
[0.62,3.95],[0.36,3.51],[0.15,3.12],[0.63,4.09],[0.23,3.46],
[0.08,3.22],[0.06,3.19],[0.92,4.63],[0.71,4.29],[0.01,3.08],
[0.34,3.45],[0.04,3.16],[0.21,3.36],[0.61,3.99],[0.54,3.89] ]
dataMat = np.array(data) # 将列表转换为二维矩阵
# 生成x和y
x = dataMat[:,0:1]
y = dataMat[:,1]
model = RidgeCV([0.1,0.5,1.0,10.0]) # 多个alpha交叉验证
model.fit(x,y)
print("效果最佳的alpha = ",model.alpha_)

运行结果:

效果最佳的alpha =  0.1

套索回归 vs 岭回归

岭回归无法剔除变量,而Lasso(Least Absolute Shrinkage and Selection Operator)回归模型,将惩罚项由L2范数变为L1范数,可以将一些不重要的回归系数缩减为0,达到剔除变量的目的。

在实践中,岭回归(Ridge)和lasso我们首选岭回归。不过如果特征数过多,但是其中只有几个特征是重要的,则选择lasso效果会更好。同时,lasso由于其模型更加便于理解(因为它只选择一部分输入特征),所以有时候用lasso回归效果也不理想。

当然,如果我们能够将两者进行优势互补,则会达到更佳的效果,在scikit-earn中提过了ElasticNet类,就是结合了这两种回归的惩罚项。在实践中效果会更好,不过需要同时调节L1和L2正则化参数。

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

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

相关文章

SQL 数据库设计、事务、视图 <13>

一、数据库设计 1.多表之间的关系 1) 一对一(了解) 如:人和身份证 分析:一个人只有一个身份证,一个身份证只能对应一个人 2)一对多(多对一) 如:部门和员…

Flink消费Kafka数据积压排查解决

0、背景 有个Flink任务每天不定时会出现数据积压,无论是白天还是数据量很少的夜里,且积压的数据量会越来越多,得不到缓解,只能每日在积压告警后重启,重启之后消费能力一点毛病没有,积压迅速缓解&#xff0…

立仪光谱共焦传感器行业应用|薄膜高度差扫描

01|检测需求:扫描薄膜圆圈的高度差 02|检测方式 客户要求扫描薄膜圆圈的高度差,根据观察样品我们选择立仪科技D40A30镜头搭配H系列控制器进行测量 03|光谱共焦测量结果 薄膜圆圈的高度差轮廓 04|光谱共焦…

在CodeBlocks搭建SDL2工程OLED液晶模拟器虚拟OLED单色液晶(128x64)

在CodeBlocks搭建SDL2工程OLED液晶模拟器虚拟OLED单色液晶 例程说明源码下载目录工程配置一、SDL2的初始化和退出二、OLED画点和读点三、更新OLDE的GRAM四、清屏和清某区域五、点阵字库六、显示字符串七、显示中文字符八、显示图片九、测试代码十、主函数十一、运行结果 例程说…

05 serv00安装typecho

下载 ‍ cd domain/xxx.serv00.net/# 下载typecho git clone https://github.com/typecho/typecho.git# 当前有两个目录 typecho/ 和 public_html/ ls# 替换html rm -rf public_html/ mv typecho public_html‍ 安装 浏览器访问你的网站 xxx.serv0.net,看见 type…

8月15日笔记

masscan安装使用 首先需要有c编译器环境。查看是否有c编译器环境: gcc -v如果系统中已经安装了 GCC,这个命令将输出 GCC 的版本信息。如果未安装,你会看到类似于 “command not found” 的错误消息。 如果没有下载,使用如下命令…

万维网与HTTP协议:基础知识简明指南

引言 在当今的数字时代,了解万维网(World Wide Web, WWW)和HTTP协议(Hyper Text Transfer Protocol)是至关重要的。本文将为基础小白们简明扼要地介绍万维网及其核心协议HTTP,并通过简单的例子和清晰的段落…

C语言内存操作函数

目录 一. C语言内存操作函数 1. memcpy的使用和模拟实现 2. memmove函数 3. memset函数 4. memcmp函数 一. C语言内存操作函数 随着知识的不断积累,我们所想要实现的目标程序就会更加复杂,今天我们来学习一个新的知识叫做C语言内存操作函数&#x…

基于Python的火车票售票系统/基于django的火车购票系统

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&…

面试经典算法150题系列-最长公共前缀

最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入:strs ["flower","flow","flight"] 输出:"fl"示例 2&…

HTML及CSS面试题4

1、BFC 1.1、介绍BFC及其应用 补充——触发BFC的方式,常见的有: 设置浮动overflow设置为:auto、scroll、hiddenpositon设置为:absolute、fixed 介绍: ○ 所谓BFC,指的是:一个独立的布局环境&am…

集合的知识点

一、集合的简介 1.1 什么是集合 集合(Collection),也是一个数据容器,类似于数组,但是和数组是不一样的。集合是一个可变的容器,可以随时向集合集合中添加元素,也可以随时从集合中删除元素。另外,集合还提…

鸿蒙(API 12 Beta3版)【录像流二次处理(C/C++)】媒体相机开发指导

通过ImageReceiver创建录像输出,获取录像流实时数据,以供后续进行图像二次处理,比如应用可以对其添加滤镜算法等。 开发步骤 导入NDK接口,接口中提供了相机相关的属性和方法,导入方法如下。 // 导入NDK接口头文件#in…

使用python实现3D聚类图

实验记录,在做XX得分预测的实验中,做了一个基于Python的3D聚类图,水平有限,仅供参考。 一、以实现三个类别聚类为例 代码: import pandas as pd import numpy as np from sklearn.decomposition import PCA from sk…

开源版最新LoveCardsV2表白墙源码下载

源码亮点 模板系统,给你无限可能 卡片不限字数,支持多图片上传 支持评论,点赞,让互动性拉满 管理后台可添加多个管理员 卡片一键分享至多平台 卡片浏览次数统计 发行版开箱即用 部署教程 1. 环境(参考开发环境&…

XSS- DOMclobbering与svg深度利用

目录 源码展示 解法一&#xff1a;绕过过滤-DOM clobbering 什么是DOM clobbering DOM clobbering原理 全局变量自动创建 属性名冲突 影响脚本执行 逐过程分析 源码展示 <script>const data decodeURIComponent(location.hash.substr(1));;const root documen…

图像处理之:Video Processing Subsystem(三)

免责声明&#xff1a; 本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下&#xff0c;作者不对因使用本文内容而导致的任何直接或间接损失承担责任&#xff0c;包括但不限于数据丢失、业务中断或其他经济…

【硬件模块】震动传感器模块

震动传感器模块实物图 DO&#xff1a;数字信号量输出&#xff0c;接单片机管脚&#xff1b; AO&#xff1a;模拟输出&#xff0c;无效&#xff0c;一般不接。 无震动&#xff0c;DO输出高电平&#xff0c;信号指示灯灭&#xff1b; 有震动&#xff0c;DO输出低电平&#xff0c;…

DHCP的原理与配置

目录 DHCP的原理 DHCP是什么 DHCP的好处 DHCP的分配方式 DHCP的工作原理 DHCP的配置 环境设置 DHCP配置 验证配置是否成功 DHCP的原理 DHCP是什么 DHCP:Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议。由Internet工作小组开发&#xff0c;专门用…

牛客网习题——通过C++实现

一、目标 实现下面4道练习题增强C代码能力。 1.求123...n_牛客题霸_牛客网 (nowcoder.com) 2.计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com) 3.日期差值_牛客题霸_牛客网 (nowcoder.com) 4.打印日期_牛客题霸_牛客网 (nowcoder.com) 二、对目标的实现 1.求123...n_…