Към съдържанието
wannacode

Доверителен интервал

Накратко: Доверителният интервал е диапазон около стойността от извадката, който при 95% хваща истинската стойност в около 95 от 100 извадки; bootstrap го строи с повторни извадки с връщане.

Проблем

„Колко харчи клиентът на поръчка?“

Управителят пита колко е средната поръчка. В живота рядко имаш всичко: да кажем, че имаш 200 поръчки, изтеглени случайно от годината. Тук имаме и цялата година, 10 459 поръчки без отказаните, и можем да видим какво става:

Pythonданни: таблиците на магазина

Три извадки по 200 дават три различни средни: 9,77 €, 10,74 € и 11,16 €. От урока за извадките знаеш, че средната шуми. Но ти имаш само една извадка. Какво казваш на управителя: едно число или нещо повече?

По-честно е да кажеш „средната е някъде между … и … €“. Остава да разбереш колко широко да е това „някъде“, само от извадката, която имаш.

Идеята

Извадката вместо годината: bootstrap

Ако можеше да теглиш нови извадки от годината, щеше да видиш колко се люшка средната. Не можеш. Затова използваш извадката като умалена година: теглиш от нея 200 поръчки с връщане и смяташ средната. Това е повторна извадка (resample). Някоя поръчка се пада два пъти, друга никак, и средната е малко по-различна всеки път.

Правиш го 10 000 пъти и гледаш къде са средните. Отрязваш 2,5% от най-малките и 2,5% от най-големите. Средните 95% са доверителният интервал (confidence interval). Методът се казва bootstrap:

Pythonданни: таблиците на магазина

Първите 8 поръчки от извадката са от 0,90 до 45,20 €. Първите три повторни извадки дават средни 10,07 €, 11,07 € и 11,13 €. Средната на извадката е 11,41 €, а 95% интервалът е от 10,04 до 12,83 €. Истинската средна на годината е 10,63 €: вътре е.

rng.choice(sample, size=(10_000, 200)) е таблица 10 000 × 200: всеки ред е една повторна извадка. mean(axis=1) дава по една средна на ред. Цикъл не трябва.

Виж го

Как от една извадка се ражда интервал

Същият код бавно: плочки от извадката се копират в повторна извадка, средната ѝ пада на оста, а 10 000 такива средни правят купчина.

import numpy as np
import pandas as pd
orders = pd.read_csv('year_orders.csv')
items = pd.read_csv('year_items.csv')
cancelled = orders.loc[orders['status'] == 'cancelled', 'id']
items = items[~items['order_id'].isin(cancelled)]
items['revenue'] = items['quantity'] * items['unit_price']
totals = items.groupby('order_id')['revenue'].sum()
rng = np.random.default_rng(42)
sample = rng.choice(totals.to_numpy(), size=200, replace=False)
print(sample[:8])
boots = rng.choice(sample, size=(10_000, 200)).mean(axis=1)
print(boots[:3].round(2))
low, high = np.quantile(boots, [0.025, 0.975])
print(round(sample.mean(), 2), round(low, 2), round(high, 2))
print(round(totals.mean(), 2))
Стъпка по стъпка, с думи
  1. totals е стойността на всяка поръчка за годината. В живота цялото не го виждаш: имаш само извадка.
  2. sample е извадка от 200 поръчки. Горе са първите 8, в евро: 3,6; 0,9; 2,1; 17; 45,2; 13,2; 3,4 и 2.
  3. Повторна извадка: 200 тегления от sample с връщане. Някоя поръчка се пада два пъти, друга изобщо не.
  4. Средната на повторната извадка пада като точка на оста. Първите три са 10,07 €, 11,07 € и 11,13 €.
  5. Така 10 000 пъти. Точките се трупат около средната на извадката, 11,41 €.
  6. Отрязваш 2,5% отляво и 2,5% отдясно. Средните 95% са интервалът: от 10,04 € до 12,83 €.
  7. Истинската средна на годината е 10,63 € и е вътре. В живота не я знаеш: интервалът казва докъде може да е.

Купчината в сцената е схема: истински са числата в надписите, от извадката до границите на интервала. Ето истинските 10 000 средни с matplotlib, с двете граници (сини линии) и истинската средна (оранжевата прекъсната):

Pythonданни: таблиците на магазина

Пробвай

Без връщане?

1. В bootstrap всяка повторна извадка тегли 200 поръчки от извадка от 200. Какво става, ако теглиш без връщане?

Медианата на поръчките е по-устойчива на големите поръчки. Направи 95% интервал за медианата със същата извадка от 200: в meds запиши медианите на 10 000 повторни извадки, а в low и high границите на интервала.

Pythonданни: таблиците на магазина

Идеята

Какво значи 95%

