def test_logit(simulated_problem: SimulatedProblemFixture, method: str, center_moments: bool, W_type: str, se_type: str) -> (None): """Test that Logit estimates are the same as those from the the linearmodels package.""" _, simulation_results, problem, _, _ = simulated_problem product_data = simulation_results.product_data # skip more complicated simulations if problem.K2 > 0 or problem.K3 > 0 or problem.H > 0: return # solve the problem results1 = problem.solve(method=method, center_moments=center_moments, W_type=W_type, se_type=se_type) # compute the delta from the logit problem delta = np.log(product_data.shares) for t in problem.unique_market_ids: shares_t = product_data.shares[product_data.market_ids == t] delta[product_data.market_ids == t] -= np.log(1 - shares_t.sum()) # configure covariance options W_options = { 'clusters': product_data.clustering_ids } if W_type == 'clustered' else {} se_options = { 'clusters': product_data.clustering_ids } if se_type == 'clustered' else {} # monkey-patch a problematic linearmodels method that shouldn't be called but is anyways linearmodels.IVLIML._estimate_kappa = lambda _: 1 # solve the problem with linearmodels model = linearmodels.IVGMM(delta, exog=None, endog=problem.products.X1, instruments=problem.products.ZD, center=center_moments, weight_type=W_type, **W_options) results2 = model.fit(iter_limit=1 if method == '1s' else 2, cov_type=se_type, **se_options) # test that results are essentially identical for key1, key2 in [('beta', 'params'), ('xi', 'resids'), ('beta_se', 'std_errors')]: values1 = getattr(results1, key1) values2 = np.c_[getattr(results2, key2)] np.testing.assert_allclose(values1, values2, atol=1e-10, rtol=1e-8, err_msg=key1)
def test_logit( simulated_problem: SimulatedProblemFixture, method: str, center_moments: bool, W_type: str, se_type: str) -> ( None): """Test that Logit estimates are the same as those from the the linearmodels package.""" _, simulation_results, problem, _, _ = simulated_problem product_data = simulation_results.product_data # skip more complicated simulations if problem.K2 > 0 or problem.K3 > 0 or problem.H > 0: return pytest.skip("This simulation cannot be tested against linearmodels.") # solve the problem results1 = problem.solve(method=method, center_moments=center_moments, W_type=W_type, se_type=se_type) # compute the delta from the logit problem delta = np.log(product_data.shares) for t in problem.unique_market_ids: shares_t = product_data.shares[product_data.market_ids == t] delta[product_data.market_ids == t] -= np.log(1 - shares_t.sum()) # configure covariance options W_options = {'clusters': product_data.clustering_ids} if W_type == 'clustered' else {} se_options = {'clusters': product_data.clustering_ids} if se_type == 'clustered' else {} # monkey-patch a problematic linearmodels method that shouldn't be called but is anyways linearmodels.IVLIML._estimate_kappa = lambda _: 1 # solve the problem with linearmodels model = linearmodels.IVGMM( delta, exog=None, endog=problem.products.X1, instruments=problem.products.ZD, center=center_moments, weight_type=W_type, **W_options ) results2 = model.fit(iter_limit=1 if method == '1s' else 2, cov_type=se_type, **se_options) # test that results are essentially identical (unadjusted second stage standard errors will be different because # linearmodels still constructs a S matrix) for key1, key2 in [('beta', 'params'), ('xi', 'resids'), ('beta_se', 'std_errors')]: if not (se_type == 'unadjusted' and key1 == 'beta_se'): values1 = getattr(results1, key1) values2 = np.c_[getattr(results2, key2)] np.testing.assert_allclose(values1, values2, atol=1e-10, rtol=1e-8, err_msg=key1) # test that test statistics in the second stage (when they make sense) are essentially identical if method == '2s' and se_type != 'unadjusted': nonconstant = (problem.products.X1[0] != problem.products.X1).any(axis=0) F1 = results1.run_wald_test(results1.parameters[nonconstant], np.eye(results1.parameters.size)[nonconstant]) J1 = results1.run_hansen_test() F2 = results2.f_statistic.stat J2 = results2.j_stat.stat np.testing.assert_allclose(F1, F2, atol=1e-10, rtol=1e-8) np.testing.assert_allclose(J1, J2, atol=1e-10, rtol=1e-8)