13-bo‘lim

SVM va Naive Bayes

Qo'llab-quvvatlovchi vektorlar usuli, yadro hiylasi va ehtimolliklarga asoslangan Naive Bayes klassifikatori.

🕑 14 daqiqa o‘qish 📄 1 043 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. SVM g'oyasi
  2. Birinchi SVM
  3. Yadro hiylasi
  4. C va gamma parametrlari
  5. SVM ehtimollik uchun
  6. SVM regressiya uchun
  7. Afzallik va kamchiliklar
  8. Naive Bayes
  9. Matn klassifikatsiyasi
  10. Naive Bayes afzalliklari
  11. Modellarni solishtirish
  12. Qaysi modelni tanlash?
  13. Xulosa

Bu bo'limda ikki mashhur algoritmni ko'rib chiqamiz: biri geometriyaga, ikkinchisi ehtimollik nazariyasiga asoslangan.

SVM g'oyasi #

Ko'p chiziq sinflarni ajratishi mumkin. SVM ulardan eng kengini tanlaydi.

SVM eng keng yo'lakni topadi Boshqa modellar Ko'p chiziq to'g'ri ajratadi Qaysi biri yaxshiroq - noma'lum SVM Eng keng yo'lak (margin) Qalin doiralar - qo'llab-quvvatlovchi vektorlar
Keng yo'lak yangi ma'lumotda ishonchliroq natija beradi
Qo'llab-quvvatlovchi vektorlar

Chegara faqat bir necha nuqtaga bog'liq - ular yo'lak chetida turadi.

Boshqa barcha nuqtalarni o'chirsangiz ham chegara o'zgarmaydi. Shuning uchun usul "qo'llab-quvvatlovchi vektorlar usuli" deb ataladi.

Bu SVM ni chetdagi qiymatlarga nisbatan barqaror qiladi.

Birinchi SVM #

Python
from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline

malumot = load_breast_cancer()
X, y = malumot.data, malumot.target

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(), SVC(kernel="linear"))
model.fit(X_o, y_o)

print(f"Aniqlik: {model.score(X_s, y_s):.3f}")
print(f"Qo'llab-quvvatlovchi vektorlar: {model.named_steps['svc'].n_support_}")
Natija
Aniqlik: 0.971
Qo'llab-quvvatlovchi vektorlar: [15 12]

398 ta namunadan faqat 27 tasi chegarani belgilaydi.

Masshtablash majburiy

SVM masofalar bilan ishlaydi. Masshtablanmagan ma'lumotda natija sezilarli yomonlashadi va o'qitish juda sekinlashadi.

Yadro hiylasi #

Sinflar to'g'ri chiziq bilan ajralmasa nima qilamiz?

Yadro hiylasi: o'lchamni oshirib, chiziq bilan ajratish 1 o'lcham - ajratib bo'lmaydi Bitta chiziq bilan ajratib bo'lmaydi y = x² 2 o'lcham - oson ajratiladi Endi oddiy gorizontal chiziq yetarli
Yadro hiylasi bu almashtirishni haqiqatda bajarmasdan amalga oshiradi
Python
for yadro in ["linear", "poly", "rbf", "sigmoid"]:
    model = make_pipeline(StandardScaler(), SVC(kernel=yadro))
    model.fit(X_o, y_o)
    print(f"{yadro:8s}: {model.score(X_s, y_s):.3f}")
Natija
linear  : 0.971
poly    : 0.912
rbf     : 0.977
sigmoid : 0.947
YadroQachon
linearBelgilar ko'p, ma'lumot chiziqli ajraladi
rbfStandart tanlov - deyarli har doim ishlaydi
polyPolinomial bog'liqlik bo'lsa
sigmoidKamdan-kam ishlatiladi
Yadro hiylasi nima uchun "hiyla"?

Ma'lumotni haqiqatan yuqori o'lchamga ko'chirish juda qimmat bo'lardi.

