Repository: statsmodels/statsmodels

Issue:
t_test ... after ARMA
are they supposed to work, are there any substitutes?

```
>>> res.t_test(np.eye(len(res.params)))
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    res.t_test(np.eye(len(res.params)))
  File "e:\josef\eclipsegworkspace\statsmodels-git\statsmodels-all-new2\statsmodels\statsmodels\base\model.py", line 1137, in t_test
    raise ValueError('Need covariance of parameters for computing '
ValueError: Need covariance of parameters for computing T statistics
```

```
>>> res.cov_params()
                const  ar.L1.D.cpi  ma.L1.D.cpi
const        0.042359    -0.001674     0.002629
ar.L1.D.cpi -0.001674     0.002089    -0.003507
ma.L1.D.cpi  0.002629    -0.003507     0.008056

>>> res._results.cov_params()
array([[ 0.04235854, -0.00167449,  0.00262911],
       [-0.00167449,  0.00208857, -0.00350679],
       [ 0.00262911, -0.00350679,  0.0080562 ]])

>>> res.t_test(np.eye(len(res.params)), cov_p=res._results.cov_params())
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    res.t_test(np.eye(len(res.params)), cov_p=res._results.cov_params())
  File "e:\josef\eclipsegworkspace\statsmodels-git\statsmodels-all-new2\statsmodels\statsmodels\base\model.py", line 1159, in t_test
    r_matrix=r_matrix, cov_p=cov_p)))
TypeError: cov_params() got an unexpected keyword argument 'r_matrix'
```

I would have expected the last case to work, maybe a problem in base.



Discussion:
The last exception is because ARMA overwrites the cov_params of LikelihoodModelResults. (Passing a cov_p works with OLS)
Looks like ARMA.cov_params should actually be cached as normalized_cov_params to be consistent with the other LikelihoodModels.

It looks like the same problem for `f_test`
http://stackoverflow.com/questions/35958857/python-and-statsmodels-how-to-evaluate-the-f-test-of-joint-parameters-in-arma-m

check the status here, either fix or close if fixed
t_test is still broken in master

```
>>> res_arma
<statsmodels.tsa.arima_model.ARMAResultsWrapper object at 0x0000000009ABA8D0>
>>> res_arma.t_test(np.eye(len(res_arma.params)))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "...\statsmodels\base\model.py", line 1274, in t_test
ValueError: Need covariance of parameters for computing T statistics
    raise ValueError('Need covariance of parameters for computing '
```

in ARMAResults

```
    @cache_readonly
    def bse(self):
        params = self.params
        hess = self.model.hessian(params)
        if len(params) == 1:  # can't take an inverse, ensure 1d
            return np.sqrt(-1./hess[0])
        return np.sqrt(np.diag(-inv(hess)))

    def cov_params(self):  # add scale argument?
        params = self.params
        hess = self.model.hessian(params)
        return -inv(hess)
```

I think there is no easy "quick-fix". 
or maybe
- rename cov_params to cov_params_default and make it into a cached property
- tvalues is inherited, pvalues are overwritten but look generic with hardcode t-distribution

