Məzmuna keç
Educora
Universitet25 dəq34 / 42

Python ilə statistika

Təsviri statistika, kənar qiymətlər, normal paylanma və `scipy.stats`, mərkəzi limit teoremi, etibarlılıq intervalı, t-testi və korrelyasiya — düsturlar, əl ilə həll olunmuş nümunələr və işlək kodla.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Orta, median, standart meyl və IQR hesablamaq, kənar qiymətləri tapmaq
  • Normal paylanmada ehtimalları və kvantilləri scipy.stats.norm ilə tapmaq
  • Orta üçün etibarlılıq intervalı qurmaq və t-testinin p-qiymətini düzgün şərh etmək
  • Pirson və Spirmen korrelyasiyasını hesablamaq, korrelyasiyanı səbəbiyyətdən ayırmaq

Yemək çatdırılması xidməti Bakıda «orta hesabla 15 dəqiqəyə» çatdırmağı vəd edir. Murad 10 sifarişin vaxtını ölçdü. Bəs bu, vədi yoxlamaq üçün kifayətdirmi? Bir sifariş 45 dəqiqə çəkibsə, nəticəyə necə təsir edir? Statistika üç addımla cavab verir: verilənləri təsvir et, onları paylanma ilə modelləşdir və seçmədən bütün baş məcmu haqqında nəticə çıxar. Python-da bunun üçün NumPy və scipy.stats kifayətdir.

Təsviri statistika və kənar qiymətlər

Mərkəzi göstəricilər «tipik» qiyməti verir: orta (ədədi orta), median (sıralanmış verilənlərin ortası) və moda (ən çox rast gəlinən qiymət). Səpələnmə göstəriciləri qiymətlərin nə qədər dağınıq olduğunu ölçür: dispersiya, standart meyl və kvartillərarası məsafə IQR = Q3 − Q1. Seçmə üçün dispersiyanı n − 1-ə bölürük (Bessel düzəlişi) — belə qiymətləndirmə sürüşməsiz olur.

x̄ = (1/n) · ∑ xᵢ s² = ∑ (xᵢ − x̄)² / (n − 1) s = √s²x̄ = (1/n) · ∑ xᵢ s² = ∑ (xᵢ − x̄)² / (n − 1) s = √s²
burada:
  • nseçmənin həcmi
  • s²seçmə dispersiyası (vahidi — verilənlərin vahidinin kvadratı)
  • sseçmə standart meyli (verilənlərlə eyni vahiddə); NumPy-da std(ddof=1)
Python
import numpy as np
from scipy import stats

minutes = np.array([12, 15, 11, 14, 13, 45, 13, 16, 14, 13])
print('mean  :', minutes.mean())
print('median:', np.median(minutes))
print('mode  :', stats.mode(minutes, keepdims=False).mode)
print('var   :', round(minutes.var(ddof=1), 2))
print('std   :', round(minutes.std(ddof=1), 2))
q1, q3 = np.percentile(minutes, [25, 75])
iqr = q3 - q1
print('Q1, Q3, IQR:', q1, q3, iqr)
low, high = q1 - 1.5 * iqr, q3 + 1.5 * iqr
print('outliers:', minutes[(minutes < low) | (minutes > high)])
▸ Gözlənilən nəticə
mean  : 16.6
median: 13.5
mode  : 13
var   : 101.6
std   : 10.08
Q1, Q3, IQR: 13.0 14.75 1.75
outliers: [45]
Bir 45 dəqiqəlik sifariş ortanı 16,6 dəqiqəyə qaldırır və standart meyli 10 dəqiqəyə çatdırır, median isə 13,5 dəqiqədə qalır. Bu sifariş olmasaydı, orta 13,44 dəqiqə olardı.
[Q1 − 1,5 · IQR; Q3 + 1,5 · IQR]
burada:
  • Q1, Q3birinci və üçüncü kvartil (25% və 75%)
  • IQRQ3 − Q1, verilənlərin ortadakı yarısının eni

Tükinin qaydası: bu intervaldan kənardakı qiymətlər kənar qiymət (outlier) sayılır. Burada: 14,75 + 1,5 · 1,75 = 17,375, deməli, 45 kənar qiymətdir.

Normal paylanma

Çoxlu kiçik müstəqil təsirin cəmi olan kəmiyyətlər (ölçmə xətaları, test balları, boy) çox vaxt normal paylanmaya yaxın olur: zəng şəkilli, orta ətrafında simmetrik əyri. Onu iki parametr müəyyən edir: orta μ və standart meyl σ. Hər qiyməti z-bal ilə standartlaşdırmaq olar — o, qiymətin ortadan neçə σ uzaqda olduğunu göstərir.

