20-bo‘lim

Amaliy loyiha - talaba muvaffaqiyatini bashorat qilish

Ma'lumot tahlilidan tayyor modelgacha - barcha bilimlarni birlashtirgan to'liq loyiha.

🕑 20 daqiqa o‘qish 📄 979 so‘z 👁 6 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Vazifa
  2. Bosqich 1 - ma'lumot
  3. Bosqich 2 - ma'lumotni o'rganish
  4. Bosqich 3 - tozalash
  5. Bosqich 4 - bo'lish
  6. Bosqich 5 - tayyorlash quvuri
  7. Bosqich 6 - modellarni solishtirish
  8. Bosqich 7 - eng yaxshi modelni sozlash
  9. Bosqich 8 - chegarani tanlash
  10. Bosqich 9 - yakuniy baholash
  11. Bosqich 10 - modelni tushuntirish
  12. Bitta talaba uchun tushuntirish
  13. Bosqich 11 - saqlash
  14. Bosqich 12 - testlar
  15. Loyiha xulosasi
  16. Yakuniy xulosa

Yigirma bo'lim davomida o'rgangan hamma narsani bitta to'liq loyihada birlashtiramiz.

Vazifa #

Loyiha shartlari

Muammo: universitet talabalarning imtihondan o'ta olmaslik xavfini oldindan aniqlamoqchi. Shunda ular semestr o'rtasida qo'shimcha yordam oladi.

Turi: ikkilik klassifikatsiya (o'tadi / o'tmaydi)

Asosiy metrika: Recall - xavf ostidagi talabani o'tkazib yuborish, keraksiz yordam taklif qilishdan yomonroq.

Talab: model qarorini tushuntira olishi kerak - o'qituvchi "nima uchun bu talaba xavf ostida?" deb so'raydi.

Bosqich 1 - ma'lumot #

Python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

np.random.seed(42)
sns.set_theme(style="whitegrid")

n = 1200

talabalar = pd.DataFrame({
    "yosh":            np.random.randint(17, 26, n),
    "oqish_soati":     np.random.gamma(3, 2.2, n).clip(0, 25),
    "davomat":         np.random.beta(6, 2, n) * 100,
    "oldingi_baho":    np.random.normal(3.6, 0.7, n).clip(2, 5),
    "uyqu_soati":      np.random.normal(7, 1.4, n).clip(3, 12),
    "topshiriqlar":    np.random.binomial(12, 0.72, n),
    "kutubxona":       np.random.poisson(4, n),
    "ishlaydi":        np.random.choice([0, 1], n, p=[0.65, 0.35]),
    "internet":        np.random.choice([0, 1], n, p=[0.15, 0.85]),
    "yonalish":        np.random.choice(
        ["Dasturlash", "Iqtisod", "Filologiya", "Muhandislik"], n),
    "turar_joy":       np.random.choice(
        ["Yotoqxona", "Uy", "Ijara"], n, p=[0.4, 0.45, 0.15]),
})

# Yashirin qonuniyat
ball = (
    talabalar["oqish_soati"] * 0.32
    + talabalar["davomat"] * 0.055
    + talabalar["oldingi_baho"] * 1.4
    + talabalar["topshiriqlar"] * 0.28
    + talabalar["kutubxona"] * 0.12
    - talabalar["ishlaydi"] * 0.9
    + np.random.normal(0, 1.3, n)
)

talabalar["otdi"] = (ball > np.percentile(ball, 28)).astype(int)

# Haqiqiy ma'lumotdagi kabi muammolar qo'shamiz
bosh_indeks = np.random.choice(n, 90, replace=False)
talabalar.loc[bosh_indeks[:50], "uyqu_soati"] = np.nan
talabalar.loc[bosh_indeks[50:], "kutubxona"] = np.nan
talabalar.loc[np.random.choice(n, 20, replace=False), "oqish_soati"] = 999

print(talabalar.shape)
print(talabalar["otdi"].value_counts(normalize=True).round(3))
Natija
(1200, 12)
otdi
1    0.72
0    0.28
Name: proportion, dtype: float64

Bosqich 2 - ma'lumotni o'rganish #