Истинската средна на годината е едно число: 10,63 €. Интервалът от една извадка или я хваща, или не. 95% е обещание на метода: ако теглиш много извадки и за всяка правиш интервал, около 95 от 100 интервала ще хванат истината. Това се казва ниво на доверие.

Тук годината е цялата у нас и можем да проверим обещанието. 100 извадки по 200, за всяка bootstrap с 1 000 повторни извадки:

Pythonданни: таблиците на магазина

93 от 100 интервала хващат 10,63 €. Близо е до 95: самите 100 извадки са случайни и следващите 100 ще дадат малко друго. Около 5 от 100 честни интервала изпускат истината и няма как да знаеш кои са.

По-точно, за любопитните

Изкушаващо е да кажеш „с вероятност 95% истинската средна е между 10,04 и 12,83 €“. Строго погледнато не е това: истинската средна не е случайна, а интервалът от твоята извадка или я съдържа, или не. Случайна е извадката. Затова 95% е за метода, а не за едно конкретно число. В отчет пиши „95% доверителен интервал: 10,04–12,83 €“.

Bootstrap работи, когато извадката е случайна. Ако 200-те поръчки са от един декември, интервалът ще е за декември, колкото и повторни извадки да направиш: повторните извадки не поправят една изкривена извадка.

1. Интервалът за средната поръчка е от 10,04 до 12,83 €. Кое изречение е вярно?

Идеята

Формулата като кратък път

За средна има кратък път без 10 000 повторни извадки. Шумът на средната е стандартната грешка: std / √n. При нормално разпределение средните 95% са на 1,96 стандартни грешки от средата. Затова интервалът е средната ± 1,96 × std / √n:

Pythonданни: таблиците на магазина

Стандартната грешка е 0,72 €, а интервалът е от 10,00 до 12,81 €. Bootstrap даде 10,04–12,83 €: почти същото. Вторият ред проверява обещанието на формулата: от 1 000 извадки по 200, 948 интервала хващат истината. Близо до 950.

std(ddof=1) дели на n − 1 вместо на n, както std() в pandas. При 200 поръчки разликата е в третия знак.

По-точно, за любопитните

Числото 1,96 идва от нормалното разпределение: между −1,96 и 1,96 стандартни отклонения е 95% от площта. Средната на 200 поръчки е близо до нормална, дори когато самите поръчки имат дълга опашка (централната гранична теорема от урока за извадките). При малки извадки, под 30, или при много дълга опашка формулата греши повече, а bootstrap е по-честен.

Идеята

Интервал за дял

Каква част от поръчките са отказани? Делът е средна на нули и единици: True е 1, False е 0, и mean() дава дела. Затова bootstrap и формулата работят и тук. Формулата за дял е p ± 1,96 × √(p(1 − p) / n):

Pythonданни: таблиците на магазина

В извадка от 500 поръчки 5,8% са отказани. Bootstrap дава от 3,8 до 8,0%, а формулата от 3,8 до 7,8%. Истинският дял за годината е 5,9%. От 500 поръчки знаеш дела с точност около ± 2 пункта: „5,8%“ без интервал звучи по-точно, отколкото е.

Идеята

Малка извадка, широк интервал

Колкото по-малко поръчки, толкова повече шуми средната и толкова по-широк е интервалът:

Pythonданни: таблиците на магазина

50 поръчки дават интервал, широк 4,73 €, 200 поръчки 2,69 €, а 800 поръчки 1,35 €. 4 пъти повече данни дават около два пъти по-тесен интервал, защото стандартната грешка пада с корена от n. Точността е скъпа: още двойно по-тесен интервал иска пак 4 пъти повече поръчки.

Упражнение

Отговорът за управителя

Нова извадка от 400 поръчки (seed 2026). Направи 95% интервал за средната поръчка по два начина: с bootstrap от 10 000 повторни извадки (boot_low, boot_high) и с формулата (se е стандартната грешка, f_low и f_high са границите).

Pythonданни: таблиците на магазина

Управителят обмисля безплатна доставка над 20 €. Каква част от поръчките са над 20 €? От извадка от 300 поръчки (seed 7) запиши в p дела, а в low и high 95% интервала му.

Pythonданни: таблиците на магазина

Тест

Провери се

1. Защо в bootstrap се взимат квантилите 0,025 и 0,975 на средните, а не 0,05 и 0,95?
2. Интервалът от 200 поръчки е широк 2,69 €. Колко поръчки ти трябват за интервал, широк около 1,35 €?
3. Формулата е средната ± 1,96 × std / √n. Кога ще предпочетеш bootstrap?
4. В извадка от 500 поръчки 5,8% са отказани, а интервалът е от 3,8 до 7,8%. Шефът казва: „Значи отказите са 5,8%.“ Какво отговаряш?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·