13-bo‘lim
SVM va Naive Bayes
Qo'llab-quvvatlovchi vektorlar usuli, yadro hiylasi va ehtimolliklarga asoslangan Naive Bayes klassifikatori.
Ushbu bo‘lim mundarijasi
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.
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 #
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_}")
Aniqlik: 0.971
Qo'llab-quvvatlovchi vektorlar: [15 12]
398 ta namunadan faqat 27 tasi chegarani belgilaydi.
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?
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}")
linear : 0.971
poly : 0.912
rbf : 0.977
sigmoid : 0.947
| Yadro | Qachon |
|---|---|
linear | Belgilar ko'p, ma'lumot chiziqli ajraladi |
rbf | Standart tanlov - deyarli har doim ishlaydi |
poly | Polinomial bog'liqlik bo'lsa |
sigmoid | Kamdan-kam ishlatiladi |
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 #
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}")
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}")
Eng yaxshi: {'svc__C': 10, 'svc__gamma': 'scale'}
CV natija: 0.977
Sinov: 0.982
SVM ehtimollik uchun #
model = make_pipeline(StandardScaler(), SVC(probability=True))
model.fit(X_o, y_o)
print(model.predict_proba(X_s[:3]).round(3))
probability=True sekinBu parametr ichki kross-validatsiya ishlatadi va o'qitishni 5-10 barobar sekinlashtiradi.
Faqat ehtimollik haqiqatan kerak bo'lsa yoqing. Aks holda
decision_function yetarli:
ball = model.decision_function(X_s) # chegaraga masofa
SVM regressiya uchun #
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 #
| Afzalligi | Kamchiligi |
|---|---|
| Ko'p o'lchamda yaxshi ishlaydi | Katta ma'lumotda juda sekin |
| Yadro bilan murakkab chegaralar | Parametrlarni sozlash qiyin |
| Chetdagi qiymatlarga barqaror | Ehtimollik tabiiy emas |
| Nazariy asosi kuchli | Natijani tushuntirish qiyin (RBF da) |
| Xotira tejamkor | Masshtablash majburiy |
O'qitish murakkabligi taxminan O(n²) dan O(n³) gacha.
| Namunalar | Taxminiy vaqt |
|---|---|
| 1 000 | Bir necha soniya |
| 10 000 | Bir necha daqiqa |
| 100 000 | Bir necha soat |
| 1 000 000 | Amalda imkonsiz |
Katta ma'lumot uchun LinearSVC yoki SGDClassifier ishlating:
from sklearn.svm import LinearSVC
model = make_pipeline(StandardScaler(), LinearSVC(dual="auto"))
Naive Bayes #
Butunlay boshqa yondashuv: ehtimollik hisoblash.
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.
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}")
Aniqlik: 0.930
| Variant | Ma'lumot turi |
|---|---|
GaussianNB | Uzluksiz sonlar (normal taqsimot) |
MultinomialNB | Sanoqlar - matn klassifikatsiyasi |
BernoulliNB | Ikkilik belgilar (bor/yo'q) |
CategoricalNB | Toifali belgilar |
Matn klassifikatsiyasi #
Naive Bayes ning eng mashhur qo'llanilishi:
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}")
SPAM (78%) Bepul sovg'a yutib oling hoziroq
oddiy (32%) Yig'ilish vaqti o'zgardi
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 #
| Afzalligi | Kamchiligi |
|---|---|
| Juda tez o'qiydi va ishlaydi | Mustaqillik farazi noto'g'ri |
| Kam ma'lumotda ham ishlaydi | Ehtimolliklar aniq emas |
| Ko'p o'lchamda muammosiz | Sonli belgilarda kuchsizroq |
| Ma'lumotni bo'lib o'qitish mumkin | Belgilar orasidagi ta'sirni ko'rmaydi |
| Masshtablash kerak emas |
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 #
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}")
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
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? #
| Vaziyat | Tavsiya |
|---|---|
| Boshlash uchun | Logistik regressiya |
| Jadval ma'lumoti | Random Forest, Gradient Boosting |
| Matn | Naive Bayes, LinearSVC |
| Kichik ma'lumot, ko'p belgi | SVM |
| Tushuntirish muhim | Qaror daraxti, logistik regressiya |
| Katta ma'lumot | SGDClassifier, LightGBM |
| Rasm, ovoz | Neyron tarmoq |
load_breast_cancerma'lumotida SVM ni o'qiting.- To'rtta yadroni solishtiring.
CvagammaniGridSearchCVbilan sozlang.- Qo'llab-quvvatlovchi vektorlar sonini chiqaring.
- Masshtablashsiz o'qitib, farqni o'lchang.
GaussianNBbilan solishtiring.- 20 ta spam va 20 ta oddiy xat yozing.
TfidfVectorizervaMultinomialNBbilan spam filtri quring.- Yangi xatlarni sinab ko'ring.
- Oltita modelni
cross_val_scorebilan 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.
Cxatolarga munosabatni,gammata'sir radiusini belgilaydi.- SVM katta ma'lumotda juda sekin -
LinearSVCni 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.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.