econmethods 2.7__tar.gz → 2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {econmethods-2.7 → econmethods-2.9}/PKG-INFO +1 -1
- {econmethods-2.7 → econmethods-2.9}/econmethods/Lib.py +74 -69
- {econmethods-2.7 → econmethods-2.9}/econmethods.egg-info/PKG-INFO +1 -1
- {econmethods-2.7 → econmethods-2.9}/setup.py +1 -1
- {econmethods-2.7 → econmethods-2.9}/README.md +0 -0
- {econmethods-2.7 → econmethods-2.9}/econmethods/CADF_Crit_Values.xlsx +0 -0
- {econmethods-2.7 → econmethods-2.9}/econmethods/__init__.py +0 -0
- {econmethods-2.7 → econmethods-2.9}/econmethods.egg-info/SOURCES.txt +0 -0
- {econmethods-2.7 → econmethods-2.9}/econmethods.egg-info/dependency_links.txt +0 -0
- {econmethods-2.7 → econmethods-2.9}/econmethods.egg-info/requires.txt +0 -0
- {econmethods-2.7 → econmethods-2.9}/econmethods.egg-info/top_level.txt +0 -0
- {econmethods-2.7 → econmethods-2.9}/setup.cfg +0 -0
|
@@ -309,10 +309,10 @@ class FECM:
|
|
|
309
309
|
- coint = "x1"
|
|
310
310
|
- coint = ["x1", "x3", ...]\n
|
|
311
311
|
Defaults to "x1"
|
|
312
|
-
- *include_x_diffs*: Specify whether the model should include the differences of exogenous variables. Defaults to True.
|
|
313
312
|
- *intercept*: Specify whether the ECM model should have an intercept. Defaults to True.
|
|
314
313
|
- *stat_vars*: a DataFrame of the same format as "df" - includes variables that will not be differenced and included into the ECM in their raw form. Ensure these variables are I(0). Defaults to None.
|
|
315
314
|
- *lr_const*: Specify whether the long-run model should have a constant.
|
|
315
|
+
- *autorem*: Enables/Disables automatic removal of insignificant regression coefficients in the ECM. Defaults to True.
|
|
316
316
|
----
|
|
317
317
|
RETURNS:
|
|
318
318
|
--
|
|
@@ -322,18 +322,18 @@ class FECM:
|
|
|
322
322
|
If a CCE- method is chosen:
|
|
323
323
|
- The AR(d) estimation results to forecast the cross-sectional mean | key = "ar"
|
|
324
324
|
'''
|
|
325
|
-
def __init__(self, df: pd.DataFrame, effects: str = 'rand', trend: int = 0, n_lags: int = 1, method: str = 'MG', coint: str | list[str] = 'x1',
|
|
325
|
+
def __init__(self, df: pd.DataFrame, effects: str = 'rand', trend: int = 0, n_lags: int = 1, method: str = 'MG', coint: str | list[str] = 'x1', intercept: bool = True, stat_vars: pd.DataFrame|None = None, lr_const: bool = False, autorem: bool = True) -> None:
|
|
326
326
|
self.__df = df
|
|
327
327
|
self.__eff = effects.lower()
|
|
328
328
|
self.__t = trend
|
|
329
|
+
self.__autorem = autorem
|
|
329
330
|
self.__C = intercept
|
|
330
331
|
self.__lag = n_lags
|
|
331
332
|
self.__method = method.lower()
|
|
332
333
|
self.__exog = len(df.columns[3:])
|
|
333
334
|
self.__l =[]
|
|
334
335
|
self.__stat_vars = stat_vars
|
|
335
|
-
self.__mean_names = ['
|
|
336
|
-
self.__x_difs = include_x_diffs
|
|
336
|
+
self.__mean_names = ['target_avg_l1']
|
|
337
337
|
self.__stat = []
|
|
338
338
|
self.__lr_c = lr_const
|
|
339
339
|
if stat_vars is not None:
|
|
@@ -360,9 +360,10 @@ class FECM:
|
|
|
360
360
|
self.__lag = 1
|
|
361
361
|
self.__verify()
|
|
362
362
|
self.__means = self.build_means()
|
|
363
|
-
if self.__method == 'ccemg' or method == 'ccep':
|
|
364
|
-
self.__ar = self.select_ar()
|
|
365
363
|
self.__lr = self.__estimate_lr()
|
|
364
|
+
self.__df = pd.concat([self.__df, pd.Series(self.__lr.resid, name='error')], axis=1)
|
|
365
|
+
self.__ccemg_units = self.get_ccemg_frames(1)
|
|
366
|
+
self.__mg_units = self.get_mg_frames(1)
|
|
366
367
|
self.__sr = self.build_sr()
|
|
367
368
|
|
|
368
369
|
def __verify(self) -> None:
|
|
@@ -387,15 +388,7 @@ class FECM:
|
|
|
387
388
|
mn = mn.set_index('time')
|
|
388
389
|
means = mn.groupby('time')[['target'] + self.__l].mean()
|
|
389
390
|
means.columns = self.__mean_names
|
|
390
|
-
means =
|
|
391
|
-
for var in means.columns[:len(self.__l)+1]:
|
|
392
|
-
if 'target' not in var:
|
|
393
|
-
if self.__x_difs:
|
|
394
|
-
means[f'{var}_diff'] = means[var] - means[f'{var}_1']
|
|
395
|
-
means = means.drop(columns=[f'{var}_1'])
|
|
396
|
-
else:
|
|
397
|
-
means[f'{var}_diff'] = means[var] - means[f'{var}_1']
|
|
398
|
-
means = means.drop(columns=[f'{var}_1'])
|
|
391
|
+
means['target_avg_l1'] = means['target_avg_l1'].shift(1)
|
|
399
392
|
return means
|
|
400
393
|
|
|
401
394
|
def build_GLS(self, w_err: float) -> np.ndarray:
|
|
@@ -452,32 +445,15 @@ class FECM:
|
|
|
452
445
|
lr_re_matrix = self.build_GLS(resid)
|
|
453
446
|
return sm.GLS(self.__lr_df.loc[:, 'target'], self.__lr_df.iloc[:, 3:], lr_re_matrix).fit()
|
|
454
447
|
|
|
455
|
-
def select_ar(self) -> Any:
|
|
456
|
-
current_d = self.__lag+1
|
|
457
|
-
while current_d >= 1:
|
|
458
|
-
frame = pd.DataFrame(self.__means.target_avg)
|
|
459
|
-
temp = []
|
|
460
|
-
for lag in range(1, current_d+1):
|
|
461
|
-
frame.loc[:, f'y_avg{lag}'] = frame['target_avg'].shift(lag)
|
|
462
|
-
temp.append(f'y_avg{lag}')
|
|
463
|
-
frame = frame.dropna()
|
|
464
|
-
part_res = sm.OLS(frame.target_avg, frame[temp]).fit()
|
|
465
|
-
if part_res.pvalues[temp[-1]] < 0.05:
|
|
466
|
-
break
|
|
467
|
-
else:
|
|
468
|
-
current_d -=1
|
|
469
|
-
print(f'Selected AR lag amount: {current_d}')
|
|
470
|
-
return part_res
|
|
471
448
|
|
|
472
449
|
def get_ccemg_frames(self, max_lag: int) -> list[pd.DataFrame]:
|
|
473
450
|
subdfs = []
|
|
474
451
|
for unit in self.__df.SpUnit.unique():
|
|
475
452
|
subdf = self.__df[self.__df.SpUnit == unit].copy(deep=True)
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
subdf = subdf.drop(columns = [f'{var}_lag1'])
|
|
453
|
+
for var in self.__l:
|
|
454
|
+
subdf[f'{var}_lag1'] = subdf[var].shift(1)
|
|
455
|
+
subdf[f'{var}_diff'] = subdf[var]- subdf[f'{var}_lag1']
|
|
456
|
+
subdf = subdf.drop(columns = [f'{var}_lag1'])
|
|
481
457
|
subdf['target_lag1'] = subdf['target'].shift(1)
|
|
482
458
|
subdf.insert(2, 'target_diff', subdf['target'] - subdf['target_lag1'])
|
|
483
459
|
subdf = subdf.drop(columns = ['target_lag1', *self.__l, 'target'])
|
|
@@ -493,11 +469,10 @@ class FECM:
|
|
|
493
469
|
subdfs = []
|
|
494
470
|
for unit in self.__df.SpUnit.unique():
|
|
495
471
|
subdf = self.__df[self.__df.SpUnit == unit].copy(deep=True)
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
subdf = subdf.drop(columns = [f'{var}_lag1'])
|
|
472
|
+
for var in self.__l:
|
|
473
|
+
subdf[f'{var}_lag1'] = subdf[var].shift(1)
|
|
474
|
+
subdf[f'{var}_diff'] = subdf[var]- subdf[f'{var}_lag1']
|
|
475
|
+
subdf = subdf.drop(columns = [f'{var}_lag1'])
|
|
501
476
|
subdf['target_lag1'] = subdf['target'].shift(1)
|
|
502
477
|
subdf.insert(2, 'target_diff', subdf['target'] - subdf['target_lag1'])
|
|
503
478
|
subdf = subdf.drop(columns = ['target_lag1', *self.__l, 'target'])
|
|
@@ -508,24 +483,27 @@ class FECM:
|
|
|
508
483
|
subdfs.append(subdf.dropna())
|
|
509
484
|
return subdfs
|
|
510
485
|
|
|
511
|
-
def build_sr(self) -> pd.DataFrame:
|
|
512
|
-
self.__df = pd.concat([self.__df, pd.Series(self.__lr.resid, name='error')], axis=1)
|
|
486
|
+
def build_sr(self, drop: list = []) -> pd.DataFrame:
|
|
513
487
|
est = []
|
|
514
488
|
if self.__method == 'ccemg':
|
|
515
|
-
units = self.
|
|
516
|
-
for model in units:
|
|
489
|
+
units = self.__ccemg_units
|
|
490
|
+
for i, model in enumerate(units):
|
|
491
|
+
model = model.drop(columns=drop)
|
|
517
492
|
if self.__C:
|
|
518
493
|
est.append(sm.OLS(model['target_diff'], sm.add_constant(model.iloc[:, 3:])).fit())
|
|
519
494
|
else:
|
|
520
495
|
est.append(sm.OLS(model['target_diff'], model.iloc[:, 3:]).fit())
|
|
496
|
+
self.__ccemg_units[i] = self.__ccemg_units[i].drop(columns=drop)
|
|
521
497
|
return est
|
|
522
498
|
elif self.__method == 'mg':
|
|
523
|
-
units = self.
|
|
524
|
-
for model in units:
|
|
499
|
+
units = self.__mg_units
|
|
500
|
+
for i, model in enumerate(units):
|
|
501
|
+
model = model.drop(columns=drop)
|
|
525
502
|
if self.__C:
|
|
526
503
|
est.append(sm.OLS(model['target_diff'], sm.add_constant(model.iloc[:, 3:])).fit())
|
|
527
504
|
else:
|
|
528
505
|
est.append(sm.OLS(model['target_diff'], model.iloc[:, 3:]).fit())
|
|
506
|
+
self.__ccemg_units[i] = self.__ccemg_units[i].drop(columns=drop)
|
|
529
507
|
return est
|
|
530
508
|
elif self.__method == 'ccep':
|
|
531
509
|
units = self.get_ccemg_frames(self.__lag)
|
|
@@ -534,37 +512,62 @@ class FECM:
|
|
|
534
512
|
est.append(sm.OLS(pool['target_diff'], sm.add_constant(pool.iloc[:, 3:])).fit())
|
|
535
513
|
else:
|
|
536
514
|
est.append(sm.OLS(pool['target_diff'], pool.iloc[:, 3:]).fit())
|
|
515
|
+
if self.__autorem:
|
|
516
|
+
while True:
|
|
517
|
+
flag = True
|
|
518
|
+
if max(zip(est[0].params.index, est[0].pvalues), key=lambda x: x[1])[1] > 0.06:
|
|
519
|
+
pool = pool.drop(columns=[max(zip(est[0].params.index, est[0].pvalues), key=lambda x: x[1])[0]])
|
|
520
|
+
flag=False
|
|
521
|
+
if flag:
|
|
522
|
+
break
|
|
523
|
+
else:
|
|
524
|
+
if self.__C:
|
|
525
|
+
est[0] = sm.OLS(pool['target_diff'], sm.add_constant(pool.iloc[:, 3:])).fit()
|
|
526
|
+
else:
|
|
527
|
+
est[0] = sm.OLS(pool['target_diff'], pool.iloc[:, 3:]).fit()
|
|
537
528
|
return est
|
|
538
529
|
|
|
530
|
+
def mg_algorithm(self) -> pd.DataFrame:
|
|
531
|
+
coefs = []
|
|
532
|
+
rsq = []
|
|
533
|
+
for result in self.__sr:
|
|
534
|
+
coefs.append(result.params)
|
|
535
|
+
rsq.append(result.rsquared)
|
|
536
|
+
coef_mean = pd.concat(coefs, axis=1).mean(axis=1)
|
|
537
|
+
coef_mean.name = 'Mean Coefs'
|
|
538
|
+
coef_std = pd.concat(coefs, axis=1).std(axis=1)
|
|
539
|
+
coef_mse = coef_std/np.sqrt(self.__N)
|
|
540
|
+
t_means = coef_mean / coef_mse
|
|
541
|
+
mg_W = sc.chi2(self.__exog).sf(np.sum(coef_mean**2 / coef_mse**2))
|
|
542
|
+
tpvalues_mean = t_means.apply(lambda x: 2*min(sc.t(self.__N-1).cdf(x), sc.t(self.__N-1).sf(x)))
|
|
543
|
+
tpvalues_mean.name = 'T-pvalues'
|
|
544
|
+
rsq_mean = np.array(rsq).mean()
|
|
545
|
+
res = {
|
|
546
|
+
'Rsquared': rsq_mean,
|
|
547
|
+
'W_Pvalue': mg_W,
|
|
548
|
+
'coefs': pd.concat([coef_mean, tpvalues_mean], axis=1)
|
|
549
|
+
}
|
|
550
|
+
return res
|
|
551
|
+
|
|
539
552
|
def fit(self) -> dict:
|
|
540
553
|
dct = dict()
|
|
541
554
|
if self.__method == 'ccep':
|
|
542
555
|
dct['sr_res'] = self.__sr[0]
|
|
543
556
|
dct['lr_res'] = self.__lr
|
|
544
|
-
dct['ar'] = self.__ar
|
|
545
557
|
elif self.__method == 'ccemg' or self.__method == 'mg':
|
|
546
558
|
dct['lr_res'] = self.__lr
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
mg_W = sc.chi2(self.__exog).sf(np.sum(coef_mean**2 / coef_mse**2))
|
|
560
|
-
tpvalues_mean = t_means.apply(lambda x: 2*min(sc.t(self.__N-1).cdf(x), sc.t(self.__N-1).sf(x)))
|
|
561
|
-
tpvalues_mean.name = 'T-pvalues'
|
|
562
|
-
rsq_mean = np.array(rsq).mean()
|
|
563
|
-
res = {
|
|
564
|
-
'Rsquared': rsq_mean,
|
|
565
|
-
'W_Pvalue': mg_W,
|
|
566
|
-
'coefs': pd.concat([coef_mean, tpvalues_mean], axis=1)
|
|
567
|
-
}
|
|
559
|
+
res = self.mg_algorithm()
|
|
560
|
+
if self.__autorem:
|
|
561
|
+
while True:
|
|
562
|
+
flag = True
|
|
563
|
+
if max(zip(res['coefs'].index, res['coefs']['T-pvalues']), key=lambda x: x[1])[1] > 0.06:
|
|
564
|
+
self.__sr = self.build_sr([max(zip(res['coefs'].index, res['coefs']['T-pvalues']), key=lambda x: x[1])[0]])
|
|
565
|
+
flag=False
|
|
566
|
+
if flag:
|
|
567
|
+
break
|
|
568
|
+
else:
|
|
569
|
+
res = self.mg_algorithm()
|
|
570
|
+
|
|
568
571
|
dct['sr_res'] = res
|
|
569
572
|
return dct
|
|
570
573
|
|
|
@@ -572,6 +575,8 @@ class FECM:
|
|
|
572
575
|
pass
|
|
573
576
|
|
|
574
577
|
|
|
578
|
+
|
|
579
|
+
|
|
575
580
|
class CDTwoWay:
|
|
576
581
|
'''
|
|
577
582
|
Implementation of the CD test to validate/reject cross-sectional dependence.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|