Python
print(talabalar.info())
print(talabalar.describe().round(2))
Natija
maydon             non-null
oqish_soati   1200   float64
davomat       1200   float64
uyqu_soati    1150   float64
kutubxona     1160   float64
...

        oqish_soati    davomat  uyqu_soati  topshiriqlar
count       1200.00    1200.00     1150.00       1200.00
mean          22.61      75.02        7.03          8.64
std          123.87      13.41        1.38          1.61
min            0.12      28.44        3.00          3.00
50%            5.94      77.11        7.02          9.00
max          999.00      99.72       11.87         12.00
Ikki muammo darhol ko'rinadi
  1. oqish_soati ning max qiymati 999 - bu aniq xato
  2. uyqu_soati va kutubxona da bo'sh qiymatlar bor

describe() ni birinchi bo'lib chaqirishning sababi shu.

Python
# Bo'sh qiymatlar
print((talabalar.isna().sum() / len(talabalar) * 100).round(1)[lambda s: s > 0])

# Chetdagi qiymatlar
print(f"999 qiymatlar soni: {(talabalar['oqish_soati'] == 999).sum()}")
Natija
uyqu_soati    4.2
kutubxona     3.3
999 qiymatlar soni: 20
Python
sonli = talabalar.select_dtypes(include="number")

plt.figure(figsize=(10, 8))
sns.heatmap(sonli.corr(), annot=True, fmt=".2f", cmap="coolwarm", center=0)
plt.title("Belgilar korrelyatsiyasi")
plt.tight_layout()
plt.show()

print(sonli.corr()["otdi"].drop("otdi").sort_values(ascending=False).round(3))
Natija
oldingi_baho    0.412
davomat         0.387
topshiriqlar    0.331
oqish_soati     0.298
kutubxona       0.164
internet        0.038
yosh           -0.012
ishlaydi       -0.187
Imtihondan o'tish bilan bog'liqlik oldingi_baho 0.41 davomat 0.39 topshiriqlar 0.33 oqish_soati 0.30 kutubxona 0.16 yosh -0.01 ishlaydi -0.19 Musbat bog'liqlik Manfiy bog'liqlik
Ishlaydigan talabalarda o'tish ehtimoli pastroq

Bosqich 3 - tozalash #

Python
# 999 - aniq xato, uni bo'sh deb belgilaymiz
talabalar.loc[talabalar["oqish_soati"] > 100, "oqish_soati"] = np.nan

# IQR bilan qolgan chetdagi qiymatlarni tekshiramiz
def chetdagilarni_sana(malumot, ustun):
    q1, q3 = malumot[ustun].quantile([0.25, 0.75])
    iqr = q3 - q1
    quyi, yuqori = q1 - 1.5 * iqr, q3 + 1.5 * iqr
    return ((malumot[ustun] < quyi) | (malumot[ustun] > yuqori)).sum()


for ustun in ["oqish_soati", "davomat", "uyqu_soati", "kutubxona"]:
    print(f"{ustun:14s}: {chetdagilarni_sana(talabalar, ustun)} ta chetdagi qiymat")
Natija
oqish_soati   : 41 ta chetdagi qiymat
davomat       : 12 ta chetdagi qiymat
uyqu_soati    : 8 ta chetdagi qiymat
kutubxona     : 15 ta chetdagi qiymat
Bularni o'chirmaymiz

Bu qiymatlar haqiqiy bo'lishi mumkin: kimdir haftasiga 20 soat o'qiydi, kimdir kutubxonaga 15 marta boradi.

Faqat 999 aniq xato edi. Qolganlarini qoldiramiz - daraxtga asoslangan model ularga chidamli.

Python
# Yangi belgilar
talabalar["topshiriq_foizi"] = talabalar["topshiriqlar"] / 12 * 100
talabalar["kunlik_oqish"] = talabalar["oqish_soati"] / 7
talabalar["faol_talaba"] = (
    (talabalar["davomat"] > 80) & (talabalar["topshiriqlar"] >= 10)
).astype(int)
talabalar["kam_uyqu"] = (talabalar["uyqu_soati"] < 6).astype(int)

Bosqich 4 - bo'lish #

Python
from sklearn.model_selection import train_test_split

X = talabalar.drop(columns=["otdi"])
y = talabalar["otdi"]

