【问题标题】:Forecasting / Extrapolating with Scipy Curve_Fit使用 Scipy Curve_Fit 进行预测/外推
【发布时间】:2020-01-21 20:14:28
【问题描述】:

我需要使用 Scipy 的curve_fit 操作预测/预测/推断过去2001-01-15 的值。我如何预测过去2001-01-15 并进入2001-01-20

import pandas as pd
import numpy as np
from datetime import timedelta
from scipy.optimize import curve_fit

def hyperbolic_equation(t, qi, b, di):
    return qi/((1.0+b*di*t)**(1.0/b))


df1 = pd.DataFrame({
        'date': ['2001-01-01','2001-01-02','2001-01-03', '2001-01-04', '2001-01-05',
                '2001-01-06','2001-01-07','2001-01-08', '2001-01-09', '2001-01-10',
                '2001-01-11','2001-01-12','2001-01-13', '2001-01-14', '2001-01-15'],
        'cumsum_days': [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
        'prod': [800, 900, 1200, 700, 600, 
                 550, 500, 650, 625, 600,
                550, 525, 500, 400, 350]})

df1['date'] = pd.to_datetime(df1['date'])

qi = max(df1['prod'])

#Hyperbolic curve fit the data to get best fit equation
popt_hyp, pcov_hyp = curve_fit(hyperbolic_equation, df1['cumsum_days'], df1['prod'],bounds=(0, [qi,1,20]))

#Adding in predicted values back into df1
df1.loc[:,'Hyperbolic_Predicted'] = hyperbolic_equation(df1['cumsum_days'], *popt_hyp)

在这里我创建一个未来的日期 df(测试集)

df1['future_date'] = df1['date']
ftr = (df1['future_date'] + pd.Timedelta(5, unit='days')).to_frame()

#Constructs empty columns for ftr dataframe
for col in df1.columns:
    if col not in ftr.columns:
        ftr[col] = None

#Subset future dataframe to predict on (test set)
ftr = ftr[(ftr['future_date'] > max(df1['date']))]
ftr['cumsum_days'] = [16,17,18,19,20]

这个sn-p会将未来的数据集与原始数据集连接起来(如果需要的话)

df1 = pd.concat([df1, ftr], ignore_index=True)
print(df1)

   Hyperbolic_Predicted  cumsum_days       date future_date  prod
0             931.054472            1 2001-01-01  2001-01-01   800
...
14            409.462743           15 2001-01-15  2001-01-15   350
15                   NaN           16        NaT  2001-01-16  None
16                   NaN           17        NaT  2001-01-17  None
17                   NaN           18        NaT  2001-01-18  None
18                   NaN           19        NaT  2001-01-19  None
19                   NaN           20        NaT  2001-01-20  None

一旦我重新运行curve_fit 操作,我就会收到错误消息。我如何预测过去2001-01-15 并进入2001-01-20

popt_hyp, pcov_hyp = curve_fit(hyperbolic_equation, df1['cumsum_days'], df1['prod'],bounds=(0, [qi,1,20]))

错误:

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

【问题讨论】:

    标签: python scipy curve-fitting


    【解决方案1】:

    Scipy Curve_Fit不提供predict新数据的函数,而是返回函数系数和系数的协方差

    你得到的系数在popt_hyp:[9.93612473e+02 2.28621390e-01 6.55150136e-02].

    而系数的协方差为:

    [[2.67920219e+04 2.62422207e+02 9.08459603e+00]
     [2.62422207e+02 4.31869797e+00 1.24995934e-01]
     [9.08459603e+00 1.24995934e-01 3.90417402e-03]]
    

    出于您的目的,您需要使用返回的popt_hyp 重新创建函数。您尝试估计系数的函数是:

    def hyperbolic_equation(t, qi, b, di):
        return qi/((1.0+b*di*t)**(1.0/b))
    

    这里t是通过值,所以从curve_fit估计的函数是:

    def fitted_hyperbolic_equation(t):
        return popt_hyp[0]/((1.0+popt_hyp[1]*popt_hyp[2]*t)**(1.0/popt_hyp[1]))
    
    

    然后使用这个函数来预测新数据。

    【讨论】:

    • 我记得,你应该也可以通过“predicted = hyperbolic_equation(t, *popt_hyp)”使用现有函数
    • 好点@JamesPhillips,我怎么能忘记使用*来解压?!
    猜你喜欢
    • 1970-01-01
    • 2019-02-26
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多