使用 Python 进行贝叶斯优化

 

一、介绍

        贝叶斯优化是一种先进的技术,用于优化评估成本高昂的函数。该策略为全局优化提供了原则性策略,强调探索(尝试新领域)和开发(尝试看起来有前途的领域)之间的平衡。

二、什么是贝叶斯优化?

贝叶斯优化的核心是一种基于概率模型的优化技术。它利用过去的评估结果形成概率模型,预测最佳解决方案可能位于何处。这里的关键是探索未知领域(我们尚未评估的功能领域)和开发已知区域(我们已经评估过并且看起来有前途的领域)之间的平衡。

简而言之,贝叶斯优化将我们过去的知识(评估)与不确定性(我们尚未评估的地方)结合起来,以对最佳解决方案可能位于何处做出有根据的猜测。

三、贝叶斯优化的组成部分

  1. 目标函数:这是我们要优化的函数。在许多现实问题中,评估目标函数可能需要大量计算、耗时或资源密集型。对于我们的示例,我们的目标函数是使用给定的超参数训练模型并返回其性能。
  2. 概率模型:贝叶斯优化使用概率模型来估计函数。通常使用高斯过程 (GP),因为它们不仅提供每个点的平均预测,而且还量化该预测的不确定性(方差)。
  3. 采集功能:该功能指导优化过程。它使用 GP 提供的均值和方差来建议目标函数中要评估的下一个点。常见的获取函数包括预期改进 (EI)、改进概率 (PI) 和置信上限 (UCB)。对于我们的示例,我们使用了预期改进函数。
  4. 贝叶斯优化循环:这是一个迭代过程,其中模型使用目标函数中的新数据点进行更新,并且采集函数建议下一个要评估的点。

四、Python 分步指南

        在本指南中,我们将使用 UCI 机器学习存储库中的葡萄酒质量数据集。

1. 下载数据集

  • 数据集:葡萄酒品质数据集
  • 直接下载链接:葡萄酒质量数据

下载数据集并将其保存到本地计算机。

2. 搭建环境

import numpy as np
import pandas as pd
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
from scipy.optimize import minimize
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

3. 加载数据集

data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv', sep=';')
X = data.drop('quality', axis=1)
y = data['quality']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

4. 贝叶斯优化

我们将尝试使用贝叶斯优化来优化简单回归器的超参数。

首先,我们将定义目标函数,它将使用给定的超参数训练模型并返回负均方误差(因为我们希望最大化质量预测精度)。

def objective_function(params):kernel = C(params[0], (1e-3, 1e3)) * RBF(params[1], (1e-2, 1e2))gp = GaussianProcessRegressor(kernel=kernel)gp.fit(X_train, y_train)predictions = gp.predict(X_test)return -mean_squared_error(y_test, predictions)

def objective_function(params):

        这定义了一个名为 的函数objective_function,它采用单个参数params,该参数应该是包含参数的列表或类似数组的对象。

  kernel = C(params[0], (1e-3, 1e3)) * RBF(params[1], (1e-2, 1e2))

        这里,正在构建高斯过程内核。该内核是两个组件的组合:

  1. 常数核 ( C):该核表示常数值,通常在高斯过程中用于定义常数缩放因子。它使用一个值进行初始化params[0],范围在 1×10−31×10−3 和 1×1031×103 之间。
  2. 径向基函数核 ( RBF):这是高斯过程中最常用的核之一。它决定了函数的形状或平滑度。它使用一个值进行初始化params[1],范围在 1×10−21×10−2 和 1×1021×102 之间。

        最终的内核是这两个内核的乘积,这是高斯过程中结合多个内核的效果的常见做法。

  gp = GaussianProcessRegressor(kernel=kernel)

        在这里,来自 scikit-learn 库的高斯过程回归器模型正在使用先前定义的内核进行初始化。

  gp.fit(X_train, y_train)

        高斯过程回归器模型正在训练数据X_train和上进行训练y_train

        predictions = gp.predict(X_test)

模型经过训练后,将用于对测试数据进行预测X_test。结果存储在变量中predictions

        return -mean_squared_error(y_test, predictions)

  y_test该函数最终返回真实测试值和预测值之间的负均方误差predictions。返回负值的原因是贝叶斯优化通常设置为最大化目标函数。通过返回负均方误差,优化过程将尝试找到给出最小误差(或最大负误差)的参数。

        本质上,这objective_function是为了评估具有给定内核配置的高斯过程回归器的性能(均方误差)。目标是找到最小化该误差的内核参数,并且该函数将用作贝叶斯优化过程的目标。

        现在,我们将定义获取函数:

