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

11.5-dars: Xi-kvadrat testlari

11-QISM — GIPOTEZA TESTLARI · 5-dars


1. Kirish va motivatsiya

t-test 11.3-bob va proporsiyalar testi (11.4) sonlar va ikkilik natijalar uchun edi. Lekin ko'p ma'lumot kategoriyali: qurilma turi, mijoz segmenti, hafta kuni, javob varianti, xato turi. Bunday ma'lumotni kontingentlik jadvali (8.4, pd.crosstab) sifatida yozamiz va xi-kvadrat testi bilan ikki savolga javob beramiz: (1) ikki kategoriya bir-biriga bog'liqmi? (2) kuzatilgan taqsimot kutilganiga mos keladimi?

Xi-kvadrat — Data Science'da juda keng ishlatiladi: A/B/C testlarda variantlar va natijalar bog'liqligi, segment va churn bog'liqligi, ma'lumot sifati tekshiruvi (trafik taqsimoti kutilganiga mosmi — A/A test), zar/generator adolatliligi, so'rovnoma javoblari tahlili. Uning kuchi — ko'p kategoriya bilan bir vaqtda ishlash; zaifligi — u faqat "bog'liqlik bor" deydi, qayerda va qanchalik ekanini aytmaydi (buning uchun qoldiqlar va effekt kattaligi kerak).

Real vaziyat. Tahlilchi to'rtta bannerni sinadi (A/B/C/D) va har juftlikni alohida solishtiradi — 6 ta test, ulardan biri p = 0.04 chiqadi: "C banner g'olib!". Data Scientist avval xi-kvadrat bilan umumiy testni o'tkazadi: p = 0.21 — bannerlar va kliklar orasida bog'liqlik topilmadi. Olti juft taqqoslashda kamida bitta "muhim" natija chiqishi ehtimoli ~26% 11.9-bob. To'g'ri tartib: avval umumiy test, agar u bog'liqlikni ko'rsatsa — qayerda ekanini tuzatilgan juft taqqoslashlar bilan aniqlash.

Bu darsda xi-kvadrat testlarini o'rganamiz.

Bu darsda:

  • Kontingentlik jadvali va mustaqillik testi
  • Kutilgan chastotalar va statistika
  • Moslik testi (goodness of fit)
  • Standartlashtirilgan qoldiqlar — qayerda farq bor
  • Effekt kattaligi (Cramer's V)
  • Shartlar va cheklovlar
  • Xi-kvadrat tuzoqlari
  • Amaliy: segment va konversiya bog'liqligi

ℹ Misollar real numpy/pandas/scipy bilan (Python 3.14).


2. Nazariya — chuqur tushuntirish

2.1. Kontingentlik jadvali va mustaqillik testi

text
                  klik yo'q   klik bor   jami
  A banner           950         50      1000
  B banner           930         70      1000
  C banner           940         60      1000
  jami              2820        180      3000

H0: banner va klik MUSTAQIL 9.3-bob — klik ehtimoli bannerdan qat'i nazar bir xil
H1: bog'liqlik bor (hech bo'lmasa bitta banner farq qiladi)

scipy: chi2, p, df, kutilgan = stats.chi2_contingency(jadval)

Mustaqillik testi — kontingentlik jadvalidagi ikki kategoriya bog'liqligini tekshiradi. H0 — mustaqillik 9.3-bob: P(klik | banner) hamma banner uchun bir xil. Test umumiy javob beradi: "bog'liqlik bor/yo'q". 2×2 jadval uchun u proporsiyalar z-testi bilan ekvivalent (11.4: chi2 = z^2). Ma'lumot — sanoqlar bo'lishi kerak (foizlar yoki o'rtachalar emas!).

2.2. Kutilgan chastotalar va statistika

text
Kutilgan (H0 da):  E[i, j] = (i-qator jami) × (j-ustun jami) / umumiy jami

  A banner, klik:  1000 × 180 / 3000 = 60

Statistika:  chi2 = sum over all cells of (O - E)^2 / E      (O — kuzatilgan)
  df = (qatorlar - 1) × (ustunlar - 1)
  chi2 katta → kuzatilgan kutilgandan uzoq → p kichik

