Chalkashlik-yechgich
Bu bob qanday ishlatiladi
Quyida talabalar eng ko'p chalkashtiradigan juftliklar. Har biri uchun bajarilgan kod bor — tushuntirish emas, isbot.
Biror tushuncha chalkash tuyulsa, shu bobdan toping va kodni o'zingiz ishga tushiring.
import warnings import numpy as np import pandas as pd from sklearn.model_selection import train_test_split uy = pd.read_csv(DATA / "uy_ijara.csv") SON = ["maydon_m2", "xonalar", "qavat", "metro_km"] X = uy[SON].fillna(uy[SON].median()) y = uy["ijaraga_berildi_30k"] Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.25, random_state=42, stratify=y) print(f"Misollar uchun: train {len(Xtr)}, test {len(Xte)}")
Misollar uchun: train 900, test 300
1. fit, transform, fit_transform
from sklearn.preprocessing import StandardScaler togri = StandardScaler().fit(Xtr) xato = StandardScaler().fit(pd.concat([Xtr, Xte])) # test ni ham ko'rdi print("TO'G'RI — scaler faqat train ni ko'radi:") print(f" train o'rtachasi: {togri.mean_[0]:.4f}") print(f" test o'rtachasi (transform dan keyin): {togri.transform(Xte)[:, 0].mean():.4f}") print(" test o'rtachasi 0 EMAS — va bu to'g'ri, test boshqa taqsimot") print() print("XATO — scaler test ni ham ko'rdi:") print(f" o'rtacha: {xato.mean_[0]:.4f} <- test ma'lumoti aralashgan") print() print("Qoida: fit FAQAT train da. test da faqat transform.") print("Pipeline ishlatsangiz, bu xatoni qilish IMKONSIZ bo'ladi.")
TO'G'RI — scaler faqat train ni ko'radi: train o'rtachasi: 57.1362 test o'rtachasi (transform dan keyin): 0.0096 test o'rtachasi 0 EMAS — va bu to'g'ri, test boshqa taqsimot XATO — scaler test ni ham ko'rdi: o'rtacha: 57.1853 <- test ma'lumoti aralashgan Qoida: fit FAQAT train da. test da faqat transform. Pipeline ishlatsangiz, bu xatoni qilish IMKONSIZ bo'ladi.
2. predict va predict_proba
from sklearn.linear_model import LogisticRegression model = LogisticRegression(max_iter=2000).fit(Xtr, ytr) ehtimol = model.predict_proba(Xte)[:, 1] bashorat = model.predict(Xte) print(f"predict_proba shakli : {model.predict_proba(Xte).shape} (har sinf uchun ustun)") print(f"predict shakli : {bashorat.shape}") print() qiyos = pd.DataFrame({"ehtimol_1": ehtimol[:6].round(4), "predict": bashorat[:6]}) show(qiyos) print(f"predict = (ehtimol >= 0.5) ekanini tekshiramiz: {bool(((ehtimol >= 0.5).astype(int) == bashorat).all())}") print() print("Ya'ni predict() — bu predict_proba() ustiga qo'yilgan 0.5 chegarasi.") print("8-bobda ko'rganmiz: 0.5 — sehrli raqam emas, uni o'zgartirish mumkin va kerak.")
predict_proba shakli : (300, 2) (har sinf uchun ustun) predict shakli : (300,) predict = (ehtimol >= 0.5) ekanini tekshiramiz: True Ya'ni predict() — bu predict_proba() ustiga qo'yilgan 0.5 chegarasi. 8-bobda ko'rganmiz: 0.5 — sehrli raqam emas, uni o'zgartirish mumkin va kerak.
| ehtimol_1 | predict |
|---|---|
| 0.471 | 0 |
| 0.389 | 0 |
| 0.618 | 1 |
| 0.687 | 1 |
| 0.186 | 0 |
| 0.519 | 1 |
3. Accuracy, precision, recall
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # nomutanosib holat yasaymiz: 10% musbat r = np.random.default_rng(0) nomutanosib_y = np.zeros(1000, dtype=int) nomutanosib_y[r.choice(1000, 100, replace=False)] = 1 hammaga_yoq = np.zeros(1000, dtype=int) show(pd.DataFrame([ {"metrika": "accuracy", "qiymat": round(accuracy_score(nomutanosib_y, hammaga_yoq), 4), "ma'nosi": "to'g'ri javoblar ulushi"}, {"metrika": "precision", "qiymat": round(precision_score(nomutanosib_y, hammaga_yoq, zero_division=0), 4), "ma'nosi": "'ha' deganlarimdan nechtasi haqiqatan ha"}, {"metrika": "recall", "qiymat": round(recall_score(nomutanosib_y, hammaga_yoq, zero_division=0), 4), "ma'nosi": "haqiqiy 'ha' lardan nechtasini topdim"}, {"metrika": "f1", "qiymat": round(f1_score(nomutanosib_y, hammaga_yoq, zero_division=0), 4), "ma'nosi": "precision va recall muvozanati"}, ])) print("Model HAMMAGA 'yo'q' dedi — hech narsa o'rganmadi.") print("Accuracy yuqori, qolgan hammasi nol. Shuning uchun nomutanosib") print("ma'lumotda accuracy ga qarash — o'zini aldash (7 va 8-bob).")
Model HAMMAGA 'yo'q' dedi — hech narsa o'rganmadi. Accuracy yuqori, qolgan hammasi nol. Shuning uchun nomutanosib ma'lumotda accuracy ga qarash — o'zini aldash (7 va 8-bob).
| metrika | qiymat | ma'nosi |
|---|---|---|
| accuracy | 0.9 | to'g'ri javoblar ulushi |
| precision | 0 | 'ha' deganlarimdan nechtasi haqiqatan ha |
| recall | 0 | haqiqiy 'ha' lardan nechtasini topdim |
| f1 | 0 | precision va recall muvozanati |
4. Parametr va giperparametr
m = LogisticRegression(C=0.5, max_iter=2000).fit(Xtr, ytr) print("GIPERPARAMETR — siz tanlaysiz, model o'rganmaydi:") print(f" C = {m.C}") print(f" max_iter = {m.max_iter}") print() print("PARAMETR — model ma'lumotdan o'rganadi, siz tanlamaysiz:") print(f" coef_ = {m.coef_[0].round(4)}") print(f" intercept_= {m.intercept_.round(4)}") print() print("Oson belgi: ism oxiri _ bilan tugasa (coef_, mean_) — bu O'RGANILGAN parametr.") print("Konstruktorga yozsangiz (C=0.5) — bu giperparametr. 23-bob ularni sozlaydi.")
GIPERPARAMETR — siz tanlaysiz, model o'rganmaydi: C = 0.5 max_iter = 2000 PARAMETR — model ma'lumotdan o'rganadi, siz tanlamaysiz: coef_ = [-0.0452 -0.1975 0.0197 0.0236] intercept_= [2.9275] Oson belgi: ism oxiri _ bilan tugasa (coef_, mean_) — bu O'RGANILGAN parametr. Konstruktorga yozsangiz (C=0.5) — bu giperparametr. 23-bob ularni sozlaydi.
5. Standartlashtirish va normallashtirish
from sklearn.preprocessing import MinMaxScaler std = StandardScaler().fit_transform(Xtr) mnm = MinMaxScaler().fit_transform(Xtr) show(pd.DataFrame([ {"usul": "StandardScaler", "o'rtacha": round(float(std.mean()), 4), "std": round(float(std.std()), 4), "min": round(float(std.min()), 2), "maks": round(float(std.max()), 2), "qachon": "taqsimot normalga yaqin bo'lsa"}, {"usul": "MinMaxScaler", "o'rtacha": round(float(mnm.mean()), 4), "std": round(float(mnm.std()), 4), "min": round(float(mnm.min()), 2), "maks": round(float(mnm.max()), 2), "qachon": "chegara aniq kerak bo'lsa (rasm: 0..1)"}, ])) print("StandardScaler: o'rtacha 0, std 1 — lekin chegara YO'Q.") print("MinMaxScaler: 0..1 oralig'ida — lekin chetdagi qiymat hammani siqib qo'yadi.")
StandardScaler: o'rtacha 0, std 1 — lekin chegara YO'Q. MinMaxScaler: 0..1 oralig'ida — lekin chetdagi qiymat hammani siqib qo'yadi.
| usul | o'rtacha | std | min | maks | qachon |
|---|---|---|---|---|---|
| StandardScaler | -0 | 1 | -1.72 | 3.46 | taqsimot normalga yaqin bo'lsa |
| MinMaxScaler | 0.333 | 0.239 | 0 | 1 | chegara aniq kerak bo'lsa (rasm: 0..1) |
6. Bagging va boosting
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier show(pd.DataFrame([ {"jihat": "Daraxtlar qanday quriladi", "Bagging (RandomForest)": "PARALLEL, mustaqil", "Boosting": "KETMA-KET, har biri oldingining xatosini tuzatadi"}, {"jihat": "Nimani kamaytiradi", "Bagging (RandomForest)": "variance (tarqoqlik)", "Boosting": "bias (siljish)"}, {"jihat": "Overfitting xavfi", "Bagging (RandomForest)": "past", "Boosting": "yuqori — qadam soni nazorat qilinadi"}, {"jihat": "Parallellashtirish", "Bagging (RandomForest)": "oson (n_jobs=-1)", "Boosting": "qiyin — ketma-ketlik majburiy"}, ])) rf = RandomForestClassifier(n_estimators=100, random_state=0).fit(Xtr, ytr) gb = GradientBoostingClassifier(random_state=0).fit(Xtr, ytr) print(f"RandomForest aniqlik : {rf.score(Xte, yte):.4f}") print(f"GradientBoosting : {gb.score(Xte, yte):.4f}") print("(18 va 19-bob: qaysi biri yutishi ma'lumotga bog'liq, qoida yo'q)")
RandomForest aniqlik : 0.7000 GradientBoosting : 0.7167 (18 va 19-bob: qaysi biri yutishi ma'lumotga bog'liq, qoida yo'q)
| jihat | Bagging (RandomForest) | Boosting |
|---|---|---|
| Daraxtlar qanday quriladi | PARALLEL, mustaqil | KETMA-KET, har biri oldingining xatosini tuzatadi |
| Nimani kamaytiradi | variance (tarqoqlik) | bias (siljish) |
| Overfitting xavfi | past | yuqori — qadam soni nazorat qilinadi |
| Parallellashtirish | oson (n_jobs=-1) | qiyin — ketma-ketlik majburiy |
7. Loss va metrika
from sklearn.metrics import log_loss a = LogisticRegression(C=100, max_iter=2000).fit(Xtr, ytr) b = LogisticRegression(C=0.01, max_iter=2000).fit(Xtr, ytr) show(pd.DataFrame([ {"model": "C=100", "accuracy": round(a.score(Xte, yte), 4), "log_loss": round(log_loss(yte, a.predict_proba(Xte)), 4)}, {"model": "C=0.01", "accuracy": round(b.score(Xte, yte), 4), "log_loss": round(log_loss(yte, b.predict_proba(Xte)), 4)}, ])) print("LOSS — model o'qitish paytida minimallashtiradi, u uzluksiz va hosilaga ega.") print("METRIKA — siz baholaysiz, u biznes ma'nosiga ega, hosilasi bo'lmasligi mumkin.") print("Ikkisi bir xil tartibda joylashmasligi mumkin — shuning uchun ikkisini ham kuzating.")
LOSS — model o'qitish paytida minimallashtiradi, u uzluksiz va hosilaga ega. METRIKA — siz baholaysiz, u biznes ma'nosiga ega, hosilasi bo'lmasligi mumkin. Ikkisi bir xil tartibda joylashmasligi mumkin — shuning uchun ikkisini ham kuzating.
| model | accuracy | log_loss |
|---|---|---|
| C=100 | 0.79 | 0.496 |
| C=0.01 | 0.78 | 0.5 |
8. Validation va test
show(pd.DataFrame([ {"to'plam": "train", "nechta marta ishlatiladi": "ko'p", "nima uchun": "model vaznlarini o'rganish"}, {"to'plam": "validation", "nechta marta ishlatiladi": "ko'p", "nima uchun": "giperparametr tanlash, model tanlash"}, {"to'plam": "test", "nechta marta ishlatiladi": "BIR MARTA", "nima uchun": "yakuniy halol baho"}, ])) print("Test to'plamiga qarab biror qaror qabul qilsangiz, u endi validation.") print("Va sizda halol baho qolmaydi. 5-bobda shu haqda.")
Test to'plamiga qarab biror qaror qabul qilsangiz, u endi validation. Va sizda halol baho qolmaydi. 5-bobda shu haqda.
| to'plam | nechta marta ishlatiladi | nima uchun |
|---|---|---|
| train | ko'p | model vaznlarini o'rganish |
| validation | ko'p | giperparametr tanlash, model tanlash |
| test | BIR MARTA | yakuniy halol baho |
9. L1 va L2 regularizatsiya
from sklearn.linear_model import Lasso, Ridge from sklearn.preprocessing import StandardScaler as SS Xs = SS().fit_transform(Xtr) yr = uy.loc[Xtr.index, "narx_usd"] qatorlar = [] for alpha in [1, 10, 50, 100, 200, 400]: l1 = Lasso(alpha=alpha, max_iter=10000).fit(Xs, yr) l2 = Ridge(alpha=alpha).fit(Xs, yr) qatorlar.append({"alpha": alpha, "L1 nol koeffitsiyent": int((l1.coef_ == 0).sum()), "L2 nol koeffitsiyent": int((l2.coef_ == 0).sum()), "L1 koeffitsiyentlari": str(l1.coef_.round(1))}) show(pd.DataFrame(qatorlar)) print(f"Ustunlar soni: {len(SON)}")
Ustunlar soni: 4
| alpha | L1 nol koeffitsiyent | L2 nol koeffitsiyent | L1 koeffitsiyentlari |
|---|---|---|---|
| 1 | 0 | 0 | [147.8 61. 9.4 -42.5] |
| 10 | 0 | 0 | [140.5 58.7 0.4 -33. ] |
| 50 | 2 | 0 | [114. 42.4 0. -0. ] |
| 100 | 2 | 0 | [88.2 16.7 0. -0. ] |
| 200 | 3 | 0 | [ 3.9 0. 0. -0. ] |
| 400 | 4 | 0 | [ 0. 0. 0. -0.] |
Jadval ikki narsani ko'rsatadi.
Birinchi: L1 alpha o'sgani sari koeffitsiyentlarni birin-ketin aynan nolga tushiradi — ya'ni ustunlarni tanlaydi. L2 ustuni esa har doim nol: Ridge koeffitsiyentni kichraytiradi, lekin nolga tushirmaydi.
Ikkinchi: kichik alpha da L1 ham hech narsani nolga tushirmaydi. "Lasso ustun tanlaydi" degan gap alpha yetarlicha katta bo'lganda to'g'ri. Alpha ni 1 qo'yib "nega hech narsa tanlanmadi?" deb hayron bo'lish — odatiy holat.
10. Korrelyatsiya, muhimlik va sababiyat
rf2 = RandomForestClassifier(n_estimators=100, random_state=0).fit(Xtr, ytr) show(pd.DataFrame({"ustun": SON, "korrelyatsiya (target bilan)": [round(float(np.corrcoef(Xtr[c], ytr)[0, 1]), 4) for c in SON], "feature importance": rf2.feature_importances_.round(4)})) print("Uchta BOSHQA narsa:") print(" korrelyatsiya — chiziqli bog'liqlik kuchi") print(" muhimlik — model shu ustundan qancha foydalangani") print(" sababiyat — ustun target ni O'ZGARTIRADIMI") print() print("Model muhimlik bersa, bu sabab degani EMAS. Sababni aniqlash uchun") print("tajriba (A/B test) kerak, kuzatuv ma'lumoti yetarli emas.")
Uchta BOSHQA narsa: korrelyatsiya — chiziqli bog'liqlik kuchi muhimlik — model shu ustundan qancha foydalangani sababiyat — ustun target ni O'ZGARTIRADIMI Model muhimlik bersa, bu sabab degani EMAS. Sababni aniqlash uchun tajriba (A/B test) kerak, kuzatuv ma'lumoti yetarli emas.
| ustun | korrelyatsiya (target bilan) | feature importance |
|---|---|---|
| maydon_m2 | -0.458 | 0.437 |
| xonalar | -0.442 | 0.108 |
| qavat | 0.025 | 0.145 |
| metro_km | -0.008 | 0.31 |
11. pandas: zanjirli o'zlashtirish
print(f"pandas versiyasi: {pd.__version__}") asl = uy[["maydon_m2", "narx_usd"]].head(5).copy() print("\nAsl narxlar:", list(asl.narx_usd)) bolak = asl[asl.maydon_m2 > 0] # bu YANGI obyekt with warnings.catch_warnings(record=True) as ogoh: warnings.simplefilter("always") bolak["narx_usd"] = 0 turlari = [w.category.__name__ for w in ogoh] print(f"Ogohlantirish : {turlari or 'YO`Q'}") print(f"bolak o'zgardi : {bool((bolak.narx_usd == 0).all())}") print(f"asl o'zgardi : {bool((asl.narx_usd == 0).any())}") print("\nAsl narxlar hali ham:", list(asl.narx_usd))
pandas versiyasi: 2.3.3 Asl narxlar: [760, 550, 1415, 985, 550] Ogohlantirish : YO`Q bolak o'zgardi : True asl o'zgardi : False Asl narxlar hali ham: [760, 550, 1415, 985, 550]
pandas 2.x da bu xato JIM — ogohlantirish ham chiqmaydi
Ilgari pandas bu holatda SettingWithCopyWarning berardi. Yangi versiyalarda (copy-on-write) u umuman chiqmaydi.
Natija yuqorida: bolak o'zgardi, asl esa o'zgarmadi. Agar siz asl jadvalni tuzatmoqchi bo'lsangiz, hech narsa bo'lmadi — va hech kim sizga aytmadi.
Bu eski ogohlantirishdan xavfliroq, chunki endi hatto ogohlantirish ham yo'q.
To'g'ri yo'l — bitta amalda .loc bilan yozish:
asl2 = uy[["maydon_m2", "narx_usd"]].head(5).copy() asl2.loc[asl2.maydon_m2 > 0, "narx_usd"] = 0 print(f".loc bilan — asl jadval o'zgardi: {bool((asl2.narx_usd == 0).all())}") print("Qoida: filtrlab, keyin o'zlashtirish EMAS. Bitta .loc amalida qiling.")
.loc bilan — asl jadval o'zgardi: True Qoida: filtrlab, keyin o'zlashtirish EMAS. Bitta .loc amalida qiling.
12. Shuffle: qachon mumkin, qachon mumkin emas
show(pd.DataFrame([ {"ma'lumot turi": "Mustaqil qatorlar (uy, mijoz)", "shuffle": "MUMKIN", "split": "train_test_split(shuffle=True)"}, {"ma'lumot turi": "Vaqt qatori", "shuffle": "MUMKIN EMAS", "split": "xronologik yoki TimeSeriesSplit (34-bob)"}, {"ma'lumot turi": "Guruhlangan (bitta uy, ko'p e'lon)", "shuffle": "EHTIYOT", "split": "GroupShuffleSplit (37-bob)"}, {"ma'lumot turi": "Nomutanosib sinflar", "shuffle": "MUMKIN", "split": "stratify=y bilan"}, ]))
| ma'lumot turi | shuffle | split |
|---|---|---|
| Mustaqil qatorlar (uy, mijoz) | MUMKIN | train_test_split(shuffle=True) |
| Vaqt qatori | MUMKIN EMAS | xronologik yoki TimeSeriesSplit (34-bob) |
| Guruhlangan (bitta uy, ko'p e'lon) | EHTIYOT | GroupShuffleSplit (37-bob) |
| Nomutanosib sinflar | MUMKIN | stratify=y bilan |
13. Eng ko'p uchraydigan xato xabarlari
show(pd.DataFrame([ {"Xato": "could not convert string to float", "Sababi": "matn ustun modelga tushdi", "Yechim": "OneHotEncoder yoki ColumnTransformer (4-bob)"}, {"Xato": "Input contains NaN", "Sababi": "bo'sh qiymat qolgan", "Yechim": "SimpleImputer, Pipeline ichida (4-bob)"}, {"Xato": "X has N features, but expects M", "Sababi": "train va test ustunlari boshqa", "Yechim": "Pipeline saqlang, ustunlarni tekshiring (39-bob)"}, {"Xato": "ConvergenceWarning", "Sababi": "max_iter yetmadi yoki scaling yo'q", "Yechim": "scaling qo'shing, keyin max_iter oshiring (15-bob)"}, {"Xato": "columns are missing", "Sababi": "kiruvchi kadrda ustun yo'q", "Yechim": "shartnoma bilan tekshiring (37, 40-bob)"}, {"Xato": "Found input variables with inconsistent numbers", "Sababi": "X va y uzunligi boshqa", "Yechim": "filtrlashda ikkisini birga filtrlang"}, ]))
| Xato | Sababi | Yechim |
|---|---|---|
| could not convert string to float | matn ustun modelga tushdi | OneHotEncoder yoki ColumnTransformer (4-bob) |
| Input contains NaN | bo'sh qiymat qolgan | SimpleImputer, Pipeline ichida (4-bob) |
| X has N features, but expects M | train va test ustunlari boshqa | Pipeline saqlang, ustunlarni tekshiring (39-bob) |
| ConvergenceWarning | max_iter yetmadi yoki scaling yo'q | scaling qo'shing, keyin max_iter oshiring (15-bob) |
| columns are missing | kiruvchi kadrda ustun yo'q | shartnoma bilan tekshiring (37, 40-bob) |
| Found input variables with inconsistent numbers | X va y uzunligi boshqa | filtrlashda ikkisini birga filtrlang |
Bir jumlalik javoblar
show(pd.DataFrame([ {"Savol": "fit_transform ni test da ishlatsam bo'ladimi?", "Javob": "Yo'q — faqat transform"}, {"Savol": "0.5 chegara majburiymi?", "Javob": "Yo'q, u shunchaki standart qiymat"}, {"Savol": "Accuracy yaxshi metrikami?", "Javob": "Sinflar muvozanatli bo'lsa — ha"}, {"Savol": "Qancha ma'lumot kerak?", "Javob": "O'quv egri chizig'i aytadi (10-bob)"}, {"Savol": "Deep learning har doim yaxshiroqmi?", "Javob": "Yo'q — kitobda bir necha marta o'lchandi"}, {"Savol": "Feature importance sababni ko'rsatadimi?", "Javob": "Yo'q"}, {"Savol": "Test ni necha marta ishlataman?", "Javob": "Bir marta"}, {"Savol": "Modelim 0.95 berdi, yaxshimi?", "Javob": "Baza nima berganini ayting (6-bob)"}, ]))
| Savol | Javob |
|---|---|
| fit_transform ni test da ishlatsam bo'ladimi? | Yo'q — faqat transform |
| 0.5 chegara majburiymi? | Yo'q, u shunchaki standart qiymat |
| Accuracy yaxshi metrikami? | Sinflar muvozanatli bo'lsa — ha |
| Qancha ma'lumot kerak? | O'quv egri chizig'i aytadi (10-bob) |
| Deep learning har doim yaxshiroqmi? | Yo'q — kitobda bir necha marta o'lchandi |
| Feature importance sababni ko'rsatadimi? | Yo'q |
| Test ni necha marta ishlataman? | Bir marta |
| Modelim 0.95 berdi, yaxshimi? | Baza nima berganini ayting (6-bob) |
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.