assert "otdi" not in X.columns

X_toliq, X_sinov, y_toliq, y_sinov = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

print(f"O'qitish + validatsiya: {len(X_toliq)}")
print(f"Sinov (yopiq):          {len(X_sinov)}")
print(f"Sinf nisbati saqlandi:  {y_toliq.mean():.3f} / {y_sinov.mean():.3f}")
Natija
O'qitish + validatsiya: 960
Sinov (yopiq):          240
Sinf nisbati saqlandi:  0.720 / 0.721

Bosqich 5 - tayyorlash quvuri #

Python
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer

sonli_ustunlar = [
    "yosh", "oqish_soati", "davomat", "oldingi_baho", "uyqu_soati",
    "topshiriqlar", "kutubxona", "topshiriq_foizi", "kunlik_oqish",
]
ikkilik_ustunlar = ["ishlaydi", "internet", "faol_talaba", "kam_uyqu"]
toifali_ustunlar = ["yonalish", "turar_joy"]

sonli_quvur = Pipeline([
    ("toldirish", SimpleImputer(strategy="median")),
    ("masshtab", StandardScaler()),
])

toifali_quvur = Pipeline([
    ("toldirish", SimpleImputer(strategy="most_frequent")),
    ("kodlash", OneHotEncoder(handle_unknown="ignore", drop="first")),
])

tayyorlovchi = ColumnTransformer([
    ("sonli", sonli_quvur, sonli_ustunlar),
    ("ikkilik", SimpleImputer(strategy="most_frequent"), ikkilik_ustunlar),
    ("toifali", toifali_quvur, toifali_ustunlar),
])

Bosqich 6 - modellarni solishtirish #

Python
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, HistGradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.dummy import DummyClassifier
from sklearn.model_selection import cross_validate, StratifiedKFold

bolinish = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

modellar = {
    "Asos (dummy)":  DummyClassifier(strategy="most_frequent"),
    "Logistik":      LogisticRegression(max_iter=1000, class_weight="balanced"),
    "Random Forest": RandomForestClassifier(
        n_estimators=200, class_weight="balanced", random_state=42, n_jobs=-1),
    "Boosting":      HistGradientBoostingClassifier(random_state=42),
    "SVM":           SVC(class_weight="balanced", probability=True, random_state=42),
}

natijalar = []

for nom, model in modellar.items():
    quvur = Pipeline([("tayyorlash", tayyorlovchi), ("model", model)])

    ballar = cross_validate(
        quvur, X_toliq, y_toliq, cv=bolinish,
        scoring=["accuracy", "precision", "recall", "f1", "roc_auc"],
    )

    natijalar.append({
        "Model":     nom,
        "Aniqlik":   ballar["test_accuracy"].mean(),
        "Precision": ballar["test_precision"].mean(),
        "Recall":    ballar["test_recall"].mean(),
        "F1":        ballar["test_f1"].mean(),
        "AUC":       ballar["test_roc_auc"].mean(),
    })

jadval = pd.DataFrame(natijalar).set_index("Model").round(3)
print(jadval)
Natija
               Aniqlik  Precision  Recall     F1    AUC
Model
Asos (dummy)     0.720      0.720   1.000  0.837  0.500
Logistik         0.798      0.891   0.822  0.855  0.869
Random Forest    0.812      0.878   0.862  0.870  0.878
Boosting         0.821      0.884   0.869  0.876  0.884
SVM              0.804      0.885   0.838  0.862  0.871
Asos modelga diqqat bilan qarang

DummyClassifier recall = 1.000 ko'rsatdi - chunki u hammani "o'tadi" deydi.

Uning AUC = 0.500 - ya'ni u hech nima o'rganmagan. Bu bitta metrikaga tayanishning xavfini yana bir bor ko'rsatadi.

Bosqich 7 - eng yaxshi modelni sozlash #

Python
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform

quvur = Pipeline([
    ("tayyorlash", tayyorlovchi),
    ("model", HistGradientBoostingClassifier(random_state=42)),
])

taqsimot = {
    "model__max_iter": randint(100, 400),
    "model__learning_rate": uniform(0.01, 0.25),
    "model__max_depth": [3, 5, 7, None],
    "model__min_samples_leaf": randint(5, 40),
    "model__l2_regularization": uniform(0, 2),
}