def acquisition_function(x):# Expected Improvement acquisition functionmu, sigma = gp.predict(x, return_std=True)return -(mu + 1.96 * sigma)

def acquisition_function(x):

这定义了一个名为 的函数acquisition_function,它采用单个参数x,它代表我们要评估采集函数的数据点(或点集)。

mu, sigma = gp.predict(x, return_std=True)

此处,高斯过程模型gp用于预测给定数据点 的平均值 ( mu) 和标准差 ( ) 。该参数确保该方法返回预测的标准差,该标准差量化了模型对该预测的不确定性。sigmaxreturn_std=True

在贝叶斯优化的背景下:

  • mu表示模型对 点 处目标函数值的最佳猜测x
  • sigma代表模型对该猜测的不确定性。越大sigma表示不确定性越高。

return -(mu + 1.96 * sigma)

mu该行返回和 1.96×1.96× σ之和的负数。

术语 1.96×1.96× σ本质上捕获高斯分布 95% 置信区间的上限。值 1.96 是 z 分数,对应于标准正态分布的第 97.5 个百分位(假设它是对称的)。

在获取函数的上下文中,这行代码可以解释如下:

  1. 探索与利用:获取函数在探索(高不确定性区域)和利用(低预测目标函数值区域)之间取得平衡。通过考虑mu(预测值)和sigma(不确定性),获取函数旨在探索有希望(低mu)或不确定(高sigma)的领域。
  2. 最大化框架:负号确保我们为最大化问题做好准备。预测值较低(负mu)或不确定性较高(正 1.96×1.96× σ)的区域将具有较高(负值较小)的采集函数值,使它们在贝叶斯优化的下一次迭代中更有吸引力。
  3. 95% 置信区间:因子 1.96 表明该函数将目标函数的值考虑到其 95% 置信区间的上限。这意味着采集函数在其探索中考虑“最坏情况”场景,查看目标函数的真实值可能高达 的点mu + 1.96 * sigma

本质上,acquisition_function量化了在 点评估目标函数的潜在收益x。它在模型不确定的探索点和模型预测低目标函数值的利用点之间取得平衡(假设我们正在处理最小化问题,如负号所示)。

最后,运行贝叶斯优化循环:

best_params = [1, 1]  # initial guess
for iteration in range(10):  # 10 iterations for demonstration purposesres = minimize(fun=objective_function, x0=best_params, bounds=[(1e-3, 1e3), (1e-2, 1e2)])best_params = res.x

best_params = [1, 1] # initial guess

此行初始化一个以两个值命名的列表best_params,均设置为 1。此列表表示我们要优化的参数的初始猜测。在前面讨论的上下文中,这些参数可能与高斯过程的内核相关,但它们通常可以是我们想要优化的任何参数。

for iteration in range(10): # 10 iterations for demonstration purposes

该行启动一个将运行 10 次的 for 循环。该循环的每次迭代都代表着寻找更好的参数集的优化尝试。

res = minimize(fun=objective_function, x0=best_params, bounds=[(1e-3, 1e3), (1e-2, 1e2)])

在这里,minimize函数(通常来自像 之类的库scipy.optimize)用于尝试找到最小化给定 的参数objective_function

  • fun=objective_function:这表明我们试图最小化的函数是objective_function
  • x0=best_params:这将优化的起点设置为我们当前对参数的最佳猜测。在第一次迭代中,这将是 [1, 1],但在后续迭代中,它将是上一次迭代中找到的最佳参数。
  • bounds=[(1e-3, 1e3), (1e-2, 1e2)]:这对参数可以采用的值设置限制。第一个参数被限制在 1×10−31×10−3 和 1×1031×103 之间,第二个参数被限制在 1×10−21×10−2 和 1×1021×102 之间。
  • 在这些迭代结束时,best_params应该包含葡萄酒质量数据集上高斯过程模型的优化超参数。

五、使用优化参数

一旦我们通过贝叶斯优化找到了优化参数,我们现在就可以将它们用于未来的预测。以下是如何加载具有优化超参数的模型并进行预测:

# Load the model with optimized parameters
optimized_kernel = C(best_params[0], (1e-3, 1e3)) * RBF(best_params[1], (1e-2, 1e2))
optimized_gp = GaussianProcessRegressor(kernel=optimized_kernel)
optimized_gp.fit(X_train, y_train)# Making predictions
predictions = optimized_gp.predict(X_test)

结论

