【问题标题】: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】:

问题陈述

目标

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

查找给定函数的常量c1 和c2:

例如它可以最大限度地减少平方误差 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

目标函数和数据集

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

首先我们定义订单n的Debye 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
    相关资源
    最近更新 更多