15-bo‘lim
O'lchamni kamaytirish va PCA
Asosiy komponentalar tahlili, tushuntirilgan tarqoqlik, vizuallashtirish va t-SNE bilan tanishuv.
Ushbu bo‘lim mundarijasi
Ma'lumotda 100 ta belgi bo'lsa, uni ko'z bilan ko'rib bo'lmaydi va ko'p algoritmlar yomon ishlaydi. Yechim - o'lchamni kamaytirish.
Nima uchun kerak? #
| Muammo | O'lchamni kamaytirish nima beradi |
|---|---|
| Vizuallashtirib bo'lmaydi | 2-3 o'lchamga tushirib chizish mumkin |
| O'lchamlilik la'nati | Masofalar yana ma'noli bo'ladi |
| Sekin o'qitish | Kam belgi = tez hisoblash |
| Qayta o'qitish | Shovqin belgilar olib tashlanadi |
| Ko'p xotira | Ma'lumot ixchamlashadi |
| Korrelyatsiyalangan belgilar | Ular birlashtiriladi |
PCA g'oyasi #
PCA ma'lumot eng ko'p tarqalgan yo'nalishlarni topadi va shu yo'nalishlarni yangi o'qlar sifatida ishlatadi.
"Tarqoqlik = ma'lumot" degan faraz.
Agar barcha nuqtalar bir yo'nalish bo'ylab cho'zilgan bo'lsa, ikkinchi yo'nalishdagi farqlar deyarli yo'q - demak uni tashlab yuborish mumkin.
Amaliyotda #
import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_breast_cancer
malumot = load_breast_cancer()
X, y = malumot.data, malumot.target
print(f"Asl o'lcham: {X.shape}")
X_masshtab = StandardScaler().fit_transform(X)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_masshtab)
print(f"Yangi o'lcham: {X_pca.shape}")
print(f"Tushuntirilgan tarqoqlik: {pca.explained_variance_ratio_.round(3)}")
print(f"Jami: {pca.explained_variance_ratio_.sum():.1%}")
Asl o'lcham: (569, 30)
Yangi o'lcham: (569, 2)
Tushuntirilgan tarqoqlik: [0.443 0.19 ]
Jami: 63.2%
30 ta belgi 2 taga qisqardi va ma'lumotning 63 foizi saqlandi.
PCA tarqoqlik bilan ishlaydi. Katta qiymatli belgi katta tarqoqlikka ega bo'ladi va PCA uni "eng muhim" deb hisoblaydi.
# XATO
pca.fit(X)
# TO'G'RI
pca.fit(StandardScaler().fit_transform(X))
Nechta komponenta kerak? #
pca_toliq = PCA().fit(X_masshtab)
jamlanuvchi = np.cumsum(pca_toliq.explained_variance_ratio_)
for n in [1, 2, 5, 10, 15, 20, 30]:
print(f"{n:2d} komponenta: {jamlanuvchi[n-1]:.1%}")
1 komponenta: 44.3%
2 komponenta: 63.2%
5 komponenta: 84.7%
10 komponenta: 95.2%
15 komponenta: 98.1%
20 komponenta: 99.4%
30 komponenta: 100.0%
# Foizni to'g'ridan-to'g'ri berish mumkin
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X_masshtab)
print(f"Tanlangan komponentalar: {pca.n_components_}")
Tanlangan komponentalar: 10
Vizuallashtirish #
import matplotlib.pyplot as plt
pca = PCA(n_components=2)
X_2d = pca.fit_transform(X_masshtab)
plt.figure(figsize=(9, 6))
for sinf, rang, nom in zip([0, 1], ["tomato", "steelblue"], malumot.target_names):
tanlangan = y == sinf
plt.scatter(X_2d[tanlangan, 0], X_2d[tanlangan, 1],
c=rang, label=nom, alpha=0.65, edgecolors="white")
plt.xlabel(f"PC1 ({pca.explained_variance_ratio_[0]:.1%})")
plt.ylabel(f"PC2 ({pca.explained_variance_ratio_[1]:.1%})")
plt.title("30 o'lchamli ma'lumot 2 o'lchamda")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
30 o'lchamli ma'lumotni ko'z bilan ko'rib bo'lmaydi. PCA dan keyin darhol ko'rinadi: sinflar ajraladimi, klasterlar bormi, chetdagi qiymatlar qayerda.
Model qurishdan oldin shu grafikni chizing.
Komponentalar nimadan iborat? #
komponentalar = pd.DataFrame(
pca.components_[:2],
columns=malumot.feature_names,
index=["PC1", "PC2"],
)
print("PC1 ga eng ko'p hissa qo'shgan belgilar:")
print(komponentalar.loc["PC1"].abs().nlargest(5).round(3))
mean concave points 0.261
mean concavity 0.258
concave points error 0.254
mean compactness 0.239
worst concave points 0.236
PC1 = 0.26·belgi1 + 0.25·belgi2 - 0.18·belgi3 + ...
Bu 30 ta belgining aralashmasi. "PC1 nimani anglatadi?" degan savolga aniq javob berish qiyin.
Tushuntirish muhim bo'lgan loyihalarda (tibbiyot, bank) buni hisobga
oling. Alternativa - belgilarni tanlash (SelectKBest, Lasso).
Model tezligiga ta'siri #
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, cross_val_score
import time
X_o, X_s, y_o, y_s = train_test_split(
X_masshtab, y, test_size=0.3, random_state=42, stratify=y
)
# PCA siz
boshlandi = time.perf_counter()
ball_1 = cross_val_score(SVC(), X_o, y_o, cv=5).mean()
vaqt_1 = time.perf_counter() - boshlandi
# PCA bilan
pca = PCA(n_components=10)
X_o_pca = pca.fit_transform(X_o)
boshlandi = time.perf_counter()
ball_2 = cross_val_score(SVC(), X_o_pca, y_o, cv=5).mean()
vaqt_2 = time.perf_counter() - boshlandi
print(f"30 belgi: aniqlik={ball_1:.3f} vaqt={vaqt_1:.3f}s")
print(f"10 belgi: aniqlik={ball_2:.3f} vaqt={vaqt_2:.3f}s")
30 belgi: aniqlik=0.975 vaqt=0.089s
10 belgi: aniqlik=0.972 vaqt=0.041s
Aniqlik deyarli o'zgarmadi, vaqt ikki barobar qisqardi.
Pipeline ichida #
from sklearn.pipeline import Pipeline
quvur = Pipeline([
("masshtab", StandardScaler()),
("pca", PCA(n_components=0.95)),
("model", SVC()),
])
quvur.fit(X_o, y_o)
print(f"Sinov aniqligi: {quvur.score(X_s, y_s):.3f}")
fit qilmang# XATO - sizib chiqish
X_pca = PCA(n_components=10).fit_transform(X)
X_o, X_s = train_test_split(X_pca, ...)
# TO'G'RI
X_o, X_s = train_test_split(X, ...)
pca = PCA(n_components=10).fit(X_o)
X_o_pca = pca.transform(X_o)
X_s_pca = pca.transform(X_s)
Pipeline buni avtomatik to'g'ri qiladi.
Ma'lumotni qayta tiklash #
pca = PCA(n_components=10).fit(X_masshtab)
X_siqilgan = pca.transform(X_masshtab)
X_tiklangan = pca.inverse_transform(X_siqilgan)
xato = np.mean((X_masshtab - X_tiklangan) ** 2)
print(f"Qayta tiklash xatosi: {xato:.4f}")
print(f"Saqlangan ma'lumot: {pca.explained_variance_ratio_.sum():.1%}")
Qayta tiklash xatosi: 0.0481
Saqlangan ma'lumot: 95.2%
Qayta tiklash xatosi katta bo'lgan namunalar - odatiy bo'lmagan nuqtalar:
xatolar = np.mean((X_masshtab - X_tiklangan) ** 2, axis=1)
chegara = np.percentile(xatolar, 95)
anomaliyalar = np.where(xatolar > chegara)[0]
Bu firibgarlikni aniqlash tizimlarida ishlatiladigan usul.
t-SNE va UMAP #
PCA chiziqli usul. Murakkab tuzilmalar uchun boshqa vositalar bor.
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_tsne = tsne.fit_transform(X_masshtab)
plt.figure(figsize=(9, 6))
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap="coolwarm", alpha=0.7)
plt.title("t-SNE")
plt.show()
| PCA | t-SNE | UMAP | |
|---|---|---|---|
| Turi | Chiziqli | Chiziqsiz | Chiziqsiz |
| Tezlik | Juda tez | Sekin | Tez |
| Yangi ma'lumotga | transform bor | Yo'q | Bor |
| Global tuzilma | Saqlanadi | Saqlanmaydi | Qisman |
| Lokal tuzilma | Qisman | Juda yaxshi | Juda yaxshi |
| Asosiy maqsad | Siqish + vizual | Faqat vizual | Vizual + siqish |
t-SNE da:
- Klasterlar orasidagi masofa ma'noga ega emas
- Klaster o'lchami ma'noga ega emas
perplexityo'zgarsa, rasm butunlay boshqacha bo'ladi
U faqat "guruhlar bormi?" degan savolga javob beradi.
Modelga kirish sifatida t-SNE natijasini ishlatmang - u faqat vizual tekshiruv uchun.
PCA ning boshqa turlari #
from sklearn.decomposition import IncrementalPCA, KernelPCA, TruncatedSVD
# Xotiraga sig'maydigan katta ma'lumot uchun
ipca = IncrementalPCA(n_components=10, batch_size=100)
# Chiziqsiz bog'liqliklar uchun
kpca = KernelPCA(n_components=10, kernel="rbf")
# Siyrak matritsalar (matn) uchun
svd = TruncatedSVD(n_components=100)
TruncatedSVDTfidfVectorizer siyrak matritsa qaytaradi - unda ko'p nollar bor.
PCA uni zich matritsaga aylantirishga urinadi va xotira yetmaydi.
TruncatedSVD esa siyrak matritsa bilan to'g'ridan-to'g'ri ishlaydi.
Matn tahlilida bu usul "Latent Semantic Analysis" deb ataladi.
Qachon ishlatmaslik kerak? #
| Vaziyat | Sabab |
|---|---|
| Belgilar kam (10 dan kam) | Foydasi yo'q |
| Tushuntirish muhim | Komponentalar tushunarsiz |
| Belgilar mustaqil | Siqiladigan narsa yo'q |
| Daraxtga asoslangan model | Ular allaqachon belgi tanlaydi |
| Toifali belgilar ko'p | PCA uzluksiz sonlar uchun |
PCA - vosita, majburiy qadam emas. Uni faqat aniq sabab bo'lganda ishlating.
Alternativa - belgilarni tanlash #
from sklearn.feature_selection import SelectKBest, f_classif, RFE
from sklearn.ensemble import RandomForestClassifier
# Statistik test bo'yicha
tanlovchi = SelectKBest(f_classif, k=10)
X_tanlangan = tanlovchi.fit_transform(X_masshtab, y)
tanlangan_nomlar = malumot.feature_names[tanlovchi.get_support()]
print(list(tanlangan_nomlar)[:5])
# Rekursiv olib tashlash
rfe = RFE(RandomForestClassifier(n_estimators=50, random_state=42), n_features_to_select=10)
rfe.fit(X_masshtab, y)
| PCA | Belgi tanlash | |
|---|---|---|
| Natija | Yangi belgilar | Asl belgilarning qismi |
| Tushuntirish | Qiyin | Oson |
| Ma'lumot yo'qolishi | Kam | Ko'proq |
| Yangi ma'lumot yig'ish | Hamma belgi kerak | Faqat tanlanganlar |
Amaliy loyihada belgi tanlash ko'pincha afzalroq: kelajakda faqat 10 ta belgini yig'ish 30 tasidan arzonroq.
load_breast_cancerma'lumotini yuklang va masshtablang.PCA(n_components=2)bilan siqing.- Ikki sinfni turli rangda chizing - ular ajraladimi?
- Jamlanuvchi tarqoqlik grafigini chizing.
- 95% uchun nechta komponenta kerakligini aniqlang.
- PCA siz va PCA bilan SVM aniqligi va vaqtini solishtiring.
inverse_transformbilan ma'lumotni tiklang va xatoni o'lchang.- Eng katta qayta tiklash xatoli 10 ta namunani toping.
t-SNEbilan ham chizing va PCA bilan solishtiring.SelectKBestbilan 10 ta belgi tanlang va PCA bilan natijani solishtiring.
Xulosa #
- O'lchamni kamaytirish vizuallashtirish, tezlik va qayta o'qitishga qarshi kurash uchun kerak.
- PCA eng ko'p tarqoqlik yo'nalishlarini topadi.
- Masshtablash majburiy - aks holda katta qiymatli belgi hukmron bo'ladi.
explained_variance_ratio_har bir komponenta qancha ma'lumot saqlaganini ko'rsatadi.n_components=0.95kerakli sonni avtomatik tanlaydi.- PCA komponentalari tushuntirilmaydi - bu asosiy kamchilik.
- PCA ni faqat o'qitish to'plamida
fitqiling - Pipeline buni avtomatik qiladi. inverse_transformanomaliya aniqlash uchun ishlatiladi.- t-SNE faqat vizuallashtirish uchun; undagi masofalarga ishonmang.
- Matn uchun
TruncatedSVDishlating. - Tushuntirish muhim bo'lsa - PCA o'rniga belgilarni tanlang.
Keyingi bo'limda kross-validatsiya va qayta o'qitishni chuqurroq ko'ramiz.
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.