Python-对时间序列数据进行最小二乘拟合?

时间:2016-03-14 15:56:29

标签: python scipy least-squares

我有一个时间序列数据集pr11(形状是(151,)),在绘制时看起来像下图。请注意非常小的数字。我想通过对直线进行最小二乘拟合来找到数据的平均斜率。

Time series of precipitation from model

我尝试了另一个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),我知道这是不对的,所以必须在这里放一些东西。 “拟合”数据最终看起来与我的原始数据完全相同。我也试过scipy.stats ......

slope, intercept, r_value, p_value, std_err = stats.linregress(len,pr11)

这次我的斜率是e-08的数字。问题在于,当我使用等式线斜率* x +截距时,该数字将我的时间序列数据乘以一个非常低的值(阶数e-15)。因此,当我绘制拟合线时,线条是水平的,根本不适合我的数据。

如何获得此数据的拟合线?

1 个答案:

答案 0 :(得分:2)

我喜欢用于拟合的包是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()

enter image description here