Repository: statsmodels/statsmodels

Issue:
RuntimeWarning and ValueWarning in grangercausalitytests
#### Describe the bug

Executing a toy sample for grangercausalitytests leads to RuntimeWarnings and a ValueWarning.

Are these warnings reasonable? Or what do I have to avoid them?


#### Code Sample, a copy-pastable example if possible

```python
import statsmodels.api as sm
from statsmodels.tsa.stattools import grangercausalitytests
import statsmodels

import pandas as pd
from scipy import stats
import numpy as np

print("statsmodels.__version__=", statsmodels.__version__)
print("np.__version__=", np.__version__)
print("pd.__version__=", pd.__version__)

a = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
b = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

df2 = pd.DataFrame({'b': b, 'a': a})
gc_res2 = grangercausalitytests(df2, [4], verbose=True)
```

#### Output
 
<output>

```
/home/user/venv/numba/bin/python3.6 /home/user/PycharmProjects/MyProject/attic03.py
statsmodels.__version__= 0.12.1

INSTALLED VERSIONS
------------------
Python: 3.6.8.final.0
OS: Linux 4.4.0-197-generic #229-Ubuntu SMP Wed Nov 25 11:05:42 UTC 2020 x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

statsmodels
===========

Installed: 0.12.1 (/home/user/venv/numba/lib/python3.6/site-packages/statsmodels)

Required Dependencies
=====================

cython: 0.29.14 (/home/user/venv/numba/lib/python3.6/site-packages/Cython)
numpy: 1.19.4 (/home/user/venv/numba/lib/python3.6/site-packages/numpy)
scipy: 1.5.2 (/home/user/venv/numba/lib/python3.6/site-packages/scipy)
pandas: 1.1.5 (/home/user/venv/numba/lib/python3.6/site-packages/pandas)
    dateutil: 2.8.1 (/home/user/venv/numba/lib/python3.6/site-packages/dateutil)
patsy: 0.5.1 (/home/user/venv/numba/lib/python3.6/site-packages/patsy)

Optional Dependencies
=====================

matplotlib: 3.3.3 (/home/user/venv/numba/lib/python3.6/site-packages/matplotlib)
    backend: Qt5Agg 
cvxopt: Not installed
joblib: 0.13.2 (/home/user/venv/numba/lib/python3.6/site-packages/joblib)

Developer Tools
================

IPython: 7.8.0 (/home/user/venv/numba/lib/python3.6/site-packages/IPython)
    jinja2: 2.11.2 (/home/user/venv/numba/lib/python3.6/site-packages/jinja2)
sphinx: Not installed
    pygments: 2.4.2 (/home/user/venv/numba/lib/python3.6/site-packages/pygments)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py:1400: RuntimeWarning: invalid value encountered in double_scalars
  * res2djoint.df_resid
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py:1421: RuntimeWarning: invalid value encountered in double_scalars
  fgc2 = res2down.nobs * (res2down.ssr - res2djoint.ssr) / res2djoint.ssr
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/regression/linear_model.py:903: RuntimeWarning: divide by zero encountered in log
  llf = -nobs2*np.log(2*np.pi) - nobs2*np.log(ssr / nobs) - nobs2
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py:1430: RuntimeWarning: invalid value encountered in double_scalars
  lr = -2 * (res2down.llf - res2djoint.llf)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 4, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1850: RuntimeWarning: invalid value encountered in true_divide
  F /= J
pytest: 5.2.2 (/home/user/venv/numba/lib/python3.6/site-packages)
virtualenv: Not installed


statsmodels.api.show_versions()= None
np.__version__= 1.19.4
pd.__version__= 1.1.5

Granger Causality
number of lags (no zero) 4
ssr based F test:         F=nan     , p=nan     , df_denom=9, df_num=4
ssr based chi2 test:   chi2=nan     , p=nan     , df=4
likelihood ratio test: chi2=nan     , p=nan     , df=4
parameter F test:         F=nan     , p=nan     , df_denom=9, df_num=0

Process finished with exit code 1
```

</details>




#### Expected Output

No warnings 

#### Output of ``import statsmodels.api as sm; sm.show_versions()``

see above


</details>



Discussion:
Thanks for the report!

The VAR(4) model has a perfect fit for that dataset, and so the sum of squared errors (the `ssr` attribute) is equal to zero. This causes problems in the test, and produces the warnings, because the sum of squared errors appears in the denominator.

So this is a corner case issue, and I think the fact that we don't handle it qualifies as a bug that we should fix (although it's not likely to show up very often, outside of toy examples).
Hi, thanks for your quick analysis!!! :+1: 

