- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
几个小时以来,我一直在尝试将模型拟合到(生成的)数据集,以此作为我一直在努力解决的问题的原因。我为函数 f(x) = A*cos^n(x)+b 生成了数据点,并添加了一些噪声。当我尝试使用此函数和 curve_fit 拟合数据集时,出现错误
./tester.py:10: RuntimeWarning: invalid value encountered in power
return Amp*(np.cos(x))**n + b
/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py:690: OptimizeWarning: Covariance of the parameters could not be estimated category=OptimizeWarning)
我用来生成数据点和拟合模型的代码如下:
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
from scipy.optimize import curve_fit
from matplotlib.pyplot import figure, show, rc, plot
def f(x, Amp, n, b):
return np.real(Amp*(np.cos(x))**n + b)
x = np.arange(0, 6.28, 0.01)
randomPart = np.random.rand(len(x))-0.5
fig = figure()
sample = f(x, 5, 2, 5)+randomPart
frame = fig.add_subplot(1,1,1)
frame.plot(x, sample, label="Sample measurements")
popt, pcov = curve_fit(f, x, sample, p0=(1,1,1))
modeldata = f(x, popt[0], popt[1], popt[2])
print(modeldata)
frame.plot(x, modeldata, label="Best fit")
frame.legend()
frame.set_xlabel("x")
frame.set_ylabel("y")
show()
显示了噪声数据 - 请参见下图。
你们中有人知道发生了什么事吗?我怀疑它与进入复杂域的幂律有关,因为函数的实部是 nowhere divergent .我试过只返回函数的实部,在 curve_fit 中设置实际边界,并使用 numpy 数组而不是 p0 的 python 列表。我正在运行最新版本的 scipy,scipy 0.17.0-1。
最佳答案
问题如下:
>>> (-2)**1.1
(-2.0386342710747223-0.6623924280875919j)
>>> np.array(-2)**1.1
__main__:1: RuntimeWarning: invalid value encountered in power
nan
与原生 python float 不同,numpy double 通常拒绝参与导致复杂结果的操作:
>>> np.sqrt(-1)
__main__:1: RuntimeWarning: invalid value encountered in sqrt
nan
作为一种快速解决方法,我建议向您的函数添加一个 np.abs
调用,并使用适当的边界进行拟合以确保这不会产生虚假拟合。如果您的模型接近真实并且您的样本(我的意思是样本中的余弦)为正,那么在它周围添加一个绝对值应该是一个空操作(更新:我意识到情况从来不是这样,请参阅正确的方法下)。
def f(x, Amp, n, b):
return Amp*(np.abs(np.cos(x)))**n + b # only change here
通过这个小改动,我得到了这个:
作为引用,与 (5,2,5)
的生成相比,拟合的参数为 (4.96482314, 2.03690954, 5.03709923])
。
经过深思熟虑后,我意识到余弦值总是对于一半的域都是负的 (duh)。所以我建议的解决方法可能有点问题,或者至少它的正确性很重要。另一方面,考虑到您的原始公式包含 cos(x)^n
,cos(x)
的负值只有在 >n
是一个整数,否则你会得到一个复杂的结果。因为我们无法解决Diophantine装修问题,我们需要妥善处理。
最合适的方法(我指的是最不可能对数据产生偏差的方法)是这样的:首先使用将数据转换为复数的模型进行拟合,然后在输出中采用复数:
def f(x, Amp, n, b):
return Amp*np.abs(np.cos(x.astype(np.complex128))**n) + b
这显然比我的解决方法效率低得多,因为在每个拟合步骤中我们都会创建一个新网格,并以复杂的算术形式和额外的幅度计算形式做一些额外的工作。即使没有设置边界,这也给了我以下拟合:
参数是(5.02849409, 1.97655728, 4.96529108)
。这些也很接近。但是,如果我们将这些值放回到实际模型中(没有 np.abs
),我们会得到与 -0.37
一样大的虚部,这不是压倒性的但很重要。
所以第二步应该是用一个合适的模型重新拟合——一个有整数指数的模型。取你的拟合中明显的指数 2,并用这个模型做一个新的拟合。我不相信任何其他方法都能为您提供数学上合理的结果。你也可以从原来的popt
开始,希望它确实接近真相。当然,我们可以使用带有一些柯里化(Currying)的原始函数,但使用模型的专用双特定版本要快得多。
from __future__ import print_function
import numpy as np
from scipy.optimize import curve_fit
from matplotlib.pyplot import subplots, show
def f_aux(x, Amp, n, b):
return Amp*np.abs(np.cos(x.astype(np.complex128))**n) + b
def f_real(x, Amp, n, b):
return Amp*np.cos(x)**n + b
x = np.arange(0, 2*np.pi, 0.01) # pi
randomPart = np.random.rand(len(x)) - 0.5
sample = f(x, 5, 2, 5) + randomPart
fig,(frame_aux,frame) = subplots(ncols=2)
for fr in frame_aux,frame:
fr.plot(x, sample, label="Sample measurements")
fr.legend()
fr.set_xlabel("x")
fr.set_ylabel("y")
# auxiliary fit for n value
popt_aux, pcov_aux = curve_fit(f_aux, x, sample, p0=(1,1,1))
modeldata = f(x, *popt_aux)
#print(modeldata)
print('Auxiliary fit parameters: {}'.format(popt_aux))
frame_aux.plot(x, modeldata, label="Auxiliary fit")
# check visually, test if it's close to an integer, but otherwise
n = np.round(popt_aux[1])
# actual fit with integral exponent
popt, pcov = curve_fit(lambda x,Amp,b,n=n: f_real(x,Amp,n,b), x, sample, p0=(popt_aux[0],popt_aux[2]))
modeldata = f(x, popt[0], n, popt[1])
#print(modeldata)
print('Final fit parameters: {}'.format([popt[0],n,popt[1]]))
frame.plot(x, modeldata, label="Best fit")
frame_aux.legend()
frame.legend()
show()
请注意,我更改了您的代码中的一些内容,但这并不真正影响我的观点。上图,所以显示辅助配合和正确配合的那个:
输出:
Auxiliary fit parameters: [ 5.02628994 2.00886409 5.00652371]
Final fit parameters: [5.0288141074549699, 2.0, 5.0009730316739462]
重申一下:虽然辅助配合和正确配合之间可能没有视觉差异,但只有后者对您的问题给出了有意义的答案。
关于python - Scipy.optimize.curve_fit 不符合余弦幂律,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44222060/
我正在尝试将数据放入 this file 中使用 Python 中 scipy 的 curve_fit。该文件包含以摄氏度和毫秒为单位的温度与时间的数据点。我将它们转换为开尔文和秒: thefile
我正在尝试将数据集拟合到这个庞大的方程中。我知道以前有人问过这个问题,但我不认为最初的猜测是我的问题,我也不能在拟合方程中添加更多项。 我的拟合方程。请注意,积分中的“u”与上面定义的 u 不同。 顺
我有一个包含多列的 pandas.DataFrame ,我想应用 curve_fit对他们每个人都有作用。我希望输出是一个数据框,其中具有适合列中数据的最佳值(目前,我对它们的协方差不感兴趣)。 df
我在这里定义了一个函数来返回任意数量的高斯分布的总和: import numpy from numpy import * import matplotlib.pyplot as plt from sc
我正在尝试将高斯拟合到光谱中,y 值大约为 10^(-19)。在我将整个数据乘以 10^(-19) 之前和之后,Curve_fit 给我的拟合结果都很差。附件是我的代码,它是一组相当简单的数据,只是值
我需要适应scipy.optimize.curve_fit一些看起来像图中点的数据。我使用函数 y(x) (见下面的 def)它给出了一个常量 y(x)=c对于 x p[0] '''
我是 Scipy.optimize curve_fit() 工具的新手。我试图找到一个最能模拟图中曲线(时间序列信号的一部分)的函数,但同时我只是将正弦曲线拟合到它并得到一条平坦的线。有人能发现我做错
the link of data from dropbox badfitting我尝试使用 curve_fit 来将数据与我在 python 中的预定义函数进行拟合,但结果远非完美。代码很简单,如下所
抱歉,我是 python 和堆栈流方面的新手。所以我无法发布图像。 我想用Python中的curve_fit函数进行幂律回归。但结果对我来说很奇怪。我用excel进一步检查了一下。看起来这两者差别很大
我正在尝试为拟合函数传递两个数组,该函数接受两个值。 数据文件: 第一栏:时间第 2 栏:温度第 3 栏:交易量第 4 栏:压力 0.000,0.946,4.668,0.981 0.050,0.946
对于我的学士论文,我正在研究一个项目,我想在其中对某些数据进行拟合。问题有点复杂,但我尽量减少这里的问题: 我们有三个数据点(可用的理论数据很少),但这些点高度相关。 使用 curve_fit 来拟合
Python 的 curve_fit计算具有单个自变量的函数的最佳拟合参数,但是有没有办法使用 curve_fit 或其他方法来拟合具有多个自变量的函数?例如: def func(x, y, a, b
本文实例讲述了Python图像处理之直线和曲线的拟合与绘制。分享给大家供大家参考,具体如下: 在数据处理和绘图中,我们通常会遇到直线或曲线的拟合问题,python中scipy模块的子模块optim
我正在尝试使用 curve_fit 来拟合一个简单的正弦波(甚至没有任何噪声)作为测试,然后再继续解决更复杂的问题。不幸的是,它甚至没有给出正确的答案。这是我的语法: x = linspace(0,1
我正在使用Scipy将数据适合一个函数。该函数为我提供了2个参数的值,在这种情况下, a 和 b 。我想使用绑定(bind)的参数来限制这些参数可以采用的值,每个参数都有自己的可接受值范围。 可接受的
我试图找到一条拟合我的数据的曲线,该曲线在视觉上似乎具有幂律分布。 我希望利用 scipy.optimize.curve_fit,但无论我尝试什么函数或数据规范化,我都会得到 RuntimeError
我尝试使用curve_fit拟合对数曲线,假设它遵循Y=a*ln(X)+b,但拟合的数据看起来仍然不正确. 现在我正在使用以下代码: from scipy.optimize import curve_
我正在尝试使用 scipy 的 curve_fit 拟合分布。我尝试拟合一个单分量指数函数,结果几乎是一条直线(见图)。我还尝试了两分量指数拟合,似乎效果很好。两个分量仅意味着方程的一部分使用不同的输
为了拟合双曲函数,我尝试使用以下代码: import numpy as np from scipy.optimize import curve_fit def hyperbola(x, s_1, s_
看起来它只适合第一个参数。 当我尝试使用 curve_fit 示例生成曲线时,这一切都很好,但当我使用自己的数据时却不然。 这是我的原始数据:https://pastebin.com/0hs2JVXL
我是一名优秀的程序员,十分优秀!