Yakuniy loyiha: hammasini bitta tizimga
Topshiriq
Bu bobda yangi tushuncha yo'q. Bu — imtihon, 21-bobdagi kabi, lekin endi butun kitob bo'yicha.
RostUy sizga aniq talab qo'ydi:
Broker aniqlash modeli ishlab chiqarishda ishlasin. Uni har hafta qayta o'qitish mumkin bo'lsin. Yomon model chiqmasin. Buzilsa o'zi qaytsin. Eskirganini o'zi aytsin.
To'rtta talab. Har biri bir necha bobga tegishli.
import pandas as pd show(pd.DataFrame([ {"Talab": "Takrorlanadigan o'qitish", "Qaysi boblar": "2, 5, 24", "Nima kerak": "Seed, ma'lumot xeshi, bitta buyruq"}, {"Talab": "Yomon model chiqmasin", "Qaysi boblar": "6, 24, 25, 31", "Nima kerak": "Sifat tekshiruvi, model testlari, darvoza"}, {"Talab": "Qaysi model ishlayapti", "Qaysi boblar": "22, 23", "Nima kerak": "Kuzatuv, registr, alias"}, {"Talab": "Buzilsa qaytsin", "Qaysi boblar": "27, 28, 30, 32", "Nima kerak": "Sog'liq, konteyner, avtomatik qaytarish"}, {"Talab": "Eskirganini aytsin", "Qaysi boblar": "34, 35", "Nima kerak": "O'lchov, PSI, ogohlantirish"}, ]))
| Talab | Qaysi boblar | Nima kerak |
|---|---|---|
| Takrorlanadigan o'qitish | 2, 5, 24 | Seed, ma'lumot xeshi, bitta buyruq |
| Yomon model chiqmasin | 6, 24, 25, 31 | Sifat tekshiruvi, model testlari, darvoza |
| Qaysi model ishlayapti | 22, 23 | Kuzatuv, registr, alias |
| Buzilsa qaytsin | 27, 28, 30, 32 | Sog'liq, konteyner, avtomatik qaytarish |
| Eskirganini aytsin | 34, 35 | O'lchov, PSI, ogohlantirish |
Tizim ko'rinishi
diagramma( { "Ma'lumot\n(manifest)": (0, 2.6, 2.1, 1.0, "manba"), "Sifat\n(6-bob)": (2.8, 2.6, 1.9, 1.0, "qayta"), "O'qitish\n(24-bob)": (5.4, 2.6, 2.0, 1.0, "qayta"), "Darvoza\n(31-bob)": (8.1, 2.6, 2.0, 1.0, "kuzatuv"), "Registr\n(23-bob)": (10.8, 2.6, 2.0, 1.0, "saqlash"), "Servis\n(27-28)": (10.8, 0.9, 2.0, 1.0, "xizmat"), "Monitoring\n(34-35)": (8.1, 0.9, 2.0, 1.0, "kuzatuv"), }, [ ("Ma'lumot\n(manifest)", "Sifat\n(6-bob)"), ("Sifat\n(6-bob)", "O'qitish\n(24-bob)"), ("O'qitish\n(24-bob)", "Darvoza\n(31-bob)"), ("Darvoza\n(31-bob)", "Registr\n(23-bob)", "o'tdi"), ("Registr\n(23-bob)", "Servis\n(27-28)"), ("Servis\n(27-28)", "Monitoring\n(34-35)"), ("Monitoring\n(34-35)", "O'qitish\n(24-bob)", "drift"), ], nom="yakuniy_tizim.png", kenglik=14, izoh="Halqa yopiq: monitoring driftni sezsa, o'qitish qaytadan boshlanadi.", )