I did some other toy tests, that seem to be related to this issue. 
Now I have been able to produce also an exception (I catch them in the code in order to continue with test execution, as you can see in the `try except`). Maybe the root cause is close to the first?

Thanks in advance also for looking at this topic.

#### code:
```
import statsmodels.api as sm
from statsmodels.tsa.stattools import grangercausalitytests
import statsmodels

import pandas as pd
import numpy as np
import traceback

# print("statsmodels.api.show_versions()=", statsmodels.api.show_versions())

np.random.seed(0)
a = np.random.random(120)

b=np.zeros_like(a)
df1 = pd.DataFrame({'b': b, 'a': a})
df2 = pd.DataFrame({'a': a, 'b': b})

b=np.ones_like(a)
df3 = pd.DataFrame({'b': b, 'a': a})
df4 = pd.DataFrame({'a': a, 'b': b})

experimentDatasets = [df1, df2, df3, df4]

for experimentDataset in experimentDatasets:
    print('--------------------------------------------')
    print("experimentDataset=\n", experimentDataset)
    try:
        gc_res2 = grangercausalitytests(experimentDataset, 4, verbose=True)
    except Exception as e:

        print(traceback.format_exc())
        print('e', e)


print('fin')
```
#### output:
```
/home/user/venv/numba/bin/python3.6 /home/user/PycharmProjects/myProject/attic03.py
--------------------------------------------
experimentDataset=
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py:1400: RuntimeWarning: invalid value encountered in double_scalars
  * res2djoint.df_resid
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py:1421: RuntimeWarning: invalid value encountered in double_scalars
  fgc2 = res2down.nobs * (res2down.ssr - res2djoint.ssr) / res2djoint.ssr
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/regression/linear_model.py:903: RuntimeWarning: divide by zero encountered in log
  llf = -nobs2*np.log(2*np.pi) - nobs2*np.log(ssr / nobs) - nobs2
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py:1430: RuntimeWarning: invalid value encountered in double_scalars
  lr = -2 * (res2down.llf - res2djoint.llf)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 1, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1850: RuntimeWarning: invalid value encountered in true_divide
  F /= J
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 2, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 3, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 4, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
        b         a
0    0.0  0.548814
1    0.0  0.715189
2    0.0  0.602763
3    0.0  0.544883
4    0.0  0.423655
..   ...       ...
115  0.0  0.396506
116  0.0  0.881103
117  0.0  0.581273
118  0.0  0.881735
119  0.0  0.692532

[120 rows x 2 columns]

Granger Causality
number of lags (no zero) 1
ssr based F test:         F=nan     , p=nan     , df_denom=117, df_num=1
ssr based chi2 test:   chi2=nan     , p=nan     , df=1
likelihood ratio test: chi2=nan     , p=nan     , df=1
parameter F test:         F=nan     , p=nan     , df_denom=117, df_num=0

Granger Causality
number of lags (no zero) 2
ssr based F test:         F=nan     , p=nan     , df_denom=115, df_num=2
ssr based chi2 test:   chi2=nan     , p=nan     , df=2
likelihood ratio test: chi2=nan     , p=nan     , df=2
parameter F test:         F=nan     , p=nan     , df_denom=115, df_num=0

Granger Causality
number of lags (no zero) 3
ssr based F test:         F=nan     , p=nan     , df_denom=113, df_num=3
ssr based chi2 test:   chi2=nan     , p=nan     , df=3
likelihood ratio test: chi2=nan     , p=nan     , df=3
parameter F test:         F=nan     , p=nan     , df_denom=113, df_num=0

Granger Causality
number of lags (no zero) 4
ssr based F test:         F=nan     , p=nan     , df_denom=111, df_num=4
ssr based chi2 test:   chi2=nan     , p=nan     , df=4
likelihood ratio test: chi2=nan     , p=nan     , df=4
parameter F test:         F=nan     , p=nan     , df_denom=111, df_num=0
--------------------------------------------
experimentDataset=
             a    b
0    0.548814  0.0
1    0.715189  0.0
2    0.602763  0.0
3    0.544883  0.0
4    0.423655  0.0
..        ...  ...
115  0.396506  0.0
116  0.881103  0.0
117  0.581273  0.0
118  0.881735  0.0
119  0.692532  0.0

[120 rows x 2 columns]

Granger Causality
number of lags (no zero) 1
ssr based F test:         F=0.0000  , p=1.0000  , df_denom=117, df_num=1
ssr based chi2 test:   chi2=0.0000  , p=1.0000  , df=1
likelihood ratio test: chi2=-0.0000 , p=1.0000  , df=1
parameter F test:         F=nan     , p=nan     , df_denom=117, df_num=0

Granger Causality
number of lags (no zero) 2
ssr based F test:         F=0.0000  , p=1.0000  , df_denom=115, df_num=2
ssr based chi2 test:   chi2=0.0000  , p=1.0000  , df=2
likelihood ratio test: chi2=-0.0000 , p=1.0000  , df=2
parameter F test:         F=nan     , p=nan     , df_denom=115, df_num=0

Granger Causality
number of lags (no zero) 3
ssr based F test:         F=0.0000  , p=1.0000  , df_denom=113, df_num=3
ssr based chi2 test:   chi2=0.0000  , p=1.0000  , df=3
likelihood ratio test: chi2=-0.0000 , p=1.0000  , df=3
parameter F test:         F=nan     , p=nan     , df_denom=113, df_num=0

Granger Causality
number of lags (no zero) 4
ssr based F test:         F=-0.0000 , p=1.0000  , df_denom=111, df_num=4
ssr based chi2 test:   chi2=-0.0000 , p=1.0000  , df=4
likelihood ratio test: chi2=-0.0000 , p=1.0000  , df=4
parameter F test:         F=nan     , p=nan     , df_denom=111, df_num=0
--------------------------------------------
experimentDataset=
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 1, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1850: RuntimeWarning: invalid value encountered in true_divide
  F /= J
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 2, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 3, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py:1834: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 4, but rank is 0
  'rank is %d' % (J, J_), ValueWarning)
        b         a
0    1.0  0.548814
1    1.0  0.715189
2    1.0  0.602763
3    1.0  0.544883
4    1.0  0.423655
..   ...       ...
115  1.0  0.396506
116  1.0  0.881103
117  1.0  0.581273
118  1.0  0.881735
119  1.0  0.692532

[120 rows x 2 columns]

Granger Causality
number of lags (no zero) 1
ssr based F test:         F=-87.7500, p=1.0000  , df_denom=117, df_num=1
ssr based chi2 test:   chi2=-89.2500, p=1.0000  , df=1
likelihood ratio test: chi2=-164.9690, p=1.0000  , df=1
Traceback (most recent call last):
  File "/home/user/PycharmProjects/myProject/attic03.py", line 30, in <module>
    gc_res2 = grangercausalitytests(experimentDataset, 4, verbose=True)
  File "/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py", line 1442, in grangercausalitytests
    ftres = res2djoint.f_test(rconstr)
  File "/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py", line 1725, in f_test
    res = self.wald_test(r_matrix, cov_p=cov_p, invcov=invcov, use_f=True)
  File "/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py", line 1802, in wald_test
    LC = DesignInfo(names).linear_constraint(r_matrix)
  File "/home/user/venv/numba/lib/python3.6/site-packages/patsy/design_info.py", line 536, in linear_constraint
    return linear_constraint(constraint_likes, self.column_names)
  File "/home/user/venv/numba/lib/python3.6/site-packages/patsy/constraint.py", line 416, in linear_constraint
    return LinearConstraint(variable_names, coefs)
  File "/home/user/venv/numba/lib/python3.6/site-packages/patsy/constraint.py", line 57, in __init__
    raise ValueError("wrong shape for coefs")
ValueError: wrong shape for coefs

e wrong shape for coefs
--------------------------------------------
experimentDataset=
             a    b
0    0.548814  1.0
1    0.715189  1.0
2    0.602763  1.0
3    0.544883  1.0
4    0.423655  1.0
..        ...  ...
115  0.396506  1.0
116  0.881103  1.0
117  0.581273  1.0
118  0.881735  1.0
119  0.692532  1.0

[120 rows x 2 columns]

Granger Causality
number of lags (no zero) 1
ssr based F test:         F=0.0000  , p=1.0000  , df_denom=117, df_num=1
ssr based chi2 test:   chi2=0.0000  , p=1.0000  , df=1
likelihood ratio test: chi2=-0.0000 , p=1.0000  , df=1
Traceback (most recent call last):
  File "/home/user/PycharmProjects/myProject/attic03.py", line 30, in <module>
    gc_res2 = grangercausalitytests(experimentDataset, 4, verbose=True)
  File "/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/tsa/stattools.py", line 1442, in grangercausalitytests
    ftres = res2djoint.f_test(rconstr)
  File "/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py", line 1725, in f_test
    res = self.wald_test(r_matrix, cov_p=cov_p, invcov=invcov, use_f=True)
  File "/home/user/venv/numba/lib/python3.6/site-packages/statsmodels/base/model.py", line 1802, in wald_test
    LC = DesignInfo(names).linear_constraint(r_matrix)
  File "/home/user/venv/numba/lib/python3.6/site-packages/patsy/design_info.py", line 536, in linear_constraint
    return linear_constraint(constraint_likes, self.column_names)
  File "/home/user/venv/numba/lib/python3.6/site-packages/patsy/constraint.py", line 416, in linear_constraint
    return LinearConstraint(variable_names, coefs)
  File "/home/user/venv/numba/lib/python3.6/site-packages/patsy/constraint.py", line 57, in __init__
    raise ValueError("wrong shape for coefs")
ValueError: wrong shape for coefs

e wrong shape for coefs
fin

Process finished with exit code 1

```



