
    ]hv_                     .   S SK JrJrJr  S SKrS SKJr  S SKJr  S SK	r
S SKrS SKr\R                  " S5      rS rSS jrS rSS	 jr\" 5       rS
 rSS jrS rS r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r \S 5       r!g)    )absolute_importdivisionprint_functionN)tqdm)deepcopyprophetc                    U S   R                  5       U-
  nX@S   R                  5       :  a  [        S5      eU/nUS   [        U S   5      U-   :  a  XC-  nU S   U:  U S   XA-   :*  -  R                  5       (       d5  X@S   R                  5       :  a  X S   U:*     R                  5       S   nXa-
  nUR	                  U5        US   [        U S   5      U-   :  a  M  USS n[        U5      S:X  a  [        S5      e[        R                  SR                  [        U5      US   US   5      5        [        [        U5      5      $ )a#  Generate cutoff dates

Parameters
----------
df: pd.DataFrame with historical data.
horizon: pd.Timedelta forecast horizon.
initial: pd.Timedelta window of the initial forecast period.
period: pd.Timedelta simulated forecasts are done with this period.

Returns
-------
list of pd.Timestamp
dszLess data than horizon.Nr   zMLess data than horizon after initial window. Make horizon or initial shorter.z2Making {} forecasts with cutoffs between {} and {})maxmin
ValueErroranyappendlenloggerinfoformatlistreversed)dfhorizoninitialperiodcutoffresultclosest_dates          fC:\Users\julio\OneDrive\Documentos\Trabajo\Ideas Frescas\venv\Lib\site-packages\prophet/diagnostics.pygenerate_cutoffsr      sO    X\\^g%F4233XF
*BtH/
/T(V#4F4D(DEJJLL4&!T(f"4599;DA%/f *BtH/
/ CR[F
6{a/
 	
 KKDKKFVBZ   !!    c           
      `  ^ ^^^ T R                   c  [        S5      eT R                   R                  5       R                  SS9m[        R
                  " T5      mSS/mT R                  (       a  TR                  SS/5        UbA  [        U[        5      (       a  U/nTR                  U Vs/ s H  oT;  d  M
  UPM     sn5        S	n	T R                  R                  5        H  n
[        XS
   5      n	M     [        R
                  " [        U	5      S-   5      nUcT  Uc  ST-  O[        R
                  " U5      nUc  [        ST-  U5      O[        R
                  " U5      n[        TTX25      nOt[        U5      TS   R                  5       ::  a  [        S5      eTS   R                  5       T-
  n[        U5      U:  a  [        S5      eUS   TS   R                  5       -
  nX;:  a0  SR!                  U	5      nUS-  nUS-  n["        R%                  U5        U(       Ga  1 SknUS:X  a  [&        R(                  R+                  5       nOUS:X  a  [&        R(                  R-                  5       nOjUS:X  a%   SSKJn  U" 5       nUR5                  TT /5      u  mm O?[7        US5      (       a  UnO+SR!                  SR9                  U5      5      n[        U5      eUUU U4S jU 5       n[;        U6 n["        R=                  SU5        UR>                  " [@        /UQ76 nUS:X  a  URC                  U5      nO1U(       d  [E        U5      OU Vs/ s H  n[A        TT UTT5      PM     nn[        RF                  " USS9R                  SS9$ s  snf ! [2         a  n[3        S5      UeSnAff = fs  snf ) a	  Cross-Validation for time series.

Computes forecasts from historical cutoff points, which user can input.
If not provided, begins from (end - horizon) and works backwards, making
cutoffs with a spacing of period until initial is reached.

When period is equal to the time interval of the data, this is the
technique described in https://robjhyndman.com/hyndsight/tscv/ .

Parameters
----------
model: Prophet class object. Fitted Prophet model.
horizon: string with pd.Timedelta compatible style, e.g., '5 days',
    '3 hours', '10 seconds'.
period: string with pd.Timedelta compatible style. Simulated forecast will
    be done at every this period. If not provided, 0.5 * horizon is used.
initial: string with pd.Timedelta compatible style. The first training
    period will include at least this much data. If not provided,
    3 * horizon is used.
cutoffs: list of pd.Timestamp specifying cutoffs to be used during
    cross validation. If not provided, they are generated as described
    above.
parallel: {None, 'processes', 'threads', 'dask', object}
    How to parallelize the forecast computation. By default no parallelism
    is used.

    * None: No parallelism.
    * 'processes': Parallelize with concurrent.futures.ProcessPoolExecutor.
    * 'threads': Parallelize with concurrent.futures.ThreadPoolExecutor.
        Note that some operations currently hold Python's Global Interpreter
        Lock, so parallelizing with threads may be slower than training
        sequentially.
    * 'dask': Parallelize with Dask.
       This requires that a dask.distributed Client be created.
    * object: Any instance with a `.map` method. This method will
      be called with :func:`single_cutoff_forecast` and a sequence of
      iterables where each element is the tuple of arguments to pass to
      :func:`single_cutoff_forecast`

      .. code-block::

         class MyBackend:
             def map(self, func, *iterables):
                 results = [
                    func(*args)
                    for args in zip(*iterables)
                 ]
                 return results
                 
disable_tqdm: if True it disables the progress bar that would otherwise show up when parallel=None
extra_output_columns: A String or List of Strings e.g. 'trend' or ['trend'].
     Additional columns to 'yhat' and 'ds' to be returned in output.

Returns
-------
A pd.DataFrame with the forecast, actual value and cutoff.
Nz^Model has not been fit. Fitting the model provides contextual parameters for cross validation.Tdropr
   yhat
yhat_lower
yhat_upperg        r   z daysg      ?   zEMinimum cutoff value is not strictly greater than min date in historyzdMaximum cutoff value is greater than end date minus horizon, no value for cross-validation remainingr   z"Seasonality has period of {} days z%which is larger than initial window. zConsider increasing initial.>   daskthreads	processesr)   r*   r(   )
get_clientz6parallel='dask' requires the optional dependency dask.mapzB'parallel' should be one of {} for an instance with a 'map' methodz, c              3   2   >#    U  H  nTTUTT4v   M     g 7fN ).0r   r   r   modelpredict_columnss     r   	<genexpr>#cross_validation.<locals>.<genexpr>   s#      ,#* %/B#*s   zApplying in parallel with %saxis)$history	Exceptioncopyreset_indexpd	Timedeltauncertainty_samplesextend
isinstancestrseasonalitiesvaluesr   r   r   r   r   r   warning
concurrentfuturesThreadPoolExecutorProcessPoolExecutordask.distributedr+   ImportErrorscatterhasattrjoinzipr   r,   single_cutoff_forecastgatherr   concat)r1   r   r   r   parallelcutoffsdisable_tqdmextra_output_columnsc
period_maxsseasonality_dtend_date_minus_horizonmsgvalidpoolr+   e	iterablespredictsr   r   r2   s   ``                   @@r   cross_validationr`   =   s}   v }}xyy					)	)t	)	4Bll7#GVnO  l;<'*C00$8#9 +?\+?aOC[+?\] J  '')x[1
 *\\#j/G";<N"(.wbll66J 18CG^,g& 	 #2w@ w<2d8<<>)dee!#D'!9w<00  D  E  E!*r$x||~-
 6==jIC::C11CNN30y %%88:D$%%99;D=7 <Db%[1IBXu%%D""(&5)9": S/!,#*,	O	2D9882?Y?v{{8,H
 1=4='I
I #2ufgOI 	 
 99XA&222==_  ]b  =! #5 6;<==0
s*   ,	N9N6N N+
N(N##N(c                 :   [        X5      nX S   U:*     nUR                  S   S:  a  [        S5      eUR                  " U40 UR                  D6  U S   U:  U S   X#-   :*  -  nS/nUR
                  S:X  a3  UR                  S5        UR                  (       a  UR                  S5        UR                  UR                  R                  5       5        UR                  UR                  R                  5        V	s/ s H  n	U	S   c  M  U	S   PM     sn	5        UR                  X   U   5      n
UR                  R                  5         [         R"                  " X   X   S	/   R%                  S
S9[         R&                  " SU/[)        U
5      -  05      /SS9$ s  sn	f )aO  Forecast for single cutoff. Used in cross validation function
when evaluating for multiple cutoffs either sequentially or in parallel.

Parameters
----------
df: pd.DataFrame.
    DataFrame with history to be used for single
    cutoff forecast.
model: Prophet model object.
cutoff: pd.Timestamp cutoff date.
    Simulated Forecast will start from this date.
horizon: pd.Timedelta forecast horizon.
predict_columns: List of strings e.g. ['ds', 'yhat'].
    Columns with date and forecast to be returned in output.

Returns
-------
A pd.DataFrame with the forecast, actual value and cutoff.

r
   r      z@Less than two datapoints before cutoff. Increase initial window.logisticcapfloorcondition_nameyTr"   r      r5   )prophet_copyshaper8   fit
fit_kwargsgrowthr   logistic_floorr>   extra_regressorskeysrA   rB   predictstan_backendcleanupr;   rP   r:   	DataFramer   )r   r1   r   r   r2   m	history_cindex_predictedcolumnspropsr$   s              r   rN   rN      s   . 	U#Ad8v%&IqA'
 	
 EE)(u''($x&(RX9I-IJOfGxx:uNN7#NN1%%**,-NN__++-0-E!" 	 -0 1 99R(12D NN99
SE"..D.9
h3t9 456 	 0s   :
F	Fc                    U R                   c  [        S5      eU R                  (       aB  U R                  nUb2  [	        U R                   S   U R                   S   U:*     5      nX"U:     nOSnU R                  U R                  U R                  U R                  USSSU R                  U R                  U R                  U R                  U R                  U R                  U R                  U R                   U R"                  U R$                  b  U R$                  R'                  5       OSS9n[)        U R*                  5      Ul        [)        U R,                  5      Ul        [)        U R.                  5      Ul        U$ )a1  Copy Prophet object

Parameters
----------
m: Prophet model.
cutoff: pd.Timestamp or None, default None.
    cutoff Timestamp for changepoints member variable.
    changepoints are only retained if 'changepoints <= cutoff'

Returns
-------
Prophet class object with the same parameter with model variable
Nz,This is for copying a fitted Prophet object.r
   F)rm   n_changepointschangepoint_rangechangepointsyearly_seasonalityweekly_seasonalitydaily_seasonalityholidaysholidays_modeseasonality_modeseasonality_prior_scalechangepoint_prior_scaleholidays_prior_scalemcmc_samplesinterval_widthr=   rr   )r7   r8   specified_changepointsr}   r   	__class__rm   r{   r|   r   r   r   r   r   r   r   r   r=   rr   get_typer   ro   rA   country_holidays)ru   r   r}   last_history_datem2s        r   ri   ri     sJ    	yyFGG~~ #AIIdOAIIdOv4M$N O'7H(HIL 
xx''--!  oo++ ! 9 9 ! 9 933^^''11)*)CANN##%' 
 
B, #1#5#56B0B"1#5#56BIr    c                 ,    U [         U R                  '   U $ )zRegister custom performance metric

Parameters that your metric should contain
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Registered metric should return following 
-------
Dataframe with columns horizon and metric.
)PERFORMANCE_METRICS__name__)funcs    r   register_performance_metricr   I  s     *.&Kr    c                    / SQnUc  UnSU ;  d  SU ;  a  SU;   a  UR                  S5        [        [        U5      5      [        U5      :w  a  [        S5      e[        U5      R	                  [        [
        5      5      (       d  [        SR                  U5      5      eU R                  5       nU(       ag  US   R                  R                  S	5      R                  [        5      US
   R                  R                  S	5      R                  [        5      -
  US'   OUS   US
   -
  US'   UR                  SSS9  SU;   aK  US   R                  5       R                  5       S:  a&  [        R!                  S5        UR                  S5        [        U5      S:X  a  g[        X%R"                  S   -  5      nUS:  a$  [%        US5      n[        XeR"                  S   5      n0 nU H  n[
        U   " XV5      Xx'   M     XqS      n	['        S[        U5      5       HN  n
XqU
      n[(        R*                  " U	S   R,                  US   R,                  5      (       d   eXU
      XU
   '   MP     U	$ )a  Compute performance metrics from cross-validation results.

Computes a suite of performance metrics on the output of cross-validation.
By default, the following metrics are included:
'mse': mean squared error
'rmse': root mean squared error
'mae': mean absolute error
'mape': mean absolute percent error
'mdape': median absolute percent error
'smape': symmetric mean absolute percentage error
'coverage': coverage of the upper and lower intervals

A subset of these can be specified by passing a list of names as the
`metrics` argument.

Metrics are calculated over a rolling window of cross validation
predictions, after sorting by horizon. Averaging is first done within each
value of horizon, and then across horizons as needed to reach the window
size. The size of that window (number of simulated forecast points) is
determined by the rolling_window argument, which specifies a proportion of
simulated forecast points to include in each window. rolling_window=0 will
compute it separately for each horizon. The default of rolling_window=0.1
will use 10% of the rows in df in each window. rolling_window=1 will
compute the metric across all simulated forecast points. The results are
set to the right edge of the window.

If rolling_window < 0, then metrics are computed at each datapoint with no
averaging (i.e., 'mse' will actually be squared error with no mean).

The output is a dataframe containing column 'horizon' along with columns
for each of the metrics computed.

Parameters
----------
df: The dataframe returned by cross_validation.
metrics: A list of performance metrics to compute. If not provided, will
    use ['mse', 'rmse', 'mae', 'mape', 'mdape', 'smape', 'coverage'].
rolling_window: Proportion of data to use in each rolling window for
    computing the metrics. Should be in [0, 1] to average.
monthly: monthly=True will compute horizons as numbers of calendar months 
    from the cutoff date, starting from 0 for the cutoff month.

Returns
-------
Dataframe with a column for each metric, and column 'horizon'
)msermsemaemapemdapesmapecoverageNr%   r&   r   z-Input metrics must be a list of unique valuesz Valid values for metrics are: {}r
   Mr   r   T)inplacer   rg   g:0yE>z"Skipping MAPE because y close to 0r   rh   )remover   setr   issubsetr   r   r9   dt	to_periodastypeintsort_valuesabsr   r   r   rj   r   rangenparray_equalrB   )r   metricsrolling_windowmonthlyvalid_metricsdf_mwdfsmetricresires_ms               r   performance_metricsr   Y  s(   ^ QMB,b"8zW?Tz"
3w<CL(HIIw<  %8!9::.55mD
 	
 779Dt*--11#6==cBT(^EVEVE`E`adEeElElmpEqqYt*tH~5YY-T#Y]]_002T989v
7|qNZZ]*+AAv1I::a=!
C)&1$: 
aj/C1c'l#AJ~~c)n33U95E5L5LMMMM
+AJ $ Jr    c                    [         R                  " XS.5      nUR                  S5      R                  SS/5      R	                  5       R                  S5      nUS   S   R                  nUS   S   R                  nUR                  R                  n[        U5      S-
  n	Sn
Sn[        R                  " [        U5      5      n[        [        U5      S-
  SS5       HK  nXU   -  n
XU   -  nX:  d  M  X-
  nXU   -  X}   -  nX-
  U-  X'   XU	   -  n
XU	   -  nU	S-  n	X:  a  M3  MM     XS-   S	 nXS-   S	 n[         R                  " S
UX<05      $ )a  Compute a rolling mean of x, after first aggregating by h.

Right-aligned. Computes a single mean for each unique value of h. Each
mean is over at least w samples.

Parameters
----------
x: Array.
h: Array of horizon for each value in x.
w: Integer window size (number of elements).
name: Name for metric in result dataframe

Returns
-------
Dataframe with columns horizon and name, the rolling mean of x.
xhr   sumcountr   rh   r   r   Nr   )r;   rt   groupbyaggr:   r   rB   r   r   r   emptyr   )r   r   r   namer   df2xsnshs
trailing_ix_sumn_sumres_xr   excess_nexcess_xres_hs                    r   rolling_mean_by_hr     sj   $ 
A&	'B


3UG,-99;GGL  
S%		B	S'		!	!B	BSAJEEHHSXE 3s8a<R(AAj yHQ%'"%/H!&!1A 5E
^#E
^#E!OJ j ) Q !E>#$E<<E4788r    c                 8   [         R                  " XS.5      nUR                  S5      nUR                  5       R	                  5       R                  S5      nUS   n/ n/ n	[        U5      S-
  n
U
S:  a  Xz   nUR                  U5      R                  R                  5       n[        R                  " X:H  5      R                  5       S-
  n[        U5      U:  a5  US:  a/  UR                  X   5        US-  n[        U5      U:  a  US:  a  M/  [        U5      U:  a  OEUR                  Xz   5        U	R                  [        R                  " U5      5        U
S-  n
U
S:  a  M  UR                  5         U	R                  5         [         R                  " SXU	05      $ )aN  Compute a rolling median of x, after first aggregating by h.

Right-aligned. Computes a single median for each unique value of h. Each
median is over at least w samples.

For each h where there are fewer than w samples, we take samples from the previous h,
moving backwards. (In other words, we ~ assume that the x's are shuffled within each h.)

Parameters
----------
x: Array.
h: Array of horizon for each value in x.
w: Integer window size (number of elements).
name: Name for metric in result dataframe

Returns
-------
Dataframe with columns horizon and name, the rolling median of x.
r   r   rh   r   r   )r;   rt   r   sizer:   r   r   	get_groupr   tolistr   arrayargmaxr   medianreverse)r   r   r   r   r   groupedr   r   r   r   r   h_ir   next_idx_to_adds                 r   rolling_median_by_hr     s]   * 
A&	'BjjoG
,,.
$
$
&
2
23
7C	SBEEB!A
q&es#%%,,. ((18,33592w{A!5 IIa()q O	 2w{A!5
 r7Q;RURYYr]#	Q! q&" 
MMO	MMO<<E788r    c                     U S   U S   -
  S-  nUS:  a  [         R                  " U S   US.5      $ [        UR                  U S   R                  USS9$ )	zMean squared error

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and mse.
rg   r$   rb   r   r   )r   r   r   r   r   r   r   r;   rt   r   rB   )r   r   ses      r   r   r     s^     S'BvJ
1	$B1u||9bABB
))r)}++qu r    c                 z    [        X5      n[        R                  " US   5      US'   UR                  SS0SSS9  U$ )zRoot mean squared error

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and rmse.
r   r   rx   T)r6   r   )r   r   sqrtrename)r   r   r   s      r   r   r   1  s>     b*CU$CJJJvYJ=Jr    c                     [         R                  " U S   U S   -
  5      nUS:  a  [        R                  " U S   US.5      $ [	        UR
                  U S   R
                  USS9$ )zMean absolute error

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and mae.
rg   r$   r   r   )r   r   r   r   r   r   r;   rt   r   rB   )r   r   aes      r   r   r   D  sb     
3"V*$	%B1u||9bABB
))r)}++qu r    c                     [         R                  " U S   U S   -
  U S   -  5      nUS:  a  [        R                  " U S   US.5      $ [	        UR
                  U S   R
                  USS9$ )zMean absolute percent error

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and mape.
rg   r$   r   r   )r   r   r   r   r   r   r   apes      r   r   r   Y  sk     &&"S'BvJ&"S'1
2C1u||9sCDD
**9,, r    c                     [         R                  " U S   U S   -
  U S   -  5      nUS:  a  [        R                  " U S   US.5      $ [	        UR
                  U S   USS9$ )zMedian absolute percent error

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and mdape.
rg   r$   r   r   )r   r   r   r   )r   r   r;   rt   r   rB   r   s      r   r   r   n  se     &&"S'BvJ&"S'1
2C1u||9DEE
**9 r    c                 Z   [         R                  " U S   U S   -
  5      [         R                  " U S   5      [         R                  " U S   5      -   S-  -  nUR                  S5      nUS:  a  [        R                  " U S   US.5      $ [        UR                  U S   R                  USS9$ )	zSymmetric mean absolute percentage error
based on Chen and Yang (2004) formula

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and smape.
rg   r$   rb   r   r   )r   r   r   r   )r   r   fillnar;   rt   r   rB   )r   r   sapes      r   r   r     s     66"S'BvJ&'BFF2c7ObffRZ>P,PTU+UVD;;q>D1u||9EFF
++I-- r    c                     U S   U S   :  U S   U S   :*  -  nUS:  a  [         R                  " U S   US.5      $ [        UR                  U S   R                  USS9$ )	zCoverage

Parameters
----------
df: Cross-validation results dataframe.
w: Aggregation window size.

Returns
-------
Dataframe with columns horizon and coverage.
rg   r%   r&   r   r   )r   r   r   r   r   )r   r   
is_covereds      r   r   r     so     S'R--"S'R=M2MNJ1u||9:NOO


r)}33qz r    )NNNNFNr.   )Ng?F)"
__future__r   r   r   logging	tqdm.autor   r9   r   concurrent.futuresrD   numpyr   pandasr;   	getLoggerr   r   r`   rN   ri   dictr   r   r   r   r   r   r   r   r   r   r   r   r/   r    r   <module>r      s    A @      			9	%&"RW>t6r5p F  Rj19j19r  (  $  (  (  (  ,  r    