Yadro funksiyasi esa faqat nuqtalar orasidagi skalyar ko'paytmani yuqori o'lchamda hisoblaydi - ma'lumotni ko'chirmasdan.

RBF yadrosi cheksiz o'lchamli fazoga mos keladi, lekin hisoblash oddiy formula bilan bajariladi.

C va gamma parametrlari #

Python
import numpy as np

print("     C   gamma   sinov")
for c in [0.1, 1, 10, 100]:
    for gamma in ["scale", 0.001, 0.01, 0.1]:
        model = make_pipeline(StandardScaler(), SVC(C=c, gamma=gamma))
        model.fit(X_o, y_o)
        print(f"{c:6.1f}  {str(gamma):>6}  {model.score(X_s, y_s):.3f}")
Ikki asosiy parametr C - xatolarga munosabat Kichik C (0.1) Keng yo'lak, ba'zi xatolarga ruxsat Soddaroq model Qayta o'qitish xavfi kam Katta C (100) Tor yo'lak, har bir xatoni jazolaydi Murakkabroq chegara Qayta o'qitish xavfi yuqori gamma - ta'sir radiusi Kichik gamma (0.001) Har bir nuqta uzoqqa ta'sir qiladi Silliq chegara Yetarli o'qimaslik xavfi Katta gamma (10) Ta'sir faqat yaqin atrofda Juda tarmoqlangan chegara Qayta o'qitish xavfi yuqori Ikkalasini birga GridSearchCV bilan tanlang
C va gamma - SVM ning eng muhim giperparametrlari
Python
from sklearn.model_selection import GridSearchCV

tor = {
    "svc__C": [0.1, 1, 10, 100],
    "svc__gamma": ["scale", 0.001, 0.01, 0.1, 1],
}

qidiruv = GridSearchCV(
    make_pipeline(StandardScaler(), SVC()),
    tor, cv=5, n_jobs=-1,
)
qidiruv.fit(X_o, y_o)

print(f"Eng yaxshi: {qidiruv.best_params_}")
print(f"CV natija:  {qidiruv.best_score_:.3f}")
print(f"Sinov:      {qidiruv.score(X_s, y_s):.3f}")
Natija
Eng yaxshi: {'svc__C': 10, 'svc__gamma': 'scale'}
CV natija:  0.977
Sinov:      0.982

SVM ehtimollik uchun #

Python
model = make_pipeline(StandardScaler(), SVC(probability=True))
model.fit(X_o, y_o)

print(model.predict_proba(X_s[:3]).round(3))
probability=True sekin

Bu parametr ichki kross-validatsiya ishlatadi va o'qitishni 5-10 barobar sekinlashtiradi.

Faqat ehtimollik haqiqatan kerak bo'lsa yoqing. Aks holda decision_function yetarli:

Python
ball = model.decision_function(X_s)   # chegaraga masofa

SVM regressiya uchun #

Python
from sklearn.svm import SVR

model = make_pipeline(StandardScaler(), SVR(kernel="rbf", C=100, epsilon=0.1))
model.fit(X_o, y_o)

epsilon - "ruxsat etilgan xato zonasi": bu oraliqdagi xatolar jazolanmaydi.

Afzallik va kamchiliklar #

AfzalligiKamchiligi
Ko'p o'lchamda yaxshi ishlaydiKatta ma'lumotda juda sekin
Yadro bilan murakkab chegaralarParametrlarni sozlash qiyin
Chetdagi qiymatlarga barqarorEhtimollik tabiiy emas
Nazariy asosi kuchliNatijani tushuntirish qiyin (RBF da)
Xotira tejamkorMasshtablash majburiy
SVM va katta ma'lumot

O'qitish murakkabligi taxminan O(n²) dan O(n³) gacha.

NamunalarTaxminiy vaqt
1 000Bir necha soniya
10 000Bir necha daqiqa
100 000Bir necha soat
1 000 000Amalda imkonsiz

