Python- 对时间序列数据进行最小二乘拟合?
Python- doing least square fitting on time series data?
我有一个时间序列数据集 pr11(形状为 (151,)),绘制后如下图所示。注意非常小的数字。我想通过对直线进行最小二乘拟合来找到数据的平均斜率。
我已经从另一个 StackExchange 页面尝试了两种不同的方法来获得答案。我尝试使用 scipy.optimize.curve_fit 如下...
len = np.arange(pr11.shape[0])
def f(x, A, B):
return A*x + B
A,B = curve_fit(f,pr11,len)[0]
但是,这给了我 1.0 的斜率 (A),我知道这是不对的,所以这里一定有问题。 "fitted" 数据最终看起来与我的原始数据完全一样。我也试过 scipy.stats...
slope, intercept, r_value, p_value, std_err = stats.linregress(len,pr11)
我这次的坡度是e-08量级的数字。问题在于,当我使用方程式来表示斜率*x + 截距时,该数字会将我的时间序列数据乘以一个非常低的值(阶数 e-15)。因此,当我绘制拟合线时,这条线是水平的,根本不适合我的数据。
如何获得此数据的拟合线?
我最喜欢用来试衣的一个套餐是lmfit
。安装后,您可以执行以下操作:
from lmfit import minimize, Parameters, Parameter, report_fit
import numpy as np
# create data to be fitted
x = np.arange(150)/100.
data = 2e-6*x-5e-7 + np.random.normal(size=len(x), scale=5e-7)
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
""" model decaying sine wave, subtract data"""
slope = params['slope'].value
offset = params['offset'].value
model = slope * x + offset
return model - data
# create a set of Parameters
params = Parameters()
params.add('slope', value= 1., min=0)
params.add('offset', value= 0.)
# do fit, here with leastsq model
result = minimize(fcn2min, params, args=(x, data))
# calculate final result
final = data + result.residual
# write error report
report_fit(result.params)
# [[Variables]]
# slope: 2.1354e-06 +/- 9.33e-08 (4.37%) (init= 1)
# offset: -6.0680e-07 +/- 8.02e-08 (13.22%) (init= 0)
# [[Correlations]] (unreported correlations are < 0.100)
# C(slope, offset) = -0.865
# plot results
import matplotlib.pyplot as plt
plt.plot(x, data, 'k+')
plt.plot(x, final, 'r')
plt.show()
我有一个时间序列数据集 pr11(形状为 (151,)),绘制后如下图所示。注意非常小的数字。我想通过对直线进行最小二乘拟合来找到数据的平均斜率。
我已经从另一个 StackExchange 页面尝试了两种不同的方法来获得答案。我尝试使用 scipy.optimize.curve_fit 如下...
len = np.arange(pr11.shape[0])
def f(x, A, B):
return A*x + B
A,B = curve_fit(f,pr11,len)[0]
但是,这给了我 1.0 的斜率 (A),我知道这是不对的,所以这里一定有问题。 "fitted" 数据最终看起来与我的原始数据完全一样。我也试过 scipy.stats...
slope, intercept, r_value, p_value, std_err = stats.linregress(len,pr11)
我这次的坡度是e-08量级的数字。问题在于,当我使用方程式来表示斜率*x + 截距时,该数字会将我的时间序列数据乘以一个非常低的值(阶数 e-15)。因此,当我绘制拟合线时,这条线是水平的,根本不适合我的数据。
如何获得此数据的拟合线?
我最喜欢用来试衣的一个套餐是lmfit
。安装后,您可以执行以下操作:
from lmfit import minimize, Parameters, Parameter, report_fit
import numpy as np
# create data to be fitted
x = np.arange(150)/100.
data = 2e-6*x-5e-7 + np.random.normal(size=len(x), scale=5e-7)
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
""" model decaying sine wave, subtract data"""
slope = params['slope'].value
offset = params['offset'].value
model = slope * x + offset
return model - data
# create a set of Parameters
params = Parameters()
params.add('slope', value= 1., min=0)
params.add('offset', value= 0.)
# do fit, here with leastsq model
result = minimize(fcn2min, params, args=(x, data))
# calculate final result
final = data + result.residual
# write error report
report_fit(result.params)
# [[Variables]]
# slope: 2.1354e-06 +/- 9.33e-08 (4.37%) (init= 1)
# offset: -6.0680e-07 +/- 8.02e-08 (13.22%) (init= 0)
# [[Correlations]] (unreported correlations are < 0.100)
# C(slope, offset) = -0.865
# plot results
import matplotlib.pyplot as plt
plt.plot(x, data, 'k+')
plt.plot(x, final, 'r')
plt.show()