f(x) = 1 / (σ · √(2π)) · e^(−(x − μ)² / (2σ²)) z = (x − μ) / σf(x) = 1 / (σ · √(2π)) · e^(−(x − μ)² / (2σ²)) z = (x − μ) / σ
burada:
  • μpaylanmanın ortası
  • σstandart meyl (σ > 0)
  • f(x)ehtimal sıxlığı; P(a < X < b) — əyri altında a ilə b arasındakı sahədir
  • zz-bal: standart normal paylanmada (μ = 0, σ = 1) mövqe

scipy.stats.norm paylanma obyekti yaradır: cdf(x) = P(X ≤ x) (paylanma funksiyası), sf(x) = P(X > x) = 1 − cdf, ppf(q) isə tərs əməliyyatdır — verilən ehtimala uyğun kvantil. Test balları μ = 70, σ = 10 ilə normal paylanıbsa:

Python
from scipy import stats

scores = stats.norm(loc=70, scale=10)
print(round(scores.cdf(85), 4))
print(round(scores.sf(85), 4))
print(round(scores.cdf(80) - scores.cdf(60), 4))
print(round(scores.ppf(0.90), 2))
z = (85 - 70) / 10
print(z, round(stats.norm.cdf(z), 4))
▸ Gözlənilən nəticə
0.9332
0.0668
0.6827
82.82
1.5 0.9332
Nümunə 1: z-bal və ehtimal

Test balları N(70; 10²) paylanıb. a) Təsadüfi seçilmiş tələbənin 85-dən çox bal toplaması ehtimalı nədir? b) Ən yaxşı 10%-ə düşmək üçün neçə bal lazımdır? Φ(1,5) = 0,9332, z₀,₉₀ = 1,2816.

Həllini göstər
a) z = (85 − 70) / 10 = 1,5.
P(X > 85) = 1 − Φ(1,5) = 1 − 0,9332 = 0,0668, yəni təxminən 6,7%.
b) x = μ + z₀,₉₀ · σ = 70 + 1,2816 · 10 ≈ 82,8 bal.
Hər iki cavab kodla (sf(85) və ppf(0.90)) üst-üstə düşür.

Seçmə, mərkəzi limit teoremi və standart xəta

Biz adətən bütün baş məcmunu (bütün sifarişlər) yox, yalnız seçməni görürük. Hər yeni seçmənin ortası bir az fərqli olur. Mərkəzi limit teoremi deyir: n kifayət qədər böyük olanda seçmə ortalarının paylanması, ilkin paylanma əyri olsa belə, normala yaxınlaşır və onun standart meyli — standart xəta — σ/√n-ə bərabərdir. Aşağıda əyri eksponensial paylanmadan 30-luq 5000 seçmə götürülür:

SE = σ / √n ≈ s / √nSE = σ / √n ≈ s / √n
burada:
  • SEortanın standart xətası
  • σ, sbaş məcmunun və seçmənin standart meyli
Python
import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(1)
population = rng.exponential(scale=10, size=100_000)
means = rng.choice(population, size=(5000, 30)).mean(axis=1)
print(f'population: mean {population.mean():.2f}, std {population.std():.2f}')
print(f'sample means: mean {means.mean():.2f}, std {means.std():.2f}')
print(f'sigma / sqrt(n) = {population.std() / np.sqrt(30):.2f}')

fig, (a, b) = plt.subplots(1, 2, figsize=(8, 3), layout='constrained')
a.hist(population, bins=50)
a.set_title('Population (skewed)')
b.hist(means, bins=40)
b.set_title('Means of samples, n = 30')
plt.show()
▸ Gözlənilən nəticə
population: mean 9.96, std 9.92
sample means: mean 9.94, std 1.81
sigma / sqrt(n) = 1.81
Sağdakı histoqram demək olar ki, simmetrik zəngdir, onun səpələnməsi (1,81) isə düz σ/√30 qədərdir.

Etibarlılıq intervalı və t-testi

σ məlum olmayanda onu s ilə əvəz edirik və normal əvəzinə sərbəstlik dərəcəsi n − 1 olan Styudent t-paylanmasından istifadə edirik — kiçik seçmələrdə onun «quyruqları» daha qalındır. Fabrik xəttindən 100 qramlıq 10 paket çay çəkilib:

x̄ ± t* · s / √n, t* = t₁₋α/₂(n − 1)x̄ ± t* · s / √n, t* = t₁₋α/₂(n − 1)
burada:
  • t*t-paylanmasının kritik qiyməti; 95% üçün α = 0,05
  • n − 1sərbəstlik dərəcələrinin sayı