qidiruv = RandomizedSearchCV(
    quvur, taqsimot,
    n_iter=60,
    cv=bolinish,
    scoring="recall",
    n_jobs=-1,
    random_state=42,
)
qidiruv.fit(X_toliq, y_toliq)

print(f"Eng yaxshi CV recall: {qidiruv.best_score_:.3f}")
for kalit, qiymat in qidiruv.best_params_.items():
    print(f"  {kalit.replace('model__', ''):22s} = {qiymat}")
Natija
Eng yaxshi CV recall: 0.898
  l2_regularization      = 0.418
  learning_rate          = 0.061
  max_depth              = 5
  max_iter               = 287
  min_samples_leaf       = 18

Bosqich 8 - chegarani tanlash #

Python
from sklearn.metrics import precision_recall_curve, f1_score

eng_yaxshi = qidiruv.best_estimator_
ehtimollik = eng_yaxshi.predict_proba(X_toliq)[:, 1]

print(f"{'Chegara':>8} {'Precision':>10} {'Recall':>8} {'F1':>7} {'Xavf ostida':>12}")

for chegara in [0.3, 0.4, 0.5, 0.6, 0.7]:
    bashorat = (ehtimollik >= chegara).astype(int)
    xavf_ostida = (bashorat == 0).sum()

    from sklearn.metrics import precision_score, recall_score
    print(f"{chegara:>8.1f} "
          f"{precision_score(y_toliq, bashorat):>10.3f} "
          f"{recall_score(y_toliq, bashorat):>8.3f} "
          f"{f1_score(y_toliq, bashorat):>7.3f} "
          f"{xavf_ostida:>12d}")
Natija
 Chegara  Precision   Recall      F1  Xavf ostida
     0.3      0.798    0.982   0.881          109
     0.4      0.842    0.951   0.893          182
     0.5      0.881    0.912   0.896          253
     0.6      0.912    0.859   0.885          321
     0.7      0.941    0.788   0.858          402
Qaysi chegarani tanlaymiz?

Bizning maqsadimiz - xavf ostidagi talabani o'tkazib yubormaslik.

0.4 chegarada:

  • Recall 0.951 - haqiqatan o'tadigan talabalarning 95 foizini to'g'ri aniqlaydik
  • 182 ta talaba "xavf ostida" deb belgilanadi

Universitet 182 talabaga qo'shimcha yordam bera oladimi? Agar ha - 0.4 ni tanlaymiz. Agar resurs 100 tagacha bo'lsa - 0.3 ni.

Bu texnik emas, tashkiliy qaror.

Python
CHEGARA = 0.4

Bosqich 9 - yakuniy baholash #

Python
from sklearn.metrics import (
    classification_report, confusion_matrix,
    ConfusionMatrixDisplay, roc_auc_score,
)

ehtimollik_sinov = eng_yaxshi.predict_proba(X_sinov)[:, 1]
bashorat_sinov = (ehtimollik_sinov >= CHEGARA).astype(int)

print(classification_report(
    y_sinov, bashorat_sinov,
    target_names=["Xavf ostida", "O'tadi"],
))

print(f"AUC: {roc_auc_score(y_sinov, ehtimollik_sinov):.3f}")
print(confusion_matrix(y_sinov, bashorat_sinov))
Natija
              precision    recall  f1-score   support

 Xavf ostida       0.79      0.61      0.69        67
      O'tadi       0.86      0.94      0.90       173

    accuracy                           0.85       240
   macro avg       0.83      0.78      0.79       240
weighted avg       0.84      0.85      0.84       240

AUC: 0.881

[[ 41  26]
 [ 11 162]]
Natijani o'qish
  • 41 ta xavf ostidagi talaba to'g'ri aniqlandi
  • 26 tasi o'tkazib yuborildi (yaxshilash kerak)
  • 11 ta talaba xato ravishda xavf ostida deb belgilandi
  • CV natijasi (0.898) va sinov natijasi (0.94) yaqin - sizib chiqish yo'q

Bosqich 10 - modelni tushuntirish #

Python
from sklearn.inspection import permutation_importance

