scipy 如何在Python中优化方程参数?

yhuiod9q  于 2023-06-29  发布在  Python
关注(0)|答案(2)|浏览(143)

我试图将一个自定义方程拟合到一个具有1个因变量(y1 - 1D numpy float数组,具有45个条目)和两个自变量(x1- 2D numpy float数组,具有45个条目)的数据集。我试图得到参数的优化值。下面的代码有什么问题?这是我使用的代码:

import numpy as np
from scipy.optimize import curve_fit

# Define your custom exponential equation
def custom_exponential_equation(X, param1, param2, param3):
    # X is a 2D array with shape (N, 2), where N is the number of data points
    # X[:, 0] corresponds to the first independent variable
    # X[:, 1] corresponds to the second independent variable
    y = param1 * np.exp(param2 * (X[:, 0]* (X[:, 1]**param3))
    return y
initial_params = [1.0, 1.0, 1.0]

# Perform the curve fitting
params, _ = curve_fit(custom_exponential_equation, x1, y1, p0=initial_params)

print(params)

错误消息为:

Result from function call is not a proper array of floats.
nvbavucw

nvbavucw1#

看来你在等式行中漏掉了一个右括号。

import numpy as np
from scipy.optimize import curve_fit

# Define your custom exponential equation
def custom_exponential_equation(X, param1, param2, param3):
    # X is a 2D array with shape (N, 2), where N is the number of data points
    # X[:, 0] corresponds to the first independent variable
    # X[:, 1] corresponds to the second independent variable
    y = param1 * np.exp(param2 * (X[:, 0]* (X[:, 1]**param3)))
    return y

# Example data
x1 = np.random.random((45, 2))
y1 = np.random.random(45)

initial_params = [1.0, 1.0, 1.0]

# Perform the curve fitting
params, _ = curve_fit(custom_exponential_equation, x1, y1, p0=initial_params)

print(params)

我还添加了x1和y1的示例数据,因为您没有提供它们。在运行代码之前,应该用实际的数据数组替换它们。

jjjwad0x

jjjwad0x2#

始终添加边界。因为你没有提供数据,所以不可能说我所证明的界限是否合适。
使用这种形式的函数,将二维数组解包为单独的变量,而不是索引。并选择更好的变量名。

import numpy as np
from numpy.random import default_rng
from scipy.optimize import curve_fit

def synthesize(a: float = 1.5, b: float = 1.9, c: float = 0.7, n: int = 45) -> tuple[np.ndarray, np.ndarray]:
    rand = default_rng(seed=0)
    xz = np.linspace(start=1.5, stop=2, num=n)[np.newaxis, :] + rand.uniform(low=-0.02, high=0.02, size=(2, n))
    x, z = xz
    y = (np.log(z/a) / b / x)**(1/c) * (1 + rand.uniform(low=-0.05, high=0.05, size=n))
    return np.vstack((x, y)), z

def exponential(xy: np.ndarray, a: float, b: float, c: float) -> np.ndarray:
    x, y = xy
    z = a * np.exp(b * x * y**c)
    return z

xy, z = synthesize()

params, _ = curve_fit(
    f=exponential,
    xdata=xy, ydata=z, p0=(1, 1, 1),
    bounds=(0.1, 10),
)
print(params)
assert np.allclose(params, (1.5, 1.9, 0.7), rtol=0, atol=0.1)

相关问题