9-bo‘lim

Logistik regressiya va klassifikatsiya

Toifani bashorat qilish, sigmoid funksiya, ehtimollik, qaror chegarasi va ko'p sinfli klassifikatsiya.

🕑 15 daqiqa o‘qish 📄 749 so‘z 👁 7 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Nima uchun chiziqli regressiya ishlamaydi?
  2. Sigmoid funksiya
  3. Birinchi klassifikator
  4. Real ma'lumot bilan
  5. Koeffitsiyentlarni talqin qilish
  6. Qaror chegarasi
  7. Ko'p sinfli klassifikatsiya
  8. Regularizatsiya
  9. Chegaraviy chiziq
  10. Nomutanosib sinflar
  11. Qachon ishlatish kerak?
  12. Xulosa

Endi sonni emas, toifani bashorat qilamiz: spam yoki spam emas, kasal yoki sog'lom, mijoz ketadimi yoki qoladimi.

Nima uchun chiziqli regressiya ishlamaydi? #

Python
import numpy as np
from sklearn.linear_model import LinearRegression

# 0 - imtihondan yiqildi, 1 - o'tdi
soatlar = np.array([1, 2, 3, 4, 5, 6, 7, 8, 20]).reshape(-1, 1)
otdi    = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1])

model = LinearRegression().fit(soatlar, otdi)
print(model.predict([[10]]))
print(model.predict([[0]]))
Natija
[1.08]
[-0.09]
Muammo

Chiziqli regressiya 1.08 va -0.09 chiqardi. Lekin ehtimollik faqat 0 va 1 orasida bo'lishi mumkin.

Bundan tashqari, 20 soat o'qigan bitta talaba butun chiziqni buzib yubordi.

Sigmoid funksiya #

Yechim - chiziqli natijani [0, 1] oralig'iga siqish.

Sigmoid: istalgan sonni [0, 1] ga aylantiradi 1.0 0.5 0.0 qaror chegarasi 0.5 manfiy kirish → 0 ga yaqin musbat kirish → 1 ga yaqin 1 / (1 + e^-z) z = w·x + b
Sigmoid natijani ehtimollikka aylantiradi
Python
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

for z in [-5, -2, 0, 2, 5]:
    print(f"sigmoid({z:3d}) = {sigmoid(z):.4f}")
Natija
sigmoid( -5) = 0.0067
sigmoid( -2) = 0.1192
sigmoid(  0) = 0.5000
sigmoid(  2) = 0.8808
sigmoid(  5) = 0.9933

Birinchi klassifikator #

Python
from sklearn.linear_model import LogisticRegression

model = LogisticRegression()
model.fit(soatlar, otdi)

print("Bashorat:", model.predict([[3], [6], [10]]))
print("Ehtimollik:")
print(model.predict_proba([[3], [6], [10]]).round(3))
Natija
Bashorat: [0 1 1]
Ehtimollik:
[[0.874 0.126]
 [0.192 0.808]
 [0.011 0.989]]
predict_proba juda muhim

predict faqat 0 yoki 1 beradi. predict_proba esa ishonch darajasini ko'rsatadi:

SoatO'tmaslikO'tish
387.4%12.6%
619.2%80.8%
101.1%98.9%

Amaliyotda ehtimollik ko'pincha muhimroq: "bu bemorda kasallik 60% ehtimol bilan bor" degan javob "bor" degandan foydaliroq.

Real ma'lumot bilan #

Python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import accuracy_score, classification_report

np.random.seed(42)
n = 500

talabalar = pd.DataFrame({
    "oqish_soati":   np.random.uniform(0, 20, n),
    "davomat":       np.random.uniform(40, 100, n),
    "oldingi_baho":  np.random.uniform(2, 5, n),
    "uyqu_soati":    np.random.uniform(4, 10, n),
})

# Yashirin qoida
ball = (
    talabalar["oqish_soati"] * 0.35
    + talabalar["davomat"] * 0.06
    + talabalar["oldingi_baho"] * 1.2
    + np.random.normal(0, 1.5, n)
)
talabalar["otdi"] = (ball > ball.median()).astype(int)

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

X_o, X_s, y_o, y_s = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

model = make_pipeline(StandardScaler(), LogisticRegression())
model.fit(X_o, y_o)

bashorat = model.predict(X_s)
print(f"Aniqlik: {accuracy_score(y_s, bashorat):.3f}")
Natija
Aniqlik: 0.890

Koeffitsiyentlarni talqin qilish #

Python
vaznlar = model.named_steps["logisticregression"].coef_[0]

for belgi, vazn in sorted(zip(X.columns, vaznlar), key=lambda p: -abs(p[1])):
    yonalish = "oshiradi" if vazn > 0 else "kamaytiradi"
    print(f"{belgi:15s} {vazn:6.2f}  o'tish ehtimolini {yonalish}")