Halqa yopiq: monitoring driftni sezsa, o'qitish qaytadan boshlanadi.
Diqqat qiling — bu halqa, chiziq emas. Oxirgi strelka monitoringdan o'qitishga qaytadi.
Chiziqli tizimda model bir marta chiqariladi va unutiladi. Halqali tizimda u yashaydi.
1-bosqich: ma'lumot va uning qaydnomasi
shu faylni yaratingsrc/quvur/loyiha_oxiri.py
"""Yakuniy quvur: ma'lumotdan monitoring darajasigacha.""" import hashlib import json import time from dataclasses import dataclass, asdict from pathlib import Path from typing import Any import numpy as np import pandas as pd from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import f1_score, precision_score, recall_score from sklearn.model_selection import train_test_split from .xususiyat import XUSUSIYATLAR, tayyorla @dataclass(frozen=True, slots=True) class Pasport: """2-bobdagi pasport + 5-bobdagi ma'lumot xeshi.""" malumot_xesh: str qatorlar: int seed: int parametrlar: dict[str, Any] metrikalar: dict[str, float] vaqt: str def malumot_xesh(yol: str | Path) -> str: h = hashlib.sha256() with open(yol, "rb") as f: for blok in iter(lambda: f.read(1 << 20), b""): h.update(blok) return h.hexdigest()[:16] QOIDA = { "narx_mln": lambda s: s.between(0.5, 200), "maydon": lambda s: s.between(10, 500), "xonalar": lambda s: s.between(1, 10), } def sifat(d: pd.DataFrame) -> tuple[pd.DataFrame, int]: """6-bob: chegarada tekshirish.""" yaxshi = pd.Series(True, index=d.index) for ustun, tekshir in QOIDA.items(): yaxshi &= tekshir(d[ustun]) return d[yaxshi], int((~yaxshi).sum()) def oqit(d: pd.DataFrame, seed: int = 42) -> tuple[Any, dict[str, float]]: """24-bob: bitta funksiya, takrorlanadigan.""" x, y = tayyorla(d), d["broker"] Xtr, Xte, ytr, yte = train_test_split( x, y, test_size=0.25, stratify=y, random_state=seed) m = RandomForestClassifier(n_estimators=150, min_samples_leaf=3, random_state=seed, n_jobs=1).fit(Xtr, ytr) p = m.predict(Xte) return m, { "f1": float(f1_score(yte, p)), "aniqlik": float(precision_score(yte, p)), "toliqlik": float(recall_score(yte, p)), }
python3 -c " import sys; sys.path.insert(0, 'src') import pandas as pd from quvur.loyiha_oxiri import malumot_xesh, sifat YOL = '../datasets/ijara.csv' d = pd.read_csv(YOL) xesh = malumot_xesh(YOL) toza, rad = sifat(d) print(f'1-BOSQICH: MALUMOT') print(f' malumot xeshi : {xesh}') print(f' kirgan qator : {len(d):,}') print(f' rad etilgan : {rad:,}') print(f' toza : {len(toza):,}') "
1-BOSQICH: MALUMOT malumot xeshi : 03dbeed95e47e74c kirgan qator : 12,000 rad etilgan : 0 toza : 12,000
Xesh — bu qaysi ma'lumot ekanining isboti (5-bob). U pasportga yoziladi va olti oydan keyin "o'sha ma'lumotmi?" degan savolga javob beradi.
2-bosqich: o'qitish va darvoza
python3 -c " import sys, json, time; sys.path.insert(0, 'src') import joblib, pandas as pd from quvur.loyiha_oxiri import Pasport, malumot_xesh, oqit, sifat from quvur.darvoza import Chegara, asos_oqi, darvoza, hisobot from dataclasses import asdict YOL = '../datasets/ijara.csv' d, _ = sifat(pd.read_csv(YOL)) m, metrikalar = oqit(d, seed=42) p = Pasport( malumot_xesh=malumot_xesh(YOL), qatorlar=len(d), seed=42, parametrlar={'n_estimators': 150, 'min_samples_leaf': 3}, metrikalar=metrikalar, vaqt=time.strftime('%Y-%m-%d %H:%M'), ) ok, sabablar = darvoza(metrikalar, Chegara(), asos_oqi('ci_asos.json')) print('2-BOSQICH: OQITISH VA DARVOZA') print(hisobot(metrikalar, ok, sabablar)) if ok: joblib.dump(m, 'yakuniy_model.joblib') open('yakuniy_pasport.json','w').write(json.dumps(asdict(p), indent=1)) print() print(' model va pasport saqlandi') "
2-BOSQICH: OQITISH VA DARVOZA ============================================== SIFAT DARVOZASI ============================================== f1 : 0.8595 aniqlik : 0.8929 toliqlik : 0.8285 ---------------------------------------------- NATIJA: O'TDI model va pasport saqlandi
Darvoza (31-bob) — bu yerda eng muhim tugun. Undan o'tmagan model hech qayerga bormaydi.
3-bosqich: model testlari
Darvoza F1 ni tekshirdi. Lekin 25-bobda ko'rgandik: yaxshi F1 mantiqiy xulqni kafolatlamaydi.
python3 -c " import sys; sys.path.insert(0, 'src') import joblib from quvur.sinov_yordam import ehtimol m = joblib.load('yakuniy_model.joblib') # 25-bob: minimal funksionallik ega = ehtimol(m, telefon_takrorlanishi=1, kunlik_elonlar=1, tavsif_uzunligi=600, rasmlar_soni=15, egasi_tasdiqlangan=1) brok = ehtimol(m, telefon_takrorlanishi=18, kunlik_elonlar=9, tavsif_uzunligi=60, rasmlar_soni=2, egasi_tasdiqlangan=0) # 25-bob: yonalish past = ehtimol(m, telefon_takrorlanishi=1) yuqori = ehtimol(m, telefon_takrorlanishi=20) print('3-BOSQICH: MODEL TESTLARI') print(f' aniq ega : {ega:.4f} {\"OK\" if ega < 0.3 else \"XATO\"}') print(f' aniq broker : {brok:.4f} {\"OK\" if brok > 0.7 else \"XATO\"}') print(f' telefon 1 -> 20 : {past:.4f} -> {yuqori:.4f} {\"OK\" if yuqori > past else \"XATO\"}') "
3-BOSQICH: MODEL TESTLARI aniq ega : 0.0563 OK aniq broker : 0.8983 OK telefon 1 -> 20 : 0.0516 -> 0.6446 OK
Uchala test ham mantiqni tekshiradi, aniqlikni emas. Tarozi yonyaptimi emas, raqam ma'nolimi.
4-bosqich: chiqarishga tayyorlash
python3 -c " import sys, json, pathlib; sys.path.insert(0, 'src') import joblib from quvur.xususiyat import XUSUSIYATLAR from quvur.format import onnx_ga, onnx_sessiya, onnx_ehtimol import numpy as np, pandas as pd from quvur.xususiyat import tayyorla m = joblib.load('yakuniy_model.joblib') onnx_ga(m, len(XUSUSIYATLAR), 'yakuniy.onnx') # 26-bob: ONNX bir xil javob beradimi d = pd.read_csv('../datasets/ijara.csv').head(500) x = tayyorla(d) a = m.predict_proba(x)[:, 1] s = onnx_sessiya('yakuniy.onnx') b = onnx_ehtimol(s, x.values) farq = float(np.max(np.abs(a - b))) qaror = int(np.sum((a >= 0.5) == (b >= 0.5))) print('4-BOSQICH: ONNX') print(f' joblib hajmi : {pathlib.Path(\"yakuniy_model.joblib\").stat().st_size/1024/1024:.1f} MB') print(f' onnx hajmi : {pathlib.Path(\"yakuniy.onnx\").stat().st_size/1024/1024:.1f} MB') print(f' eng katta farq: {farq:.2e}') print(f' qaror mosligi : {qaror}/{len(d)}') "
4-BOSQICH: ONNX joblib hajmi : 14.0 MB onnx hajmi : 6.8 MB eng katta farq: 4.61e-07 qaror mosligi : 500/500 [0;93m2026-09-29 21:38:24.084126709 [W:onnxruntime:Default, device_discovery.cc:164 DiscoverDevicesForPlatform] GPU device discovery failed: device_discovery.cc:89 ReadFileContents Failed to open file: "/sys/class/drm/card0/device/vendor"[m
5-bosqich: drift kuzatuvi
python3 -c " import sys; sys.path.insert(0, 'src') import pandas as pd from quvur.drift import hisobot, KATTA eski = pd.read_csv('../datasets/ijara.csv') yangi = pd.read_csv('../datasets/ijara_yangi.csv') USTUN = ['tavsif_uzunligi','rasmlar_soni','telefon_takrorlanishi','kunlik_elonlar','narx_mln'] h = hisobot(eski, yangi, USTUN) print('5-BOSQICH: DRIFT') print(h.to_string(index=False)) ogoh = h[h['psi'] >= 0.10] print() if len(ogoh): print(f' OGOHLANTIRISH: {len(ogoh)} ustunda siljish') print(f' qaror: qayta oqitish kerak (35-bob)') else: print(' siljish yoq - tegmang') "
5-BOSQICH: DRIFT
ustun psi baho
rasmlar_soni 0.2251 o'rtacha
tavsif_uzunligi 0.1262 o'rtacha
telefon_takrorlanishi 0.0089 barqaror
kunlik_elonlar 0.0075 barqaror
narx_mln 0.0046 barqaror
OGOHLANTIRISH: 2 ustunda siljish
qaror: qayta oqitish kerak (35-bob)
Yakuniy hisobot
python3 -c " import json, pathlib p = json.load(open('yakuniy_pasport.json')) print('=' * 50) print('LOYIHA HISOBOTI') print('=' * 50) print(f' malumot xeshi : {p[\"malumot_xesh\"]}') print(f' qatorlar : {p[\"qatorlar\"]:,}') print(f' seed : {p[\"seed\"]}') print(f' F1 : {p[\"metrikalar\"][\"f1\"]:.4f}') print(f' aniqlik : {p[\"metrikalar\"][\"aniqlik\"]:.4f}') print(f' toliqlik : {p[\"metrikalar\"][\"toliqlik\"]:.4f}') print(f' vaqt : {p[\"vaqt\"]}') print('-' * 50) for f in ('yakuniy_model.joblib', 'yakuniy.onnx', 'yakuniy_pasport.json'): bor = pathlib.Path(f).exists() print(f' {f:26s} {\"bor\" if bor else \"YOQ\"}') print('=' * 50) "
================================================== LOYIHA HISOBOTI ================================================== malumot xeshi : 03dbeed95e47e74c qatorlar : 12,000 seed : 42 F1 : 0.8595 aniqlik : 0.8929 toliqlik : 0.8285 vaqt : 2026-09-29 21:38 -------------------------------------------------- yakuniy_model.joblib bor yakuniy.onnx bor yakuniy_pasport.json bor ==================================================
Bu hisobot — loyihaning javobgarligi. Unda uchta savolga javob bor: qaysi ma'lumot, qanday sozlama, qanday natija.
Olti oydan keyin kimdir so'rasa, javob faylda turibdi — kimningdir esida emas.
Nimani qurdingiz
Kitob boshida model bor edi va u jim buzilardi. Endi sizda tizim bor:
| Xususiyat | Qayerdan |
|---|---|
| Bir xil natija ikki marta | Seed + ma'lumot xeshi (2, 5-bob) |
| Buzuq ma'lumot kirmaydi | Chegarada tekshiruv (6-bob) |
| Bitta buyruq bilan o'qitish | Quvur (24-bob) |
| Yomon model chiqmaydi | Darvoza (31-bob) |
| Mantiqsiz xulq ushlanadi | Model testlari (25-bob) |
| Qaysi model ishlayapti | Registr va alias (23-bob) |
| Tez va kichik xizmat | ONNX va konteyner (26, 28-bob) |
| Buzilsa qaytadi | Avtomatik qaytarish (32-bob) |
| Foydalanuvchi ko'rmaydi | Shadow va canary (33-bob) |
| Eskirgani bilinadi | O'lchov va PSI (34, 35-bob) |
Hammasini birdan qurmang
Bu ro'yxat to'liq ko'rinadi va yangi loyihada uni butunlay qurish vasvasasi bo'ladi.
Qilmang. Har element muammo paydo bo'lganda qo'shiladi:
- Avval takrorlanish (2-bob) — usiz qolgani ma'nosiz.
- Keyin sifat tekshiruvi (6-bob) — eng ko'p muammo shundan.
- Keyin darvoza (31-bob) — birinchi marta yomon model chiqqanda.
- Keyin monitoring (34-bob) — birinchi marta "qachondan beri buzuq?" deb so'raganda.
Qolganlari kerak bo'lganda qo'shiladi. 19-bobdagi qoida bu yerda ham amal qiladi: murakkablikni muammo talab qilganda qo'shing, oldindan emas.
Tozalash
rm -f yakuniy_model.joblib yakuniy.onnx yakuniy_pasport.json echo "vaqtinchalik fayllar tozalandi"
vaqtinchalik fayllar tozalandi
Talaba ishi
Bu bobning talaba ishi — o'z loyihangiz.
- O'z ma'lumotingizni oling (yoki
ballon.csv/buyurtma.csv). Masalani aniqlang: nimani bashorat qilasiz va qaror kim uchun? - 1–8 boblarni takrorlang: manifest, sifat qoidalari, xususiyat kodi, quvur.
- Darvoza chegarasini o'zingiz tanlang va nega shu raqam ekanini yozib qo'ying.
- Servisni ko'taring va p99 ni o'lchang (29-bob). Sizning talabingiz qancha?
- Bir oy ishlatib, PSI ni o'lchang. Nimadir siljidimi?
Oxirgi punkt eng muhimi. Kitobdagi hamma narsa vaqt bilan ma'noga ega bo'ladi — bir oy ishlatmaguncha, siz faqat kodni ko'rgan bo'lasiz, tizimni emas.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.