Katta ma'lumot uchun LinearSVC yoki SGDClassifier ishlating:

Python
from sklearn.svm import LinearSVC
model = make_pipeline(StandardScaler(), LinearSVC(dual="auto"))

Naive Bayes #

Butunlay boshqa yondashuv: ehtimollik hisoblash.

Bayes teoremasi P(sinf | belgilar) ∝ P(belgilar | sinf) · P(sinf) P(sinf) Oldindan ehtimollik Xatlarning 30% spam P(belgilar | sinf) Ishonchlilik Spamda "bepul" so'zi 40% P(sinf | belgilar) Keyingi ehtimollik Bu xat spam bo'lish ehtimoli
"Sodda" (naive) deyilishining sababi - belgilar mustaqil deb faraz qilinadi
Nima uchun "sodda"?

Algoritm barcha belgilar bir-biridan mustaqil deb faraz qiladi.

Bu deyarli har doim noto'g'ri: "arzon" va "chegirma" so'zlari xatda birga uchraydi.

Lekin amalda bu faraz buzilsa ham, model ajablanarli darajada yaxshi ishlaydi.

Python
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB

model = GaussianNB()
model.fit(X_o, y_o)
print(f"Aniqlik: {model.score(X_s, y_s):.3f}")
Natija
Aniqlik: 0.930
VariantMa'lumot turi
GaussianNBUzluksiz sonlar (normal taqsimot)
MultinomialNBSanoqlar - matn klassifikatsiyasi
BernoulliNBIkkilik belgilar (bor/yo'q)
CategoricalNBToifali belgilar

Matn klassifikatsiyasi #

Naive Bayes ning eng mashhur qo'llanilishi:

Python
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline

xatlar = [
    "Bepul chegirma! Hoziroq bosing va sovg'a yutib oling",
    "Ertangi yig'ilish soat 10 da bo'ladi",
    "Siz million so'm yutdingiz! Havolaga o'ting",
    "Hisobot fayli biriktirildi, ko'rib chiqing",
    "Aksiya! Faqat bugun 90 foiz chegirma",
    "Loyiha bo'yicha savollaringiz bormi?",
    "Kredit kartangiz bloklandi, ma'lumot kiriting",
    "Rahmat, hujjatlarni oldim",
]
belgilar = [1, 0, 1, 0, 1, 0, 1, 0]     # 1 - spam

model = make_pipeline(TfidfVectorizer(), MultinomialNB())
model.fit(xatlar, belgilar)

yangi = [
    "Bepul sovg'a yutib oling hoziroq",
    "Yig'ilish vaqti o'zgardi",
]

for matn, bashorat, ehtimol in zip(
    yangi, model.predict(yangi), model.predict_proba(yangi)[:, 1]
):
    natija = "SPAM" if bashorat else "oddiy"
    print(f"{natija:6s} ({ehtimol:.0%})  {matn}")
Natija
SPAM   (78%)  Bepul sovg'a yutib oling hoziroq
oddiy  (32%)  Yig'ilish vaqti o'zgardi
TF-IDF nima?

TF (Term Frequency) - so'z shu hujjatda necha marta uchraydi.

IDF (Inverse Document Frequency) - so'z barcha hujjatlarda qanchalik kam uchraydi.

Natijada "va", "bu", "uchun" kabi keng tarqalgan so'zlar past vazn, "chegirma", "aksiya" kabi xos so'zlar yuqori vazn oladi.

Naive Bayes afzalliklari #

AfzalligiKamchiligi
Juda tez o'qiydi va ishlaydiMustaqillik farazi noto'g'ri
Kam ma'lumotda ham ishlaydiEhtimolliklar aniq emas
Ko'p o'lchamda muammosizSonli belgilarda kuchsizroq
Ma'lumotni bo'lib o'qitish mumkinBelgilar orasidagi ta'sirni ko'rmaydi
Masshtablash kerak emas
Naive Bayes - matn uchun asos model

Yangi matn klassifikatsiyasi loyihasini boshlaganda undan boshlang:

  • Bir necha soniyada o'qiydi
  • Ko'pincha 85-90% aniqlik beradi
  • Murakkab modellar bilan solishtirish uchun ajoyib asos

Modellarni solishtirish #

Python
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
import time

modellar = {
    "Logistik":      make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000)),
    "KNN":           make_pipeline(StandardScaler(), KNeighborsClassifier()),
    "Qaror daraxti": DecisionTreeClassifier(max_depth=5, random_state=42),
    "Random Forest": RandomForestClassifier(n_estimators=100, random_state=42),
    "SVM (RBF)":     make_pipeline(StandardScaler(), SVC()),
    "Naive Bayes":   GaussianNB(),
}