BUG: in cov_params if repeated fit with different `method`
hessian is computed using numerical diff of loglike which depends on method which is attached to the model, and the `method` attribute is set and changed in fit.
(Asymptotically the `method` shouldn't matter, and either cov_params should be consistent.)

Fixing the stateful attribute in the model class will need more work and unit tests. e.g. attach method to results instance but loglike will need a method keyword argument. 
An immediate fix for bse/cov_params is to compute them in `Results.__init__` as in other models.

postponed to 0.10
Still a bug.
> BUG: in cov_params if repeated fit with different method
hessian is computed using numerical diff of loglike which depends on method which is attached to the model, and the method attribute is set and changed in fit.
(Asymptotically the method shouldn't matter, and either cov_params should be consistent.)

This is fixed in master.  Models can no longer be refit with configurations that fundamentally alter the model. Might want to attach copy(self) to results instances for safety. 

Resolving patch:
diff --git a/statsmodels/tsa/ar_model.py b/statsmodels/tsa/ar_model.py
--- a/statsmodels/tsa/ar_model.py
+++ b/statsmodels/tsa/ar_model.py
@@ -1,4 +1,6 @@
 # -*- coding: utf-8 -*-
+import copy
+
 import numpy as np
 from numpy.linalg import inv, slogdet
 from scipy.stats import norm
@@ -593,7 +595,7 @@ def fit(self, maxlag=None, method='cmle', ic=None, trend='c',
 
         pinv_exog = np.linalg.pinv(X)
         normalized_cov_params = np.dot(pinv_exog, pinv_exog.T)
-        arfit = ARResults(self, params, normalized_cov_params)
+        arfit = ARResults(copy.copy(self), params, normalized_cov_params)
         if method == 'mle' and full_output:
             arfit.mle_retvals = mlefit.mle_retvals
             arfit.mle_settings = mlefit.mle_settings
diff --git a/statsmodels/tsa/arima_model.py b/statsmodels/tsa/arima_model.py
--- a/statsmodels/tsa/arima_model.py
+++ b/statsmodels/tsa/arima_model.py
@@ -4,6 +4,7 @@
 #       This code does not allow this, but it adds consistency with other
 #       packages such as gretl and X12-ARIMA
 
+import copy
 from datetime import datetime
 
 import numpy as np
@@ -12,7 +13,7 @@
 from numpy.linalg import inv
 from scipy import optimize
 from scipy.signal import lfilter
-from scipy.stats import t, norm
+from scipy.stats import norm
 
 import statsmodels.base.wrapper as wrap
 from statsmodels.regression.linear_model import yule_walker, OLS
@@ -1008,7 +1009,7 @@ def fit(self, start_params=None, trend='c', method="css-mle",
         self.transparams = False  # so methods do not expect transf.
 
         normalized_cov_params = None  # TODO: fix this
-        armafit = ARMAResults(self, params, normalized_cov_params)
+        armafit = ARMAResults(copy.copy(self), params, normalized_cov_params)
         armafit.mle_retvals = mlefit.mle_retvals
         armafit.mle_settings = mlefit.mle_settings
         # Save core fit parameters for future checks
@@ -1494,9 +1495,9 @@ def bse(self):
             return np.sqrt(-1. / hess[0])
         return np.sqrt(np.diag(-inv(hess)))
 
-    def cov_params(self):  # add scale argument?
-        params = self.params
-        hess = self.model.hessian(params)
+    @cache_readonly
+    def cov_params_default(self):
+        hess = self.model.hessian(self.params)
         return -inv(hess)
 
     @cache_readonly
@@ -1532,12 +1533,6 @@ def fittedvalues(self):
     def resid(self):
         return self.model.geterrors(self.params)
 
-    @cache_readonly
-    def pvalues(self):
-        # TODO: same for conditional and unconditional?
-        df_resid = self.df_resid
-        return t.sf(np.abs(self.tvalues), df_resid) * 2
-
     def predict(self, start=None, end=None, exog=None, dynamic=False,
                 **kwargs):
         return self.model.predict(self.params, start, end, exog, dynamic,


Test patch:
diff --git a/statsmodels/tsa/tests/test_arima.py b/statsmodels/tsa/tests/test_arima.py
--- a/statsmodels/tsa/tests/test_arima.py
+++ b/statsmodels/tsa/tests/test_arima.py
@@ -2699,3 +2699,22 @@ def test_arima_repeated_fit():
     assert_allclose(res.params, repeat.params)
     assert isinstance(res.summary().as_text(), str)
     assert isinstance(repeat.summary().as_text(), str)
+
+
+def test_arma_ttest_ftest():
+    # GH947
+    ar, ma = [1, -0.5], [1., 0.4]
+    x = 2 + fa.ArmaFft(ar, ma, 40).generate_sample(nsample=1000, burnin=100)
+    arma = ARMA(x, (1, 1))
+    res = arma.fit(disp=-1)
+    r = np.array([0, 1, 1])
+    t_test = res.t_test(r)
+    c = res.cov_params()
+    v = r @ c @ r
+    numerator = res.params @ r
+    denom = np.sqrt(v)
+    stat = numerator / denom
+    assert_allclose(stat, t_test.statistic)
+
+    f_test = res.f_test(r)
+    assert_allclose(stat**2, f_test.statistic)