예제 #1
0
def test_summary():
    """
    Ensures that calls to summary when the model has not been fit warns the
    user
    """
    model = MultinomialLogit()
    with pytest.warns(UserWarning):
        model.summary()
예제 #2
0
def test__bfgs_optimization():
    """
    Ensure that the bfgs optimization properly processes the input for one
    iteration. The value of 0.276999 was computed by hand for
    comparison purposes
    """
    X_, y_ = X.reshape(N, J, K), y.reshape(N, J)
    betas = np.array([.1, .1])
    model = MultinomialLogit()
    res = model._bfgs_optimization(betas, X_, y_, None, None, 0, 1e-5)

    assert res['fun'] == approx(0.276999)
예제 #3
0
def test_predict():
    """
    Computes predictions "by hand" for a simple example and ensures that the
    probabilities returned by xlogit are the same
    """
    X_ = X.reshape(N, J, K)
    betas = np.array([.1, .1])

    #=== 1. Compute predictions using xlogit
    model = MultinomialLogit()
    model.alternatives = np.array([1, 2])
    model.coeff_ = betas
    model._isvars, model._asvars, model._varnames = [], varnames, varnames
    model._fit_intercept = False
    model.coeff_names = np.array(["a", "b", "sd.a", "sd.b"])
    ypred, proba, freq = model.predict(X,
                                       varnames,
                                       alts,
                                       ids,
                                       return_proba=True,
                                       return_freq=True)

    #=== 2. Compute predictions by hand
    eXB = np.exp(X_.dot(betas))
    expec_proba = eXB / np.sum(eXB, axis=1, keepdims=True)
    expec_ypred = model.alternatives[np.argmax(expec_proba, axis=1)]
    alt_list, counts = np.unique(expec_ypred, return_counts=True)
    expec_freq = dict(
        zip(list(alt_list), list(np.round(counts / np.sum(counts), 3))))
    #=== 3. Assert predictions are the same
    assert np.allclose(expec_proba, proba)
    assert np.array_equal(expec_ypred, ypred)
    assert expec_freq == freq
예제 #4
0
def test__setup_design_matrix():
    """
    Ensures that xlogit properly adds an intercept when necessary

    """
    model = MultinomialLogit()
    model._pre_fit(alts,
                   varnames,
                   isvars=None,
                   base_alt=None,
                   fit_intercept=True,
                   maxiter=0)
    X_, Xnames_ = model._setup_design_matrix(X)
    assert X_.shape == (3, 2, 3)
    assert list(Xnames_) == ["_intercept.2", "a", "b"]
예제 #5
0
def test_fit():
    """
    Ensures the log-likelihood works for a single iterations with the default
    initial coefficients. The value of 0.4044 was computed by hand for
    comparison purposes
    """
    model = MultinomialLogit()
    model.fit(X,
              y,
              varnames=varnames,
              alts=alts,
              ids=ids,
              maxiter=0,
              verbose=0)

    assert model.loglikelihood == approx(-0.40443136)
예제 #6
0
def test_log_likelihood():
    """
    Computes the log-likelihood "by hand" for a simple example and ensures
    that the one returned by xlogit is the same
    """
    X_, y_ = X.reshape(N, J, K), y.reshape(N, J)
    betas = np.array([.1, .1])

    # Compute log likelihood using xlogit
    model = MultinomialLogit()
    obtained_loglik = model._loglik_gradient(betas, X_, y_, None, None)

    # Compute expected log likelihood "by hand"
    eXB = np.exp(X_.dot(betas))
    expected_loglik = -np.sum(
        np.log(np.sum(eXB / np.sum(eXB, axis=1, keepdims=True) * y_, axis=1)))

    assert obtained_loglik == approx(expected_loglik)
예제 #7
0
def test__format_choice_var():
    """
    Ensures that the variable y is properly formatted as needed by internal 
    procedures regardless of the input data type.
    """
    model = MultinomialLogit()
    expected = np.array([1, 0, 0, 1, 1, 0])

    y1 = np.array([1, 1, 2, 2, 1, 1])
    assert np.array_equal(model._format_choice_var(y1, alts), expected)

    y2 = np.array(['a', 'a', 'b', 'b', 'a', 'a'])
    alts2 = np.array([
        'a',
        'b',
        'a',
        'b',
        'a',
        'b',
    ])
    assert np.array_equal(model._format_choice_var(y2, alts2), expected)
예제 #8
0
def test__validate_inputs():
    """
    Covers potential mistakes in parameters of the fit method that xlogit
    should be able to identify
    """
    model = MultinomialLogit()
    validate = model._validate_inputs
    with pytest.raises(ValueError):  # match between columns in X and varnames
        validate(X,
                 y,
                 alts,
                 varnames=["a"],
                 isvars=None,
                 ids=ids,
                 weights=None)

    with pytest.raises(ValueError):  # alts can't be None
        validate(X,
                 y,
                 None,
                 varnames=varnames,
                 isvars=None,
                 ids=ids,
                 weights=None)

    with pytest.raises(ValueError):  # varnames can't be None
        validate(X, y, alts, varnames=None, isvars=None, ids=ids, weights=None)

    with pytest.raises(ValueError):  # X dimensions
        validate(np.array([]),
                 y,
                 alts,
                 varnames=None,
                 isvars=None,
                 ids=ids,
                 weights=None)

    with pytest.raises(ValueError):  # y dimensions
        validate(X,
                 np.array([]),
                 alts,
                 varnames=None,
                 isvars=None,
                 ids=ids,
                 weights=None)