Kutilgan chastota — H0 (mustaqillik) rost bo'lsa, har katakda nechta kuzatuv bo'lishi kerakligi: chetki yig'indilardan hisoblanadi. Statistika — nisbiy og'ishlar kvadratlari yig'indisi: har katak o'z hissasini qo'shadi. Erkinlik darajasi — jadval o'lchamidan (qiymatlardan emas). Katta chi2 — kuzatilgan va kutilgan orasida katta farq.

2.3. Moslik testi (goodness of fit)

text
Savol: kuzatilgan taqsimot kutilgan taqsimotga mos keladimi?

  A/A test tekshiruvi: trafik 3 ta guruhga teng taqsimlanganmi?
  kuzatilgan: [3312, 3286, 3402], kutilgan: teng (har biri 3333.3)
  stats.chisquare(f_obs=[3312, 3286, 3402])            # teng deb faraz qiladi
  stats.chisquare(f_obs=..., f_exp=[...])              # o'z kutilganingiz bilan

df = kategoriyalar soni - 1 (agar parametr baholanmasa)

Moslik testi — bitta kategoriyali o'zgaruvchining taqsimoti nazariy taqsimotga mosligini tekshiradi: A/A testda trafik taqsimoti, zar adolatliligi, kunlar bo'yicha buyurtmalar bir tekisligi, Benford qonuni (firibgarlik tekshiruvi). Muhim: f_exp sanoqlarda beriladi va yig'indisi kuzatilganlar yig'indisiga teng bo'lishi kerak.

2.4. Standartlashtirilgan qoldiqlar

text
Qoldiq:                  O - E
Standartlashtirilgan:    r = (O - E) / sqrt(E)
Tuzatilgan (Pearson):    z = (O - E) / sqrt(E (1 - qator ulushi)(1 - ustun ulushi))

|z| > 2 — shu katak "farqning asosiy manbai" (taxminiy qoida)

Test faqat "bog'liqlik bor" deydi — qayerda ekanini qoldiqlar ko'rsatadi: qaysi kataklarda kuzatilgan kutilgandan sezilarli ko'p yoki kam. Bu — natijani biznesga tushuntirishning asosiy vositasi: "C bannerda kliklar kutilganidan 25% ko'p". Qoldiqlar xaritasini heatmap bilan ko'rsatish 5.8-bob — hisobot uchun qulay.