natija = permutation_importance(
    eng_yaxshi, X_sinov, y_sinov,
    n_repeats=20, random_state=42, scoring="recall", n_jobs=-1,
)

muhimlik = pd.Series(
    natija.importances_mean, index=X_sinov.columns
).sort_values(ascending=False)

print(muhimlik.head(8).round(4))
Natija
oldingi_baho       0.0682
davomat            0.0541
topshiriq_foizi    0.0388
oqish_soati        0.0312
ishlaydi           0.0164
kutubxona          0.0098
kunlik_oqish       0.0071
faol_talaba        0.0043
Python
plt.figure(figsize=(9, 6))
muhimlik.head(10).sort_values().plot(kind="barh", color="steelblue")
plt.xlabel("Recall ga ta'siri")
plt.title("Belgilar muhimligi (permutatsiya usuli)")
plt.tight_layout()
plt.show()
Qaysi belgilar bashoratga ta'sir qiladi? oldingi_baho 0.068 davomat 0.054 topshiriq_foizi 0.039 oqish_soati 0.031 ishlaydi 0.016 kutubxona 0.010 O'qituvchi bu grafikni tushunadi va unga ishonadi
Tushuntirish - loyihaning asosiy talablaridan biri edi

Bitta talaba uchun tushuntirish #

Python
def talabani_tushuntir(model, talaba, chegara=CHEGARA):
    ehtimol = model.predict_proba(talaba)[0, 1]
    holat = "XAVF OSTIDA" if ehtimol < chegara else "Xavf yo'q"

    sabablar = []
    q = talaba.iloc[0]

    if q["davomat"] < 70:
        sabablar.append(f"davomat past ({q['davomat']:.0f}%)")
    if q["topshiriqlar"] < 8:
        sabablar.append(f"topshiriqlar kam ({int(q['topshiriqlar'])}/12)")
    if q["oldingi_baho"] < 3.2:
        sabablar.append(f"oldingi baho past ({q['oldingi_baho']:.1f})")
    if q["oqish_soati"] < 4:
        sabablar.append(f"kam o'qiydi ({q['oqish_soati']:.1f} soat/hafta)")
    if q["ishlaydi"] == 1:
        sabablar.append("ishlaydi")

    return {
        "holat": holat,
        "otish_ehtimoli": round(float(ehtimol), 3),
        "sabablar": sabablar or ["aniq xavf omili topilmadi"],
    }


namuna = X_sinov.iloc[[3]]
natija = talabani_tushuntir(eng_yaxshi, namuna)

print(f"Holat:     {natija['holat']}")
print(f"Ehtimol:   {natija['otish_ehtimoli']}")
print(f"Sabablari: {', '.join(natija['sabablar'])}")
Natija
Holat:     XAVF OSTIDA
Ehtimol:   0.284
Sabablari: davomat past (61%), topshiriqlar kam (6/12), ishlaydi
Bu o'qituvchi uchun ishlatiladigan shakl

Model 0.284 degan raqam beradi. O'qituvchiga esa nima qilish kerakligi kerak.

Bunday tushuntirish modelni haqiqiy vositaga aylantiradi.

Bosqich 11 - saqlash #

Python
import joblib, json, sklearn
from datetime import datetime
from pathlib import Path

Path("modellar").mkdir(exist_ok=True)

joblib.dump(eng_yaxshi, "modellar/talaba_xavfi_v1.joblib", compress=3)

metama = {
    "nom": "talaba_xavfi",
    "versiya": "1.0.0",
    "yaratilgan": datetime.now().isoformat(),
    "sklearn": sklearn.__version__,
    "model_turi": "HistGradientBoostingClassifier",
    "chegara": CHEGARA,
    "belgilar": list(X.columns),
    "asosiy_metrika": "recall",
    "natijalar": {
        "cv_recall": round(float(qidiruv.best_score_), 4),
        "sinov_recall": round(float(recall_score(y_sinov, bashorat_sinov)), 4),
        "sinov_auc": round(float(roc_auc_score(y_sinov, ehtimollik_sinov)), 4),
    },
    "giperparametrlar": {
        k.replace("model__", ""): (float(v) if isinstance(v, float) else v)
        for k, v in qidiruv.best_params_.items()
    },
    "oqitish_namunalari": len(X_toliq),
    "cheklovlar": [
        "Model faqat 17-25 yoshli talabalar uchun tekshirilgan",
        "Sun'iy ma'lumotda o'qitilgan - haqiqiy ma'lumotda qayta sinash kerak",
        "Har semestr oxirida qayta o'qitilishi tavsiya etiladi",
    ],
}