Resolving patch:
diff --git a/statsmodels/tools/sm_exceptions.py b/statsmodels/tools/sm_exceptions.py
--- a/statsmodels/tools/sm_exceptions.py
+++ b/statsmodels/tools/sm_exceptions.py
@@ -231,6 +231,14 @@ class CollinearityWarning(ModelWarning):
     pass
 
 
+class InfeasibleTestError(RuntimeError):
+    """
+    Test statistic cannot be computed
+    """
+
+    pass
+
+
 recarray_warning = """\
 recarray support has been deprecated and will be removed after 0.12.  Please \
 use pandas DataFrames and Series for structured data.
diff --git a/statsmodels/tsa/stattools.py b/statsmodels/tsa/stattools.py
--- a/statsmodels/tsa/stattools.py
+++ b/statsmodels/tsa/stattools.py
@@ -16,6 +16,7 @@
 from statsmodels.regression.linear_model import OLS, yule_walker
 from statsmodels.tools.sm_exceptions import (
     CollinearityWarning,
+    InfeasibleTestError,
     InterpolationWarning,
     MissingDataError,
 )
@@ -1378,6 +1379,14 @@ def grangercausalitytests(x, maxlag, addconst=True, verbose=True):
         if addconst:
             dtaown = add_constant(dta[:, 1 : (mxlg + 1)], prepend=False)
             dtajoint = add_constant(dta[:, 1:], prepend=False)
+            if (
+                    dtajoint.shape[1] == (dta.shape[1] - 1)
+                    or (dtajoint.max(0) == dtajoint.min(0)).sum() != 1
+            ):
+                raise InfeasibleTestError(
+                    "The x values include a column with constant values and so"
+                    " the test statistic cannot be computed."
+                )
         else:
             raise NotImplementedError("Not Implemented")
             # dtaown = dta[:, 1:mxlg]
@@ -1393,6 +1402,21 @@ def grangercausalitytests(x, maxlag, addconst=True, verbose=True):
         # the other tests are made-up
 
         # Granger Causality test using ssr (F statistic)
+        if res2djoint.model.k_constant:
+            tss = res2djoint.centered_tss
+        else:
+            tss =res2djoint.centered_tss
+        if (
+                tss == 0
+                or res2djoint.ssr == 0
+                or np.isnan(res2djoint.rsquared)
+                or (res2djoint.ssr / tss) < np.finfo(float).eps
+                or res2djoint.params.shape[0] != dtajoint.shape[1]
+        ):
+            raise InfeasibleTestError(
+                "The Granger causality test statistic cannot be compute "
+                "because the VAR has a perfect fit of the data."
+            )
         fgc1 = (
             (res2down.ssr - res2djoint.ssr)
             / res2djoint.ssr


Test patch:
diff --git a/statsmodels/tsa/tests/test_stattools.py b/statsmodels/tsa/tests/test_stattools.py
--- a/statsmodels/tsa/tests/test_stattools.py
+++ b/statsmodels/tsa/tests/test_stattools.py
@@ -21,8 +21,9 @@
 from statsmodels.datasets import macrodata, modechoice, nile, randhie, sunspots
 from statsmodels.tools.sm_exceptions import (
     CollinearityWarning,
+    InfeasibleTestError,
     InterpolationWarning,
-    MissingDataError,
+    MissingDataError
 )
 from statsmodels.tsa.arima_process import arma_acovf
 from statsmodels.tsa.statespace.sarimax import SARIMAX
@@ -1214,3 +1215,21 @@ def test_coint_auto_tstat():
         return_results=False,
     )
     assert np.abs(res[0]) < 1.65
+
+
+rs = np.random.RandomState(1)
+a = rs.random_sample(120)
+b = np.zeros_like(a)
+df1 = pd.DataFrame({'b': b, 'a': a})
+df2 = pd.DataFrame({'a': a, 'b': b})
+
+b = np.ones_like(a)
+df3 = pd.DataFrame({'b': b, 'a': a})
+df4 = pd.DataFrame({'a': a, 'b': b})
+
+gc_data_sets = [df1, df2, df3, df4]
+
+@pytest.mark.parametrize("dataset",gc_data_sets)
+def test_granger_causality_exceptions(dataset):
+    with pytest.raises(InfeasibleTestError):
+        grangercausalitytests(dataset, 4)