F-tests can be two-tailed (to test that $s_1^2 ne s_2^2$) or one-tailed (to test that $s_1^2 > s_2^2$).
How can I modify Levene/Brown-Forsythe to be “one-tailed”, that is, to test $s_1^2 > s_2^2$ instead of $s_1^2 ne s_2^2$?
Here is a demo:
The image shows normally distributed training data (n=1000) and a model. An F-test is used to compare the variance of one point’s residuals (n=2) to the variance of all of the residuals (n=2000), so the point is an outlier if its residual variance is “too large.” The points are colored by p-value, where light points fit the model and dark points are outliers, and you can see that the two-tailed Brown-Forsythe rejects points that are too close to the model as well as too far.
Note: A different non-parametric, one-sided variance test would be fine as well.
Glen_b gave the information I needed, but I thought I would leave some implementation details (using scipy).
#basic F-test F = var(a) / var(b) Fp = stats.f.sf(F, df1, df2) #Brown Forsythe BF, BFp = stats.levene(a, b, center='median') #two tailed t-test on transformed data za = abs(a-median(a)) zb = abs(b-median(b)) t, tp_two_tailed = stats.ttest_ind(za, zb) #the two tailed t test recapitulates the BF test assert(t**2 == BF) assert(p_BF == p_two_tailed) #one tailed t test p value tp = stats.t.sf(t, df)
Above shows scatter plots of the p values from the one-tailed $F$-test and two-tailed BF-test (left), and the one-tailed $t$ tests (right). Red points are “too close” ($s_1^2 < s_2^2$).