with open("modellar/talaba_xavfi_v1.json", "w", encoding="utf-8") as fayl:
    json.dump(metama, fayl, ensure_ascii=False, indent=2)

print("Model saqlandi.")

Bosqich 12 - testlar #

Python
# testlar/test_model.py
import pytest
import joblib
import pandas as pd


@pytest.fixture(scope="module")
def model():
    return joblib.load("modellar/talaba_xavfi_v1.joblib")


@pytest.fixture
def yaxshi_talaba():
    return pd.DataFrame([{
        "yosh": 20, "oqish_soati": 15, "davomat": 95, "oldingi_baho": 4.5,
        "uyqu_soati": 8, "topshiriqlar": 12, "kutubxona": 8,
        "ishlaydi": 0, "internet": 1,
        "yonalish": "Dasturlash", "turar_joy": "Yotoqxona",
        "topshiriq_foizi": 100, "kunlik_oqish": 15 / 7,
        "faol_talaba": 1, "kam_uyqu": 0,
    }])


def test_model_yuklanadi(model):
    assert hasattr(model, "predict_proba")


def test_yaxshi_talaba_otadi(model, yaxshi_talaba):
    ehtimol = model.predict_proba(yaxshi_talaba)[0, 1]
    assert ehtimol > 0.7


def test_yomon_talaba_xavf_ostida(model, yaxshi_talaba):
    yomon = yaxshi_talaba.copy()
    yomon.loc[0, ["oqish_soati", "davomat", "oldingi_baho",
                  "topshiriqlar", "topshiriq_foizi", "faol_talaba"]] = [
        1, 45, 2.3, 3, 25, 0
    ]
    ehtimol = model.predict_proba(yomon)[0, 1]
    assert ehtimol < 0.5


def test_davomat_ijobiy_tasir(model, yaxshi_talaba):
    past = yaxshi_talaba.copy()
    past.loc[0, "davomat"] = 50

    assert (model.predict_proba(yaxshi_talaba)[0, 1]
            > model.predict_proba(past)[0, 1])


def test_bosh_qiymat_bilan_ishlaydi(model, yaxshi_talaba):
    import numpy as np
    bosh = yaxshi_talaba.copy()
    bosh.loc[0, "uyqu_soati"] = np.nan

    natija = model.predict_proba(bosh)
    assert 0 <= natija[0, 1] <= 1
Terminal
pytest testlar/ -v
Natija
test_model.py::test_model_yuklanadi PASSED
test_model.py::test_yaxshi_talaba_otadi PASSED
test_model.py::test_yomon_talaba_xavf_ostida PASSED
test_model.py::test_davomat_ijobiy_tasir PASSED
test_model.py::test_bosh_qiymat_bilan_ishlaydi PASSED

5 passed in 1.24s

Loyiha xulosasi #

BosqichNima qilindi
Ma'lumot tahliliinfo, describe, korrelyatsiya, grafiklar
Muammolarni topish999 qiymatlar, bo'sh qiymatlar aniqlandi
TozalashXato qiymat NaN ga, chetdagilar qoldirildi
Yangi belgilartopshiriq_foizi, faol_talaba, kam_uyqu
Bo'lishStratifikatsiya bilan 80/20
QuvurColumnTransformer bilan uch xil tayyorlash
Modellar5 ta model kross-validatsiya bilan solishtirildi
SozlashRandomizedSearchCV, 60 urinish
ChegaraBiznes talabidan kelib chiqib 0.4 tanlandi
BaholashSinov to'plami bir marta ishlatildi
TushuntirishPermutatsiya muhimligi va matnli izoh
SaqlashModel + metama + cheklovlar
Testlar5 ta mantiqiy test
Model cheklovlari - hujjatlashtiring

