Python 幂律数据拟合不正确

Python 幂律数据拟合不正确,python,matplotlib,curve-fitting,power-law,Python,Matplotlib,Curve Fitting,Power Law,当我试图用对数y轴拟合以下数据时,我做错了什么。下面是代码和生成的图表 所有的代码实际上都在工作。如下图所示,我运行了您的代码,但在打印之前没有在y轴上进行缩放。你可以看到,这条线实际上是拟合的,除了第一点,它是一个非常离群的点。解决此问题的方法是,在拟合函数之前,首先缩放y值。试试看,如果你需要更多的帮助,请告诉我们 如果不进行初步猜测,就很难拟合您的数据。因此,在调用curve_fit作为p0时提供猜测(如文档中所述): 输出: 注意:这有助于解决问题。您仍然必须实现对数轴。为日志。我建

当我试图用对数y轴拟合以下数据时,我做错了什么。下面是代码和生成的图表


所有的代码实际上都在工作。如下图所示,我运行了您的代码,但在打印之前没有在y轴上进行缩放。你可以看到,这条线实际上是拟合的,除了第一点,它是一个非常离群的点。解决此问题的方法是,在拟合函数之前,首先缩放y值。试试看,如果你需要更多的帮助,请告诉我们


如果不进行初步猜测,就很难拟合您的数据。因此,在调用
curve_fit
作为
p0
时提供猜测(如文档中所述):

输出:

注意:这有助于解决问题。您仍然必须实现对数轴。为日志。我建议删减数据,比如

y_pruned = np.where(y<1, 1, y)
popt, pcov = curve_fit(func, x, np.log(y_pruned), p0=p0)
ax.plot(x, func(x, *popt), 'g--', label = 'fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
ax.plot(x,  np.log(y_pruned), 'ro', label='data')

y_pruned=np。其中(y我能对您的数据做的最好的处理就是将两组数据值按对数进行缩放,然后尝试用函数拟合它们。我包括了下面的代码和图表


您使用什么函数进行曲线拟合?它是来自软件包还是您自己编写的?抱歉,它来自scipy.optimize import curve\u fit所以我猜问题在于执行拟合后的
popt
值。您能打印它们吗?这很有帮助,因为
curve\u fit
喜欢在标准化范围。但是我删除了我的注释,因为现在我看到你的数据在对数图中看起来像一个负参数的指数!!!如果你尝试一个不同的函数,你会有更好的运气。例如,从
ln(y)=a exp(-b x))+c
我们有(也就是说,Emacs的
calc
has)
y=exp(c+a exp(((bx)))
,你可以尝试拟合这个双指数,不是吗?是的,第一个点肯定是一个异常值,但为了使y轴可读,我需要一个对数刻度it@JamesPhillips你误解了我想说的话,我只是展示了问题中的代码产生了一个“体面”的匹配,这使得它看起来更糟糕,因为se y轴是按对数缩放的。我没有提出新的解决方案,所以我知道它显然不适合数据。另外,请看作者如何同意第一个点是异常值。当然,它确实适合对数缩放后创建的曲线,但显然在这张图中,一个点与其他点不同,请参见异常值的定义(远离主体或系统的人或物)。如果您愿意,请删除它。我认为这确实回答了这个问题。问题是“我做错了什么?”指的是标题“幂律数据拟合不正确”。我的回答假定幂律数据拟合是正确的,我指出作者可能做错的是应用了使幂律缩放的缩放看起来不正确。因此,我回答了这个问题。我的意思是作者从其他人那里得到了答案,所以请务必删除此项。很好,我已经尝试过,输出结果是所需的。谢谢!@AlexandraBradan,但请注意,原始数据可能是双指数的。初始衰减相当快(你可以通过查看图中的1/e快速检查,看看x和y是否匹配).@JamesPhillips
a
c
可以通过目视检查从y值中提取。
b
我通过查看图表第一点和第二点之间的陡峭衰减来猜测。@JamesPhillips谢谢,顺便说一句,我查看了您出色的在线曲线拟合工具,继续努力!@AlexandraBradan Do o如果数据来自一个没有两个不同衰减率的过程,那么就选择单指数。谢谢你的解决方案!
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def func(x, a, b, c):
    return a * np.exp(-b * x) + c

x = np.array([88.08064516, 264.24193548, 440.40322581, 616.56451613, 792.72580645, 968.88709677, 1145.0483871, 1321.20967742, 1497.37096774, 1673.53225806, 1849.69354839, 2025.85483871, 2202.01612903, 2378.17741935, 2554.33870968, 2730.5, 2906.66129032,3082.82258065, 3258.98387097, 3435.14516129, 3611.30645161, 3787.46774194, 3963.62903226, 4139.79032258, 4315.9516129, 4492.11290323, 4668.27419355, 4844.43548387, 5020.59677419, 5196.75806452, 5372.91935484, 5549.08064516])
y = np.array([210737, 2175, 514, 158, 90, 46, 27, 22, 10, 11, 3, 7, 3, 2, 0, 1, 1, 1, 0, 0, 1, 0, 0,0, 0, 0, 1, 0, 0, 0, 0,1])

p0 = [20000,0.003,1]
popt, pcov = curve_fit(func, x, y, p0=p0)

fig, ax = plt.subplots()
ax.plot(x, func(x, *popt), 'g--', label = 'fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
ax.plot(x,  y, 'ro', label='data')
y_pruned = np.where(y<1, 1, y)
popt, pcov = curve_fit(func, x, np.log(y_pruned), p0=p0)
ax.plot(x, func(x, *popt), 'g--', label = 'fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
ax.plot(x,  np.log(y_pruned), 'ro', label='data')
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c):
    return a * np.exp(-b * x) + c

fig, ax = plt.subplots()
x = np.array([88.08064516, 264.24193548, 440.40322581, 616.56451613, 792.72580645, 968.88709677, 1145.0483871, 1321.20967742, 1497.37096774, 1673.53225806, 1849.69354839, 2025.85483871, 2202.01612903, 2378.17741935, 2554.33870968, 2730.5, 2906.66129032, 3082.82258065, 3258.98387097, 3435.14516129, 3611.30645161, 3787.46774194, 3963.62903226, 4139.79032258, 4315.9516129, 4492.11290323, 4668.27419355, 4844.43548387, 5020.59677419, 5196.75806452, 5372.91935484, 5549.08064516])
y = np.array([210737, 2175, 514, 158, 90, 46, 27, 22, 10, 11, 3, 7, 3, 2, 0, 1, 1, 1, 0, 0, 1, 0, 0,0, 0, 0, 1, 0, 0, 0, 0,1])

x = np.log(x)
y = np.log(y + 1) # Need to add something to make log work

popt, pcov = curve_fit(func, x, y)
ax.plot(x, func(x, *popt), 'g--')
ax.plot(x,  y, 'ro', label='data')

plt.show()