作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,我试图用以下类型的幂律拟合一组数据:
def f(x,N,a): # Power law fit
if a >0:
return N*x**(-a)
else:
return 10.**300
par,cov = scipy.optimize.curve_fit(f,data,time,array([10**(-7),1.2]))
最佳答案
更新
在原帖中,我展示了一个使用 lmfit
的解决方案。这允许为您的参数分配界限。从 0.17 版本开始,scipy 还允许直接为您的参数分配边界(请参阅 documentation )。请在以下 之后找到此解决方案编辑 希望可以作为如何使用 scipy 的最小示例 curve_fit
带参数边界。
原帖
正如@Warren Weckesser 所建议的,您可以使用 lmfit完成此任务,这允许您为参数分配界限并避免这个“丑陋”的 if 子句。
由于您没有提供任何数据,因此我创建了一些数据,如下所示:
他们守法f(x) = 10.5 * x ** (-0.08)
我适合它们 - 正如@roadrunner66 所建议的 - 通过将幂律转换为线性函数:
y = N * x ** a
ln(y) = ln(N * x ** a)
ln(y) = a * ln(x) + ln(N)
np.log
在原始数据上,然后进行拟合。当我现在使用 lmfit 时,我得到以下输出:
[[Variables]]
lN: 2.35450302 +/- 0.019531 (0.83%) (init= 1.704748)
a: -0.08035342 +/- 0.005158 (6.42%) (init=-0.5)
a
非常接近原始值和
np.exp(2.35450302)
给出 10.53 这也非常接近原始值。
import numpy as np
import matplotlib.pyplot as plt
from lmfit import minimize, Parameters, Parameter, report_fit
# generate some data with noise
xData = np.linspace(0.01, 100., 50.)
aOrg = 0.08
Norg = 10.5
yData = Norg * xData ** (-aOrg) + np.random.normal(0, 0.5, len(xData))
plt.plot(xData, yData, 'bo')
plt.show()
# transform data so that we can use a linear fit
lx = np.log(xData)
ly = np.log(yData)
plt.plot(lx, ly, 'bo')
plt.show()
def decay(params, x, data):
lN = params['lN'].value
a = params['a'].value
# our linear model
model = a * x + lN
return model - data # that's what you want to minimize
# create a set of Parameters
params = Parameters()
params.add('lN', value=np.log(5.5), min=0.01, max=100) # value is the initial value
params.add('a', value=-0.5, min=-1, max=-0.001) # min, max define parameter bounds
# do fit, here with leastsq model
result = minimize(decay, params, args=(lx, ly))
# write error report
report_fit(params)
# plot data
xnew = np.linspace(0., 100., 5000.)
# plot the data
plt.plot(xData, yData, 'bo')
plt.plot(xnew, np.exp(result.values['lN']) * xnew ** (result.values['a']), 'r')
plt.show()
curve_fit
执行以下操作.我将它用于您对幂律的原始定义(下图中的红线)以及对数数据(下图中的黑线)。数据的生成方式与上述相同。情节如下:
popt
和
popt_log
,您获得
array([ 10.47463426, 0.07914812])
和
array([ 2.35158653, -0.08045776])
, 分别(注意:对于字母,您必须取第一个参数的指数 -
np.exp(popt_log[0]) = 10.502
接近原始数据)。
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# generate some data with noise
xData = np.linspace(0.01, 100., 50)
aOrg = 0.08
Norg = 10.5
yData = Norg * xData ** (-aOrg) + np.random.normal(0, 0.5, len(xData))
# get logarithmic data
lx = np.log(xData)
ly = np.log(yData)
def f(x, N, a):
return N * x ** (-a)
def f_log(x, lN, a):
return a * x + lN
# optimize using the appropriate bounds
popt, pcov = curve_fit(f, xData, yData, bounds=(0, [30., 20.]))
popt_log, pcov_log = curve_fit(f_log, lx, ly, bounds=([0, -10], [30., 20.]))
xnew = np.linspace(0.01, 100., 5000)
# plot the data
plt.plot(xData, yData, 'bo')
plt.plot(xnew, f(xnew, *popt), 'r')
plt.plot(xnew, f(xnew, np.exp(popt_log[0]), -popt_log[1]), 'k')
plt.show()
关于python - SciPy 曲线拟合失败幂律,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35903506/
我有一个带有 id、x 和 y 坐标的顶点 vector ,我想为我的顶点生成一个幂律图。 Boost 库图提供幂律 plod_iterator() 但我如何用我的顶点生成它。任何人都可以帮忙吗? 最
我是一名优秀的程序员,十分优秀!