Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Muammo kattaligi
- 2.2. FWER va Bonferroni
- 2.3. Holm usuli
- 2.4. FDR va Benjamini-Hochberg
- 2.5. Qaysi birini qachon
- 2.6. statsmodels multipletests
- 2.7. Ko'p taqqoslash tuzoqlari
- 2.8. Ko'p taqqoslash — halollik masalasi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Muammo kattaligi (simulyatsiya)
- Misol 2 — Bonferroni, Holm, BH solishtiruvi
- Misol 3 — FWER va FDR: nazorat va quvvat
- Misol 4 — Ko'p metrikali A/B hisobot
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
11.9-dars: Ko'p taqqoslash muammosi
11-QISM — GIPOTEZA TESTLARI · 9-dars
1. Kirish va motivatsiya
11.1-darsda ko'rdik: H0 rost bo'lganda ham har 20 testdan bittasi "muhim" chiqadi (alfa = 0.05). Amalda esa bitta test kamdan-kam o'tkaziladi: A/B testda 15 ta metrika kuzatiladi, 8 ta segment tekshiriladi, model uchun 50 ta belgi baholanadi, monitoringda har kuni o'nlab ko'rsatkich taqqoslanadi. Natija — yolg'on kashfiyotlar oqimi: 8.8-darsdagi "Texas snayperi" muammosining statistik shakli.
Bu darsda muammoning kattaligini o'lchaymiz va ikki xil yechimni o'rganamiz: oilaviy xato darajasini (FWER) nazorat qilish (Bonferroni, Holm — "hech bo'lmaganda bitta yolg'on" ehtimolini ushlash) va yolg'on kashfiyot ulushini (FDR) nazorat qilish (Benjamini-Hochberg — "topilganlarning qancha qismi yolg'on" ni cheklash). Birinchisi tasdiqlash uchun, ikkinchisi kashfiyot uchun mos.
Real vaziyat. A/B test tugadi: asosiy metrika (konversiya) bo'yicha farq yo'q. Jamoa 20 ta qo'shimcha metrikani tekshiradi — biri "muhim" chiqadi: "mobil foydalanuvchilarda savatga qo'shish +7%, p = 0.03!". Data Scientist hisoblaydi: 20 ta mustaqil testda kamida bitta yolg'on "muhim" ehtimoli 64%. Bonferroni bilan chegara 0.05/20 = 0.0025 — p = 0.03 o'tmaydi. To'g'ri hisobot: "asosiy metrika bo'yicha farq topilmadi; qo'shimcha metrikalardagi natija tuzatishdan keyin muhim emas va alohida test bilan tekshirilishi kerak".
Bu darsda ko'p taqqoslash muammosini o'rganamiz.
Bu darsda:
- Muammo kattaligi: yolg'on kashfiyotlar
- FWER va Bonferroni
- Holm usuli (kuchliroq)
- FDR va Benjamini-Hochberg
- Qaysi birini qachon tanlash
- statsmodels multipletests
- Ko'p taqqoslash tuzoqlari
- Amaliy: ko'p metrikali A/B tahlil
ℹ Misollar real numpy/scipy/statsmodels bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Muammo kattaligi
m ta MUSTAQIL test, hammasida H0 rost, alfa = 0.05:
P(kamida bitta "muhim") = 1 - 0.95^m
m = 1: 0.05 m = 10: 0.40
m = 5: 0.23 m = 20: 0.64
m = 14: 0.51 m = 100: 0.99
Qayerda uchraydi:
ko'p metrika, ko'p segment, ko'p variant (A/B/C/D), ko'p belgi,
har kuni tekshirish (ketma-ket), ko'p model/parametrMuammo sanoqli: har test — yangi imkoniyat "yolg'on kashfiyot" uchun. 14 ta testda yolg'on natija ehtimoli 50% dan oshadi. Bu 8.8-darsdagi tug'ilgan kun paradoksi va Texas snayperi bilan bir xil mexanizm: ko'p qarasang — nimadir "topiladi". Muhim: bu tasodif, ma'lumotdagi tuzilma emas.
2.2. FWER va Bonferroni
FWER (family-wise error rate) — kamida bitta I tur xato ehtimoli
BONFERRONI: har testni alfa / m darajasida sinash
yoki ekvivalent: p_tuzatilgan = min(1, p × m)
m = 20, alfa = 0.05 → har test uchun chegara 0.0025
Afzalligi: sodda, har qanday bog'liqlikda ishlaydi
Kamchiligi: juda konservativ — quvvat keskin tushadi (II tur xato oshadi)Bonferroni — eng sodda va eng qat'iy tuzatish: FWER ni alfa dan past ushlaydi. Ko'p test bo'lganda (m = 100) chegara 0.0005 — deyarli hech narsa o'tmaydi, haqiqiy effektlar ham yo'qoladi. Shuning uchun u kam sonli, muhim taqqoslashlar uchun mos (masalan, 3-5 ta oldindan belgilangan gipoteza).
2.3. Holm usuli
HOLM (ketma-ket Bonferroni) — FWER ni bir xil nazorat qiladi, lekin QUVVATLIROQ
1. p-qiymatlarni o'sish tartibida tartiblang: p(1) <= p(2) <= ... <= p(m)
2. p(1) ni alfa/m bilan, p(2) ni alfa/(m-1) bilan, ... solishtiring
3. Birinchi o'tmagan joyda to'xtang — qolganlari ham rad etilmaydi
Har doim Bonferroni dan kuchliroq yoki teng → Bonferroni o'rniga Holm ishlatingHolm — Bonferroni ning "yaxshilangan" versiyasi: eng kichik p ga eng qat'iy chegara, keyingilariga yumshoqroq. FWER kafolati bir xil, lekin ko'proq haqiqiy effektni topadi. Amaliy qoida: FWER kerak bo'lsa — Holm (Bonferroni faqat tushuntirish uchun sodda).
2.4. FDR va Benjamini-Hochberg
FDR (false discovery rate) — "muhim" deb topilganlarning KUTILGAN yolg'on ulushi
BENJAMINI-HOCHBERG (BH):
1. p larni o'sish tartibida tartiblang
2. Eng katta k ni toping: p(k) <= (k / m) × q (q — maqsad FDR, masalan 0.10)
3. 1..k gacha bo'lgan barcha testlarni "muhim" deb belgilang
Ma'nosi: "topilgan 100 ta natijadan ~10 tasi yolg'on bo'lishi mumkin" (q = 0.10)FDR — boshqa savol: "hech bo'lmaganda bitta xato" emas, "topilganlarning qancha qismi xato". Kashfiyot bosqichida (genomika, ko'p belgi, ko'p segment) bu ancha mantiqiy: 100 ta nomzoddan 10 tasi yolg'on bo'lsa ham, qolgan 90 tasi qimmatli. BH — FDR ning standart usuli; Bonferroni/Holm dan ancha quvvatliroq.
2.5. Qaysi birini qachon
FWER (Holm/Bonferroni):
- tasdiqlovchi tahlil, yakuniy qaror
- kam sonli oldindan belgilangan gipoteza
- xato qimmat (tibbiyot, xavfsizlik, katta investitsiya)
FDR (BH):
- kashfiyot bosqichi, ko'p nomzod (belgilar, segmentlar, genlar)
- keyin tekshiriladigan ro'yxat tuzish
- xato "arzon" (qo'shimcha tekshiruv mumkin)
TUZATISHSIZ:
- bitta oldindan belgilangan asosiy metrika (11.2, 11.10)
- lekin qolgan natijalar "kashfiyot" deb belgilanadiAsosiy metrika g'oyasi 11.10-bob: testdan oldin bitta asosiy metrika e'lon qilinadi — u tuzatishsiz baholanadi; qolganlari ikkilamchi deb belgilanadi va tuzatish bilan (yoki "gipoteza" sifatida) hisobot qilinadi. Bu — sanoat standarti (klinik sinovlar, yirik texnologiya kompaniyalari).
2.6. statsmodels multipletests
from statsmodels.stats.multitest import multipletests
rad, p_tuz, _, _ = multipletests(p_lar, alpha=0.05, method="holm") # FWER
rad, p_tuz, _, _ = multipletests(p_lar, alpha=0.10, method="fdr_bh") # FDR
# method: "bonferroni", "holm", "fdr_bh", "fdr_by", "sidak", ... multipletests — barcha usullarni bitta funksiyada beradi: rad (rad etilgan/etilmagan), p_tuz (tuzatilgan p-qiymatlar — ularni to'g'ridan-to'g'ri alfa bilan solishtirish mumkin). Tuzatilgan p ni hisobotda ko'rsatish — shaffoflik uchun eng yaxshi amaliyot: o'quvchi xom va tuzatilgan qiymatni ko'radi.
2.7. Ko'p taqqoslash tuzoqlari
Asosiy tuzoqlar: tuzatishsiz ko'p metrika (eng keng tarqalgan); faqat "muhim" natijalarni hisobot qilish (nechta test qilingani yashiriladi — 8.8); ketma-ket tekshirish (har kuni p ni ko'rish — bu ham ko'p taqqoslash, 11.2); segmentlarni "qidirish" (20 segmentda bittasida effekt topish); tuzatishni noto'g'ri oilaga qo'llash (butunlay boshqa savollarga ham); FDR ni tasdiqlash uchun ishlatish (yakuniy qarorda FWER kerak); tuzatishdan keyin ham CI larni tuzatmaslik (CI lar ham kengaytirilishi kerak); p-hacking (ko'p variantni sinab, eng yaxshisini tanlash).
2.8. Ko'p taqqoslash — halollik masalasi
m ta testda kamida bitta yolg'on "muhim" ehtimoli 1 - (1 - alfa)^m — 20 testda 64%. FWER usullari (Bonferroni — sodda; Holm — kuchliroq, bir xil kafolat) "hech bo'lmaganda bitta xato" ehtimolini ushlaydi — tasdiqlash uchun. FDR (Benjamini-Hochberg) "topilganlarning yolg'on ulushini" cheklaydi — kashfiyot uchun. Amaliyot: bitta asosiy metrika (tuzatishsiz) + ikkilamchilar (tuzatish bilan yoki gipoteza sifatida), barcha o'tkazilgan testlarni hisobot qilish. Keyingi dars — A/B test loyihasi: butun qismni bitta amaliy ishda birlashtirish.
3. Tez ma'lumotnoma
import numpy as np
from statsmodels.stats.multitest import multipletests
p_lar = np.array([0.001, 0.008, 0.03, 0.04, 0.2, 0.7])
# FWER
rad, p_holm, _, _ = multipletests(p_lar, alpha=0.05, method="holm")
rad_b, p_bonf, _, _ = multipletests(p_lar, alpha=0.05, method="bonferroni")
# FDR
rad_f, p_bh, _, _ = multipletests(p_lar, alpha=0.10, method="fdr_bh")
# qo'lda Bonferroni
chegara = 0.05 / len(p_lar)
# qo'lda BH
m = len(p_lar); tartib = np.argsort(p_lar)
k = np.max(np.where(p_lar[tartib] <= (np.arange(1, m + 1) / m) * 0.10, np.arange(1, m + 1), 0))
QOIDA: asosiy metrika bitta · FWER — tasdiq, FDR — kashfiyot · barcha testlarni hisobot qilKo'p taqqoslash xulosasi
m testda kamida bitta yolg'on: 1 - (1 - alfa)^m (m=20 → 64%)
FWER — Bonferroni (alfa/m), Holm (ketma-ket, kuchliroq)
FDR — Benjamini-Hochberg: topilganlarning yolg'on ulushi <= q
Tasdiqlash — FWER; kashfiyot — FDR
Asosiy metrika — bitta, oldindan; qolgani ikkilamchi
Shaffoflik: nechta test qilingani hisobotda4. Batafsil misollar
Misollar real numpy/scipy/statsmodels bilan (Python 3.14).
Misol 1 — Muammo kattaligi (simulyatsiya)
"""m ta testda yolg'on kashfiyot ehtimoli (real numpy/scipy)."""
import numpy as np
from scipy import stats
def main() -> None:
rng = np.random.default_rng(0)
N, n = 5000, 50
print("=== 1. H0 rost: m ta metrikani tekshirish ===")
for m in [1, 5, 10, 20, 50]:
a = rng.normal(0, 1, (N, m, n))
b = rng.normal(0, 1, (N, m, n))
p = stats.ttest_ind(a, b, axis=2, equal_var=False).pvalue # (N, m)
kamida_bitta = (p < 0.05).any(axis=1).mean()
print(f" m={m:>2}: kamida bitta 'muhim' {kamida_bitta:.3f} "
f"(nazariy {1 - 0.95 ** m:.3f})")
print("\n=== 2. Ko'p segmentda 'kashfiyot' qidirish ===")
a = rng.normal(0, 1, (N, 8, n))
b = rng.normal(0, 1, (N, 8, n))
p = stats.ttest_ind(a, b, axis=2, equal_var=False).pvalue
eng_kichik = p.min(axis=1)
print(f" 8 segment: eng kichik p ning medianasi {np.median(eng_kichik):.4f}")
print(f" kamida bitta segmentda p < 0.05: {(eng_kichik < 0.05).mean():.3f}")
print("\n=== 3. Ketma-ket tekshirish (har kuni) ===")
kunlar = 14
yolgon = 0
for _ in range(2000):
x = rng.normal(0, 1, (kunlar, 40))
y = rng.normal(0, 1, (kunlar, 40))
for k in range(1, kunlar + 1):
if stats.ttest_ind(x[:k].ravel(), y[:k].ravel(), equal_var=False).pvalue < 0.05:
yolgon += 1
break
print(f" 14 kun har kuni tekshirish: yolg'on to'xtatish {yolgon / 2000:.3f}")
print(" ⭐ Ko'p qarasang — nimadir 'topiladi'")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. H0 rost: m ta metrikani tekshirish ===
m= 1: kamida bitta 'muhim' 0.047 (nazariy 0.050)
m= 5: kamida bitta 'muhim' 0.220 (nazariy 0.226)
m=10: kamida bitta 'muhim' 0.389 (nazariy 0.401)
m=20: kamida bitta 'muhim' 0.649 (nazariy 0.642)
m=50: kamida bitta 'muhim' 0.929 (nazariy 0.923)
=== 2. Ko'p segmentda 'kashfiyot' qidirish ===
8 segment: eng kichik p ning medianasi 0.0821
kamida bitta segmentda p < 0.05: 0.341
=== 3. Ketma-ket tekshirish (har kuni) ===
14 kun har kuni tekshirish: yolg'on to'xtatish 0.217
⭐ Ko'p qarasang — nimadir 'topiladi'Nima ko'rsatdi: 2.1, 2.7-bo'limlar.
Misol 2 — Bonferroni, Holm, BH solishtiruvi
"""Uch tuzatish usuli bitta p-qiymatlar to'plamida (real numpy/statsmodels)."""
import numpy as np
from statsmodels.stats.multitest import multipletests
def main() -> None:
p_lar = np.array([0.0005, 0.004, 0.012, 0.021, 0.033, 0.048, 0.07, 0.15, 0.32, 0.67])
nom = [f"metrika{i + 1}" for i in range(len(p_lar))]
print("=== 1. Xom p-qiymatlar ===")
print(f" p < 0.05: {(p_lar < 0.05).sum()} ta / {len(p_lar)}")
natija = {}
for usul, alfa in [("bonferroni", 0.05), ("holm", 0.05), ("fdr_bh", 0.05)]:
rad, p_tuz, _, _ = multipletests(p_lar, alpha=alfa, method=usul)
natija[usul] = (rad, p_tuz)
print("\n=== 2. Tuzatilgan p-qiymatlar ===")
print(f" {'metrika':<10} {'xom':>8} {'bonf':>8} {'holm':>8} {'BH':>8}")
for i in range(len(p_lar)):
print(f" {nom[i]:<10} {p_lar[i]:>8.4f} {natija['bonferroni'][1][i]:>8.4f} "
f"{natija['holm'][1][i]:>8.4f} {natija['fdr_bh'][1][i]:>8.4f}")
print("\n=== 3. Nechta 'muhim' qoladi ===")
for usul in ["bonferroni", "holm", "fdr_bh"]:
print(f" {usul:<12}: {natija[usul][0].sum()} ta")
print("\n=== 4. Bonferroni chegarasi ===")
print(f" alfa / m = 0.05 / {len(p_lar)} = {0.05 / len(p_lar):.4f}")
print(" ⭐ Holm — Bonferroni dan kuchliroq; BH — eng ko'p topadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Xom p-qiymatlar ===
p < 0.05: 6 ta / 10
=== 2. Tuzatilgan p-qiymatlar ===
metrika xom bonf holm BH
metrika1 0.0005 0.0050 0.0050 0.0050
metrika2 0.0040 0.0400 0.0360 0.0200
metrika3 0.0120 0.1200 0.0960 0.0400
metrika4 0.0210 0.2100 0.1470 0.0525
metrika5 0.0330 0.3300 0.1980 0.0660
metrika6 0.0480 0.4800 0.2400 0.0800
metrika7 0.0700 0.7000 0.2800 0.1000
metrika8 0.1500 1.0000 0.4500 0.1875
metrika9 0.3200 1.0000 0.6400 0.3556
metrika10 0.6700 1.0000 0.6700 0.6700
=== 3. Nechta 'muhim' qoladi ===
bonferroni : 2 ta
holm : 2 ta
fdr_bh : 3 ta
=== 4. Bonferroni chegarasi ===
alfa / m = 0.05 / 10 = 0.0050
⭐ Holm — Bonferroni dan kuchliroq; BH — eng ko'p topadiNima ko'rsatdi: 2.2, 2.3, 2.4, 2.6-bo'limlar.
Misol 3 — FWER va FDR: nazorat va quvvat
"""Simulyatsiya: usullar FWER, FDR va quvvatni qanday ushlaydi (real numpy/scipy/statsmodels)."""
import numpy as np
from scipy import stats
from statsmodels.stats.multitest import multipletests
def main() -> None:
rng = np.random.default_rng(1)
N, m, n = 2000, 20, 40
haqiqiy = 5 # 20 metrikadan 5 tasida haqiqiy effekt
effekt = np.concatenate([np.full(haqiqiy, 0.8), np.zeros(m - haqiqiy)])
natija = {u: {"fwer": 0, "fdr": [], "quvvat": []} for u in ["yo'q", "bonferroni", "holm", "fdr_bh"]}
for _ in range(N):
a = rng.normal(effekt[:, None], 1, (m, n))
b = rng.normal(0, 1, (m, n))
p = stats.ttest_ind(a, b, axis=1, equal_var=False).pvalue
for usul in natija:
rad = p < 0.05 if usul == "yo'q" else multipletests(p, alpha=0.05, method=usul)[0]
yolgon = rad[haqiqiy:].sum()
natija[usul]["fwer"] += yolgon > 0
natija[usul]["fdr"].append(yolgon / rad.sum() if rad.sum() else 0.0)
natija[usul]["quvvat"].append(rad[:haqiqiy].mean())
print("=== 20 metrika, 5 tasida haqiqiy effekt (d = 0.8) ===")
print(f" {'usul':<12} {'FWER':>8} {'FDR':>8} {'quvvat':>8}")
for usul, d in natija.items():
print(f" {usul:<12} {d['fwer'] / N:>8.3f} {np.mean(d['fdr']):>8.3f} "
f"{np.mean(d['quvvat']):>8.3f}")
print("\n tuzatishsiz: FWER juda yuqori; Bonferroni/Holm: FWER < 0.05, quvvat past")
print(" BH: FDR ~0.05 atrofida, quvvat yuqoriroq")
print(" ⭐ Nazorat turi va quvvat — muvozanat")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 20 metrika, 5 tasida haqiqiy effekt (d = 0.8) ===
usul FWER FDR quvvat
yo'q 0.539 0.120 0.945
bonferroni 0.037 0.009 0.668
holm 0.048 0.012 0.686
fdr_bh 0.175 0.036 0.835
tuzatishsiz: FWER juda yuqori; Bonferroni/Holm: FWER < 0.05, quvvat past
BH: FDR ~0.05 atrofida, quvvat yuqoriroq
⭐ Nazorat turi va quvvat — muvozanatNima ko'rsatdi: 2.2-2.5-bo'limlar.
Misol 4 — Ko'p metrikali A/B hisobot
"""Asosiy metrika + ikkilamchi metrikalar: to'g'ri hisobot (real numpy/scipy/statsmodels)."""
import numpy as np
from scipy import stats
from statsmodels.stats.multitest import multipletests
def main() -> None:
rng = np.random.default_rng(9)
n = 3000
metrikalar = ["konversiya", "savatga qo'shish", "sessiya vaqti", "sahifalar soni",
"qidiruv ishlatish", "qaytish", "chek", "yordamga murojaat"]
# haqiqatda hech qanday effekt yo'q
p_lar = []
for i, nom in enumerate(metrikalar):
a = rng.normal(0, 1, n)
b = rng.normal(0, 1, n)
p_lar.append(stats.ttest_ind(a, b, equal_var=False).pvalue)
p_lar = np.array(p_lar)
print("=== 1. Xom natijalar ===")
for nom, p in zip(metrikalar, p_lar):
belgi = " ← 'muhim'" if p < 0.05 else ""
print(f" {nom:<18}: p = {p:.4f}{belgi}")
print("\n=== 2. Asosiy metrika (oldindan belgilangan: konversiya) ===")
print(f" p = {p_lar[0]:.4f} → {'rad etiladi' if p_lar[0] < 0.05 else 'farq topilmadi'}")
print("\n=== 3. Ikkilamchi metrikalar (Holm tuzatishi) ===")
rad, p_tuz, _, _ = multipletests(p_lar[1:], alpha=0.05, method="holm")
for nom, p, pt, r in zip(metrikalar[1:], p_lar[1:], p_tuz, rad):
print(f" {nom:<18}: xom {p:.4f}, tuzatilgan {pt:.4f}{' ← muhim' if r else ''}")
print("\n=== 4. Hisobot matni ===")
print(" Asosiy metrika bo'yicha farq topilmadi.")
print(f" {len(metrikalar) - 1} ta ikkilamchi metrika tekshirildi; tuzatishdan keyin")
print(" muhim natija yo'q. Qiziq ko'ringan natijalar alohida test talab qiladi.")
print(" ⭐ Nechta test qilinganini har doim yozing")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Xom natijalar ===
konversiya : p = 0.4032
savatga qo'shish : p = 0.2878
sessiya vaqti : p = 0.0213 ← 'muhim'
sahifalar soni : p = 0.6944
qidiruv ishlatish : p = 0.8052
qaytish : p = 0.6613
chek : p = 0.3036
yordamga murojaat : p = 0.4644
=== 2. Asosiy metrika (oldindan belgilangan: konversiya) ===
p = 0.4032 → farq topilmadi
=== 3. Ikkilamchi metrikalar (Holm tuzatishi) ===
savatga qo'shish : xom 0.2878, tuzatilgan 1.0000
sessiya vaqti : xom 0.0213, tuzatilgan 0.1492
sahifalar soni : xom 0.6944, tuzatilgan 1.0000
qidiruv ishlatish : xom 0.8052, tuzatilgan 1.0000
qaytish : xom 0.6613, tuzatilgan 1.0000
chek : xom 0.3036, tuzatilgan 1.0000
yordamga murojaat : xom 0.4644, tuzatilgan 1.0000
=== 4. Hisobot matni ===
Asosiy metrika bo'yicha farq topilmadi.
7 ta ikkilamchi metrika tekshirildi; tuzatishdan keyin
muhim natija yo'q. Qiziq ko'ringan natijalar alohida test talab qiladi.
⭐ Nechta test qilinganini har doim yozingNima ko'rsatdi: 2.5, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Ko'p metrika tekshirish bepul" | Har test — yolg'on xavfi |
| "Bonferroni — yagona usul" | Holm kuchliroq, BH quvvatliroq |
| "FDR = FWER" | Turli kafolatlar |
| "Tuzatish — quvvatni yo'qotish" | Yolg'onni cheklash narxi |
| "Faqat muhim natijalarni yozsam bo'ladi" | Nechta test — majburiy |
| "Har kuni tekshirish zararsiz" | Ketma-ket ko'p taqqoslash |
| "Segmentda topilgan effekt — kashfiyot" | Gipoteza (alohida test kerak) |
| "Tuzatishdan keyin p — xom p" | Tuzatilganini ko'rsating |
6. Keng tarqalgan xatolar va yechimlari
1. Tuzatishsiz ko'p metrika
for m in metrikalar: test(m) # p < 0.05 bo'lsa "kashfiyot" # ⚠️
rad, p_tuz, _, _ = multipletests(p_lar, alpha=0.05, method="holm") # ✅2. Bonferroni o'rniga Holm
multipletests(p, method="bonferroni") # ⚠️ (konservativ)
multipletests(p, method="holm") # ✅3. Kashfiyotda FWER
multipletests(p_1000_belgi, method="bonferroni") # deyarli hech nima # ⚠️
multipletests(p_1000_belgi, alpha=0.10, method="fdr_bh") # ✅4. Ketma-ket tekshirish
# har kuni p < 0.05 ni tekshirish # ⚠️
# oldindan belgilangan muddat yoki ketma-ket usullar # ✅5. Testlar sonini yashirish
print("savatga qo'shish +7%, p = 0.03") # ⚠️
print("20 metrikadan biri; tuzatilgan p = 0.6 — muhim emas") # ✅6. Segment qidirish
eng_yaxshi = min(segmentlar, key=lambda s: p[s]) # ⚠️
# oldindan segmentlarni belgilash + tuzatish # ✅7. CI larni tuzatmaslik
ci = res.confidence_interval(0.95) # 10 ta metrika uchun # ⚠️
ci = res.confidence_interval(1 - 0.05 / 10) # tuzatilgan daraja # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8.8-dars (o'tilgan): P-hacking, Texas snayperi
- 11.1-11.2-darslar (o'tilgan): alfa, quvvat
- 11.6-dars (o'tilgan): Post-hoc testlar
- 11.10-dars: A/B test loyihasi
- Feature engineering qismi: Ko'p belgi tanlovi
8. Eng yaxshi amaliyotlar
Asosiy metrikani oldindan belgilang.
Testlar sonini hisobotda yozing.
FWER uchun Holm, FDR uchun BH.
Tuzatilgan p ni ko'rsating.
Kashfiyotlarni gipoteza deb belgilang 8.8-bob.
Ketma-ket tekshirishdan saqlaning.
Segmentlarni oldindan belgilang.
Ishonch oraliqlarini ham tuzating.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # 10 testda kamida bitta yolg'on (alfa=0.05)?
2. # 20 testda?
3. # FWER nima?
4. # FDR nima?
5. # Bonferroni chegarasi (m=25)?
6. # Holm Bonferroni dan?
7. # BH nima nazorat qiladi?
8. # tasdiqlash uchun qaysi?
9. # 1000 belgi skrining uchun?
10. # ketma-ket tekshirish nima muammo?
11. # asosiy metrika nechta?
12. # tuzatilgan p ni qanday o'qish?Javoblar
- ~0.40
- ~0.64
- Kamida bitta I tur xato ehtimoli
- Topilganlarning yolg'on ulushi
- 0.002
- Kuchliroq (yoki teng)
- FDR
- FWER (Holm)
- FDR (BH)
- Ko'p taqqoslash
- Bitta
- To'g'ridan-to'g'ri alfa bilan solishtirish
Vazifa 2: Xatolarni tuzating
1. for m in metrikalar: print(m, ttest(m).pvalue < 0.05)
2. multipletests(p_5000_belgi, method="bonferroni")
3. print("eng yaxshi segment: p =", min(p_segmentlar))
4. # har kuni natijani tekshirish va p < 0.05 da to'xtatish
5. print("savatga qo'shish p = 0.03 — g'alaba!")Javoblar
1. rad, p_tuz, _, _ = multipletests(p_lar, alpha=0.05, method="holm")
2. multipletests(p_5000_belgi, alpha=0.10, method="fdr_bh")
3. # segmentlarni oldindan belgilang; tuzatish bilan hisobot qiling
4. # oldindan hisoblangan n ga yetguncha kutish (11.2)
5. print(f"20 metrikadan biri; Holm bilan p = {p_tuz:.3f} — muhim emas")Vazifa 3: Simulyatsiya
Modellang:
- 30 metrika, 5 tasida effekt
- Tuzatishsiz, Holm, BH
- FWER, FDR, quvvat
- Jadval va tavsiya
Vazifa 4: A/B hisobot
Modellang:
- 1 asosiy + 12 ikkilamchi metrika
- Holm tuzatishi
- Hisobot matni
- "Kashfiyot" bo'limini alohida yozish
Vazifa 5: Ketma-ket tekshirish
Modellang:
- 21 kunlik test
- Har kuni tekshirish ta'siri
- Faqat oxirida tekshirish
- I tur xato farqi
Vazifa 6: Integratsiya
Modellang:
- Gipoteza shakllantirish (8.8)
- Quvvat (11.2)
- Post-hoc (11.6)
- Hisobot (8.9)
Vazifa 7: O'ylash
Ko'p taqqoslash tuzatishlari "haqiqiy kashfiyotlarni ham yo'qotadi" deb tanqid qilinadi: Bonferroni bilan 1000 ta belgi tekshirilsa, chegara 0.00005 bo'ladi va deyarli hech narsa o'tmaydi. Bu tanqid qanchalik o'rinli? Yolg'on kashfiyot va o'tkazib yuborish orasidagi muvozanatni qanday tanlash kerak?
Javob
Qisqa javob: tanqid qisman o'rinli — shuning uchun FDR ishlab chiqilgan. Tuzatish turini "xato narxi" belgilaydi: agar yolg'on kashfiyot qimmat bo'lsa (dori ishga tushirish), FWER; agar keyin tekshirish mumkin bo'lsa (nomzodlar ro'yxati), FDR.
1. Muvozanat
| Yondashuv | Yolg'on kashfiyot | O'tkazib yuborish |
|---|---|---|
| Tuzatishsiz | Ko'p | Kam |
| FDR (BH) | Nazorat ostida (ulush) | O'rtacha |
| FWER (Holm) | Juda kam | Ko'p |
2. Qaror mezonlari
- Yolg'on kashfiyot narxi (resurs, obro', xavfsizlik)
- O'tkazib yuborish narxi (yo'qotilgan imkoniyat)
- Keyingi tekshiruv imkoniyati (bor bo'lsa — FDR)
- Testlar soni va ularning bog'liqligi
3. Amaliy strategiya
- Kashfiyot bosqichi: FDR bilan nomzodlar ro'yxati
- Tasdiqlash bosqichi: mustaqil ma'lumotda, FWER bilan (8.8)
- Asosiy metrika: oldindan, tuzatishsiz
- Shaffoflik: barcha testlar hisobotda
4. Data Scientist qanday
- Tuzatish turini savolga qarab tanlaydi, avtomatik emas
- Kashfiyot va tasdiqlashni ajratadi
- Effekt kattaligi va CI ni har doim beradi
- Takroriy tekshiruvni rejalashtiradi
5. Xulosa
- Tuzatishsizlik — yolg'on kashfiyotlar oqimi
- FWER — qat'iy, FDR — moslashuvchan
- Tanlov xato narxiga bog'liq
- Eng yaxshi himoya — mustaqil tasdiqlash
Nimani mustahkamlaydi: 2.4, 2.5-bo'limlar.
Xulosa
Bu darsda ko'p taqqoslash muammosini o'rgandik.
Eng muhim uch fikr:
Muammo sanoqli. m ta mustaqil testda kamida bitta yolg'on "muhim" ehtimoli 1 - (1 - alfa)^m: 10 testda 40%, 20 testda 64%. Bu ko'p metrika, ko'p segment, ko'p variant va ketma-ket tekshirishda uchraydi.
Ikki xil nazorat. FWER — "kamida bitta xato" ehtimoli (Bonferroni: alfa/m; Holm — bir xil kafolat, lekin kuchliroq) — tasdiqlash uchun. FDR — "topilganlarning yolg'on ulushi" (Benjamini-Hochberg) — kashfiyot uchun (ko'p nomzod, keyin tekshiriladi).
Amaliyot va halollik. Bitta asosiy metrika oldindan belgilanadi (tuzatishsiz baholanadi), qolganlari ikkilamchi — tuzatish bilan yoki "gipoteza" sifatida 8.8-bob. Hisobotda: nechta test qilingani, xom va tuzatilgan p-qiymatlar, effekt kattaligi va CI.
Keyingi darsda A/B test loyihasini qilamiz: butun qismni bitta amaliy ishda birlashtiramiz — dizayn, quvvat, sanity-check, asosiy va ikkilamchi metrikalar, segmentlar va yakuniy hisobot.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!