【问题标题】:python fitting curve with integral funcpython拟合曲线与积分函数
【发布时间】:2022-01-13 15:18:09
【问题描述】:

PyQt5:程序在尝试调用函数时挂起。问题是什么?输入数据:temp、ylmbd

import numpy as np
from scipy import integrate
from numpy import exp
from scipy.optimize import curve_fit


def debay(temp, ylambd):
    def func(tem, const, theta):
        f = const * tem * (tem / theta) ** 3 * integrate.quad(lambda x: (x ** 3 / (exp(x) - 1)), 0.0, theta / tem)[0]
        return f

    constants = curve_fit(func, temp, ylambd)
    const_fit = constants[0][0]
    theta_fit = constants[0][1]

    fit_lambda = []
    for i in temp:
        fit_lambda.append(func(i, const_fit, theta_fit))
    return fit_lambda

【问题讨论】:

  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。
  • 您是否介意使用真实数据向您的函数添加实际调用。这足以调试它。

标签: python scipy curve-fitting integrate


【解决方案1】:

问题陈述

目标

您似乎想解决以下非线性最小二乘问题。

查找给定函数的常量c1c2

例如它可以最大限度地减少平方误差 w.r.t。实验数据集。

挑战

您已经在scipy 包中选择了正确的工具,您实现了解决问题的逻辑,并且您指的是在图形界面(Qt5)中运行您的程序时的一些阻塞过程。

但是我们错过了试验数据集和框架返回的错误。那肯定会有所帮助。

无论如何,在调查您的问题时,我发现至少有两个关键点需要解决:

  • 确保曲线拟合算法收敛;
  • 确保 ad hoc 方法签名。

观察

当使用一些潜在的数据集运行你的 sn-p 时,我得到:

OptimizeWarning: Covariance of the parameters could not be estimated

这表明问题可能是病态的,可能不会收敛到所需的解决方案。

当我尝试一次将它应用于多个点时,我得到:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

这表明函数调用中某处存在签名错误。

MCVE

目标函数和数据集

让我们定义目标函数和试验数据集来进行讨论。

首先我们定义订单nDebye function

import numpy as np
from scipy import integrate, optimize
import matplotlib.pyplot as plt

def Debye(n):
    
    def integrand(t):
        return t**n/(np.exp(t) - 1)
    
    @np.vectorize
    def function(x):
        return (n/x**n)*integrate.quad(integrand, 0, x)[0]
    
    return function

注意包装函数上的@np.vectorize 装饰器。它将阻止上面引用的ValueError

然后我们根据3阶德拜函数定义目标函数:

debye3 = Debye(3)
def objective(x, c, theta):
    return c*(x/theta)*debye3(x/theta)

最后,我们创建了一个实验设置,观察结果存在一些正常错误:

np.random.seed(123)
T = np.linspace(200, 400, 21)
c1 = 1e-1
c2 = 298.15
sigma = 5e-4
f = objective(T, c1, c2)
data = f + sigma*np.random.randn(f.size)

优化

然后我们可以执行优化程序:

parameters, covariance = optimize.curve_fit(objective, T, data, (0, 300))

对于试验数据集,它返回:

(array([1.02509632e-01, 3.10534004e+02]),
 array([[1.85637330e-06, 9.46948796e-03],
        [9.46948796e-03, 4.92873904e+01]]))

这似乎是一个相当可接受的调整。

现在您可以在拟合范围内插入任何点。从图形上看是这样的:

Tlin = np.linspace(200, 400, 201)
fhat = objective(Tlin, *parameters)

fig, axe = plt.subplots()
axe.plot(T, data, '.', label="Data")
axe.plot(Tlin, fhat, '-', label="Fit")
# ...

请注意,我们在 curve_fit 方法中添加了初始猜测,以使其收敛到正确的最优值。

这在您的 sn-p 中缺失,可能会阻止您的过程以可接受的迭代次数收敛或达到所需的最优值。

实时调频

阅读文档,方法cureve_fit可以提出:

  • ValueError:如果 ydata 或 xdata 包含 NaN,或者使用了不兼容的选项;
  • RuntimeError:如果最小二乘最小化失败;
  • OptimizeWarning: 如果无法估计参数的协方差。

结论

在为机器定义问题时,拟合曲线需要一些创造力和非常小心。

要解决您的问题,您当然需要注意:

  • 防止调用不匹配的方法签名和参数提要;
  • 确保稳定性和收敛性的优化方法(问题实现、集成方法、优化方法、初始猜测);
  • 解决流程引发的所有错误和警告(它会告诉您问题出在哪里,即使它们乍一看很神秘,也不要忽略它们);
  • 使用拟合元数据(例如:参数协方差、MSE)验证结果。

检查清单完成后,问题可能就解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 2018-10-09
    • 2021-09-01
    • 1970-01-01
    • 2013-11-08
    • 2015-07-01
    相关资源
    最近更新 更多