贝叶斯优化提供了一种结构化且有效的方法,通过从过去的评估中学习来找到问题的最佳解决方案。通过平衡探索和利用,它确保搜索既广泛(涵盖各种可能性)又深入(扩大到有希望的领域)。借助 Python 强大的库,该技术的实现变得简单直观。

参考

  • UCI 机器学习存储库:葡萄酒质量数据集
  • Scikit-learn 的高斯过程
  • 贝叶斯优化入门

六、附录

对于那些寻求更简化方法的人来说,该bayesian-optimization库提供了一种运行贝叶斯优化的简单方法,而无需涉及复杂的高斯过程或采集函数。

1. 安装

首先,使用 pip 安装库:

!pip install bayesian-optimization

2. 搭建环境

from bayes_opt import BayesianOptimization
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C

3. 加载数据集

data = pd.read_csv('winequality-red.csv', sep=';')
X = data.drop('quality', axis=1)
y = data['quality']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

4. 目标函数

该库需要参数的范围作为输入。它将在这些范围内自动探索和利用。

def objective_function(C, RBF_length_scale):kernel = C * RBF(RBF_length_scale)gp = GaussianProcessRegressor(kernel=kernel)gp.fit(X_train, y_train)predictions = gp.predict(X_test)return -mean_squared_error(y_test, predictions)

5. 运行贝叶斯优化

# Defining bounds for the hyperparameters
pbounds = {'C': (1e-3, 1e3),'RBF_length_scale': (1e-2, 1e2)
}optimizer = BayesianOptimization(f=objective_function,pbounds=pbounds,random_state=42
)optimizer.maximize(init_points=2,  # Random exploratory stepsn_iter=10       # Steps of Bayesian Optimization
)

.maximize函数将运行优化,完成后,可以使用以下方法检索最佳参数:

best_params = optimizer.max['params']

6. 使用优化参数

# Load the model with optimized parameters
optimized_kernel = C(best_params['C']) * RBF(best_params['RBF_length_scale'])
optimized_gp = GaussianProcessRegressor(kernel=optimized_kernel)
optimized_gp.fit(X_train, y_train)# Making predictions
predictions = optimized_gp.predict(X_test)

七、结论

        该bayesian-optimization库提供了一种快速有效的方法来执行贝叶斯优化,而无需深入研究其复杂的数学知识。通过抽象复杂性,它使优化过程更易于访问和用户友好。

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

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

相关文章

Mysql 分割字符串,一行变多行,@rownum,mysql.help_topic

1 前言 朋友最近遇到一个比较棘手的 sql 问题,让我帮忙看看: 他有两张表 testa 和 testb ,一个表存的日期,另一个表存字符串例如 2023-11-01,2023-11-02,如何将这两张表关联起来,只查 testa 表的数据&#…

streamlit 入门demo

一、介绍 Streamlit 是一个用于创建数据应用程序的 Python 库,它致力于简化从数据脚本到可部署应用程序的整个过程。通过 Streamlit,你可以使用熟悉的 Python 语言创建交互式的、美观的数据应用,而无需深入了解前端开发。 二、优势和特点 简…

分布式基础概念

分布式基础概念 1 微服务 微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署机制…

AUTOSAR从入门到精通-漫谈autosar软件架构(七)

目录 前言 原理 AUTOSAR软件开发现状 Autosar分层架构 基础软件层(BSW)

【Path的使用】Node.js中的使用Path模块操作文件路径

😁 作者简介:一名大四的学生,致力学习前端开发技术 ⭐️个人主页:夜宵饽饽的主页 ❔ 系列专栏:Node.js 👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇…

Jenkins集成部署java项目

文章目录 Jenkins简介安装 Jenkins简介 Jenkins能实时监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象的展示项目构建的趋势和稳定性。 官网 安装 在官网下载windows版本的Jenkins 但是我点击这里浏览器没有反应&#xff0…

Vue3-38-路由-路由的懒加载

什么是路由的懒加载 一句话概括 : 懒加载,就是在初次用到的时候才执行加载;而非一上来就全部加载完毕。优点 : 可以提高项目的访问效率。因为一上来不用加载所有的资源。建议 : 项目中的所有路由配置都配置为 懒加载…

使用 KubeSphere 与极狐GitLab 打造云原生持续交付系统