2.5. Effekt kattaligi (Cramer's V)

text
Cramer's V = sqrt( chi2 / (n × min(qatorlar - 1, ustunlar - 1)) )     [0, 1]

  0.1 — kuchsiz, 0.3 — o'rtacha, 0.5 — kuchli bog'liqlik (taxminiy)

2×2 uchun V = phi = sqrt(chi2 / n)

chi2 va p namuna hajmiga kuchli bog'liq: n = 1 000 000 da arzimas bog'liqlik ham p < 0.001 beradi 11.1-bob. Cramer's V — hajmdan mustaqil effekt kattaligi: bog'liqlik qanchalik kuchli. Hisobotda: chi2, p, V va qoldiqlar; hamda amaliy talqin (masalan, konversiya foizlari jadvali).

2.6. Shartlar va cheklovlar

text
1. SANOQLAR (foiz emas, o'rtacha emas) — har kuzatuv bitta katakka tushadi
2. MUSTAQIL kuzatuvlar — bir foydalanuvchi bir marta 11.3-bob
3. KUTILGAN chastotalar yetarli: barcha E >= 5 (yoki kamida 80% kataklarda)
   buzilsa: kategoriyalarni birlashtirish yoki Fisher aniq testi 11.4-bob
4. Kategoriyalar o'zaro istisno va to'liq

Eng ko'p buziladigan shart — kutilgan chastota (kam uchraydigan kategoriyalar): bunday kataklarda chi2 yaqinlashishi ishonchsiz bo'ladi (ba'zi hollarda I tur xato alfa dan oshadi, ba'zilarida — aksincha, test juda konservativ bo'lib qoladi). Yechim: mantiqiy birlashtirish ("boshqa" kategoriyasi) yoki aniq test. 2×2 jadvalda kichik namunada — Fisher 11.4-bob yoki Yates tuzatishi (scipy standart, correction=True). Diqqat: Fisher va Yates ikkalasi ham konservativ — haqiqiy I tur xato 0.05 dan ancha past bo'lishi mumkin (Misol 3), ya'ni xavfsiz, lekin quvvati kamroq.

2.7. Xi-kvadrat tuzoqlari

Asosiy tuzoqlar: foizlar bilan test (sanoqlar kerak!); soxta mustaqillik (bir foydalanuvchining ko'p yozuvi); kam kutilgan chastota (< 5 — birlashtiring yoki Fisher); faqat p (Cramer's V va qoldiqlar kerak); umumiy testdan keyin juft taqqoslashlarni tuzatmaslik 11.9-bob; sabab xulosasi (bog'liqlik ≠ sabab, 4.10); tartibli kategoriyalarni e'tiborsiz qoldirish (past/o'rta/yuqori — tartib testi kuchliroq); katta n da arzimas bog'liqlikni "muhim" deb e'lon qilish; Simpson paradoksi 8.7-bob.

2.8. Xi-kvadrat — kategoriyalar testi

Xi-kvadrat: mustaqillik testi (kontingentlik jadvali — ikki kategoriya bog'liqmi; H0: mustaqil; chi2 = sum (O-E)^2/E, df = (r-1)(c-1)) va moslik testi (bitta o'zgaruvchi nazariy taqsimotga mosmi — A/A test, adolatlilik). Qoldiqlar — qayerda farq bor; Cramer's V — bog'liqlik kuchi (n dan mustaqil). Shartlar: sanoqlar, mustaqillik, kutilgan >= 5. 2×2 da z-test bilan ekvivalent, kichik n da — Fisher. Keyingi dars — ANOVA: uch va undan ko'p guruh o'rtachalari.


3. Tez ma'lumotnoma

python
import numpy as np
import pandas as pd
from scipy import stats

jadval = pd.crosstab(df["banner"], df["klik"])            # sanoqlar!
chi2, p, df_, kutilgan = stats.chi2_contingency(jadval)

# 2x2 da Yates tuzatishisiz
stats.chi2_contingency(jadval, correction=False)

# moslik testi
stats.chisquare(f_obs=[3312, 3286, 3402])                 # teng taqsimot
stats.chisquare(f_obs=kuzatilgan, f_exp=kutilgan)         # yig'indilar teng bo'lsin

# qoldiqlar
qoldiq = (jadval.to_numpy() - kutilgan) / np.sqrt(kutilgan)

# effekt kattaligi
n = jadval.to_numpy().sum()
V = np.sqrt(chi2 / (n * (min(jadval.shape) - 1)))

# kichik namunada
stats.fisher_exact(jadval_2x2)
QOIDA: sanoqlar · E >= 5 · qoldiqlar bilan tushuntir · V bilan kuchni o'lcha

Xi-kvadrat xulosasi

Mustaqillik testi — ikki kategoriya bog'liqmi (crosstab)
E[i,j] = qator jami × ustun jami / umumiy; chi2 = sum (O-E)^2 / E
df = (r-1)(c-1); moslik testida df = k - 1
Qoldiqlar (O-E)/sqrt(E) — qaysi katak farqli
Cramer's V — bog'liqlik kuchi (n dan mustaqil)
Shart: sanoqlar, mustaqillik, E >= 5 (aks holda Fisher)

4. Batafsil misollar

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

Misol 1 — Mustaqillik testi va kutilgan chastotalar

python
"""Kontingentlik jadvali: chi2, kutilgan, qoldiqlar, Cramer's V (real numpy/pandas/scipy)."""

import numpy as np
import pandas as pd
from scipy import stats


def main() -> None:
    jadval = pd.DataFrame(
        [[950, 50], [930, 70], [900, 100]],
        index=["A banner", "B banner", "C banner"],
        columns=["klik yo'q", "klik bor"],
    )

    print("=== 1. Kuzatilgan ===")
    print(jadval.to_string())
    print(f"  klik ulushi: {(jadval['klik bor'] / jadval.sum(axis=1)).round(3).to_dict()}")

    chi2, p, df_, kutilgan = stats.chi2_contingency(jadval)
    print("\n=== 2. Kutilgan (H0: mustaqil) ===")
    print(pd.DataFrame(kutilgan.round(1), index=jadval.index, columns=jadval.columns).to_string())

    print(f"\n=== 3. Test ===")
    print(f"  chi2 = {chi2:.3f}, df = {df_}, p = {p:.5f}")

    print("\n=== 4. Qoldiqlar (O - E) / sqrt(E) ===")
    qoldiq = (jadval.to_numpy() - kutilgan) / np.sqrt(kutilgan)
    print(pd.DataFrame(qoldiq.round(2), index=jadval.index, columns=jadval.columns).to_string())

    n = jadval.to_numpy().sum()
    V = np.sqrt(chi2 / (n * (min(jadval.shape) - 1)))
    print(f"\n  Cramer's V = {V:.4f} (kuchsiz bog'liqlik)")
    print("  ⭐ Test — 'bormi'; qoldiqlar — 'qayerda'; V — 'qanchalik kuchli'")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Kuzatilgan ===
          klik yo'q  klik bor
A banner        950        50
B banner        930        70
C banner        900       100
  klik ulushi: {'A banner': 0.05, 'B banner': 0.07, 'C banner': 0.1}

=== 2. Kutilgan (H0: mustaqil) ===
          klik yo'q  klik bor
A banner      926.7      73.3
B banner      926.7      73.3
C banner      926.7      73.3

=== 3. Test ===
  chi2 = 18.640, df = 2, p = 0.00009

=== 4. Qoldiqlar (O - E) / sqrt(E) ===
          klik yo'q  klik bor
A banner       0.77     -2.72
B banner       0.11     -0.39
C banner      -0.88      3.11

  Cramer's V = 0.0788 (kuchsiz bog'liqlik)
  ⭐ Test — 'bormi'; qoldiqlar — 'qayerda'; V — 'qanchalik kuchli'

Nima ko'rsatdi: 2.1, 2.2, 2.4, 2.5-bo'limlar.

Misol 2 — Moslik testi: A/A trafik tekshiruvi

python
"""Moslik testi: trafik teng taqsimlanganmi; zar adolatlimi (real numpy/scipy)."""

import numpy as np
from scipy import stats


def main() -> None:
    print("=== 1. A/A test: 3 guruhga teng taqsimot ===")
    kuzatilgan = np.array([3312, 3286, 3402])
    res = stats.chisquare(f_obs=kuzatilgan)
    print(f"  kuzatilgan: {kuzatilgan.tolist()}, kutilgan: {kuzatilgan.sum() / 3:.1f} har birida")
    print(f"  chi2 = {res.statistic:.3f}, p = {res.pvalue:.4f} → taqsimot normal")

    print("\n=== 2. Buzilgan taqsimot (bug: 50/25/25 o'rniga 33/33/33 kutilgan) ===")
    buzuq = np.array([4900, 2600, 2500])
    res2 = stats.chisquare(f_obs=buzuq)
    print(f"  kuzatilgan: {buzuq.tolist()}, chi2 = {res2.statistic:.1f}, p = {res2.pvalue:.2e}")

    print("\n=== 3. O'z kutilgan taqsimotingiz bilan ===")
    # dam olish kunlarida 2 barobar ko'p buyurtma kutiladi
    kuz = np.array([300, 290, 310, 305, 320, 610, 590])
    ulush = np.array([1, 1, 1, 1, 1, 2, 2], dtype=float)
    kut = ulush / ulush.sum() * kuz.sum()
    res3 = stats.chisquare(f_obs=kuz, f_exp=kut)
    print(f"  kutilgan: {kut.round(0).tolist()}")
    print(f"  chi2 = {res3.statistic:.2f}, p = {res3.pvalue:.3f}")

    print("\n=== 4. Simulyatsiya: H0 da p tekismi ===")
    rng = np.random.default_rng(0)
    p_lar = [stats.chisquare(rng.multinomial(3000, [1/3, 1/3, 1/3])).pvalue for _ in range(5000)]
    print(f"  p < 0.05 ulushi: {np.mean(np.array(p_lar) < 0.05):.3f}")
    print("  ⭐ Moslik testi — kutilgan taqsimot bilan solishtirish")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. A/A test: 3 guruhga teng taqsimot ===
  kuzatilgan: [3312, 3286, 3402], kutilgan: 3333.3 har birida
  chi2 = 2.223, p = 0.3290 → taqsimot normal

=== 2. Buzilgan taqsimot (bug: 50/25/25 o'rniga 33/33/33 kutilgan) ===
  kuzatilgan: [4900, 2600, 2500], chi2 = 1106.0, p = 6.84e-241

=== 3. O'z kutilgan taqsimotingiz bilan ===
  kutilgan: [303.0, 303.0, 303.0, 303.0, 303.0, 606.0, 606.0]
  chi2 = 2.17, p = 0.904

=== 4. Simulyatsiya: H0 da p tekismi ===
  p < 0.05 ulushi: 0.051
  ⭐ Moslik testi — kutilgan taqsimot bilan solishtirish

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Shartlar: kam kutilgan chastota va 2×2

python
"""Kam kutilgan chastota muammosi; 2x2 da chi2, Yates va Fisher (real numpy/scipy)."""

import numpy as np
from scipy import stats


def main() -> None:
    print("=== 1. 2x2: chi2 (Yates bilan/siz) va Fisher ===")
    jadval = np.array([[50, 950], [70, 930]])
    chi2_y, p_y, *_ = stats.chi2_contingency(jadval)
    chi2_n, p_n, *_ = stats.chi2_contingency(jadval, correction=False)
    _, p_f = stats.fisher_exact(jadval)
    z_kvadrat = chi2_n
    print(f"  Yates bilan: p = {p_y:.4f}")
    print(f"  Yatessiz:    p = {p_n:.4f}  (chi2 = {chi2_n:.3f} = z^2)")
    print(f"  Fisher:      p = {p_f:.4f}")

    print("\n=== 2. Kam kutilgan chastota: E < 5 ===")
    kichik = np.array([[1, 29], [7, 23]])
    chi2, p, df_, kut = stats.chi2_contingency(kichik, correction=False)
    print(f"  kutilgan: {kut.round(2).tolist()}")
    print(f"  chi2 p = {p:.4f}, Fisher p = {stats.fisher_exact(kichik)[1]:.4f}")

    print("\n=== 3. Simulyatsiya: E kichik bo'lganda I tur xato ===")
    rng = np.random.default_rng(1)
    N = 20_000
    yolgon_chi2 = yolgon_fisher = 0
    for _ in range(N):
        a = rng.binomial(30, 0.08); b = rng.binomial(30, 0.08)
        t = np.array([[a, 30 - a], [b, 30 - b]])
        if min(t.sum(axis=0).min(), t.sum(axis=1).min()) == 0:
            continue
        yolgon_chi2 += stats.chi2_contingency(t, correction=False)[1] < 0.05
        yolgon_fisher += stats.fisher_exact(t)[1] < 0.05
    print(f"  chi2 (Yatessiz): {yolgon_chi2 / N:.4f}, Fisher: {yolgon_fisher / N:.4f}  (kutilgan 0.05)")
    print("  ⭐ Fisher konservativ (alfa dan past) — xavfsiz, lekin quvvati kamroq")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. 2x2: chi2 (Yates bilan/siz) va Fisher ===
  Yates bilan: p = 0.0736
  Yatessiz:    p = 0.0597  (chi2 = 3.546 = z^2)
  Fisher:      p = 0.0732

=== 2. Kam kutilgan chastota: E < 5 ===
  kutilgan: [[4.0, 26.0], [4.0, 26.0]]
  chi2 p = 0.0227, Fisher p = 0.0523

=== 3. Simulyatsiya: E kichik bo'lganda I tur xato ===
  chi2 (Yatessiz): 0.0474, Fisher: 0.0058  (kutilgan 0.05)
  ⭐ Fisher konservativ (alfa dan past) — xavfsiz, lekin quvvati kamroq

Nima ko'rsatdi: 2.6, 2.7-bo'limlar.

Misol 4 — n ning ta'siri va Cramer's V

python
"""Katta n da arzimas bog'liqlik ham 'muhim'; V — hajmdan mustaqil (real numpy/scipy)."""

import numpy as np
from scipy import stats


def tahlil(jadval: np.ndarray) -> tuple[float, float, float]:
    chi2, p, _, _ = stats.chi2_contingency(jadval, correction=False)
    n = jadval.sum()
    V = np.sqrt(chi2 / (n * (min(jadval.shape) - 1)))
    return chi2, p, V


def main() -> None:
    print("=== 1. Bir xil ulushlar (10.0% va 10.5%), turli n ===")
    for n in [1_000, 10_000, 100_000, 1_000_000]:
        a = np.array([[round(n * 0.10), n - round(n * 0.10)],
                      [round(n * 0.105), n - round(n * 0.105)]])
        chi2, p, V = tahlil(a)
        print(f"  n={n:>9,} har guruhda: chi2 = {chi2:8.2f}, p = {p:.2e}, V = {V:.4f}")

    print("\n=== 2. Kuchli bog'liqlik, kichik n ===")
    b = np.array([[40, 10], [10, 40]])
    chi2, p, V = tahlil(b)
    print(f"  n=100: chi2 = {chi2:.2f}, p = {p:.2e}, V = {V:.3f}  (kuchli)")

    print("\n=== 3. Xulosa ===")
    print("  p — n bilan o'sadi; V — bog'liqlik kuchini beradi")
    print("  ⭐ Hisobot: jadval, foizlar, chi2, p, V, qoldiqlar")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bir xil ulushlar (10.0% va 10.5%), turli n ===
  n=    1,000 har guruhda: chi2 =     0.14, p = 7.12e-01, V = 0.0082
  n=   10,000 har guruhda: chi2 =     1.36, p = 2.44e-01, V = 0.0082
  n=  100,000 har guruhda: chi2 =    13.59, p = 2.28e-04, V = 0.0082
  n=1,000,000 har guruhda: chi2 =   135.88, p = 2.12e-31, V = 0.0082

=== 2. Kuchli bog'liqlik, kichik n ===
  n=100: chi2 = 36.00, p = 1.97e-09, V = 0.600  (kuchli)

=== 3. Xulosa ===
  p — n bilan o'sadi; V — bog'liqlik kuchini beradi
  ⭐ Hisobot: jadval, foizlar, chi2, p, V, qoldiqlar

Nima ko'rsatdi: 2.5-bo'lim.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Foizlar bilan chi2" Sanoqlar kerak
"chi2 qayerda farq borligini aytadi" Qoldiqlar aytadi
"p kichik — kuchli bog'liqlik" Cramer's V ni ko'ring
"E < 5 muammo emas" Fisher yoki birlashtirish
"2x2 uchun chi2 va z-test har xil" Ekvivalent (chi2 = z^2)
"Bog'liqlik — sabab" Aloqa (4.10)
"Ko'p juft taqqoslash mayli" Avval umumiy test + tuzatish
"Yates tuzatishi doim yaxshi" Ko'pincha juda konservativ

6. Keng tarqalgan xatolar va yechimlari

1. Foizlar bilan

python
stats.chi2_contingency([[0.10, 0.90], [0.12, 0.88]])              # ⚠️
stats.chi2_contingency([[100, 900], [120, 880]])                  # ✅

2. normalize bilan crosstab

python
j = pd.crosstab(df.a, df.b, normalize="index")                    # ⚠️
j = pd.crosstab(df.a, df.b)                                       # ✅

3. Kam kutilgan chastota

python
stats.chi2_contingency(kichik_jadval)                             # ⚠️
stats.fisher_exact(kichik_jadval)   # yoki kategoriyalarni birlashtiring  # ✅

4. Faqat p

python
print("p =", p)                                                   # ⚠️
print(f"chi2={chi2:.2f}, p={p:.4f}, V={V:.3f}"); print(qoldiqlar) # ✅

5. Soxta mustaqillik

python
pd.crosstab(sessiyalar["banner"], sessiyalar["klik"])             # ⚠️
pd.crosstab(foydalanuvchilar["banner"], foydalanuvchilar["klik"]) # ✅

6. Umumiy testsiz juft taqqoslash

python
for a, b in combinations(variantlar, 2): fisher_exact(...)        # ⚠️
chi2_contingency(toliq_jadval)   # keyin tuzatish bilan 11.9-bob     # ✅

7. Tartibli kategoriyalar

python
chi2_contingency(jadval)   # past/o'rta/yuqori — tartib yo'qoladi  # ⚠️
stats.spearmanr(daraja, natija)   # yoki tartib testi              # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 8.4-dars (o'tilgan): Kontingentlik jadvali, crosstab
  • 9.3-dars (o'tilgan): Mustaqillik ta'rifi
  • 11.4-dars (o'tilgan): Proporsiyalar (2×2 ekvivalenti)
  • 11.9-dars: Ko'p taqqoslash tuzatishlari
  • Feature engineering qismi: Kategoriyali belgilar tanlovi

8. Eng yaxshi amaliyotlar

  1. Sanoqlar bilan ishlang.

  2. Kutilgan chastotalarni tekshiring (E >= 5).

  3. Qoldiqlar bilan tushuntiring.

  4. Cramer's V ni hisobot qiling.

  5. Foizlar jadvalini ham ko'rsating.

  6. Umumiy testdan keyin tuzatilgan juft taqqoslash.

  7. Mustaqil birlikni ta'minlang.

  8. Tartibli kategoriyalar uchun tartib testi.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # chi2 mustaqillik testida H0?
2.  # kutilgan chastota formulasi?
3.  # df (3x2 jadval)?
4.  # df (moslik, 5 kategoriya)?
5.  # chi2 statistikasi formulasi?
6.  # qoldiq formulasi?
7.  # |z| > 2 nimani anglatadi?
8.  # Cramer's V nima uchun?
9.  # E < 5 bo'lsa?
10. # 2x2 da chi2 va z-test?
11. # foizlar bilan test mumkinmi?
12. # bog'liqlik = sabab?
Javoblar
  1. Ikki kategoriya mustaqil
  2. Qator jami × ustun jami / umumiy
  3. 2
  4. 4
  5. sum (O-E)^2 / E
  6. (O-E)/sqrt(E)
  7. Katak farqning asosiy manbai
  8. Bog'liqlik kuchi (n dan mustaqil)
  9. Fisher yoki birlashtirish
  10. Ekvivalent (chi2 = z^2)
  11. Yo'q
  12. Yo'q

Vazifa 2: Xatolarni tuzating

python
1.  stats.chi2_contingency(pd.crosstab(df.a, df.b, normalize="index"))

2.  stats.chi2_contingency([[2, 18], [1, 19]])

3.  print("bog'liqlik bor, p =", p)   # hisobot

4.  pd.crosstab(sessiya["variant"], sessiya["xarid"])

5.  chi2_contingency(jadval)   # daraja: past/o'rta/yuqori
Javoblar
python
1.  stats.chi2_contingency(pd.crosstab(df.a, df.b))

2.  stats.fisher_exact([[2, 18], [1, 19]])

3.  print(f"chi2={chi2:.2f}, p={p:.4f}, V={V:.3f}, qoldiqlar:", qoldiq)

4.  pd.crosstab(user_df["variant"], user_df["xarid"])

5.  stats.spearmanr(daraja_kodi, natija)

Vazifa 3: A/B/C tahlili

Modellang:

  1. 3 variant × 2 natija jadvali
  2. chi2, qoldiqlar, V
  3. Qaysi variant farq qiladi
  4. Tuzatilgan juft taqqoslashlar

Vazifa 4: A/A tekshiruvi

Modellang:

  1. Trafik taqsimoti (3 guruh)
  2. Moslik testi
  3. Buzilgan holat (bug)
  4. Monitoring qoidasi

Vazifa 5: Shartlar

Modellang:

  1. Kam hodisali jadval
  2. chi2 va Fisher
  3. Simulyatsiya bilan I tur xato
  4. Kategoriyalarni birlashtirish

Vazifa 6: Integratsiya

Modellang:

  1. crosstab (8.4)
  2. Mustaqillik (9.3)
  3. Proporsiyalar (11.4)
  4. Ko'p taqqoslash (11.9 ga tayyorgarlik)

Vazifa 7: O'ylash

Xi-kvadrat testi "bog'liqlik bor" deb javob beradi, lekin ko'pincha bu javob o'z-o'zidan foydasiz: katta ma'lumotda deyarli har qanday ikki kategoriya "bog'liq" chiqadi. Nima uchun shunday, va kategoriyali ma'lumot tahlilida qanday savol berish kerak?

Javob

Qisqa javob: haqiqiy dunyoda mutlaq mustaqillik deyarli uchramaydi — har doim kichik bog'liqlik bor. Katta n da test shu kichik bog'liqlikni ham aniqlaydi. Shuning uchun "bog'liqmi?" savoli o'rniga "qanchalik kuchli va qayerda?" savoli berilishi kerak.

1. Nega hamma narsa "bog'liq"

  • H0 (aniq mustaqillik) — ideallashtirilgan holat
  • n oshgani sari kichik og'ishlar ham aniqlanadi (11.1)
  • chi2 ~ n × (bog'liqlik kuchi)^2

2. Yaxshiroq savollar

Savol Vosita
Qanchalik kuchli? Cramer's V
Qayerda farq? Qoldiqlar, foizlar jadvali
Amaliy ahamiyati? Konversiya farqi × trafik
Barqarormi? Segment va davrlar bo'yicha takrorlash
Sabab bormi? Eksperiment (4.10)

3. Amaliy yondashuv

  1. Foizlar jadvalini chizish (ko'z bilan ko'rish)
  2. Effekt kattaligi va ishonch oraliqlari
  3. Qoldiqlar heatmap (5.8)
  4. Faqat keyin — p-qiymat

4. Data Scientist qanday

  • p ni "signal bormi" filtri sifatida ishlatadi, xulosa sifatida emas
  • Biznes uchun farqni tushunarli birlikda beradi
  • Katta ma'lumotda amaliy chegarani oldindan belgilaydi

5. Xulosa

  1. Katta n da "bog'liqlik bor" — deyarli har doim
  2. Kuch (V) va joy (qoldiqlar) — asosiy natija
  3. Amaliy ahamiyat biznes birligida o'lchanadi
  4. Sabab uchun eksperiment kerak

Nimani mustahkamlaydi: 2.4, 2.5-bo'limlar.


Xulosa

Bu darsda xi-kvadrat testlarini o'rgandik.

Eng muhim uch fikr:

  1. Ikki test. Mustaqillik testi — kontingentlik jadvalida ikki kategoriya bog'liqligini tekshiradi (H0: mustaqil; kutilgan = qator jami × ustun jami / umumiy; chi2 = sum (O-E)^2/E; df = (r-1)(c-1)). Moslik testi — bitta o'zgaruvchi taqsimoti nazariy taqsimotga mosligini (A/A test, adolatlilik).

  2. Qayerda va qanchalik. Test faqat "bog'liqlik bor" deydi. Standartlashtirilgan qoldiqlar (O-E)/sqrt(E) — qaysi kataklar farqni yaratgani; Cramer's V — bog'liqlik kuchi (n dan mustaqil). Hisobotda: sanoqlar va foizlar jadvali, chi2, p, V, qoldiqlar.

  3. Shartlar. Sanoqlar (foiz emas), mustaqil kuzatuvlar (foydalanuvchi darajasi), kutilgan chastota >= 5 (aks holda birlashtirish yoki Fisher — u konservativ: xavfsiz, lekin quvvati kamroq). 2×2 da z-test bilan ekvivalent. Katta n da arzimas bog'liqlik ham "muhim" — amaliy ahamiyatni alohida baholang.

Keyingi darsda ANOVAni o'rganamiz: uch va undan ko'p guruh o'rtachalarini bir vaqtda solishtirish, F-statistikasi, post-hoc testlar va farazlar.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
11.5-dars: Xi-kvadrat testlari — IlmHamroh