99from scipy import stats
1010from statsmodels .regression .linear_model import RegressionResults
1111from statsmodels .regression .mixed_linear_model import MixedLMResults
12+ from statsmodels .stats .anova import anova_lm
1213
1314
1415def ols_from_model (
@@ -106,6 +107,7 @@ def likelihood_ratio_test(
106107 )
107108
108109 # first analysis: mixed vs. fixed effects for type + base_type
110+ # TODO: refactor this into its own method?
109111
110112 mixed_model_results = mixed_lm_from_model (
111113 model ,
@@ -136,15 +138,63 @@ def likelihood_ratio_test(
136138 "convexity_qmw ~ type + base_type + optimality + complexity + accuracy" ,
137139 data = model ,
138140 )
139- print (big_model .fit ().summary ())
141+ big_model_result = big_model .fit ()
142+ print (big_model_result .summary ())
140143
141- big_model = smf .ols (
142- "convexity_qmw ~ type + base_type + optimality * complexity * accuracy" ,
144+ interaction_model = smf .ols (
145+ "convexity_qmw ~ type + base_type + optimality * complexity * accuracy" ,
143146 data = model ,
144147 )
145- big_model_result = big_model .fit ()
146- print (big_model_result .summary ())
148+ interaction_model_result = interaction_model .fit ()
149+ print (interaction_model_result .summary ())
150+
151+ print (anova_lm (big_model_result , interaction_model_result ))
152+ print (anova_lm (interaction_model_result ))
153+
154+ interaction_mixed_model = smf .mixedlm (
155+ "convexity_qmw ~ type + base_type + optimality * complexity * accuracy" ,
156+ data = model ,
157+ groups = model ["base_item_id" ],
158+ )
159+ interaction_mixed_model_result = interaction_mixed_model .fit (reml = False )
160+ print (interaction_mixed_model_result .summary ())
161+ lr_stat , p_value , df = likelihood_ratio_test (
162+ interaction_mixed_model_result , interaction_model_result
163+ )
164+ print (f"Likelihood Ratio Test: χ²(1) = { lr_stat :.3f} , p = { p_value :.4g} " )
147165
166+ medium_model = ols_from_model (
167+ model ,
168+ dependent_var = "convexity_qmw" ,
169+ independent_vars = ("optimality" , "complexity" , "accuracy" ),
170+ interactions = True ,
171+ )
172+ print (anova_lm (medium_model , interaction_model_result ))
173+
174+ medium_mixed_model = mixed_lm_from_model (
175+ model ,
176+ dependent_var = "convexity_qmw" ,
177+ independent_vars = ("optimality" , "complexity" , "accuracy" ),
178+ interactions = True ,
179+ groups_col = "base_item_id" ,
180+ )
181+ lr_stat , p_value , df = likelihood_ratio_test (medium_mixed_model , medium_model )
182+ print (f"Likelihood Ratio Test: χ²(1) = { lr_stat :.3f} , p = { p_value :.4g} " )
183+
184+ print ("\n \n AIC \t \t BIC \n " )
185+ print (f"Big OLS Model: \t { big_model_result .aic :.2f} \t { big_model_result .bic :.2f} " )
186+ print (f"Medium OLS Model: { medium_model .aic :.2f} \t { medium_model .bic :.2f} " )
187+ print (
188+ f"Medium Mixed Model: { medium_mixed_model .aic :.2f} \t { medium_mixed_model .bic :.2f} "
189+ )
190+ print (
191+ f"Interaction OLS Model: { interaction_model_result .aic :.2f} \t { interaction_model_result .bic :.2f} "
192+ )
193+ print (
194+ f"Interaction Mixed Model: { interaction_mixed_model_result .aic :.2f} \t { interaction_mixed_model_result .bic :.2f} "
195+ )
196+
197+ """
148198 # --- Define ranges for your predictors ---
149199 opt_range = np.linspace(model["optimality"].min(), model["optimality"].max(), 100)
150200 comp_levels = np.linspace(
@@ -156,7 +206,6 @@ def likelihood_ratio_test(
156206
157207 # --- Helper: predict convexity from fitted model ---
158208 def predict_convexity(opt, comp, acc):
159- """Use big_model_result.predict() for consistent term handling."""
160209 df = pd.DataFrame(
161210 {
162211 "optimality": opt,
@@ -306,3 +355,4 @@ def predict_convexity(opt, comp, acc):
306355 ax.legend(loc="best", fontsize=8, ncol=2)
307356 plt.tight_layout()
308357 plt.show()
358+ """
0 commit comments