Orta üçün 95% etibarlılıq intervalı. stats.t.ppf(0.975, df=n - 1) t*-ı, stats.t.interval isə bütün intervalı qaytarır.

Python
import numpy as np
from scipy import stats

packs = np.array([99.2, 100.4, 98.7, 100.9, 99.5, 100.1, 99.8, 98.9, 100.6, 99.4])
n = packs.size
mean = packs.mean()
s = packs.std(ddof=1)
se = s / np.sqrt(n)
t_crit = stats.t.ppf(0.975, df=n - 1)
print(f'mean = {mean:.2f} g, s = {s:.3f} g, SE = {se:.3f} g')
print(f't* = {t_crit:.3f}')
print(f'95% CI: [{mean - t_crit * se:.2f}; {mean + t_crit * se:.2f}] g')
low, high = stats.t.interval(0.95, df=n - 1, loc=mean, scale=se)
print(round(low, 2), round(high, 2))
▸ Gözlənilən nəticə
mean = 99.75 g, s = 0.738 g, SE = 0.233 g
t* = 2.262
95% CI: [99.22; 100.28] g
99.22 100.28
Nümunə 2: etibarlılıq intervalı əl ilə

16 tələbənin imtahana hazırlaşma vaxtı: x̄ = 52 saat, s = 8 saat. Orta üçün 95% etibarlılıq intervalını tap. t₀,₉₇₅(15) = 2,131.

Həllini göstər
SE = s / √n = 8 / √16 = 8 / 4 = 2 saat.
Xəta payı = t* · SE = 2,131 · 2 = 4,262.
İnterval: 52 ± 4,26 → [47,74; 56,26] saat.
Seçməni 64 tələbəyə qədər artırsaq, SE 1-ə düşər və interval təxminən iki dəfə daralar (√n qanunu).

Fərziyyənin yoxlanması sualı belə qoyur: sıfır fərziyyəsi H₀ («fərq yoxdur») doğru olsaydı, müşahidə etdiyimiz qədər və ya daha böyük fərqin alınma ehtimalı — p-qiyməti — nə qədər olardı? p < α (adətən 0,05) olarsa, H₀-ı rədd edirik. Bir seçməli t-testi ortanı verilmiş ədədlə, iki seçməli test isə iki qrupun ortalarını müqayisə edir; qrupların dispersiyaları fərqli ola bildiyi üçün Uelç variantını (equal_var=False) seçirik.

t = (x̄₁ − x̄₂) / √(s₁²/n₁ + s₂²/n₂)t = (x̄₁ − x̄₂) / √(s₁²/n₁ + s₂²/n₂)
burada:
  • x̄₁, x̄₂qrupların ortaları
  • s₁², s₂²qrupların seçmə dispersiyaları
  • n₁, n₂qrupların həcmi

Uelç t-statistikası: ortaların fərqi, onun standart xətasına bölünür. |t| nə qədər böyükdürsə, p o qədər kiçikdir.

Python
import numpy as np
from scipy import stats

packs = np.array([99.2, 100.4, 98.7, 100.9, 99.5, 100.1, 99.8, 98.9, 100.6, 99.4])
res1 = stats.ttest_1samp(packs, popmean=100)
print(f'one-sample: t = {res1.statistic:.3f}, p = {res1.pvalue:.3f}')

group_a = np.array([72, 85, 78, 90, 66, 81, 77, 88, 74, 83])
group_b = np.array([80, 91, 86, 94, 79, 88, 85, 97, 82, 90])
print(group_a.mean(), group_b.mean())
res2 = stats.ttest_ind(group_b, group_a, equal_var=False)
print(f'Welch: t = {res2.statistic:.3f}, p = {res2.pvalue:.4f}')
▸ Gözlənilən nəticə
one-sample: t = -1.071, p = 0.312
79.4 87.2
Welch: t = 2.581, p = 0.0194
Paketlər: p = 0,312 > 0,05 — orta çəkinin 100 q-dan fərqləndiyinə dair sübut yoxdur. Qruplar (A — köhnə, B — yeni tədris üsulu): p ≈ 0,019 < 0,05 — fərq statistik əhəmiyyətlidir.

Korrelyasiya

Pirson korrelyasiya əmsalı r iki dəyişən arasındakı xətti əlaqənin gücünü və istiqamətini −1-dən 1-ə qədər ölçür; r² isə y-in variasiyasının neçə hissəsinin x ilə xətti izah olunduğunu göstərir. Spirmen əmsalı ρ eyni hesablamanı ranqlar (sıra nömrələri) üzərində aparır, ona görə kənar qiymətlərə davamlıdır və istənilən monoton əlaqəni tutur.

