Skip to content

Commit

Permalink
ENH/TST: add pred_table, adjust and add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
josef-pkt committed Sep 4, 2020
1 parent 11571a8 commit 1a16997
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 5 deletions.
2 changes: 1 addition & 1 deletion statsmodels/examples/ex_ordered_model.py
Expand Up @@ -24,7 +24,7 @@
print(np.bincount(y))

mod = OrderedModel(y, x)
start_params = np.ones(k_vars + 4)
# start_params = np.ones(k_vars + 4)
start_params = np.concatenate((np.ones(k_vars), np.arange(4)))
start_ppf = stats.norm.ppf((np.bincount(y) / len(y)).cumsum())
start_threshold = np.concatenate((start_ppf[:1],
Expand Down
18 changes: 17 additions & 1 deletion statsmodels/miscmodels/ordinal_model.py
Expand Up @@ -118,7 +118,7 @@ def _check_inputs(self, endog, exog):
exog_name = ([exog.name] if isinstance(exog, pd.Series)
else exog.columns.tolist())
names['xname'] = exog_name
exog = np.asarray(exog)
# exog = np.asarray(exog)

if isinstance(endog, pd.Series):
if isinstance(endog.dtypes, CategoricalDtype):
Expand Down Expand Up @@ -315,6 +315,22 @@ def fit(self, start_params=None, method='nm', maxiter=500, full_output=1,


class OrderedResults(GenericLikelihoodModelResults):

def pred_table(self):
"""prediction table
returns pandas DataFrame
"""
# todo: add category labels
categories = np.arange(self.model.k_levels)
observed = pd.Categorical(self.model.endog,
categories=categories, ordered=True)
predicted = pd.Categorical(self.predict().argmax(1),
categories=categories, ordered=True)
table = pd.crosstab(observed, predicted, margins=True, dropna=False)
return table

@Appender(GenericLikelihoodModelResults.summary.__doc__)
def summary(self, yname=None, xname=None, title=None, alpha=.05):
names = self.model.names
Expand Down
Empty file.
33 changes: 30 additions & 3 deletions statsmodels/miscmodels/tests/test_ordinal_model.py
Expand Up @@ -5,7 +5,7 @@
import numpy as np
import scipy.stats as stats

from numpy.testing import assert_allclose
from numpy.testing import assert_allclose, assert_equal
from .results.results_ordinal_model import data_store as ds
from statsmodels.miscmodels.ordinal_model import OrderedModel

Expand Down Expand Up @@ -70,6 +70,27 @@ def test_unordered(self):
assert_allclose(res1.model.endog, resf.model.endog, rtol=1e-10)
assert_allclose(res1.model.exog, resf.model.exog, rtol=1e-10)

def test_results_other(self):

res1 = self.res1

# results
if hasattr(self, "pred_table"):
table = res1.pred_table()
assert_equal(table.values, self.pred_table)

# smoke test
res1.summary()

# inherited
tt = res1.t_test(np.eye(len(res1.params)))
assert_allclose(tt.pvalue, res1.pvalues, rtol=1e-13)
# TODO: test using string definition of constraints

pred = res1.predict(exog=res1.model.exog[-5:])
fitted = res1.predict()
assert_allclose(pred, fitted[-5:], rtol=1e-13)


class TestLogitModel(CheckOrdinalModelMixin):

Expand Down Expand Up @@ -151,6 +172,12 @@ def setup_class(cls):
cls.resf = resf
cls.resu = resu

# regression numbers
cls.pred_table = np.array([[202, 18, 0, 220],
[112, 28, 0, 140],
[ 27, 13, 0, 40], # noqa
[341, 59, 0, 400]], dtype=np.int64)

def test_loglikerelated(self):

res1 = self.res1
Expand All @@ -161,8 +188,8 @@ def test_loglikerelated(self):
score1 = mod.score(res1.params * fact)
score_obs_numdiff = mod.score_obs(res1.params * fact)
score_obs_exog = mod.score_obs_(res1.params * fact)
assert_allclose(score_obs_numdiff.sum(0), score1, rtol=1e-8)
assert_allclose(score_obs_exog.sum(0), score1[:mod.k_vars], rtol=1e-7)
assert_allclose(score_obs_numdiff.sum(0), score1, atol=1e-7)
assert_allclose(score_obs_exog.sum(0), score1[:mod.k_vars], atol=1e-7)

# null model
mod_null = OrderedModel(mod.endog, None,
Expand Down

0 comments on commit 1a16997

Please sign in to comment.