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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: econmethods
3
- Version: 2.7
3
+ Version: 2.9
4
4
  Summary: A python package implementing various econometrical tests and estimators
5
5
  Home-page: https://github.com/NaturionBG/econmethods
6
6
  Author: NaturionBG
@@ -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', include_x_diffs: bool = True, intercept: bool = True, stat_vars: pd.DataFrame|None = None, lr_const: bool = False) -> None:
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 = ['target_avg']
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 = pd.concat([means, means.shift([1])], axis=1)
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
- if self.__x_difs:
477
- for var in self.__l:
478
- subdf[f'{var}_lag1'] = subdf[var].shift(1)
479
- subdf[f'{var}_diff'] = subdf[var]- subdf[f'{var}_lag1']
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
- if self.__x_difs:
497
- for var in self.__l:
498
- subdf[f'{var}_lag1'] = subdf[var].shift(1)
499
- subdf[f'{var}_diff'] = subdf[var]- subdf[f'{var}_lag1']
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.get_ccemg_frames(self.__lag)
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.get_mg_frames(self.__lag)
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
- if self.__method == 'ccemg':
548
- dct['ar'] = self.__ar
549
- coefs = []
550
- rsq = []
551
- for result in self.__sr:
552
- coefs.append(result.params)
553
- rsq.append(result.rsquared)
554
- coef_mean = pd.concat(coefs, axis=1).mean(axis=1)
555
- coef_mean.name = 'Mean Coefs'
556
- coef_std = pd.concat(coefs, axis=1).std(axis=1)
557
- coef_mse = coef_std/np.sqrt(self.__N)
558
- t_means = coef_mean / coef_mse
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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: econmethods
3
- Version: 2.7
3
+ Version: 2.9
4
4
  Summary: A python package implementing various econometrical tests and estimators
5
5
  Home-page: https://github.com/NaturionBG/econmethods
6
6
  Author: NaturionBG
@@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
5
5
 
6
6
  setup(
7
7
  name = 'econmethods',
8
- version = 'v2.7',
8
+ version = 'v2.9',
9
9
  description='A python package implementing various econometrical tests and estimators',
10
10
  packages = find_packages(),
11
11
  long_description=long_desc,
File without changes
File without changes