r = ∑ (xᵢ − x̄)(yᵢ − ȳ) / √( ∑ (xᵢ − x̄)² · ∑ (yᵢ − ȳ)² )r = ∑ (xᵢ − x̄)(yᵢ − ȳ) / √( ∑ (xᵢ − x̄)² · ∑ (yᵢ − ȳ)² )
burada:
  • r−1 ≤ r ≤ 1; işarə istiqaməti, |r| gücü göstərir
  • x̄, ȳhər dəyişənin ortası
Python
import numpy as np
from scipy import stats

hours = np.array([1, 2, 2, 3, 4, 5, 5, 6, 7, 8])
score = np.array([52, 55, 61, 60, 68, 70, 75, 74, 82, 88])
r, p = stats.pearsonr(hours, score)
rho, _ = stats.spearmanr(hours, score)
print(f'Pearson r = {r:.3f}, p = {p:.1e}')
print(f'Spearman rho = {rho:.3f}')
print(f'r squared = {r ** 2:.3f}')
print(np.corrcoef(hours, score).round(3))
▸ Gözlənilən nəticə
Pearson r = 0.980, p = 6.5e-07
Spearman rho = 0.957
r squared = 0.961
[[1.   0.98]
 [0.98 1.  ]]
Hazırlıq saatları ilə bal arasında çox güclü müsbət əlaqə var: balın variasiyasının 96%-i saatlarla xətti izah olunur. np.corrcoef korrelyasiya matrisini qaytarır.
Nümunə 3: r-i əl ilə hesablayaq

x = (1, 2, 3, 4, 5), y = (2, 4, 5, 4, 5). Pirson korrelyasiya əmsalını tap.

Həllini göstər
x̄ = 3, ȳ = 4.
xᵢ − x̄: −2, −1, 0, 1, 2; yᵢ − ȳ: −2, 0, 1, 0, 1.
Hasillərin cəmi: 4 + 0 + 0 + 0 + 2 = 6.
∑ (xᵢ − x̄)² = 10, ∑ (yᵢ − ȳ)² = 4 + 0 + 1 + 0 + 1 = 6.
r = 6 / √(10 · 6) = 6 / √60 ≈ 0,775; r² ≈ 0,6.
Yoxlama: np.corrcoef(x, y)[0, 1] → 0,7746.
Tapşırıq

data massivi üçün birinci sətirdə ortanı (1 onluq rəqəmlə), medianı və seçmə standart meylini (ddof=1, 2 onluq rəqəmlə) boşluqla ayıraraq çap et. İkinci sətirdə Tükinin 1,5 · IQR qaydasına görə kənar qiymətlərin siyahısını çap et.

Tapşırıq · Python
import numpy as np

data = np.array([48, 52, 50, 47, 53, 51, 49, 95, 50, 52])
# line 1: mean (1 decimal), median, sample std (2 decimals)
# line 2: outliers as a list
▸ Gözlənilən nəticə
54.7 50.5 14.28
[95]
Tapşırıq

Laboratoriyada 8 ölçmə aparılıb. Birinci sətirdə seçmə ortasını, ikinci sətirdə orta üçün 95% etibarlılıq intervalının aşağı və yuxarı sərhədlərini (boşluqla) çap et; hamısı 2 onluq rəqəmə qədər yuvarlaqlaşdırılsın. stats.t.ppf ilə t*-ı tap.

Tapşırıq · Python
import numpy as np
from scipy import stats

sample = np.array([23.1, 24.5, 22.8, 25.0, 23.9, 24.2, 23.5, 24.8])
# mean, then the 95% confidence interval
▸ Gözlənilən nəticə
23.98
23.31 24.64

Əsas fikirlər

  • Seçmə dispersiyası n − 1-ə bölünür (ddof=1); əyri verilənlər üçün median və IQR daha etibarlıdır.
  • Tükinin qaydası: [Q1 − 1,5 · IQR; Q3 + 1,5 · IQR] xaricindəki qiymətlər kənar qiymətlərdir.
  • z = (x − μ) / σ; norm.cdf, norm.sf, norm.ppf ehtimal və kvantilləri verir; 68–95–99,7 qaydası.
  • Standart xəta SE = s / √n; orta üçün interval x̄ ± t* · SE.
  • p < α olanda H₀ rədd edilir, amma p nə H₀-ın ehtimalı, nə də effektin ölçüsüdür.
  • Pirson r xətti əlaqəni ölçür, Spirmen ρ ranqlarla işləyir; korrelyasiya səbəbiyyəti sübut etmir.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Maaşlar: 800, 900, 950, 1000, 12 000 manat. Hansı göstərici «tipik» maaşı daha yaxşı təsvir edir?