Natija
oqish_soati       2.14  o'tish ehtimolini oshiradi
oldingi_baho      0.92  o'tish ehtimolini oshiradi
davomat           0.71  o'tish ehtimolini oshiradi
uyqu_soati       -0.04  o'tish ehtimolini kamaytiradi
Koeffitsiyent ma'nosi

Logistik regressiyada koeffitsiyent log-odds ga ta'sirni ko'rsatadi.

Amaliy talqin uchun eksponentaga ko'taring:

Python
print(np.exp(2.14))   # 8.5

"O'qish soati bir standart og'ishga oshsa, o'tish shansi 8.5 barobar oshadi."

Qaror chegarasi #

Python
ehtimollik = model.predict_proba(X_s)[:, 1]

# Standart chegara 0.5
bashorat_05 = (ehtimollik >= 0.5).astype(int)

# Qattiqroq chegara
bashorat_07 = (ehtimollik >= 0.7).astype(int)

print(f"0.5 chegara: {bashorat_05.sum()} ta 'o'tdi'")
print(f"0.7 chegara: {bashorat_07.sum()} ta 'o'tdi'")
Natija
0.5 chegara: 52 ta 'o'tdi'
0.7 chegara: 38 ta 'o'tdi'
Chegara vazifaga qarab tanlanadi Past chegara (0.2) Ko'proq "ha" javobi beriladi Kam kasallik o'tkazib yuboriladi Ko'p noto'g'ri xavotir Yuqori chegara (0.8) Kamroq "ha" javobi beriladi Faqat ishonchli holatlar Ba'zi holatlar o'tkazib yuboriladi Misollar Saraton skrininigi → past chegara: kasallikni o'tkazib yuborish qimmatroq Spam filtri → yuqori chegara: muhim xatni spamga yuborish qimmatroq Kredit berish → biznes qarori: yo'qotish va foyda muvozanati
0.5 - standart, lekin har doim to'g'ri emas
Chegarani tanlash - biznes qarori

Model chegarani bilmaydi. Uni siz xatoning narxiga qarab tanlaysiz:

"Kasallikni o'tkazib yuborish" 100 barobar qimmatroq bo'lsa - chegarani pasaytiring, ko'proq "shubhali" deb belgilang.

Keyingi bo'limda buni o'lchash usullarini ko'ramiz.

Ko'p sinfli klassifikatsiya #

Python
from sklearn.datasets import load_iris

iris = load_iris()
X, y = iris.data, iris.target

print("Sinflar:", iris.target_names)
Natija
Sinflar: ['setosa' 'versicolor' 'virginica']
Python
X_o, X_s, y_o, y_s = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
model.fit(X_o, y_o)

print(f"Aniqlik: {model.score(X_s, y_s):.3f}")
print("Ehtimolliklar:")
print(model.predict_proba(X_s[:3]).round(3))
Natija
Aniqlik: 0.911
Ehtimolliklar:
[[0.    0.024 0.976]
 [0.978 0.022 0.   ]
 [0.    0.918 0.082]
]

Har bir qatordagi ehtimolliklar yig'indisi 1 ga teng.

Ikki strategiya
StrategiyaQanday ishlaydi
One-vs-RestHar bir sinf uchun alohida ikkilik model
MultinomialBarcha sinflar uchun bitta model (softmax)

scikit-learn 1.5 dan boshlab multinomial standart bo'lgan - u odatda aniqroq natija beradi.

Regularizatsiya #

Python
# C - regularizatsiya kuchining TESKARISI
for c in [0.01, 0.1, 1, 100]:
    model = make_pipeline(StandardScaler(), LogisticRegression(C=c, max_iter=1000))
    model.fit(X_o, y_o)
    print(f"C={c:6.2f}  o'qitish={model.score(X_o, y_o):.3f}  "
          f"sinov={model.score(X_s, y_s):.3f}")
Natija
C=  0.01  o'qitish=0.867  sinov=0.867
C=  0.10  o'qitish=0.914  sinov=0.911
C=  1.00  o'qitish=0.962  sinov=0.911
C=100.00  o'qitish=0.981  sinov=0.889
C teskari ishlaydi

Ridge da alpha katta = kuchli regularizatsiya.

LogisticRegression da C kichik = kuchli regularizatsiya.

Bu chalkashlik manbai - eslab qoling: C = 1 / alpha.

Chegaraviy chiziq #

Python
import matplotlib.pyplot as plt

X_ikki = X[:, :2]     # faqat ikkita belgi
model = make_pipeline(StandardScaler(), LogisticRegression())
model.fit(X_ikki, y)