print(f"{'Model':16s} {'CV aniqlik':>12} {'Vaqt (s)':>10}")

for nom, model in modellar.items():
    boshlandi = time.perf_counter()
    ballar = cross_val_score(model, X_o, y_o, cv=5)
    vaqt = time.perf_counter() - boshlandi

    print(f"{nom:16s} {ballar.mean():>10.3f}   {vaqt:>8.2f}")
Natija
Model             CV aniqlik   Vaqt (s)
Logistik              0.977       0.09
KNN                   0.965       0.04
Qaror daraxti         0.925       0.02
Random Forest         0.960       0.62
SVM (RBF)             0.975       0.06
Naive Bayes           0.935       0.01
Har doim bir nechta modelni sinang

Ushbu ma'lumotda eng oddiy model (logistik regressiya) eng yaxshi natija berdi va eng tez ishladi.

"Murakkab model = yaxshi natija" degan qoida yo'q. Har doim solishtiring.

Qaysi modelni tanlash? #

VaziyatTavsiya
Boshlash uchunLogistik regressiya
Jadval ma'lumotiRandom Forest, Gradient Boosting
MatnNaive Bayes, LinearSVC
Kichik ma'lumot, ko'p belgiSVM
Tushuntirish muhimQaror daraxti, logistik regressiya
Katta ma'lumotSGDClassifier, LightGBM
Rasm, ovozNeyron tarmoq
Amaliy topshiriq
  1. load_breast_cancer ma'lumotida SVM ni o'qiting.
  2. To'rtta yadroni solishtiring.
  3. C va gamma ni GridSearchCV bilan sozlang.
  4. Qo'llab-quvvatlovchi vektorlar sonini chiqaring.
  5. Masshtablashsiz o'qitib, farqni o'lchang.
  6. GaussianNB bilan solishtiring.
  7. 20 ta spam va 20 ta oddiy xat yozing.
  8. TfidfVectorizer va MultinomialNB bilan spam filtri quring.
  9. Yangi xatlarni sinab ko'ring.
  10. Oltita modelni cross_val_score bilan solishtirib jadval tuzing.

Xulosa #

  • SVM sinflar orasidagi eng keng yo'lakni topadi.
  • Chegara faqat qo'llab-quvvatlovchi vektorlarga bog'liq.
  • Yadro hiylasi o'lchamni oshirmasdan murakkab chegara qurish imkonini beradi.
  • RBF - standart va eng ko'p ishlatiladigan yadro.
  • C xatolarga munosabatni, gamma ta'sir radiusini belgilaydi.
  • SVM katta ma'lumotda juda sekin - LinearSVC ni ishlating.
  • Naive Bayes belgilar mustaqil deb faraz qiladi - bu noto'g'ri, lekin amalda yaxshi ishlaydi.
  • MultinomialNB + TfidfVectorizer - matn klassifikatsiyasi uchun ideal.
  • Naive Bayes juda tez - matn loyihalari uchun ajoyib asos model.
  • Har doim bir nechta modelni solishtiring; murakkab har doim yaxshiroq emas.

Keyingi bo'limda nazoratsiz o'qitishga o'tamiz.

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.