Vektor va matritsa — ma'lumotning tili
Sahna: nega matematika kerak
Siz 10-bobga qadar model qurdingiz, bahladingiz, xatolarini tahlil qildingiz. Matematika kerak bo'lmadi.
Shunday bo'lsa, nega endi kerak?
Chunki fit() ning ichida nima bo'layotganini bilmasangiz, siz uchta narsani qilolmaysiz:
- Model nega aynan shunday bashorat qilganini tushuntirish
- Model yiqilganda nega yiqilganini topish
- Yangi algoritmni o'rganganda uni oldingilariga bog'lash
Bu qism — kitobdagi eng "matematik" uch bob. Lekin qo'rqmang: bizga faqat uchta amal kerak bo'ladi, va ularning hammasini numpy bajaradi.
Agar matematikadan qo'rqsangiz
Bu bobni o'tkazib yuborib, 14-bobga o'tsangiz ham kitob ishlaydi. Keyin qaytib kelasiz.
Lekin bitta narsani bilib qo'ying: pastdagi skalyar ko'paytma — bu butun ML dagi eng muhim amal. U logistic regression da ham, neyron tarmoqda ham, Transformer da ham aynan bir xil ishlaydi.
Bitta qator — bu vektor
import pandas as pd import numpy as np df = pd.read_csv(DATA / "uy_ijara.csv") son = ["xonalar", "maydon_m2", "metro_km", "mebel"] bitta = df.loc[0, son] print("Bitta kvartira (bitta qator):") print(bitta.to_string()) print() x = bitta.to_numpy(dtype=float) print("numpy vektori:", x) print("shakli (shape):", x.shape, " -> 4 ta son")
Bitta kvartira (bitta qator): xonalar 2 maydon_m2 40.6 metro_km 1.43 mebel 1 numpy vektori: [ 2. 40.6 1.43 1. ] shakli (shape): (4,) -> 4 ta son
Matematikada bu shunday yoziladi:
Qalin harf x — vektor (sonlar ro'yxati). Oddiy
Butun jadval — bu matritsa
X = df[son].to_numpy(dtype=float) print("Butun jadval:") print(f" shakli: {X.shape} -> {X.shape[0]} qator (namuna), {X.shape[1]} ustun (xususiyat)") print() print("Birinchi 3 qator:") print(X[:3]) print() print("Matritsadan element olish:") print(f" X[0, 1] = {X[0, 1]} -> 1-qator, 2-ustun (birinchi kvartiraning maydoni)") print(f" X[0] = {X[0]} -> butun 1-qator (bitta kvartira)") print(f" X[:, 1][:5] = {X[:, 1][:5]} -> 2-ustunning birinchi 5 qiymati (maydonlar)")
Butun jadval: shakli: (1200, 4) -> 1200 qator (namuna), 4 ustun (xususiyat) Birinchi 3 qator: [[ 2. 40.6 1.43 1. ] [ 2. 55.5 4.18 1. ] [ 5. 114. 3.84 1. ]] Matritsadan element olish: X[0, 1] = 40.6 -> 1-qator, 2-ustun (birinchi kvartiraning maydoni) X[0] = [ 2. 40.6 1.43 1. ] -> butun 1-qator (bitta kvartira) X[:, 1][:5] = [ 40.6 55.5 114. 72.1 46.4] -> 2-ustunning birinchi 5 qiymati (maydonlar)
Qoida: qator — namuna, ustun — xususiyat. sklearn har doim shu shaklni kutadi: (n_samples, n_features).
`shape` ni har doim tekshiring
ML dagi xatolarning yarmi shakl mos kelmasligidan chiqadi:
ValueError: Found input variables with inconsistent numbers of samples: [840, 360]
Bu xatoni ko'rganingizda birinchi ish — print(X.shape, y.shape). Ikkinchi ish — qaysi biri noto'g'ri ekanini aniqlash.
Eng muhim amal: skalyar ko'paytma
Endi butun ML ning yuragiga keldik.
Savol: kvartiraning narxini bashorat qilish uchun nima qilamiz?
Har bir xususiyatga vazn beramiz va qo'shamiz:
# vaznlar: har bir xususiyat narxga qancha ta'sir qiladi w = np.array([55.0, 7.5, -28.0, 90.0]) b = 180.0 # bias (boshlang'ich qiymat) print("Vaznlar va ularning ma'nosi:") for nom, vazn in zip(son, w): print(f" {nom:12s} {vazn:>7.1f}") print(f" {'bias':12s} {b:>7.1f}") print() print("Bitta kvartira uchun bashorat — QO'LDA:") qadamlar = [f"{x[i]:.2f} x {w[i]:.1f}" for i in range(len(w))] print(" " + " + ".join(qadamlar) + f" + {b:.0f}") bashorat_qolda = sum(x[i] * w[i] for i in range(len(w))) + b print(f" = {bashorat_qolda:.2f}")
Vaznlar va ularning ma'nosi: xonalar 55.0 maydon_m2 7.5 metro_km -28.0 mebel 90.0 bias 180.0 Bitta kvartira uchun bashorat — QO'LDA: 2.00 x 55.0 + 40.60 x 7.5 + 1.43 x -28.0 + 1.00 x 90.0 + 180 = 644.46
Endi xuddi shu hisobni bitta amal bilan:
bashorat_dot = x @ w + b # @ — skalyar ko'paytma belgisi print(f"x @ w + b = {bashorat_dot:.2f}") print(f"Qo'lda hisoblangan: {bashorat_qolda:.2f}") print(f"Bir xilmi: {np.isclose(bashorat_dot, bashorat_qolda)}")
x @ w + b = 644.46 Qo'lda hisoblangan: 644.46 Bir xilmi: True
Mana shu — skalyar ko'paytma (dot product). Matematikada:
Bu formula butun kitobda takrorlanadi
- Linear regression (14-bob):
y = x @ w + b— aynan shu - Logistic regression (15-bob):
sigmoid(x @ w + b)— ustiga bitta funksiya - Neyron tarmoq (29-bob):
activation(x @ W + b)— shu amal, ko'p qatlamda takrorlangan - Transformer (35-bob): attention ichida ham skalyar ko'paytma
Ya'ni siz hozir bitta amalni o'rganyapsiz, va u kitobning oxirigacha yetadi.
Butun jadval uchun birdan: matritsa ko'paytirish
Bitta kvartira uchun bashorat qildik. 1200 tasi uchun-chi? Sikl yozamizmi?
import time # 1-yo'l: sikl bilan t0 = time.perf_counter() bashoratlar_sikl = [] for i in range(len(X)): s = 0.0 for j in range(X.shape[1]): s += X[i, j] * w[j] bashoratlar_sikl.append(s + b) sikl_vaqti = time.perf_counter() - t0 bashoratlar_sikl = np.array(bashoratlar_sikl) # 2-yo'l: matritsa ko'paytirish t0 = time.perf_counter() bashoratlar_vek = X @ w + b vek_vaqti = time.perf_counter() - t0 print(f"Sikl bilan : {sikl_vaqti*1000:.2f} ms") print(f"X @ w bilan : {vek_vaqti*1000:.4f} ms") print(f"Natijalar bir xilmi: {np.allclose(bashoratlar_sikl, bashoratlar_vek)}") print(f"Tezlik farqi : {sikl_vaqti/max(vek_vaqti, 1e-9):.0f} barobar")
Sikl bilan : 0.83 ms X @ w bilan : 0.0118 ms Natijalar bir xilmi: True Tezlik farqi : 71 barobar
Bu tezlik farqi MENING kompyuterimda
Yuqoridagi "barobar" raqami sizda boshqa chiqadi — protsessor, numpy versiyasi, yuk hammasi ta'sir qiladi.
Lekin yo'nalish har doim bir xil: vektorlashtirilgan amal siklidan ancha tez. Sabab: numpy ichki qismi C tilida yozilgan va protsessorning SIMD ko'rsatmalaridan foydalanadi, Python sikli esa har qadamda interpretator orqali o'tadi.
Qoida: ML kodida for sikli ko'rsangiz, shubhalaning. Deyarli har doim vektorlashtirish yo'li bor.
print(f"X shakli : {X.shape}") print(f"w shakli : {w.shape}") print(f"X @ w shakli : {(X @ w).shape} -> har bir qator uchun bitta son") print() print("Birinchi 5 bashorat:", (X @ w + b)[:5].round(1)) print("Haqiqiy narxlar :", df.narx_usd.head(5).to_numpy())
X shakli : (1200, 4) w shakli : (4,) X @ w shakli : (1200,) -> har bir qator uchun bitta son Birinchi 5 bashorat: [ 644.5 679.2 1292.5 892. 509.8] Haqiqiy narxlar : [ 760 550 1415 985 550]
Vaznlarni men qo'lda yozdim, shuning uchun bashorat yaqin lekin aniq emas. 12-bobda model ularni o'zi topadi.
Shakl qoidasi: matritsa ko'paytirishning yagona sharti
A = np.array([[1., 2., 3.], [4., 5., 6.]]) # 2x3 B = np.array([[1., 0.], [0., 1.], [1., 1.]]) # 3x2 print(f"A shakli: {A.shape}") print(f"B shakli: {B.shape}") print(f"A @ B : {(A @ B).shape} <- 3 va 3 MOS keldi, natija 2x2") print(A @ B) print() try: B @ A @ B @ A except ValueError as e: pass try: _ = A @ A except ValueError as e: print("A @ A xato beradi:", str(e)[:62]) print() print("QOIDA: (n x m) @ (m x k) = (n x k). O'rtadagi ikki son MOS kelishi shart.")
A shakli: (2, 3) B shakli: (3, 2) A @ B : (2, 2) <- 3 va 3 MOS keldi, natija 2x2 [[ 4. 5.] [10. 11.]] A @ A xato beradi: matmul: Input operand 1 has a mismatch in its core dimension 0 QOIDA: (n x m) @ (m x k) = (n x k). O'rtadagi ikki son MOS kelishi shart.
Transpose — shaklni burish
print(f"X shakli : {X.shape}") print(f"X.T shakli : {X.T.shape} <- qator va ustun almashdi") print() print("Nega kerak: ustunlar o'zaro bog'liqligini hisoblash uchun") Xm = X - X.mean(axis=0) # markazlashtirish kov = (Xm.T @ Xm) / (len(X) - 1) # kovariatsiya matritsasi print(f"Xm.T @ Xm shakli: {kov.shape} <- 4x4, har ustun juftligi uchun bitta son") print() print("Korrelyatsiya (kovariatsiyadan normallashtirilgan):") std = np.sqrt(np.diag(kov)) korr = kov / np.outer(std, std) print(pd.DataFrame(korr.round(3), index=son, columns=son).to_string())
X shakli : (1200, 4)
X.T shakli : (4, 1200) <- qator va ustun almashdi
Nega kerak: ustunlar o'zaro bog'liqligini hisoblash uchun
Xm.T @ Xm shakli: (4, 4) <- 4x4, har ustun juftligi uchun bitta son
Korrelyatsiya (kovariatsiyadan normallashtirilgan):
xonalar maydon_m2 metro_km mebel
xonalar 1.000 0.940 0.036 0.013
maydon_m2 0.940 1.000 0.050 0.014
metro_km 0.036 0.050 1.000 -0.021
mebel 0.013 0.014 -0.021 1.000
xonalar va maydon_m2 orasida 0.94 — 3-bobda heatmap da ko'rgan raqam, endi qo'lda hisoblandi.
`X.T @ X` — PCA va normal tenglamaning yuragi
Bu ifoda kitobda yana ikki marta uchraydi: - 13-bobda normal tenglamada:
- 26-bobda PCA da: kovariatsiya matritsasining xos vektorlari
Ikkisi ham aynan shu X.T @ X dan boshlanadi. Shuning uchun uni hozir tushunib olish foydali.
Broadcasting — numpy ning jim yordamchisi
print("Har bir ustundan uning o'rtachasini ayirish — SIKL KERAK EMAS:") print(f" X shakli : {X.shape}") print(f" X.mean(axis=0) : {X.mean(axis=0).shape} -> 4 ta son") markaz = X - X.mean(axis=0) print(f" X - mean natijasi : {markaz.shape} <- numpy 4 ta sonni 1200 qatorga YOYDI") print() print(f" Tekshiruv — yangi o'rtachalar: {markaz.mean(axis=0).round(10)}") print() print("Bu — broadcasting. StandardScaler ichida aynan shu bo'ladi:") shkala = (X - X.mean(axis=0)) / X.std(axis=0) print(f" o'rtacha: {shkala.mean(axis=0).round(6)}") print(f" std : {shkala.std(axis=0).round(6)}")
Har bir ustundan uning o'rtachasini ayirish — SIKL KERAK EMAS: X shakli : (1200, 4) X.mean(axis=0) : (4,) -> 4 ta son X - mean natijasi : (1200, 4) <- numpy 4 ta sonni 1200 qatorga YOYDI Tekshiruv — yangi o'rtachalar: [ 0. 0. 0. -0.] Bu — broadcasting. StandardScaler ichida aynan shu bo'ladi: o'rtacha: [ 0. 0. 0. -0.] std : [1. 1. 1. 1.]
4-bobda ishlatgan StandardScaler — bu ikki qatorlik amal. Endi uning ichini bilasiz.
Broadcasting jim xato ham qiladi
a = np.array([1, 2, 3]) # shakli (3,) b = np.array([[1], [2], [3]]) # shakli (3, 1) a + b # XATO BERMAYDI -> 3x3 matritsa qaytaradi!
Siz 3 elementli natija kutgandingiz, 9 element oldingiz. Kod ishlaydi, natija noto'g'ri.
Shuning uchun: har bir amaldan keyin shape ni tekshiring, ayniqsa o'zingiz yozgan hisoblarda.
a = np.array([1, 2, 3]) bb = np.array([[1], [2], [3]]) print(f"a shakli : {a.shape}") print(f"b shakli : {bb.shape}") print(f"a + b shakli : {(a + bb).shape} <- 3 ta son kutgandingiz, 9 ta oldingiz") print(a + bb)
a shakli : (3,) b shakli : (3, 1) a + b shakli : (3, 3) <- 3 ta son kutgandingiz, 9 ta oldingiz [[2 3 4] [3 4 5] [4 5 6]]
Norma — vektorning "uzunligi"
Regularizatsiya (16-bob) uchun bitta tushuncha kerak: vektor qanchalik "katta"?
v = np.array([3.0, 4.0]) print(f"v = {v}") print() print(f"L2 norma (Evklid) : {np.linalg.norm(v, 2):.4f} = sqrt(3^2 + 4^2)") print(f"L1 norma (Manhattan): {np.linalg.norm(v, 1):.4f} = |3| + |4|") print() print("Bizning vaznlarimiz uchun:") print(f" w = {w}") print(f" L2 norma: {np.linalg.norm(w, 2):.2f}") print(f" L1 norma: {np.linalg.norm(w, 1):.2f}")
v = [3. 4.] L2 norma (Evklid) : 5.0000 = sqrt(3^2 + 4^2) L1 norma (Manhattan): 7.0000 = |3| + |4| Bizning vaznlarimiz uchun: w = [ 55. 7.5 -28. 90. ] L2 norma: 109.39 L1 norma: 180.50
show(pd.DataFrame([ {"Norma": "L2 (kvadratlar yig'indisining ildizi)", "Formula": "sqrt(sum(w^2))", "Qayerda ishlatiladi": "Ridge regression — katta vaznni jazolaydi"}, {"Norma": "L1 (mutlaq qiymatlar yig'indisi)", "Formula": "sum(|w|)", "Qayerda ishlatiladi": "Lasso — vaznni AYNAN nolga tushiradi"}, ]))
| Norma | Formula | Qayerda ishlatiladi |
|---|---|---|
| L2 (kvadratlar yig'indisining ildizi) | sqrt(sum(w^2)) | Ridge regression — katta vaznni jazolaydi |
| L1 (mutlaq qiymatlar yig'indisi) | sum(|w|) | Lasso — vaznni AYNAN nolga tushiradi |
16-bobda shu ikki norma ikki xil regularizatsiyani beradi — va nega Lasso xususiyat tanlaydi, L2 esa tanlamaydi, aynan shu farqdan chiqadi.
Bugun nima o'rgandik
show(pd.DataFrame([ {"Tushuncha": "Vektor", "Kodda": "x = np.array([...])", "ML da": "Bitta namuna (bitta kvartira)"}, {"Tushuncha": "Matritsa", "Kodda": "X.shape = (n, m)", "ML da": "n namuna, m xususiyat"}, {"Tushuncha": "Skalyar ko'paytma", "Kodda": "x @ w + b", "ML da": "BITTA bashorat — eng muhim amal"}, {"Tushuncha": "Matritsa ko'paytirish", "Kodda": "X @ w + b", "ML da": "HAMMA bashorat birdan"}, {"Tushuncha": "Shakl qoidasi", "Kodda": "(n,m) @ (m,k) = (n,k)", "ML da": "Xatolarning yarmi shu yerda"}, {"Tushuncha": "Transpose", "Kodda": "X.T", "ML da": "X.T @ X — normal tenglama va PCA"}, {"Tushuncha": "Broadcasting", "Kodda": "X - X.mean(axis=0)", "ML da": "StandardScaler ning ichi"}, {"Tushuncha": "L1 / L2 norma", "Kodda": "np.linalg.norm(w, 1/2)", "ML da": "Lasso va Ridge (16-bob)"}, ]))
| Tushuncha | Kodda | ML da |
|---|---|---|
| Vektor | x = np.array([...]) | Bitta namuna (bitta kvartira) |
| Matritsa | X.shape = (n, m) | n namuna, m xususiyat |
| Skalyar ko'paytma | x @ w + b | BITTA bashorat — eng muhim amal |
| Matritsa ko'paytirish | X @ w + b | HAMMA bashorat birdan |
| Shakl qoidasi | (n,m) @ (m,k) = (n,k) | Xatolarning yarmi shu yerda |
| Transpose | X.T | X.T @ X — normal tenglama va PCA |
| Broadcasting | X - X.mean(axis=0) | StandardScaler ning ichi |
| L1 / L2 norma | np.linalg.norm(w, 1/2) | Lasso va Ridge (16-bob) |
Keyingi bobda: vaznlarni men qo'lda yozdim. Model ularni qanday o'zi topadi?
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.