x_min, x_max = X_ikki[:, 0].min() - 0.5, X_ikki[:, 0].max() + 0.5
y_min, y_max = X_ikki[:, 1].min() - 0.5, X_ikki[:, 1].max() + 0.5

tor_x, tor_y = np.meshgrid(
    np.linspace(x_min, x_max, 300),
    np.linspace(y_min, y_max, 300),
)

Z = model.predict(np.c_[tor_x.ravel(), tor_y.ravel()]).reshape(tor_x.shape)

plt.figure(figsize=(8, 6))
plt.contourf(tor_x, tor_y, Z, alpha=0.25, cmap="viridis")
plt.scatter(X_ikki[:, 0], X_ikki[:, 1], c=y, cmap="viridis", edgecolors="k")
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title("Logistik regressiya qaror chegaralari")
plt.show()
Chegara har doim to'g'ri chiziq

Logistik regressiya chiziqli chegara chizadi. Sinflar egri chiziq bilan ajralsa - u yaxshi ishlamaydi.

Bunday holatda:

  1. PolynomialFeatures qo'shing
  2. Yoki daraxt, SVM (RBF yadro) kabi modellarni ishlating

Nomutanosib sinflar #

Python
from collections import Counter

# 95% sog'lom, 5% kasal
y_nomutanosib = np.array([0] * 950 + [1] * 50)
print(Counter(y_nomutanosib))
Natija
Counter({0: 950, 1: 50})
Aniqlik bu yerda aldaydi

Har doim "sog'lom" deb javob beradigan model 95% aniqlik ko'rsatadi - lekin u bironta ham kasalni topa olmaydi.

Yechimlar:

Python
# 1. Sinf vaznlarini muvozanatlash
model = LogisticRegression(class_weight="balanced")

# 2. Aniqlik emas, boshqa metrikalar ishlatish
from sklearn.metrics import f1_score, recall_score

# 3. Kam sinfni ko'paytirish yoki ko'p sinfni kamaytirish (SMOTE)

Keyingi bo'lim to'liq shu mavzuga bag'ishlangan.

Python
model_oddiy = LogisticRegression()
model_muvozanat = LogisticRegression(class_weight="balanced")

Qachon ishlatish kerak? #

AfzalligiKamchiligi
Tez o'qiydi va tez ishlaydiFaqat chiziqli chegara
Natija tushuntiriladiMurakkab naqshni topa olmaydi
Ehtimollik beradiBelgilar masshtablanishi kerak
Kam ma'lumotda ham ishlaydiChetdagi qiymatlarga sezgir
Regularizatsiya qo'llab-quvvatlanadi
Har doim shundan boshlang

Logistik regressiya - klassifikatsiya uchun asos model (baseline).

Uni birinchi bo'lib sinang. Agar u 88% bersa va murakkab neyron tarmoq 89% bersa - oddiy modelni tanlang: u tezroq, tushunarliroq va qo'llab-quvvatlash osonroq.

Amaliy topshiriq
  1. sigmoid funksiyasini yozing va -10 dan 10 gacha chizing.
  2. Talabalar ma'lumotini yarating va logistik regressiya bilan o'qiting.
  3. predict va predict_proba natijalarini solishtiring.
  4. Koeffitsiyentlarni chiqaring va eng muhim belgini toping.
  5. Chegarani 0.3, 0.5, 0.7 qilib, "ha" javoblari sonini sanang.
  6. Iris ma'lumotida uch sinfli model quring.
  7. C ni 0.001 dan 1000 gacha o'zgartirib, natijani jadvalga chiqaring.
  8. Ikki belgi bilan qaror chegarasini chizing.
  9. PolynomialFeatures(2) qo'shing - chegara egri bo'ldimi?
  10. Nomutanosib ma'lumot yarating va class_weight="balanced" ta'sirini o'lchang.

Xulosa #

  • Logistik regressiya toifani bashorat qiladi, nomiga qaramay.
  • Sigmoid funksiya istalgan sonni [0, 1] oralig'iga siqadi.
  • predict_proba ehtimollik beradi - ko'pincha predict dan foydaliroq.
  • Qaror chegarasi standart holatda 0.5, lekin uni o'zgartirish mumkin.
  • Chegara biznes qarori: xatoning narxiga qarab tanlanadi.
  • Koeffitsiyentlar log-odds ga ta'sirni ko'rsatadi; exp() bilan talqin qilinadi.
  • C regularizatsiya kuchining teskarisi: kichik C = kuchli cheklov.
  • Chegara har doim chiziqli - egri chegara uchun boshqa model kerak.
  • Nomutanosib sinflarda aniqlik aldaydi - class_weight="balanced" ishlating.
  • Bu model klassifikatsiya uchun eng yaxshi asos model.

Keyingi bo'limda modellarni to'g'ri baholashni o'rganamiz.

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.