Dataset qurish: tozalash, label va split
Sahna: 300 qator, biror foydali narsa yo'q
36-bob ish/xom/elonlar_xom.csv ni qoldirdi. Unda 300 qator bor, lekin hech bir ustun modelga berib bo'ladigan holatda emas: narx uch xil formatda matn, maydon "45.5 m²" ko'rinishida, dublikatlar o'chirilmagan.
Bu bob xom fayldan dataset yasaydi. Dataset — shunchaki toza jadval emas. Dataset — bu:
- har ustun tipi va diapazoni ma'lum
- har qator nimani anglatishi yozilgan
- target aniq belgilangan
- train/val/test to'g'ri ajratilgan
- hammasi takrorlanadigan
import re import sys import numpy as np import pandas as pd # 36-bobda yozgan yig'uvchimizni qayta ishlatamiz — xom ma'lumot shu yerdan keladi. # Har bob mustaqil ishlashi kerak, shuning uchun faylga emas, MANBAGA murojaat qilamiz. sys.path.insert(0, str(ISH)) from yiguv.tahlil import sahifani_tahlil FIX = DATA / "fixture" yozuvlar = [] for sahifa in sorted(FIX.glob("elonlar_*.html")): yozuvlar += sahifani_tahlil(sahifa.read_text(encoding="utf-8")) xom = pd.DataFrame(yozuvlar) print(f"Xom ma'lumot: {xom.shape[0]} qator, {xom.shape[1]} ustun") print() print(xom.dtypes.to_string()) print() print("Hamma ustun `object` — ya'ni MATN. Bitta ham son yo'q.")
Xom ma'lumot: 300 qator, 7 ustun manba_id object sarlavha object narx_xom object xona_xom object maydon_xom object tuman object qavat_xom object Hamma ustun `object` — ya'ni MATN. Bitta ham son yo'q.
Qoida: har qadamda qator sanaladi
Jim yo'qolgan qatorlar — eng xavfli xato turi
Tozalash jarayonida dropna(), drop_duplicates(), filtrlar ketma-ket qo'llanadi. Har biri qatorlarni o'chiradi.
Men ko'rgan eng ko'p uchraydigan xato: talaba 10 000 qatorli fayldan boshlaydi, 6 qadam tozalash qiladi, oxirida 400 qator qoladi va buni sezmaydi. Keyin "modelim nega yomon?" deb so'raydi.
Yechim — qadam jurnali. Har amaldan keyin qator soni yoziladi va yo'qolgan qatorlar sababi bilan hisobga olinadi.
Agar bir qadamda 50% qator yo'qolsa, bu sizdan qaror talab qiladi: shunchaki tashlab yuborasizmi, yoki to'ldirasizmi? Jurnal bo'lmasa, siz bu savolni ko'rmaysiz ham.
class Jurnal: """Har tozalash qadamini yozib boradi.""" def __init__(self, boshlangich): self.qadamlar = [{"qadam": "boshlanish", "qator": boshlangich, "yo'qoldi": 0}] def yoz(self, nom, qator): oldingi = self.qadamlar[-1]["qator"] self.qadamlar.append({"qadam": nom, "qator": qator, "yo'qoldi": oldingi - qator}) return qator def jadval(self): t = pd.DataFrame(self.qadamlar) t["qolgan %"] = (t["qator"] / t["qator"].iloc[0] * 100).round(1) return t jurnal = Jurnal(len(xom)) print(f"Jurnal boshlandi: {len(xom)} qator")
Jurnal boshlandi: 300 qator
Narxni songa aylantirish
Eng qiyin ustun. Uch format, uchta qoida.
print("Xom narx qiymatlari (birinchi 10 noyob):") for v in xom["narx_xom"].dropna().unique()[:10]: print(f" {v!r}")
Xom narx qiymatlari (birinchi 10 noyob): "10 625 000 so'm" "12 500 000 so'm" '500\xa0у.е.' 'Kelishilgan' '450\xa0у.е.' "8 750 000 so'm" '700\xa0у.е.' '400\xa0у.е.' '350\xa0у.е.' '850\xa0у.е.'
shu faylni yaratingtozalash/matndan_son.py
"""Matn ko'rinishidagi qiymatlarni songa aylantirish.""" import re import numpy as np SOM_KURSI = 12500 # 1 USD = 12500 so'm (dataset yasalgan paytdagi kurs) def narxni_ol(matn, kurs=SOM_KURSI): """Narx matnini USD ga aylantiradi. Uch format qo'llab-quvvatlanadi: "500 у.е." -> 500.0 "6 250 000 so'm" -> 500.0 "Kelishilgan" -> nan (raqam YO'Q, to'qib chiqarilmaydi) """ if not isinstance(matn, str): return np.nan if "Kelishilgan" in matn: return np.nan # narx yo'q — taxmin qilmaymiz raqamlar = re.sub(r"[^\d]", "", matn.replace("\xa0", " ")) if not raqamlar: return np.nan qiymat = int(raqamlar) return qiymat / kurs if "so'm" in matn else float(qiymat) def birinchi_son(matn, naqsh=r"([\d.]+)"): """Matndan birinchi sonni ajratadi: "45.5 m²" -> 45.5, "11-qavat" -> 11.0""" if not isinstance(matn, str): return np.nan topildi = re.search(naqsh, matn) return float(topildi.group(1)) if topildi else np.nan
from tozalash.matndan_son import narxni_ol, birinchi_son sinovlar = ["500\xa0у.е.", "6 250 000 so'm", "Kelishilgan", None, "12 500 000 so'm"] print(f"{'kirish':<22} {'natija (USD)':>14}") print("-" * 38) for s in sinovlar: print(f"{repr(s):<22} {narxni_ol(s)!s:>14}") print() RAQAM = r"(\d+)" maydon_sinov = birinchi_son("45.5 m²") qavat_sinov = birinchi_son("11-qavat", RAQAM) print(f"birinchi_son('45.5 m²') = {maydon_sinov}") print(f"birinchi_son('11-qavat') = {qavat_sinov}")
kirish natija (USD)
--------------------------------------
'500\xa0у.е.' 500.0
"6 250 000 so'm" 500.0
'Kelishilgan' nan
None nan
"12 500 000 so'm" 1000.0
birinchi_son('45.5 m²') = 45.5
birinchi_son('11-qavat') = 11.0
Yo'q qiymatni to'qib chiqarmaslik
"Kelishilgan" ni ko'rganda o'rtacha narx qo'yish juda jozibali — qator saqlanadi, NaN yo'qoladi.
Qilmang. Siz bu uyning narxini bilmaysiz. O'rtacha qo'ysangiz, modelga "bu uy o'rtacha narxda" degan yolg'on ma'lumot berasiz. 4-bobda imputatsiyani ko'rganmiz, lekin target ni imputatsiya qilish boshqa narsa: target — bu modelning haqiqat manbasi. Uni to'qib chiqarish butun o'qitishni buzadi.
Qoida: feature ni to'ldirish mumkin, target ni — yo'q. Target yo'q bo'lsa, qator o'qitishga yaramaydi.
toza = pd.DataFrame({ "manba_id": xom["manba_id"], "tuman": xom["tuman"], "xonalar": xom["xona_xom"].apply(lambda s: birinchi_son(s, r"(\d+)")), "maydon_m2": xom["maydon_xom"].apply(birinchi_son), "qavat": xom["qavat_xom"].apply(lambda s: birinchi_son(s, r"(\d+)")), "narx_usd": xom["narx_xom"].apply(narxni_ol), }) print("Aylantirishdan keyin bo'sh qiymatlar:") for u in ["tuman", "xonalar", "maydon_m2", "qavat", "narx_usd"]: n = int(toza[u].isna().sum()) print(f" {u:<12} {n:>4} ta bo'sh ({n / len(toza):.1%})")
Aylantirishdan keyin bo'sh qiymatlar: tuman 0 ta bo'sh (0.0%) xonalar 26 ta bo'sh (8.7%) maydon_m2 35 ta bo'sh (11.7%) qavat 0 ta bo'sh (0.0%) narx_usd 46 ta bo'sh (15.3%)
Target yo'q bo'lgan qatorlarni ajratish
narxsiz = int(toza["narx_usd"].isna().sum()) toza_t = toza[toza["narx_usd"].notna()].copy() jurnal.yoz("narxi yo'q qatorlar olib tashlandi", len(toza_t)) print(f"Narxi yo'q ('Kelishilgan' va bo'sh): {narxsiz} qator") print(f"Qoldi: {len(toza_t)} qator") print() print("Bu qatorlar BEKOR emas — ular bashorat qilish uchun ishlatiladi.") print("Faqat O'QITISH uchun yaramaydi. Shuning uchun ularni alohida saqlash mumkin.")
Narxi yo'q ('Kelishilgan' va bo'sh): 46 qator
Qoldi: 254 qator
Bu qatorlar BEKOR emas — ular bashorat qilish uchun ishlatiladi.
Faqat O'QITISH uchun yaramaydi. Shuning uchun ularni alohida saqlash mumkin.
oldin = len(toza_t) toza_t = toza_t.dropna(subset=["xonalar", "maydon_m2", "qavat"]) jurnal.yoz("feature lari to'liq bo'lmagan qatorlar", len(toza_t)) print(f"Feature si yetishmaydigan qatorlar: {oldin - len(toza_t)}") print(f"Qoldi: {len(toza_t)} qator")
Feature si yetishmaydigan qatorlar: 47 Qoldi: 207 qator
Tekshiruv: ma'lumot shartnomasi
Tozalangan ma'lumot kutilgan diapazonda ekanini tekshirish kerak. Aks holda xato keyinroq, modelni o'qitganda chiqadi.
shu faylni yaratingtozalash/shartnoma.py
"""Dataset shartnomasi: har ustun uchun tip va diapazon.""" SHARTNOMA = { "tuman": {"tur": "matn", "ruxsat": {"Yunusobod", "Chilonzor", "Mirzo Ulug'bek", "Shayxontohur", "Yakkasaroy", "Olmazor", "Sergeli", "Bektemir"}}, "xonalar": {"tur": "son", "min": 1, "maks": 10}, "maydon_m2": {"tur": "son", "min": 15, "maks": 400}, "qavat": {"tur": "son", "min": 1, "maks": 50}, "narx_usd": {"tur": "son", "min": 50, "maks": 20000}, } def tekshir(df, shartnoma=SHARTNOMA): """Shartnomaga mos kelmagan holatlar ro'yxatini qaytaradi. Bo'sh ro'yxat — hammasi joyida.""" muammolar = [] for ustun, qoida in shartnoma.items(): if ustun not in df.columns: muammolar.append(f"{ustun}: ustun YO'Q") continue qiymat = df[ustun] if qoida["tur"] == "son": chegaradan = ((qiymat < qoida["min"]) | (qiymat > qoida["maks"])).sum() if chegaradan: muammolar.append( f"{ustun}: {chegaradan} qiymat [{qoida['min']}, {qoida['maks']}] dan tashqarida") else: notogri = set(qiymat.dropna().unique()) - qoida["ruxsat"] if notogri: muammolar.append(f"{ustun}: ruxsat etilmagan qiymat {sorted(notogri)[:5]}") if qiymat.isna().any(): muammolar.append(f"{ustun}: {int(qiymat.isna().sum())} bo'sh qiymat") return muammolar
from tozalash.shartnoma import tekshir muammolar = tekshir(toza_t) print(f"Shartnoma tekshiruvi: {len(muammolar)} muammo") for m in muammolar: print(f" - {m}") if not muammolar: print(" (hammasi shartnomaga mos)") print() print("Shartnoma — kodda yozilgan KUTISH. U buzilsa, siz darhol bilasiz,") print("3 kundan keyin 'modelim g'alati' deb o'ylamasdan.")
Shartnoma tekshiruvi: 0 muammo (hammasi shartnomaga mos) Shartnoma — kodda yozilgan KUTISH. U buzilsa, siz darhol bilasiz, 3 kundan keyin 'modelim g'alati' deb o'ylamasdan.
Dublikat: guruh identifikatori
36-bobda o'lchagandik: manba_id noyob bo'lsa ham, bitta uy bir necha marta e'lon qilingan. Endi har uyga guruh raqami beramiz.
toza_t["guruh"] = toza_t.groupby(["tuman", "maydon_m2", "xonalar"]).ngroup() noyob_uy = toza_t["guruh"].nunique() print(f"Qator soni : {len(toza_t)}") print(f"Noyob uy (guruh): {noyob_uy}") print(f"Ortiqcha yozuv : {len(toza_t) - noyob_uy} ({(len(toza_t) - noyob_uy) / len(toza_t):.1%})") print() katta = toza_t["guruh"].value_counts() print(f"Eng ko'p takrorlangan uy {int(katta.iloc[0])} marta e'lon qilingan:") show(toza_t[toza_t["guruh"] == katta.index[0]][["manba_id", "tuman", "maydon_m2", "xonalar", "narx_usd"]])
Qator soni : 207 Noyob uy (guruh): 176 Ortiqcha yozuv : 31 (15.0%) Eng ko'p takrorlangan uy 5 marta e'lon qilingan:
| manba_id | tuman | maydon_m2 | xonalar | narx_usd |
|---|---|---|---|---|
| 131 | Mirzo Ulug'bek | 60.4 | 2 | 600 |
| 176 | Mirzo Ulug'bek | 60.4 | 2 | 600 |
| 190 | Mirzo Ulug'bek | 60.4 | 2 | 600 |
| 250 | Mirzo Ulug'bek | 60.4 | 2 | 600 |
| 284 | Mirzo Ulug'bek | 60.4 | 2 | 600 |
Dublikatni O'CHIRISH shart emas — ajratishda hisobga olish shart
Birinchi fikr: dublikatni drop_duplicates() bilan o'chirish. Ba'zan bu to'g'ri.
Lekin takroriy e'lon ham ma'lumot: uy uzoq vaqt ijaraga berilmaganini ko'rsatadi. O'chirsangiz, shu signalni yo'qotasiz.
Muhimi — bitta uy train va test ga ikkalasiga tushmasligi. Buning yo'li: guruh ustunini saqlash va split ni guruh bo'yicha qilish. Pastdagi bo'limda nima bo'lishini o'lchaymiz.
Split: endi o'lchaymiz, nega guruh muhim
from sklearn.ensemble import RandomForestRegressor from sklearn.neighbors import KNeighborsRegressor from sklearn.model_selection import train_test_split, GroupShuffleSplit from sklearn.metrics import r2_score X = pd.get_dummies(toza_t[["tuman", "xonalar", "maydon_m2", "qavat"]], columns=["tuman"]) y = toza_t["narx_usd"].values guruhlar = toza_t["guruh"].values natija = [] for nom, yasa in [("KNN (k=1)", lambda: KNeighborsRegressor(1)), ("KNN (k=3)", lambda: KNeighborsRegressor(3)), ("random forest", lambda: RandomForestRegressor(200, random_state=0))]: tasodifiy = [r2_score(yb, yasa().fit(Xa, ya).predict(Xb)) for Xa, Xb, ya, yb in (train_test_split(X, y, test_size=.25, random_state=s) for s in range(5))] guruhli = [] for s in range(5): tr, te = next(GroupShuffleSplit(n_splits=1, test_size=.25, random_state=s).split(X, y, groups=guruhlar)) guruhli.append(r2_score(y[te], yasa().fit(X.iloc[tr], y[tr]).predict(X.iloc[te]))) natija.append({"model": nom, "tasodifiy split R2": round(float(np.mean(tasodifiy)), 3), "guruh split R2": round(float(np.mean(guruhli)), 3), "soxta farq": round(float(np.mean(tasodifiy) - np.mean(guruhli)), 3)}) show(pd.DataFrame(natija))
| model | tasodifiy split R2 | guruh split R2 | soxta farq |
|---|---|---|---|
| KNN (k=1) | -0.796 | -0.97 | 0.174 |
| KNN (k=3) | -0.28 | -0.378 | 0.098 |
| random forest | -0.126 | -0.297 | 0.171 |
Uchta model, uchta xil ichki mexanizm — lekin farq ishorasi bir xil: tasodifiy split har safar yaxshiroq ko'rsatadi.
Bu datasetda R2 manfiy — va bu TO'G'RI natija
Jadvaldagi R2 qiymatlari manfiy. Bu xato emas, va buni tushunish muhim.
datasets/fixture_qur.py generatorida narx tasodifiy tanlanadi — u tuman, maydon yoki xonaga bog'liq emas. Ya'ni bu ma'lumotda o'rganiladigan naqsh yo'q.
Manfiy R2 ma'nosi: model o'rtacha qiymatni aytishdan ham yomonroq ishlaydi. 6-bobdagi baza aynan shu — DummyRegressor o'rtachani aytadi va R2 = 0 oladi. Modelimiz 0 dan past, demak u shovqinga moslashgan (overfitting).
Nega bu bizga qulay: naqsh yo'q bo'lgani uchun har qanday ijobiy natija faqat leakage dan kelishi mumkin. Shuning uchun "tasodifiy split" ustunining yuqoriligi — sof o'lchangan leakage, boshqa hech narsa emas.
Haqiqiy loyihada siz buni ko'rmaysiz: o'sha yerda naqsh ham bor, leakage ham bor, va ikkisi aralashib ketadi. Shuning uchun halol split birinchi navbatda qilinadi, natijani ko'rgandan keyin emas.
Uch qismga ajratish
# 1-bosqich: test ni GURUH bo'yicha ajratamiz tr_idx, te_idx = next(GroupShuffleSplit(n_splits=1, test_size=0.2, random_state=42).split(X, y, groups=guruhlar)) qolgan = toza_t.iloc[tr_idx] test = toza_t.iloc[te_idx] # 2-bosqich: qolganidan validation ni ham GURUH bo'yicha ajratamiz X2 = X.iloc[tr_idx] tr2, va2 = next(GroupShuffleSplit(n_splits=1, test_size=0.2, random_state=42).split(X2, y[tr_idx], groups=qolgan["guruh"].values)) train = qolgan.iloc[tr2] val = qolgan.iloc[va2] print(f"{'bo`lak':<8} {'qator':>7} {'noyob uy':>10} {'ulush':>8}") print("-" * 36) for nom, b in [("train", train), ("val", val), ("test", test)]: print(f"{nom:<8} {len(b):>7} {b['guruh'].nunique():>10} {len(b) / len(toza_t):>7.1%}") print() kesishma = (set(train["guruh"]) & set(test["guruh"])) | (set(train["guruh"]) & set(val["guruh"])) print(f"Bo'laklar orasida umumiy uy: {len(kesishma)} <- 0 bo'lishi SHART") jurnal.yoz("uch bo'lakka ajratildi", len(train) + len(val) + len(test))
bo`lak qator noyob uy ulush ------------------------------------ train 136 112 65.7% val 33 28 15.9% test 38 36 18.4% Bo'laklar orasida umumiy uy: 0 <- 0 bo'lishi SHART
Qadam jurnali: hamma qator hisobda
show(jurnal.jadval()) print(f"Boshlangan: {jurnal.qadamlar[0]['qator']} qator") print(f"Qolgan : {jurnal.qadamlar[-1]['qator']} qator") print(f"Yo'qolgan : {jurnal.qadamlar[0]['qator'] - jurnal.qadamlar[-1]['qator']} qator — har biri sababi bilan yuqorida")
Boshlangan: 300 qator Qolgan : 207 qator Yo'qolgan : 93 qator — har biri sababi bilan yuqorida
| qadam | qator | yo'qoldi | qolgan % |
|---|---|---|---|
| boshlanish | 300 | 0 | 100 |
| narxi yo'q qatorlar olib tashlandi | 254 | 46 | 84.7 |
| feature lari to'liq bo'lmagan qatorlar | 207 | 47 | 69 |
| uch bo'lakka ajratildi | 207 | 0 | 69 |
Datasheet: datasetning pasporti
Hujjatsiz dataset — vaqt bombasi
Olti oydan keyin siz (yoki hamkasbingiz) bu faylni ochadi va so'raydi: narx qaysi valyutada? qachon yig'ilgan? nega 93 qator yo'q? Kelishilgan qatorlar qayerda?
Javoblar yozilmagan bo'lsa, dataset ishonchsiz bo'lib qoladi va qaytadan yasash kerak bo'ladi.
Shuning uchun har dataset bilan birga datasheet saqlanadi — oddiy matn fayl, 10 daqiqalik ish.
datasheet = f"""# uy_ijara dataseti — datasheet ## Nima Toshkent ijara e'lonlari. Bitta qator = bitta e'lon. ## Manba `datasets/fixture/elonlar_*.html` — SUN'IY saqlangan sahifalar (`datasets/fixture_qur.py`, qat'iy seed). Jonli sayt EMAS. Shuning uchun raqamlar har safar bir xil chiqadi. ## Hajmi - xom yozuv: {len(xom)} - tozalangandan keyin: {len(toza_t)} - noyob uy: {toza_t['guruh'].nunique()} - train / val / test: {len(train)} / {len(val)} / {len(test)} ## Target `narx_usd` — oylik ijara narxi, AQSh dollarida. Kurs: 1 USD = 12500 so'm (so'mda berilgan e'lonlar shu kurs bilan aylantirilgan). ## MUHIM ogohlantirish Generatorda narx feature lardan MUSTAQIL tanlangan. Ya'ni bu datasetda o'rganiladigan haqiqiy naqsh YO'Q. U faqat quyidagilarni o'rgatish uchun: tozalash, dublikat, guruh bo'yicha split va leakage o'lchash. Bu datasetda yaxshi R2 olishga urinish ma'nosiz. ## Olib tashlangan - narxi yo'q qatorlar ("Kelishilgan"): o'qitishga yaramaydi, target to'qilmaydi - feature si yetishmaydigan qatorlar ## Shaxsiy ma'lumot Telefon raqamlari YIG'ILMAGAN (`yiguv/qoidalar.py` -> `shaxsiyni_tashla`). Datasetda shaxsga doir hech qanday maydon yo'q. ## Split qoidasi GroupShuffleSplit, guruh = (tuman, maydon_m2, xonalar). Bitta uy faqat bitta bo'lakka tushadi. Tasodifiy split ISHLATILMAYDI. """ yol = ISH / "dataset" yol.mkdir(exist_ok=True) (yol / "DATASHEET.md").write_text(datasheet, encoding="utf-8") print(datasheet)
# uy_ijara dataseti — datasheet
## Nima
Toshkent ijara e'lonlari. Bitta qator = bitta e'lon.
## Manba
`datasets/fixture/elonlar_*.html` — SUN'IY saqlangan sahifalar
(`datasets/fixture_qur.py`, qat'iy seed). Jonli sayt EMAS.
Shuning uchun raqamlar har safar bir xil chiqadi.
## Hajmi
- xom yozuv: 300
- tozalangandan keyin: 207
- noyob uy: 176
- train / val / test: 136 / 33 / 38
## Target
`narx_usd` — oylik ijara narxi, AQSh dollarida.
Kurs: 1 USD = 12500 so'm (so'mda berilgan e'lonlar shu kurs bilan aylantirilgan).
## MUHIM ogohlantirish
Generatorda narx feature lardan MUSTAQIL tanlangan. Ya'ni bu datasetda
o'rganiladigan haqiqiy naqsh YO'Q. U faqat quyidagilarni o'rgatish uchun:
tozalash, dublikat, guruh bo'yicha split va leakage o'lchash.
Bu datasetda yaxshi R2 olishga urinish ma'nosiz.
## Olib tashlangan
- narxi yo'q qatorlar ("Kelishilgan"): o'qitishga yaramaydi, target to'qilmaydi
- feature si yetishmaydigan qatorlar
## Shaxsiy ma'lumot
Telefon raqamlari YIG'ILMAGAN (`yiguv/qoidalar.py` -> `shaxsiyni_tashla`).
Datasetda shaxsga doir hech qanday maydon yo'q.
## Split qoidasi
GroupShuffleSplit, guruh = (tuman, maydon_m2, xonalar).
Bitta uy faqat bitta bo'lakka tushadi. Tasodifiy split ISHLATILMAYDI.
for nom, b in [("train", train), ("val", val), ("test", test)]: b.to_csv(yol / f"{nom}.csv", index=False) narxsiz_df = toza[toza["narx_usd"].isna()] narxsiz_df.to_csv(yol / "narxsiz_bashorat_uchun.csv", index=False) print("ish/dataset/ papkasiga saqlandi:") for p in sorted(yol.iterdir()): print(f" {p.name:<32} {p.stat().st_size:>7} bayt") print() print("Endi bu papkani boshqa odamga berish mumkin: ma'lumot + hujjat + split qoidasi.")
ish/dataset/ papkasiga saqlandi: DATASHEET.md 1234 bayt narxsiz_bashorat_uchun.csv 1359 bayt test.csv 1484 bayt train.csv 5153 bayt val.csv 1278 bayt Endi bu papkani boshqa odamga berish mumkin: ma'lumot + hujjat + split qoidasi.
Protokolga ulanish
Bu bob 0-bobdagi protokolning 1–4 qadamlarini bajardi, lekin o'z ma'lumotingiz ustida:
show(pd.DataFrame([ {"Qadam": "1. Ustun tiplarini aniqla", "Bu bobda": "matn -> son, uch narx formati"}, {"Qadam": "2. Bo'sh qiymatlarni hisobla", "Bu bobda": "jurnal bilan, har qadamda"}, {"Qadam": "3. Target ni belgila", "Bu bobda": "narx_usd; target to'qilmaydi"}, {"Qadam": "4. Split qil", "Bu bobda": "GroupShuffleSplit — leakage o'lchandi"}, {"Qadam": "5. Baza qur", "Keyingi": "38-bob: fine-tuning; 6-bob: baza qoidasi"}, ]))
| Qadam | Bu bobda | Keyingi |
|---|---|---|
| 1. Ustun tiplarini aniqla | matn -> son, uch narx formati | NaN |
| 2. Bo'sh qiymatlarni hisobla | jurnal bilan, har qadamda | NaN |
| 3. Target ni belgila | narx_usd; target to'qilmaydi | NaN |
| 4. Split qil | GroupShuffleSplit — leakage o'lchandi | NaN |
| 5. Baza qur | NaN | 38-bob: fine-tuning; 6-bob: baza qoidasi |
Bugun nima o'rgandik
show(pd.DataFrame([ {"Tushuncha": "Qadam jurnali", "Bitta jumla": "Har amaldan keyin qator sanaladi — jim yo'qotish bo'lmaydi"}, {"Tushuncha": "Target to'qilmaydi", "Bitta jumla": "Feature to'ldiriladi, target — yo'q"}, {"Tushuncha": "Ma'lumot shartnomasi", "Bitta jumla": "Tip va diapazon kodda yozilgan kutish"}, {"Tushuncha": "Guruh identifikatori", "Bitta jumla": "Bitta uy = bitta guruh, barqaror maydonlardan"}, {"Tushuncha": "GroupShuffleSplit", "Bitta jumla": "O'lchandi: tasodifiy split R2 ni soxta oshiradi"}, {"Tushuncha": "Manfiy R2", "Bitta jumla": "O'rtachadan yomon — 6-bobdagi bazadan past"}, {"Tushuncha": "Datasheet", "Bitta jumla": "Dataset pasporti — 10 daqiqa, keyin bir yil tejaydi"}, {"Tushuncha": "Narxsiz qatorlar", "Bitta jumla": "O'qitishga yaramaydi, bashoratga yaraydi"}, ]))
| Tushuncha | Bitta jumla |
|---|---|
| Qadam jurnali | Har amaldan keyin qator sanaladi — jim yo'qotish bo'lmaydi |
| Target to'qilmaydi | Feature to'ldiriladi, target — yo'q |
| Ma'lumot shartnomasi | Tip va diapazon kodda yozilgan kutish |
| Guruh identifikatori | Bitta uy = bitta guruh, barqaror maydonlardan |
| GroupShuffleSplit | O'lchandi: tasodifiy split R2 ni soxta oshiradi |
| Manfiy R2 | O'rtachadan yomon — 6-bobdagi bazadan past |
| Datasheet | Dataset pasporti — 10 daqiqa, keyin bir yil tejaydi |
| Narxsiz qatorlar | O'qitishga yaramaydi, bashoratga yaraydi |
Keyingi bobda tayyor modelni o'z ma'lumotimizga moslashtiramiz: fine-tuning.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.