极狐GitLab 简介 极狐GitLab 是一个一体化的 DevOps 平台,可以简单理解为 GitLab 在国内的“发行版”。是由极狐(GitLab)公司推出的产品(极狐(GitLab)公司是以“中外合资3.0”模式成立的公司,在国内独立运营,为国内用户提供适合本…

test mutation-00-变异测试概览

拓展阅读 test 系统学习-04-test converate 测试覆盖率 jacoco 原理介绍 test 系统学习-05-test jacoco 测试覆盖率与 idea 插件 test 系统学习-06-test jacoco SonarQube Docker learn-29-docker 安装 sonarQube with mysql Ubuntu Sonar 突变测试是什么? …

2024你好!

在刚刚过去的一年里,科技行业犹如璀璨的星辰照亮了全球的进步之路。特别是在人工智能的疆域中,大模型技术犹如破晓的曙光,以其数十亿乃至千亿级别的参数力量,掀起了前所未有的变革浪潮。 2023年,大模型技术无疑成为了人…

谷歌浏览器启用实时字幕功能

在 Chrome 中使用“实时字幕”功能 - Google Chrome帮助 在 Chrome 中使用“实时字幕”功能 从计算机上的 Chrome 浏览器中,您可以使用“实时字幕”功能自动为视频、播客、游戏、直播、视频通话或其他音频媒体生成字幕。音频和字幕均在本地处理,并会保…

K8S学习指南(64)-K8S源代码走读之Kubelet

文章目录 前言Kubelet 的代码结构Kubelet 的核心逻辑1. Pod 生命周期管理1.1 Pod 启动逻辑1.2 Pod 状态管理1.3 Pod 事件处理 2. 容器启动和监控2.1 容器启动逻辑2.2 容器监控 3. 容器网络和存储3.1 容器网络3.2 容器存储 4. 资源管理4.1 资源分配 5. 启动和注册 Kubelet5.1 启…

【动态规划】【字符串】132.分割回文串 II

作者推荐 【动态规划】【字符串】扰乱字符串 本文涉及的基础知识点 动态规划 字符串 LeetCode132. 分割回文串 II 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 1: 输入&#x…

基于R语言(SEM)结构方程模型教程

详情点击链接:基于R语言(SEM)结构方程模型教程 01、R/Rstudio (2)R语言基本操作,包括向量、矩阵、数据框及数据列表等生成和数据提取等 (3)R语言数据文件读取、整理(清洗)、结果存储等(含tidve…

提升图像分割精度:学习UNet++算法

文章目录 一、UNet 算法简介1.1 什么是 UNet 算法1.2 UNet 的优缺点1.3 UNet 在图像分割领域的应用 二、准备工作2.1 Python 环境配置2.2 相关库的安装 三、数据处理3.1 数据的获取与预处理3.2 数据的可视化与分析 四、网络结构4.1 UNet 的网络结构4.2 UNet 各层的作用 五、训练…

Simply简洁博客主题源码 | EmlogPro主题模版

Simply是一款简约风格的Emlog博客模板,响应式布局、界面简单大方,实用性强! 支持夜间模式,采用localStorage存储配置。IOS系统下支持随系统自动切换浅/深色模式。 文章页支持显示文章字数及阅读时间。 支持http/https 响应式主…

基于PyTorch的Transformer组件实现

最近看了不少介绍LLM工作原理的文章,发现每一篇都会试图跟读者讲明白作为baseline的Transformer架构到底长啥样。但是好像比较少有代码实现的示例和具体的例子帮助理解。于是自己也想尝试着写一篇含有代码实现和具体例子解释的文章,希望能够给喜欢编程朋…

fmincon函数求解非线性超越方程的学习记录

最近的算法中用到了fmincon函数,寻找多变量非线性方程最小值的函数;因此学习一下; fmincon函数的基础语法如下所示: fmincon函数是为了求解下列方程的最小值; b 和 beq 是向量,A 和 Aeq 是矩阵&#xff0c…

2024年最新51单片机+Proteus嵌入式开发入门实战完整版教程

我们为什么要学嵌入式开发? 嵌入式系统是一种专为特定任务或特定应用设计的计算机系统。与通用计算机系统不同,嵌入式系统通常具有更小的体积、更低的功耗和更强的可靠性。由于这些特点,嵌入式系统广泛应用于工业控制、医疗设备、智能家居、…

【C++进阶04】STL中map、set、multimap、multiset的介绍及使用

一、关联式容器 vector/list/deque… 这些容器统称为序列式容器 因为其底层为线性序列的数据结构 里面存储的是元素本身 map/set… 这些容器统称为关联式容器 关联式容器也是用来存储数据的 与序列式容器不同的是 其里面存储的是<key, value>结构的键值对 在数据检索时…