PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/statsmodels/tsa/vector_ar/tests/test_var.py

http://github.com/statsmodels/statsmodels
Python | 968 lines | 928 code | 32 blank | 8 comment | 4 complexity | a812fc46e2b776b0e28bc5b10a9bdc5c MD5 | raw file
Possible License(s): BSD-3-Clause
  1. # -*- coding: utf-8 -*-
  2. """
  3. Test VAR Model
  4. """
  5. from statsmodels.compat.pandas import assert_index_equal
  6. from statsmodels.compat.python import lrange
  7. from io import BytesIO, StringIO
  8. import os
  9. import sys
  10. import warnings
  11. import numpy as np
  12. from numpy.testing import assert_allclose, assert_almost_equal, assert_equal
  13. import pandas as pd
  14. import pytest
  15. from statsmodels.datasets import macrodata
  16. import statsmodels.tools.data as data_util
  17. from statsmodels.tools.sm_exceptions import ValueWarning
  18. from statsmodels.tsa.base.datetools import dates_from_str
  19. import statsmodels.tsa.vector_ar.util as util
  20. from statsmodels.tsa.vector_ar.var_model import VAR, var_acf
  21. DECIMAL_12 = 12
  22. DECIMAL_6 = 6
  23. DECIMAL_5 = 5
  24. DECIMAL_4 = 4
  25. DECIMAL_3 = 3
  26. DECIMAL_2 = 2
  27. @pytest.fixture()
  28. def bivariate_var_data(reset_randomstate):
  29. """A bivariate dataset for VAR estimation"""
  30. e = np.random.standard_normal((252, 2))
  31. y = np.zeros_like(e)
  32. y[:2] = e[:2]
  33. for i in range(2, 252):
  34. y[i] = 0.2 * y[i - 1] + 0.1 * y[i - 2] + e[i]
  35. return y
  36. @pytest.fixture()
  37. def bivariate_var_result(bivariate_var_data):
  38. """A bivariate VARResults for reuse"""
  39. mod = VAR(bivariate_var_data)
  40. return mod.fit()
  41. class CheckVAR(object): # FIXME: not inherited, so these tests are never run!
  42. # just so pylint will not complain
  43. res1 = None
  44. res2 = None
  45. def test_params(self):
  46. assert_almost_equal(self.res1.params, self.res2.params, DECIMAL_3)
  47. def test_neqs(self):
  48. assert_equal(self.res1.neqs, self.res2.neqs)
  49. def test_nobs(self):
  50. assert_equal(self.res1.avobs, self.res2.nobs)
  51. def test_df_eq(self):
  52. assert_equal(self.res1.df_eq, self.res2.df_eq)
  53. def test_rmse(self):
  54. results = self.res1.results
  55. for i in range(len(results)):
  56. assert_almost_equal(
  57. results[i].mse_resid ** 0.5,
  58. eval("self.res2.rmse_" + str(i + 1)),
  59. DECIMAL_6,
  60. )
  61. def test_rsquared(self):
  62. results = self.res1.results
  63. for i in range(len(results)):
  64. assert_almost_equal(
  65. results[i].rsquared,
  66. eval("self.res2.rsquared_" + str(i + 1)),
  67. DECIMAL_3,
  68. )
  69. def test_llf(self):
  70. results = self.res1.results
  71. assert_almost_equal(self.res1.llf, self.res2.llf, DECIMAL_2)
  72. for i in range(len(results)):
  73. assert_almost_equal(
  74. results[i].llf, eval("self.res2.llf_" + str(i + 1)), DECIMAL_2
  75. )
  76. def test_aic(self):
  77. assert_almost_equal(self.res1.aic, self.res2.aic)
  78. def test_bic(self):
  79. assert_almost_equal(self.res1.bic, self.res2.bic)
  80. def test_hqic(self):
  81. assert_almost_equal(self.res1.hqic, self.res2.hqic)
  82. def test_fpe(self):
  83. assert_almost_equal(self.res1.fpe, self.res2.fpe)
  84. def test_detsig(self):
  85. assert_almost_equal(self.res1.detomega, self.res2.detsig)
  86. def test_bse(self):
  87. assert_almost_equal(self.res1.bse, self.res2.bse, DECIMAL_4)
  88. def get_macrodata():
  89. data = macrodata.load_pandas().data[["realgdp", "realcons", "realinv"]]
  90. data = data.to_records(index=False)
  91. nd = data.view((float, 3), type=np.ndarray)
  92. nd = np.diff(np.log(nd), axis=0)
  93. return nd.ravel().view(data.dtype, type=np.ndarray)
  94. def generate_var(): # FIXME: make a test?
  95. import pandas.rpy.common as prp
  96. from rpy2.robjects import r
  97. r.source("tests/var.R")
  98. return prp.convert_robj(r["result"], use_pandas=False)
  99. def write_generate_var(): # FIXME: make a test?
  100. result = generate_var()
  101. np.savez("tests/results/vars_results.npz", **result)
  102. class RResults(object):
  103. """
  104. Simple interface with results generated by "vars" package in R.
  105. """
  106. def __init__(self):
  107. # data = np.load(resultspath + 'vars_results.npz')
  108. from .results.results_var_data import var_results
  109. data = var_results.__dict__
  110. self.names = data["coefs"].dtype.names
  111. self.params = data["coefs"].view(
  112. (float, len(self.names)), type=np.ndarray
  113. )
  114. self.stderr = data["stderr"].view(
  115. (float, len(self.names)), type=np.ndarray
  116. )
  117. self.irf = data["irf"].item()
  118. self.orth_irf = data["orthirf"].item()
  119. self.nirfs = int(data["nirfs"][0])
  120. self.nobs = int(data["obs"][0])
  121. self.totobs = int(data["totobs"][0])
  122. crit = data["crit"].item()
  123. self.aic = crit["aic"][0]
  124. self.sic = self.bic = crit["sic"][0]
  125. self.hqic = crit["hqic"][0]
  126. self.fpe = crit["fpe"][0]
  127. self.detomega = data["detomega"][0]
  128. self.loglike = data["loglike"][0]
  129. self.nahead = int(data["nahead"][0])
  130. self.ma_rep = data["phis"]
  131. self.causality = data["causality"]
  132. _orig_stdout = None
  133. def setup_module():
  134. global _orig_stdout
  135. _orig_stdout = sys.stdout
  136. sys.stdout = StringIO()
  137. class CheckIRF(object):
  138. ref = None
  139. res = None
  140. irf = None
  141. k = None
  142. # ---------------------------------------------------------------------------
  143. # IRF tests
  144. def test_irf_coefs(self):
  145. self._check_irfs(self.irf.irfs, self.ref.irf)
  146. self._check_irfs(self.irf.orth_irfs, self.ref.orth_irf)
  147. def _check_irfs(self, py_irfs, r_irfs):
  148. for i, name in enumerate(self.res.names):
  149. ref_irfs = r_irfs[name].view((float, self.k), type=np.ndarray)
  150. res_irfs = py_irfs[:, :, i]
  151. assert_almost_equal(ref_irfs, res_irfs)
  152. @pytest.mark.matplotlib
  153. def test_plot_irf(self, close_figures):
  154. self.irf.plot()
  155. self.irf.plot(plot_stderr=False)
  156. self.irf.plot(impulse=0, response=1)
  157. self.irf.plot(impulse=0)
  158. self.irf.plot(response=0)
  159. self.irf.plot(orth=True)
  160. self.irf.plot(impulse=0, response=1, orth=True)
  161. @pytest.mark.matplotlib
  162. def test_plot_cum_effects(self, close_figures):
  163. self.irf.plot_cum_effects()
  164. self.irf.plot_cum_effects(plot_stderr=False)
  165. self.irf.plot_cum_effects(impulse=0, response=1)
  166. self.irf.plot_cum_effects(orth=True)
  167. self.irf.plot_cum_effects(impulse=0, response=1, orth=True)
  168. @pytest.mark.matplotlib
  169. def test_plot_figsizes(self):
  170. assert_equal(self.irf.plot().get_size_inches(), (10, 10))
  171. assert_equal(
  172. self.irf.plot(figsize=(14, 10)).get_size_inches(), (14, 10)
  173. )
  174. assert_equal(self.irf.plot_cum_effects().get_size_inches(), (10, 10))
  175. assert_equal(
  176. self.irf.plot_cum_effects(figsize=(14, 10)).get_size_inches(),
  177. (14, 10),
  178. )
  179. @pytest.mark.smoke
  180. class CheckFEVD(object):
  181. fevd = None
  182. # ---------------------------------------------------------------------------
  183. # FEVD tests
  184. @pytest.mark.matplotlib
  185. def test_fevd_plot(self, close_figures):
  186. self.fevd.plot()
  187. def test_fevd_repr(self):
  188. self.fevd
  189. def test_fevd_summary(self):
  190. self.fevd.summary()
  191. @pytest.mark.xfail(
  192. reason="FEVD.cov() is not implemented",
  193. raises=NotImplementedError,
  194. strict=True,
  195. )
  196. def test_fevd_cov(self):
  197. # test does not crash
  198. # not implemented
  199. covs = self.fevd.cov()
  200. raise NotImplementedError
  201. class TestVARResults(CheckIRF, CheckFEVD):
  202. @classmethod
  203. def setup_class(cls):
  204. cls.p = 2
  205. cls.data = get_macrodata()
  206. cls.model = VAR(cls.data)
  207. cls.names = cls.model.endog_names
  208. cls.ref = RResults()
  209. cls.k = len(cls.ref.names)
  210. cls.res = cls.model.fit(maxlags=cls.p)
  211. cls.irf = cls.res.irf(cls.ref.nirfs)
  212. cls.nahead = cls.ref.nahead
  213. cls.fevd = cls.res.fevd()
  214. def test_constructor(self):
  215. # make sure this works with no names
  216. ndarr = self.data.view((float, 3), type=np.ndarray)
  217. model = VAR(ndarr)
  218. res = model.fit(self.p)
  219. def test_names(self):
  220. assert_equal(self.model.endog_names, self.ref.names)
  221. model2 = VAR(self.data)
  222. assert_equal(model2.endog_names, self.ref.names)
  223. def test_get_eq_index(self):
  224. assert type(self.res.names) is list # noqa: E721
  225. for i, name in enumerate(self.names):
  226. idx = self.res.get_eq_index(i)
  227. idx2 = self.res.get_eq_index(name)
  228. assert_equal(idx, i)
  229. assert_equal(idx, idx2)
  230. with pytest.raises(Exception):
  231. self.res.get_eq_index("foo")
  232. @pytest.mark.smoke
  233. def test_repr(self):
  234. # just want this to work
  235. foo = str(self.res)
  236. bar = repr(self.res)
  237. def test_params(self):
  238. assert_almost_equal(self.res.params, self.ref.params, DECIMAL_3)
  239. @pytest.mark.smoke
  240. def test_cov_params(self):
  241. # do nothing for now
  242. self.res.cov_params
  243. @pytest.mark.smoke
  244. def test_cov_ybar(self):
  245. self.res.cov_ybar()
  246. @pytest.mark.smoke
  247. def test_tstat(self):
  248. self.res.tvalues
  249. @pytest.mark.smoke
  250. def test_pvalues(self):
  251. self.res.pvalues
  252. @pytest.mark.smoke
  253. def test_summary(self):
  254. summ = self.res.summary()
  255. def test_detsig(self):
  256. assert_almost_equal(self.res.detomega, self.ref.detomega)
  257. def test_aic(self):
  258. assert_almost_equal(self.res.aic, self.ref.aic)
  259. def test_bic(self):
  260. assert_almost_equal(self.res.bic, self.ref.bic)
  261. def test_hqic(self):
  262. assert_almost_equal(self.res.hqic, self.ref.hqic)
  263. def test_fpe(self):
  264. assert_almost_equal(self.res.fpe, self.ref.fpe)
  265. def test_lagorder_select(self):
  266. ics = ["aic", "fpe", "hqic", "bic"]
  267. for ic in ics:
  268. res = self.model.fit(maxlags=10, ic=ic, verbose=True)
  269. with pytest.raises(Exception):
  270. self.model.fit(ic="foo")
  271. def test_nobs(self):
  272. assert_equal(self.res.nobs, self.ref.nobs)
  273. def test_stderr(self):
  274. assert_almost_equal(self.res.stderr, self.ref.stderr, DECIMAL_4)
  275. def test_loglike(self):
  276. assert_almost_equal(self.res.llf, self.ref.loglike)
  277. def test_ma_rep(self):
  278. ma_rep = self.res.ma_rep(self.nahead)
  279. assert_almost_equal(ma_rep, self.ref.ma_rep)
  280. # --------------------------------------------------
  281. # Lots of tests to make sure stuff works...need to check correctness
  282. def test_causality(self):
  283. causedby = self.ref.causality["causedby"]
  284. for i, name in enumerate(self.names):
  285. variables = self.names[:i] + self.names[i + 1 :]
  286. result = self.res.test_causality(name, variables, kind="f")
  287. assert_almost_equal(result.pvalue, causedby[i], DECIMAL_4)
  288. rng = lrange(self.k)
  289. rng.remove(i)
  290. result2 = self.res.test_causality(i, rng, kind="f")
  291. assert_almost_equal(result.pvalue, result2.pvalue, DECIMAL_12)
  292. # make sure works
  293. result = self.res.test_causality(name, variables, kind="wald")
  294. # corner cases
  295. _ = self.res.test_causality(self.names[0], self.names[1])
  296. _ = self.res.test_causality(0, 1)
  297. with pytest.raises(Exception):
  298. self.res.test_causality(0, 1, kind="foo")
  299. def test_causality_no_lags(self):
  300. res = VAR(self.data).fit(maxlags=0)
  301. with pytest.raises(RuntimeError, match="0 lags"):
  302. res.test_causality(0, 1)
  303. @pytest.mark.smoke
  304. def test_select_order(self):
  305. result = self.model.fit(10, ic="aic", verbose=True)
  306. result = self.model.fit(10, ic="fpe", verbose=True)
  307. # bug
  308. model = VAR(self.model.endog)
  309. model.select_order()
  310. def test_is_stable(self):
  311. # may not necessarily be true for other datasets
  312. assert self.res.is_stable(verbose=True)
  313. def test_acf(self):
  314. # test that it works...for now
  315. acfs = self.res.acf(10)
  316. # defaults to nlags=lag_order
  317. acfs = self.res.acf()
  318. assert len(acfs) == self.p + 1
  319. def test_acf_2_lags(self):
  320. c = np.zeros((2, 2, 2))
  321. c[0] = np.array([[0.2, 0.1], [0.15, 0.15]])
  322. c[1] = np.array([[0.1, 0.9], [0, 0.1]])
  323. acf = var_acf(c, np.eye(2), 3)
  324. gamma = np.zeros((6, 6))
  325. gamma[:2, :2] = acf[0]
  326. gamma[2:4, 2:4] = acf[0]
  327. gamma[4:6, 4:6] = acf[0]
  328. gamma[2:4, :2] = acf[1].T
  329. gamma[4:, :2] = acf[2].T
  330. gamma[:2, 2:4] = acf[1]
  331. gamma[:2, 4:] = acf[2]
  332. recovered = np.dot(gamma[:2, 2:], np.linalg.inv(gamma[:4, :4]))
  333. recovered = [recovered[:, 2 * i : 2 * (i + 1)] for i in range(2)]
  334. recovered = np.array(recovered)
  335. assert_allclose(recovered, c, atol=1e-7)
  336. @pytest.mark.smoke
  337. def test_acorr(self):
  338. acorrs = self.res.acorr(10)
  339. @pytest.mark.smoke
  340. def test_forecast(self):
  341. self.res.forecast(self.res.endog[-5:], 5)
  342. @pytest.mark.smoke
  343. def test_forecast_interval(self):
  344. y = self.res.endog[: -self.p :]
  345. point, lower, upper = self.res.forecast_interval(y, 5)
  346. @pytest.mark.matplotlib
  347. def test_plot_sim(self, close_figures):
  348. self.res.plotsim(steps=100)
  349. @pytest.mark.matplotlib
  350. def test_plot(self, close_figures):
  351. self.res.plot()
  352. @pytest.mark.matplotlib
  353. def test_plot_acorr(self, close_figures):
  354. self.res.plot_acorr()
  355. @pytest.mark.matplotlib
  356. def test_plot_forecast(self, close_figures):
  357. self.res.plot_forecast(5)
  358. def test_reorder(self):
  359. # manually reorder
  360. data = self.data.view((float, 3), type=np.ndarray)
  361. names = self.names
  362. data2 = np.append(
  363. np.append(data[:, 2, None], data[:, 0, None], axis=1),
  364. data[:, 1, None],
  365. axis=1,
  366. )
  367. names2 = []
  368. names2.append(names[2])
  369. names2.append(names[0])
  370. names2.append(names[1])
  371. res2 = VAR(data2).fit(maxlags=self.p)
  372. # use reorder function
  373. res3 = self.res.reorder(["realinv", "realgdp", "realcons"])
  374. # check if the main results match
  375. assert_almost_equal(res2.params, res3.params)
  376. assert_almost_equal(res2.sigma_u, res3.sigma_u)
  377. assert_almost_equal(res2.bic, res3.bic)
  378. assert_almost_equal(res2.stderr, res3.stderr)
  379. def test_pickle(self):
  380. fh = BytesIO()
  381. # test wrapped results load save pickle
  382. del self.res.model.data.orig_endog
  383. self.res.save(fh)
  384. fh.seek(0, 0)
  385. res_unpickled = self.res.__class__.load(fh)
  386. assert type(res_unpickled) is type(self.res) # noqa: E721
  387. class E1_Results(object):
  388. """
  389. Results from Lütkepohl (2005) using E2 dataset
  390. """
  391. def __init__(self):
  392. # Lutkepohl p. 120 results
  393. # I asked the author about these results and there is probably rounding
  394. # error in the book, so I adjusted these test results to match what is
  395. # coming out of the Python (double-checked) calculations
  396. self.irf_stderr = np.array(
  397. [
  398. [
  399. [0.125, 0.546, 0.664],
  400. [0.032, 0.139, 0.169],
  401. [0.026, 0.112, 0.136],
  402. ],
  403. [
  404. [0.129, 0.547, 0.663],
  405. [0.032, 0.134, 0.163],
  406. [0.026, 0.108, 0.131],
  407. ],
  408. [
  409. [0.084, 0.385, 0.479],
  410. [0.016, 0.079, 0.095],
  411. [0.016, 0.078, 0.103],
  412. ],
  413. ]
  414. )
  415. self.cum_irf_stderr = np.array(
  416. [
  417. [
  418. [0.125, 0.546, 0.664],
  419. [0.032, 0.139, 0.169],
  420. [0.026, 0.112, 0.136],
  421. ],
  422. [
  423. [0.149, 0.631, 0.764],
  424. [0.044, 0.185, 0.224],
  425. [0.033, 0.140, 0.169],
  426. ],
  427. [
  428. [0.099, 0.468, 0.555],
  429. [0.038, 0.170, 0.205],
  430. [0.033, 0.150, 0.185],
  431. ],
  432. ]
  433. )
  434. self.lr_stderr = np.array(
  435. [
  436. [0.134, 0.645, 0.808],
  437. [0.048, 0.230, 0.288],
  438. [0.043, 0.208, 0.260],
  439. ]
  440. )
  441. basepath = os.path.split(__file__)[0]
  442. resultspath = os.path.join(basepath, "results")
  443. def get_lutkepohl_data(name="e2"):
  444. path = os.path.join(resultspath, f"{name}.dat")
  445. return util.parse_lutkepohl_data(path)
  446. def test_lutkepohl_parse():
  447. files = ["e%d" % i for i in range(1, 7)]
  448. for f in files:
  449. get_lutkepohl_data(f)
  450. class TestVARResultsLutkepohl(object):
  451. """
  452. Verify calculations using results from Lütkepohl's book
  453. """
  454. @classmethod
  455. def setup_class(cls):
  456. cls.p = 2
  457. sdata, dates = get_lutkepohl_data("e1")
  458. data = data_util.struct_to_ndarray(sdata)
  459. adj_data = np.diff(np.log(data), axis=0)
  460. # est = VAR(adj_data, p=2, dates=dates[1:], names=names)
  461. cls.model = VAR(adj_data[:-16], dates=dates[1:-16], freq="BQ-MAR")
  462. cls.res = cls.model.fit(maxlags=cls.p)
  463. cls.irf = cls.res.irf(10)
  464. cls.lut = E1_Results()
  465. def test_approx_mse(self):
  466. # 3.5.18, p. 99
  467. mse2 = (
  468. np.array(
  469. [
  470. [25.12, 0.580, 1.300],
  471. [0.580, 1.581, 0.586],
  472. [1.300, 0.586, 1.009],
  473. ]
  474. )
  475. * 1e-4
  476. )
  477. assert_almost_equal(mse2, self.res.forecast_cov(3)[1], DECIMAL_3)
  478. def test_irf_stderr(self):
  479. irf_stderr = self.irf.stderr(orth=False)
  480. for i in range(1, 1 + len(self.lut.irf_stderr)):
  481. assert_almost_equal(
  482. np.round(irf_stderr[i], 3), self.lut.irf_stderr[i - 1]
  483. )
  484. def test_cum_irf_stderr(self):
  485. stderr = self.irf.cum_effect_stderr(orth=False)
  486. for i in range(1, 1 + len(self.lut.cum_irf_stderr)):
  487. assert_almost_equal(
  488. np.round(stderr[i], 3), self.lut.cum_irf_stderr[i - 1]
  489. )
  490. def test_lr_effect_stderr(self):
  491. stderr = self.irf.lr_effect_stderr(orth=False)
  492. orth_stderr = self.irf.lr_effect_stderr(orth=True)
  493. assert_almost_equal(np.round(stderr, 3), self.lut.lr_stderr)
  494. def test_get_trendorder():
  495. results = {"c": 1, "n": 0, "ct": 2, "ctt": 3}
  496. for t, trendorder in results.items():
  497. assert util.get_trendorder(t) == trendorder
  498. def test_var_constant():
  499. # see 2043
  500. import datetime
  501. from pandas import DataFrame, DatetimeIndex
  502. series = np.array([[2.0, 2.0], [1, 2.0], [1, 2.0], [1, 2.0], [1.0, 2.0]])
  503. data = DataFrame(series)
  504. d = datetime.datetime.now()
  505. delta = datetime.timedelta(days=1)
  506. index = []
  507. for i in range(data.shape[0]):
  508. index.append(d)
  509. d += delta
  510. data.index = DatetimeIndex(index)
  511. # with pytest.warns(ValueWarning): #does not silence warning in test output
  512. with warnings.catch_warnings():
  513. warnings.simplefilter("ignore", category=ValueWarning)
  514. model = VAR(data)
  515. with pytest.raises(ValueError):
  516. model.fit(1)
  517. def test_var_trend():
  518. # see 2271
  519. data = get_macrodata().view((float, 3), type=np.ndarray)
  520. model = VAR(data)
  521. results = model.fit(4) # , trend = 'c')
  522. irf = results.irf(10)
  523. data_nc = data - data.mean(0)
  524. model_nc = VAR(data_nc)
  525. results_nc = model_nc.fit(4, trend="n")
  526. with pytest.raises(ValueError):
  527. model.fit(4, trend="t")
  528. def test_irf_trend():
  529. # test for irf with different trend see #1636
  530. # this is a rough comparison by adding trend or subtracting mean to data
  531. # to get similar AR coefficients and IRF
  532. data = get_macrodata().view((float, 3), type=np.ndarray)
  533. model = VAR(data)
  534. results = model.fit(4) # , trend = 'c')
  535. irf = results.irf(10)
  536. data_nc = data - data.mean(0)
  537. model_nc = VAR(data_nc)
  538. results_nc = model_nc.fit(4, trend="n")
  539. irf_nc = results_nc.irf(10)
  540. assert_allclose(irf_nc.stderr()[1:4], irf.stderr()[1:4], rtol=0.01)
  541. trend = 1e-3 * np.arange(len(data)) / (len(data) - 1)
  542. # for pandas version, currently not used, if data is a pd.DataFrame
  543. # data_t = pd.DataFrame(data.values + trend[:,None], index=data.index, columns=data.columns)
  544. data_t = data + trend[:, None]
  545. model_t = VAR(data_t)
  546. results_t = model_t.fit(4, trend="ct")
  547. irf_t = results_t.irf(10)
  548. assert_allclose(irf_t.stderr()[1:4], irf.stderr()[1:4], rtol=0.03)
  549. class TestVARExtras(object):
  550. @classmethod
  551. def setup_class(cls):
  552. mdata = macrodata.load_pandas().data
  553. mdata = mdata[["realgdp", "realcons", "realinv"]]
  554. data = mdata.values
  555. data = np.diff(np.log(data), axis=0) * 400
  556. cls.res0 = VAR(data).fit(maxlags=2)
  557. def test_process(self, close_figures):
  558. res0 = self.res0
  559. k_ar = res0.k_ar
  560. fc20 = res0.forecast(res0.endog[-k_ar:], 20)
  561. mean_lr = res0.mean()
  562. assert_allclose(mean_lr, fc20[-1], rtol=5e-4)
  563. ysim = res0.simulate_var(seed=987128)
  564. assert_allclose(ysim.mean(0), mean_lr, rtol=0.1)
  565. # initialization does not use long run intercept, see #4542
  566. assert_allclose(ysim[0], res0.intercept, rtol=1e-10)
  567. assert_allclose(ysim[1], res0.intercept, rtol=1e-10)
  568. n_sim = 900
  569. ysimz = res0.simulate_var(
  570. steps=n_sim, offset=np.zeros((n_sim, 3)), seed=987128
  571. )
  572. zero3 = np.zeros(3)
  573. assert_allclose(ysimz.mean(0), zero3, atol=0.4)
  574. # initialization does not use long run intercept, see #4542
  575. assert_allclose(ysimz[0], zero3, atol=1e-10)
  576. assert_allclose(ysimz[1], zero3, atol=1e-10)
  577. # check attributes
  578. assert_equal(res0.k_trend, 1)
  579. assert_equal(res0.k_exog_user, 0)
  580. assert_equal(res0.k_exog, 1)
  581. assert_equal(res0.k_ar, 2)
  582. irf = res0.irf()
  583. @pytest.mark.matplotlib
  584. def test_process_plotting(self, close_figures):
  585. # Partially a smoke test
  586. res0 = self.res0
  587. k_ar = res0.k_ar
  588. fc20 = res0.forecast(res0.endog[-k_ar:], 20)
  589. irf = res0.irf()
  590. res0.plotsim()
  591. res0.plot_acorr()
  592. fig = res0.plot_forecast(20)
  593. fcp = fig.axes[0].get_children()[1].get_ydata()[-20:]
  594. # Note values are equal, but keep rtol buffer
  595. assert_allclose(fc20[:, 0], fcp, rtol=1e-13)
  596. fcp = fig.axes[1].get_children()[1].get_ydata()[-20:]
  597. assert_allclose(fc20[:, 1], fcp, rtol=1e-13)
  598. fcp = fig.axes[2].get_children()[1].get_ydata()[-20:]
  599. assert_allclose(fc20[:, 2], fcp, rtol=1e-13)
  600. fig_asym = irf.plot()
  601. fig_mc = irf.plot(stderr_type="mc", repl=1000, seed=987128)
  602. for k in range(3):
  603. a = fig_asym.axes[1].get_children()[k].get_ydata()
  604. m = fig_mc.axes[1].get_children()[k].get_ydata()
  605. # use m as desired because it is larger
  606. # a is for some irf much smaller than m
  607. assert_allclose(a, m, atol=0.1, rtol=0.9)
  608. def test_forecast_cov(self):
  609. # forecast_cov can include parameter uncertainty if contant-only
  610. res = self.res0
  611. covfc1 = res.forecast_cov(3)
  612. assert_allclose(covfc1, res.mse(3), rtol=1e-13)
  613. # ignore warning, TODO: assert OutputWarning
  614. with warnings.catch_warnings():
  615. warnings.simplefilter("ignore")
  616. covfc2 = res.forecast_cov(3, method="auto")
  617. assert_allclose(covfc2, covfc1, rtol=0.05)
  618. # regression test, TODO: replace with verified numbers (Stata)
  619. res_covfc2 = np.array(
  620. [
  621. [
  622. [9.45802013, 4.94142038, 37.1999646],
  623. [4.94142038, 7.09273624, 5.66215089],
  624. [37.1999646, 5.66215089, 259.61275869],
  625. ],
  626. [
  627. [11.30364479, 5.72569141, 49.28744123],
  628. [5.72569141, 7.409761, 10.98164091],
  629. [49.28744123, 10.98164091, 336.4484723],
  630. ],
  631. [
  632. [12.36188803, 6.44426905, 53.54588026],
  633. [6.44426905, 7.88850029, 13.96382545],
  634. [53.54588026, 13.96382545, 352.19564327],
  635. ],
  636. ]
  637. )
  638. assert_allclose(covfc2, res_covfc2, atol=1e-6)
  639. def test_exog(self):
  640. # check that trend and exog are equivalent for basics and varsim
  641. data = self.res0.model.endog
  642. res_lin_trend = VAR(data).fit(maxlags=2, trend="ct")
  643. ex = np.arange(len(data))
  644. res_lin_trend1 = VAR(data, exog=ex).fit(maxlags=2)
  645. ex2 = np.arange(len(data))[:, None] ** [0, 1]
  646. res_lin_trend2 = VAR(data, exog=ex2).fit(maxlags=2, trend="n")
  647. # TODO: intercept differs by 4e-3, others are < 1e-12
  648. assert_allclose(res_lin_trend.params, res_lin_trend1.params, rtol=5e-3)
  649. assert_allclose(res_lin_trend.params, res_lin_trend2.params, rtol=5e-3)
  650. assert_allclose(
  651. res_lin_trend1.params, res_lin_trend2.params, rtol=1e-10
  652. )
  653. y1 = res_lin_trend.simulate_var(seed=987128)
  654. y2 = res_lin_trend1.simulate_var(seed=987128)
  655. y3 = res_lin_trend2.simulate_var(seed=987128)
  656. assert_allclose(y2.mean(0), y1.mean(0), rtol=1e-12)
  657. assert_allclose(y3.mean(0), y1.mean(0), rtol=1e-12)
  658. assert_allclose(y3.mean(0), y2.mean(0), rtol=1e-12)
  659. h = 10
  660. fc1 = res_lin_trend.forecast(res_lin_trend.endog[-2:], h)
  661. exf = np.arange(len(data), len(data) + h)
  662. fc2 = res_lin_trend1.forecast(
  663. res_lin_trend1.endog[-2:], h, exog_future=exf
  664. )
  665. with pytest.raises(ValueError, match="exog_future only has"):
  666. wrong_exf = np.arange(len(data), len(data) + h // 2)
  667. res_lin_trend1.forecast(
  668. res_lin_trend1.endog[-2:], h, exog_future=wrong_exf
  669. )
  670. exf2 = exf[:, None] ** [0, 1]
  671. fc3 = res_lin_trend2.forecast(
  672. res_lin_trend2.endog[-2:], h, exog_future=exf2
  673. )
  674. assert_allclose(fc2, fc1, rtol=1e-12)
  675. assert_allclose(fc3, fc1, rtol=1e-12)
  676. assert_allclose(fc3, fc2, rtol=1e-12)
  677. fci1 = res_lin_trend.forecast_interval(res_lin_trend.endog[-2:], h)
  678. exf = np.arange(len(data), len(data) + h)
  679. fci2 = res_lin_trend1.forecast_interval(
  680. res_lin_trend1.endog[-2:], h, exog_future=exf
  681. )
  682. exf2 = exf[:, None] ** [0, 1]
  683. fci3 = res_lin_trend2.forecast_interval(
  684. res_lin_trend2.endog[-2:], h, exog_future=exf2
  685. )
  686. assert_allclose(fci2, fci1, rtol=1e-12)
  687. assert_allclose(fci3, fci1, rtol=1e-12)
  688. assert_allclose(fci3, fci2, rtol=1e-12)
  689. def test_var_cov_params_pandas(bivariate_var_data):
  690. df = pd.DataFrame(bivariate_var_data, columns=["x", "y"])
  691. mod = VAR(df)
  692. res = mod.fit(2)
  693. cov = res.cov_params()
  694. assert isinstance(cov, pd.DataFrame)
  695. exog_names = ("const", "L1.x", "L1.y", "L2.x", "L2.y")
  696. index = pd.MultiIndex.from_product((exog_names, ("x", "y")))
  697. assert_index_equal(cov.index, cov.columns)
  698. assert_index_equal(cov.index, index)
  699. def test_summaries_exog(reset_randomstate):
  700. y = np.random.standard_normal((500, 6))
  701. df = pd.DataFrame(y)
  702. cols = ["endog_{0}".format(i) for i in range(2)] + [
  703. "exog_{0}".format(i) for i in range(4)
  704. ]
  705. df.columns = cols
  706. df.index = pd.date_range("1-1-1950", periods=500, freq="MS")
  707. endog = df.iloc[:, :2]
  708. exog = df.iloc[:, 2:]
  709. res = VAR(endog=endog, exog=exog).fit(maxlags=0)
  710. summ = res.summary().summary
  711. assert "exog_0" in summ
  712. assert "exog_1" in summ
  713. assert "exog_2" in summ
  714. assert "exog_3" in summ
  715. res = VAR(endog=endog, exog=exog).fit(maxlags=2)
  716. summ = res.summary().summary
  717. assert "exog_0" in summ
  718. assert "exog_1" in summ
  719. assert "exog_2" in summ
  720. assert "exog_3" in summ
  721. def test_whiteness_nlag(reset_randomstate):
  722. # GH 6686
  723. y = np.random.standard_normal((200, 2))
  724. res = VAR(y).fit(maxlags=1, ic=None)
  725. with pytest.raises(ValueError, match="The whiteness test can only"):
  726. res.test_whiteness(1)
  727. def test_var_maxlag(reset_randomstate):
  728. y = np.random.standard_normal((22, 10))
  729. VAR(y).fit(maxlags=None, ic="aic")
  730. with pytest.raises(ValueError, match="maxlags is too large"):
  731. VAR(y).fit(maxlags=8, ic="aic")
  732. def test_from_formula():
  733. with pytest.raises(NotImplementedError):
  734. VAR.from_formula("y ~ x", None)
  735. def test_correct_nobs():
  736. # GH6748
  737. mdata = macrodata.load_pandas().data
  738. # prepare the dates index
  739. dates = mdata[["year", "quarter"]].astype(int).astype(str)
  740. quarterly = dates["year"] + "Q" + dates["quarter"]
  741. quarterly = dates_from_str(quarterly)
  742. mdata = mdata[["realgdp", "realcons", "realinv"]]
  743. mdata.index = pd.DatetimeIndex(quarterly)
  744. data = np.log(mdata).diff().dropna()
  745. data.index.freq = data.index.inferred_freq
  746. data_exog = pd.DataFrame(index=data.index)
  747. data_exog["exovar1"] = np.random.normal(size=data_exog.shape[0])
  748. # make a VAR model
  749. model = VAR(endog=data, exog=data_exog)
  750. results = model.fit(maxlags=1)
  751. irf = results.irf_resim(
  752. orth=False, repl=100, steps=10, seed=1, burn=100, cum=False
  753. )
  754. assert irf.shape == (100, 11, 3, 3)
  755. @pytest.mark.slow
  756. def test_irf_err_bands():
  757. # smoke tests
  758. data = get_macrodata()
  759. model = VAR(data)
  760. results = model.fit(maxlags=2)
  761. irf = results.irf()
  762. bands_sz1 = irf.err_band_sz1()
  763. bands_sz2 = irf.err_band_sz2()
  764. bands_sz3 = irf.err_band_sz3()
  765. bands_mc = irf.errband_mc()