Проверка статистической значимости желания британцев покинуть ЕС

По данным, представленным BBC, за выход Британии из ЕС проголосовали 17.410.742 чел. (51.9%), против - 16.141.241 (48.1%).

In [1]:
N_LEAVE, N_REMAIN = 17410742, 16141241
In [2]:
import numpy as np
referendum_results = np.array([1] * N_LEAVE + [0] * N_REMAIN)

Точечная оценка доли желающих покинуть ЕС:

In [3]:
np.mean(referendum_results)
Out[3]:
0.51891841981441156

Доверительный интервал на основе нормального распределения для доли желающих покинуть ЕС:

$$\hat{p}\pm z_{1-\frac{\alpha}{2}} \sqrt{\frac{\hat{p}\left(1-\hat{p}\right)}{n}}$$
In [4]:
from statsmodels.stats.proportion import proportion_confint

normal_interval = proportion_confint(np.sum(referendum_results), 
                                     referendum_results.shape[0], 
                                     method = 'normal')
print 'normal_interval [%f, %f] with width %f' % (normal_interval[0],
                                                  normal_interval[1], 
                                                  normal_interval[1] - 
                                                  normal_interval[0])
normal_interval [0.518749, 0.519087] with width 0.000338

У нас выборка большая, поэтому доверительный интервал Уилсона получается точно таким же.

$$\frac1{ 1 + \frac{z^2}{n} } \left( \hat{p} + \frac{z^2}{2n} \pm z \sqrt{ \frac{ \hat{p}\left(1-\hat{p}\right)}{n} + \frac{ z^2}{4n^2} } \right), \;\; z \equiv z_{1-\frac{\alpha}{2}}$$

In [5]:
wilson_interval = proportion_confint(np.sum(referendum_results), 
                                     referendum_results.shape[0],
                                     method = 'wilson')
print 'wilson_interval [%f, %f] with width %f' % (wilson_interval[0],
                                                  wilson_interval[1],
                                                  wilson_interval[1] - 
                                                  wilson_interval[0])
wilson_interval [0.518749, 0.519087] with width 0.000338

Одновыборочный критерий Стьюдента говорит о том, что отличие выборочного среднего от 0.5 статистически значимо.

In [6]:
from scipy.stats import ttest_1samp

ttest_1samp(referendum_results, 0.5)
Out[6]:
Ttest_1sampResult(statistic=219.32343584383185, pvalue=0.0)

Это же подтверждают критерий знаков, критерий знаковых рангов Вилкоксона и биномиальный критерий для доли:

In [7]:
from scipy.stats import wilcoxon, binom_test
from statsmodels.stats.descriptivestats import sign_test
In [8]:
sign_test(referendum_results, 0.5)
Out[8]:
(634750.5, 1.8774494541967369e-322)
In [9]:
wilcoxon(referendum_results - 0.5)
Out[9]:
WilcoxonResult(statistic=270785329886072.0, pvalue=0.0)
In [10]:
binom_test(N_LEAVE, N_LEAVE + N_REMAIN, 0.5, alternative = 'greater')
Out[10]:
0.0