Har bir modelning chegaralari bor:

  • Sun'iy ma'lumotda o'qitilgan
  • Faqat ma'lum yosh oralig'i uchun
  • Ijtimoiy-iqtisodiy omillarni hisobga olmaydi
  • Yangi o'quv dasturida qayta sinash kerak

Bu cheklovlarni yozib qo'yish - professional yondashuvning ajralmas qismi.

Etik masalalar

Talabalarni "xavf ostida" deb belgilash jiddiy oqibatlarga olib kelishi mumkin:

XavfOldini olish
Yorliq qo'yishNatija faqat o'qituvchiga, talabaga emas
O'z-o'zini oqlovchi bashoratModel yordam uchun, saralash uchun emas
AdolatsizlikGuruhlar bo'yicha alohida tekshiring
Avtomatik qarorYakuniy qaror insonda qolsin
Python
# Adolatlilikni tekshirish
for guruh in talabalar["turar_joy"].unique():
    niqob = X_sinov["turar_joy"] == guruh
    if niqob.sum() > 20:
        r = recall_score(y_sinov[niqob], bashorat_sinov[niqob])
        print(f"{guruh:12s}: recall = {r:.3f}  (n={niqob.sum()})")

Agar bir guruhda recall sezilarli past bo'lsa - model o'sha guruhga nisbatan adolatsiz ishlayapti.

Yakuniy topshiriq

Butun loyihani o'z ma'lumotingizda takrorlang:

  1. Kaggle dan o'zingizga qiziq ma'lumotlar to'plamini tanlang.
  2. Muammoni aniq shakllantiring va asosiy metrikani oldindan tanlang.
  3. To'liq razvedka tahlilini o'tkazing: info, describe, grafiklar.
  4. Kamida uchta muammoni toping va hal qiling.
  5. Kamida ikkita yangi belgi yarating.
  6. ColumnTransformer bilan quvur quring.
  7. Beshta modelni kross-validatsiya bilan solishtiring.
  8. Eng yaxshisini RandomizedSearchCV bilan sozlang.
  9. Chegarani biznes talabidan kelib chiqib tanlang.
  10. Sinov to'plamida bir marta baholang.
  11. Belgilar muhimligini chizing va natijani izohlang.
  12. Modelni metama bilan saqlang va 5 ta test yozing.
  13. Flask API yarating va sinab ko'ring.
  14. README.md yozing: muammo, yechim, natija, cheklovlar.

Yakuniy xulosa #

Yigirma bo'lim davomida siz quyidagilarni o'rgandingiz:

  • Mashinali o'qitish nima va qachon kerak
  • NumPy va Pandas bilan ma'lumot qayta ishlash
  • Matplotlib va Seaborn bilan vizuallashtirish
  • Ma'lumotni tozalash, kodlash va masshtablash
  • Chiziqli va logistik regressiya
  • Polinomial belgilar va regularizatsiya (Ridge, Lasso)
  • Modelni to'g'ri baholash: precision, recall, F1, AUC
  • KNN, qaror daraxti, Random Forest, boosting
  • SVM va Naive Bayes
  • Klasterlash (K-means, DBSCAN) va PCA
  • Kross-validatsiya va ma'lumot sizib chiqishi
  • Giperparametrlarni sozlash va Pipeline
  • Neyron tarmoqlar asoslari
  • Modelni ishlab chiqarishga chiqarish va monitoring
Keyingi qadamlar
  1. Amaliyot - Kaggle da 3-5 ta loyiha bajaring
  2. Chuqurlashtiring - PyTorch yoki TensorFlow o'rganing
  3. Ixtisoslashing - kompyuter ko'rish, NLP yoki vaqt qatorlari
  4. Portfolio - GitHub da loyihalaringizni joylang
  5. Jamoa - ochiq loyihalarga hissa qo'shing

Eng muhimi: haqiqiy muammolarni yeching. Darslikdagi toza ma'lumot bilan ishlash oson; haqiqiy loyihaning qiyinligi va qiziqarliligi ham shundaki, u tayyor javob bermaydi.

Foydali manbalar
ManbaNima uchun
scikit-learn.orgRasmiy hujjat, eng ishonchli
kaggle.comMa'lumotlar, musobaqalar, daftarlar
paperswithcode.comZamonaviy usullar va kod
distill.pubMurakkab g'oyalarning vizual izohi

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.