Fitting Seasonal Harmonics with Nonlinear Least Squares
Summary
The document describes estimating coefficients for a deterministic seasonal function from observations using SciPy’s nonlinear least-squares optimizer. The model includes a constant, a linear time term, and sine and cosine components at two frequencies. The residual function must return the vector of observation-by-observation differences between measured values and the model predictions; converting those residuals to integers or wrapping the function with vectorization interferes with fitting.
The answer shows a revised call that passes the time and value columns as data, uses an initial coefficient vector, and applies bounds to the six parameters. The optimizer result’s parameter vector is accessed through its solution field. The example concerns hourly electricity observations, but it supplies no fitted coefficients, goodness-of-fit assessment, or out-of-sample evaluation. The chosen harmonic structure and time scale therefore need validation for a particular dataset, and bounded least squares does not by itself establish that the seasonal model is appropriate.
Key ideas
- Define the residual function to return a numeric vector of model errors across all observations.
- Use sine and cosine terms at chosen frequencies to represent recurring seasonal patterns.
- SciPy’s least-squares result contains the estimated parameters in its solution vector.
- Parameter bounds can constrain the search, but the seasonal model still requires validation.
Tags
Full text
# Least Squares fit function - Python
# Least Squares fit function - Python
I would like to find an approximation of deterministic function parameters with least_squares() python function but i get several issues - i am quite new in Python. Most of the issues were:
- https://www.stechies.com/typeerror-only-size1-arrays-converted-python-scalars/
- https://stackoverflow.com/questions/23353585/got-1-columns-instead-of-error-in-numpy
So I tried to take into account, but the function least_squares() doesn't return any parameter or something expected, I guess the least_squares() returns an array (https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html#:~:text=Solve%20a%20nonlinear%20least%2Dsquares%20problem%20with%20bounds%20on%20the%20variables.&text=The%20purpose%20of%20the%20loss,of%20outliers%20on%20the%20solution.)
```
from scipy.optimize import least_squares, curve_fit, minimize, leastsq, shgo, fmin_cg
import numpy as np
def seasonality(coeff,x,y):
a = coeff[0]
b = coeff[1]
c1 =coeff[2]
c2 =coeff[3]
d1 = coeff[4]
d2 = coeff[5]
result = y - a - (b*x) - c1*math.sin(2*math.pi*x) - c2*math.cos(2*math.pi*x) - d1*math.sin(4*math.pi*x) - d2*math.cos(4*math.pi*x)
return np.int(result)
result = np.arange(1, 15.1, 0.1)
x0 = np.array([0.0,0.0,0.0,0.0,0.0,0.0])
df_bis = np.genfromtxt("NordPool_2013-2019_2.csv", delimiter = ',', skip_header = 1, invalid_raise = False)
seasonality2 = np.vectorize(seasonality)
z = least_squares(seasonality2, x0, jac="2-point", method="dogbox", verbose=2, f_scale=0.01,args=(df_bis[:,0],df_bis[:,2]))
print(z["y"])
```
I would like to estimate all the parameters a, b, c1, c2, d1 and d2 and the data I have is a csv file with:
```
1st col: Observations (1,2,3....)
2nd col: Hours(01-02, 02-03,...23-00, 01 - 02...)
3st col: Values (34.45, 37.38,...)
```
Maybe it comes from the structure of the function i ve created
## Answer by Jul (score 2)
https://quant.stackexchange.com/a/57723
I found the answer - could be useful for someone else :)
```
from scipy.optimize import least_squares, curve_fit, minimize, leastsq, shgo, fmin_cg
def seasonality(coeff,t,y):
a = coeff[0]
b = coeff[1]
c1 =coeff[2]
c2 =coeff[3]
d1 = coeff[4]
d2 = coeff[5]
return y - a - (b*t) - c1*np.sin(2*math.pi*t) - c2*np.cos(2*math.pi*t) - d1*np.sin(4*math.pi*t) - d2*np.cos(4*math.pi*t)
#result = np.arange(1, 15.1, 0.1)
x0 = np.array([0.0,0.0,0.0,0.0,0.0,0.0])
#df_bis = np.genfromtxt("NordPool_2013-2019_3.csv", delimiter = ';', skip_header = 1, invalid_raise = False)
#seasonality2 = np.vectorize(seasonality)
z = least_squares(seasonality, x0, jac="2-point", method="dogbox", verbose=2, f_scale=0.01,
args=(df_bis[:,0],df_bis[:,1]),
bounds=([-100,-100,-100,-100,-100,-100],[1000,1000,1000,1000,1000,1000]))
print(z["x"])```
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.