21
21
from scipy .stats import boxcox
22
22
23
23
from statsmodels .base .model import Results
24
- from statsmodels .base .wrapper import populate_wrapper , union_dicts , ResultsWrapper
25
- from statsmodels .tools .validation import array_like
24
+ from statsmodels .base .wrapper import (populate_wrapper , union_dicts ,
25
+ ResultsWrapper )
26
+ from statsmodels .tools .validation import (array_like , bool_like , float_like ,
27
+ string_like , int_like )
26
28
from statsmodels .tsa .base .tsa_model import TimeSeriesModel
27
29
from statsmodels .tsa .tsatools import freq_to_period
28
30
import statsmodels .tsa ._exponential_smoothers as smoothers
@@ -488,10 +490,14 @@ def __init__(self, endog, trend=None, damped=False, seasonal=None,
488
490
self .endog = self .endog
489
491
self ._y = self ._data = array_like (endog , 'endog' , contiguous = True ,
490
492
order = 'C' )
493
+ options = ("add" , "mul" , "additive" , "multiplicative" )
494
+ trend = string_like (trend , 'trend' , options = options , optional = True )
491
495
if trend in ['additive' , 'multiplicative' ]:
492
496
trend = {'additive' : 'add' , 'multiplicative' : 'mul' }[trend ]
493
497
self .trend = trend
494
- self .damped = damped
498
+ self .damped = bool_like (damped , 'damped' )
499
+ seasonal = string_like (seasonal , 'seasonal' , options = options ,
500
+ optional = True )
495
501
if seasonal in ['additive' , 'multiplicative' ]:
496
502
seasonal = {'additive' : 'add' , 'multiplicative' : 'mul' }[seasonal ]
497
503
self .seasonal = seasonal
@@ -504,7 +510,8 @@ def __init__(self, endog, trend=None, damped=False, seasonal=None,
504
510
if self .damped and not self .trending :
505
511
raise ValueError ('Can only dampen the trend component' )
506
512
if self .seasoning :
507
- self .seasonal_periods = seasonal_periods
513
+ self .seasonal_periods = int_like (seasonal_periods ,
514
+ 'seasonal_periods' , optional = True )
508
515
if seasonal_periods is None :
509
516
self .seasonal_periods = freq_to_period (self ._index_freq )
510
517
if self .seasonal_periods <= 1 :
@@ -608,13 +615,15 @@ def fit(self, smoothing_level=None, smoothing_slope=None, smoothing_seasonal=Non
608
615
"""
609
616
# Variable renames to alpha,beta, etc as this helps with following the
610
617
# mathematical notation in general
611
- alpha = smoothing_level
612
- beta = smoothing_slope
613
- gamma = smoothing_seasonal
614
- phi = damping_slope
615
- l0 = self ._l0 = initial_level
616
- b0 = self ._b0 = initial_slope
617
-
618
+ alpha = float_like (smoothing_level , 'smoothing_level' , True )
619
+ beta = float_like (smoothing_slope , 'smoothing_slope' , True )
620
+ gamma = float_like (smoothing_seasonal , 'smoothing_seasonal' , True )
621
+ phi = float_like (damping_slope , 'damping_slope' , True )
622
+ l0 = self ._l0 = float_like (initial_level , 'initial_level' , True )
623
+ b0 = self ._b0 = float_like (initial_slope , 'initial_slope' , True )
624
+ if start_params is not None :
625
+ start_params = array_like (start_params , 'start_params' ,
626
+ contiguous = True )
618
627
data = self ._data
619
628
damped = self .damped
620
629
seasoning = self .seasoning
@@ -675,18 +684,22 @@ def fit(self, smoothing_level=None, smoothing_slope=None, smoothing_seasonal=Non
675
684
txi = txi .astype (np .bool )
676
685
bounds = np .array ([(0.0 , 1.0 ), (0.0 , 1.0 ), (0.0 , 1.0 ),
677
686
(0.0 , None ), (0.0 , None ), (0.0 , 1.0 )] + [(None , None ), ] * m )
678
- args = (txi .astype (np .uint8 ), p , y , lvls , b , s , m , self .nobs , max_seen )
687
+ args = (txi .astype (np .uint8 ), p , y , lvls , b , s , m , self .nobs ,
688
+ max_seen )
679
689
if start_params is None and np .any (txi ) and use_brute :
680
- res = brute (func , bounds [txi ], args , Ns = 20 , full_output = True , finish = None )
690
+ res = brute (func , bounds [txi ], args , Ns = 20 ,
691
+ full_output = True , finish = None )
681
692
p [txi ], max_seen , _ , _ = res
682
693
else :
683
694
if start_params is not None :
684
- start_params = np .atleast_1d (np .squeeze (start_params ))
685
695
if len (start_params ) != xi .sum ():
686
- raise ValueError ('start_params must have {0} values but '
687
- 'has {1} instead' .format (len (xi ), len (start_params )))
696
+ msg = 'start_params must have {0} values but ' \
697
+ 'has {1} instead'
698
+ nxi , nsp = len (xi ), len (start_params )
699
+ raise ValueError (msg .format (nxi , nsp ))
688
700
p [xi ] = start_params
689
- args = (xi .astype (np .uint8 ), p , y , lvls , b , s , m , self .nobs , max_seen )
701
+ args = (xi .astype (np .uint8 ), p , y , lvls , b , s , m ,
702
+ self .nobs , max_seen )
690
703
max_seen = func (np .ascontiguousarray (p [xi ]), * args )
691
704
# alpha, beta, gamma, l0, b0, phi = p[:6]
692
705
# s0 = p[6:]
0 commit comments