【问题标题】:Optimization: finding optimal inputs优化:寻找最优输入
【发布时间】:2023-03-24 12:49:02
【问题描述】:

之前发布了一个类似的问题,但太模糊了,希望这能解决我的问题:

我有一个函数IVcal(rho,alpha,K),我想找到rhoalpha 的最佳值,这样数据列表smiledata(变化K 的函数的输出)最适合数据列表calibrate

xaxis = np.linspace(0.006,0.036,20)
calibrate = [calfun(K) for K in xaxis]
smiledata = [IVcal(rho,alpha,K) for K in xaxis]

我的想法是,我希望图形 plt.plot(xaxis,smiledata, 'b--') 尽可能接近图形 plt.plot(xaxis,calibrate, 'r--'),只需改变 rhoalpha

我只是不确定如何进行优化以找到这些最佳值。我考虑过将smiledatacalibrate 之间的差异最小化,但我还是找不到这样做的好方法,特别是因为我需要输入的值而不是输出的值。对于之前含糊不清的任何建议和道歉,我将不胜感激。如果还有什么需要澄清的,请告诉我。

【问题讨论】:

  • IVcal(如果有的话还有calfun)的公式是什么?
  • Hill climbing 也许?
  • 它们都是相当长的公式,引用了几个先前定义的函数/表达式。我不认为它们会相关,但是如果您需要它们,我可以尝试浓缩它们吗?如果你不介意我问,你为什么要它们?理想情况下,我会采用一种更通用的方法,该方法适用于与微笑数据长度相同的任何数据列表(calfun 只是为了说明我正在尝试近似以找到另一个数据集的“最佳拟合”)
  • 你可以试试梯度下降

标签: python numpy optimization


【解决方案1】:

不受约束

你可以试试scipy.optimize.leastsq

这是一种优化方法,旨在减少当前值集与目标值集之间的差异。

import scipy.optimize as opt
import numpy as np


def calfun(k):
    """Example calibration function"""
    return k * 2 * 4

def IVcal(rho, alpha, k):
    """Example test function"""
    return rho * alpha * k

def error_function(x0, **args):
    """Calculates error between functions with current inputs"""
    xaxis = np.linspace(0.006, 0.036, 20)
    calibrate = np.array([calfun(K) for K in xaxis])
    smiledata = np.array([IVcal(x0[0], x0[1], K) for K in xaxis])

    # Get error between data
    error = smiledata - calibrate

    # Print square root of sum of errors
    print np.sqrt(np.sum(error**2.0))

    return error

# Initial guesses
rho = 1
alpha = 1
x0 = np.array([rho, alpha])

# Run optimisation
result = opt.leastsq(func=error_function, x0=x0)[0]
print 'opt rho: ', result[0]
print 'opt alpha: ', result[1]

一些注意事项:

  • 优化的质量很大程度上取决于您的起始条件!
  • calibratesmiledata 的输出从list 转换为np.array 允许您计算两个数组中每个值之间的误差,而无需遍历列表
  • 只有opt.leastsq 的输出中的第一个条目被采用,因为这是优化变量的数组
  • 打印误差和的平方根显示优化器的收敛

受限

看起来从 scipy 第 17 版开始,有一个称为 scipy.optimize.least_squares 的最小二乘法的约束版本

从上面的链接:

自变量的下限和上限。默认为无边界。每个数组必须与 x0 的大小匹配或者是一个标量,在后一种情况下,所有变量的界限都是相同的。使用带有适当符号的 np.inf 来禁用所有或部分变量的界限。

对于你的情况,我相信这是

 bounds = ([rho_lower, rho_higher],[-np.inf, np.inf])

【讨论】:

  • 谢谢!还忘了提到 rho 仅用于获取范围内的值 - 是否可以限制其中一个输入的域?
  • 在答案中添加了一些信息。不能说我已经尝试过了,但我使用了其他优化方法,并且边界看起来很相似
猜你喜欢
  • 2021-10-27
  • 2012-07-13
  • 2013-07-30
  • 2018-11-28
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 2023-03-25
  • 2011-02-08
相关资源
最近更新 更多