Вычислить доверительный интервал из выборочных данных, предполагая, что распределение неизвестно.

У меня есть образцы данных, для которых я хотел бы вычислить доверительный интервал, предполагая, что распределение не является нормальным и неизвестно. По сути, похоже, что дистрибутив Парето  Гистограмма распределения , но я не знаю наверняка.

Ответы на нормальное распределение:

Вычислить доверительный интервал на основе выборочных данных

Правильный способ получения доверительного интервала с помощью scipy


person Brans Ds    schedule 06.06.2017    source источник


Ответы (4)


Если вы не знаете базовый дистрибутив, то моей первой мыслью было бы использовать начальную загрузку: https://en.wikipedia.org/wiki/Bootstrapping_(statistics)

В псевдокоде, если x является массивом numpy, содержащим ваши данные:

import numpy as np
N = 10000
mean_estimates = []
for _ in range(N):
    re_sample_idx = np.random.randint(0, len(x), x.shape)
    mean_estimates.append(np.mean(x[re_sample_idx]))

mean_estimates теперь представляет собой список из 10000 оценок среднего значения распределения. Возьмите 2,5-й и 97,5-й процентили этих 10000 значений, и у вас будет доверительный интервал вокруг среднего значения ваших данных:

sorted_estimates = np.sort(np.array(mean_estimates))
conf_interval = [sorted_estimates[int(0.025 * N)], sorted_estimates[int(0.975 * N)]]
person acdr    schedule 06.06.2017
comment
Я проверил с реальными данными .. похоже не так. Я получил Conf Int: [22.78, 69.93]. (np.array (x) ‹22,79) .sum () / len (x) - 0,91. 91% данных ниже нижней границы подтверждения. Среднее арифметическое составляет 40,78 - это сложный набор данных в реальном мире. - person Brans Ds; 06.06.2017

Исходя из обсуждения другого ответа, я предполагаю, что вам нужен доверительный интервал для среднего значения генеральной совокупности, да? (У вас должен быть доверительный интервал для некоторого количества, а не самого распределения.)

Для всех распределений с конечными моментами выборочное распределение среднего асимптотически стремится к нормальному распределению со средним значением, равным среднему значению генеральной совокупности, и дисперсией, равной дисперсии генеральной совокупности, деленной на n. Поэтому, если у вас много данных, $ \ mu \ pm \ Phi ^ {- 1} (p) \ sigma / \ sqrt {n} $ должно быть хорошим приближением к p-доверительному интервалу среднего генерального значения, даже если раздача не нормальная.

person David Wright    schedule 07.06.2017

вы можете использовать бутстрап для аппроксимации КАЖДОГО количества, также поступающего из НЕИЗВЕСТНЫХ дистрибутивов

def bootstrap_ci(
    data, 
    statfunction=np.average, 
    alpha = 0.05, 
    n_samples = 100):

    """inspired by https://github.com/cgevans/scikits-bootstrap"""
    import warnings

    def bootstrap_ids(data, n_samples=100):
        for _ in range(n_samples):
            yield np.random.randint(data.shape[0], size=(data.shape[0],))    
    
    alphas = np.array([alpha/2, 1 - alpha/2])
    nvals = np.round((n_samples - 1) * alphas).astype(int)
    if np.any(nvals < 10) or np.any(nvals >= n_samples-10):
        warnings.warn("Some values used extremal samples; results are probably unstable. "
                      "Try to increase n_samples")

    data = np.array(data)
    if np.prod(data.shape) != max(data.shape):
        raise ValueError("Data must be 1D")
    data = data.ravel()
    
    boot_indexes = bootstrap_ids(data, n_samples)
    stat = np.asarray([statfunction(data[_ids]) for _ids in boot_indexes])
    stat.sort(axis=0)

    return stat[nvals]

смоделировать некоторые данные из распределения Парето

np.random.seed(33)
data = np.random.pareto(a=1, size=111)
sample_mean = np.mean(data)

plt.hist(data, bins=25)
plt.axvline(sample_mean, c='red', label='sample mean'); plt.legend()

введите описание изображения здесь

генерировать доверительные интервалы для SAMPLE MEAN с начальной загрузкой

low_ci, up_ci = bootstrap_ci(data, np.mean, n_samples=1000)

подготовить результаты

plt.hist(data, bins=25)
plt.axvline(low_ci, c='orange', label='low_ci mean')
plt.axvline(up_ci, c='magenta', label='up_ci mean')
plt.axvline(sample_mean, c='red', label='sample mean'); plt.legend()

введите описание изображения здесь

генерировать доверительные интервалы для ПАРАМЕТРОВ РАСПРЕДЕЛЕНИЯ с начальной загрузкой

from scipy.stats import pareto

true_params = pareto.fit(data)
low_ci, up_ci = bootstrap_ci(data, pareto.fit, n_samples=1000)

low_ci[0] и up_ci[0] - доверительные интервалы для параметра формы.

low_ci[0], true_params[0], up_ci[0] ---> (0.8786, 1.0983, 1.4599)
person Marco Cerliani    schedule 02.02.2021

Текущее решение не сработало, потому что randint, похоже, устарел

np.random.seed(10)
point_estimates = []         # Make empty list to hold point estimates

for x in range(200):         # Generate 200 samples
    sample = np.random.choice(a= x, size=x.shape)
    point_estimates.append( sample.mean() )
sorted_estimates = np.sort(np.array(point_estimates))
conf_interval = [sorted_estimates[int(0.025 * N)], sorted_estimates[int(0.975 * N)]]
print(conf_interval, conf_interval[1] - conf_interval[0])
pd.DataFrame(point_estimates).plot(kind="density", legend= False)
person Rocketq    schedule 17.09.2018