IlmHamroh
Data Science va sun'iy intellekt/Gipoteza testlari9/10-dars18 daqiqa
Mundarija (22)

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

text
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/parametr

Muammo 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

text
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

text
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 ishlating

Holm — 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

text
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

text
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 belgilanadi

Asosiy 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

python
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

python
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 qil

Ko'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 hisobotda

4. Batafsil misollar

Misollar real numpy/scipy/statsmodels bilan (Python 3.14).

Misol 1 — Muammo kattaligi (simulyatsiya)

python
"""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:

text
=== 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

python
"""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:

text
=== 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 topadi

Nima ko'rsatdi: 2.2, 2.3, 2.4, 2.6-bo'limlar.

Misol 3 — FWER va FDR: nazorat va quvvat

python
"""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:

text
=== 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 — muvozanat

Nima ko'rsatdi: 2.2-2.5-bo'limlar.

Misol 4 — Ko'p metrikali A/B hisobot

python
"""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:

text
=== 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 yozing

Nima 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

python
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

python
multipletests(p, method="bonferroni")                             # ⚠️ (konservativ)
multipletests(p, method="holm")                                   # ✅

3. Kashfiyotda FWER

python
multipletests(p_1000_belgi, method="bonferroni")   # deyarli hech nima  # ⚠️
multipletests(p_1000_belgi, alpha=0.10, method="fdr_bh")          # ✅

4. Ketma-ket tekshirish

python
# har kuni p < 0.05 ni tekshirish                                 # ⚠️
# oldindan belgilangan muddat yoki ketma-ket usullar               # ✅

5. Testlar sonini yashirish

python
print("savatga qo'shish +7%, p = 0.03")                           # ⚠️
print("20 metrikadan biri; tuzatilgan p = 0.6 — muhim emas")      # ✅

6. Segment qidirish

python
eng_yaxshi = min(segmentlar, key=lambda s: p[s])                  # ⚠️
# oldindan segmentlarni belgilash + tuzatish                       # ✅

7. CI larni tuzatmaslik

python
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

  1. Asosiy metrikani oldindan belgilang.

  2. Testlar sonini hisobotda yozing.

  3. FWER uchun Holm, FDR uchun BH.

  4. Tuzatilgan p ni ko'rsating.

  5. Kashfiyotlarni gipoteza deb belgilang 8.8-bob.

  6. Ketma-ket tekshirishdan saqlaning.

  7. Segmentlarni oldindan belgilang.

  8. Ishonch oraliqlarini ham tuzating.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
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
  1. ~0.40
  2. ~0.64
  3. Kamida bitta I tur xato ehtimoli
  4. Topilganlarning yolg'on ulushi
  5. 0.002
  6. Kuchliroq (yoki teng)
  7. FDR
  8. FWER (Holm)
  9. FDR (BH)
  10. Ko'p taqqoslash
  11. Bitta
  12. To'g'ridan-to'g'ri alfa bilan solishtirish

Vazifa 2: Xatolarni tuzating

python
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
python
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:

  1. 30 metrika, 5 tasida effekt
  2. Tuzatishsiz, Holm, BH
  3. FWER, FDR, quvvat
  4. Jadval va tavsiya

Vazifa 4: A/B hisobot

Modellang:

  1. 1 asosiy + 12 ikkilamchi metrika
  2. Holm tuzatishi
  3. Hisobot matni
  4. "Kashfiyot" bo'limini alohida yozish

Vazifa 5: Ketma-ket tekshirish

Modellang:

  1. 21 kunlik test
  2. Har kuni tekshirish ta'siri
  3. Faqat oxirida tekshirish
  4. I tur xato farqi

Vazifa 6: Integratsiya

Modellang:

  1. Gipoteza shakllantirish (8.8)
  2. Quvvat (11.2)
  3. Post-hoc (11.6)
  4. 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

  1. Kashfiyot bosqichi: FDR bilan nomzodlar ro'yxati
  2. Tasdiqlash bosqichi: mustaqil ma'lumotda, FWER bilan (8.8)
  3. Asosiy metrika: oldindan, tuzatishsiz
  4. 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

  1. Tuzatishsizlik — yolg'on kashfiyotlar oqimi
  2. FWER — qat'iy, FDR — moslashuvchan
  3. Tanlov xato narxiga bog'liq
  4. 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:

  1. 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.

  2. 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).

  3. 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.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
11.9-dars: Ko'p taqqoslash muammosi — IlmHamroh