15-bo‘lim

O'lchamni kamaytirish va PCA

Asosiy komponentalar tahlili, tushuntirilgan tarqoqlik, vizuallashtirish va t-SNE bilan tanishuv.

🕑 14 daqiqa o‘qish 📄 899 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Nima uchun kerak?
  2. PCA g'oyasi
  3. Amaliyotda
  4. Nechta komponenta kerak?
  5. Vizuallashtirish
  6. Komponentalar nimadan iborat?
  7. Model tezligiga ta'siri
  8. Pipeline ichida
  9. Ma'lumotni qayta tiklash
  10. t-SNE va UMAP
  11. PCA ning boshqa turlari
  12. Qachon ishlatmaslik kerak?
  13. Alternativa - belgilarni tanlash
  14. Xulosa

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? #

MuammoO'lchamni kamaytirish nima beradi
Vizuallashtirib bo'lmaydi2-3 o'lchamga tushirib chizish mumkin
O'lchamlilik la'natiMasofalar yana ma'noli bo'ladi
Sekin o'qitishKam belgi = tez hisoblash
Qayta o'qitishShovqin belgilar olib tashlanadi
Ko'p xotiraMa'lumot ixchamlashadi
Korrelyatsiyalangan belgilarUlar birlashtiriladi

PCA g'oyasi #

PCA ma'lumot eng ko'p tarqalgan yo'nalishlarni topadi va shu yo'nalishlarni yangi o'qlar sifatida ishlatadi.

PCA eng ko'p ma'lumot saqlangan yo'nalishni topadi Asl ma'lumot (2 o'lcham) PC1 PC2 PC1 ga proyeksiya (1 o'lcham) Bir o'lchamda ham nuqtalar ajralib turibdi Tarqoqlikning ~95 foizi saqlandi PC1 - eng ko'p tarqoqlik yo'nalishi · PC2 - unga perpendikulyar
Ikkita korrelyatsiyalangan belgi bitta yangi belgiga siqiladi
Asosiy g'oya

"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 #

Python
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%}")
Natija
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.

Masshtablash majburiy

PCA tarqoqlik bilan ishlaydi. Katta qiymatli belgi katta tarqoqlikka ega bo'ladi va PCA uni "eng muhim" deb hisoblaydi.

Python
# XATO
pca.fit(X)

# TO'G'RI
pca.fit(StandardScaler().fit_transform(X))

Nechta komponenta kerak? #

Python
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%}")
Natija
 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%
Jamlanuvchi tushuntirilgan tarqoqlik Komponentalar soni Tarqoqlik 95% 10 1 5 20 30 0% 95% 100% Xulosa 10 ta komponenta 30 tasining o'rnini bosadi Ma'lumotning atigi 5 foizi yo'qoladi
Odatiy chegara - 90 yoki 95 foiz tarqoqlik
Python
# 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_}")
Natija
Tanlangan komponentalar: 10

Vizuallashtirish #

Python
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()
Bu PCA ning eng foydali qo'llanilishi

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? #

Python
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))
Natija
mean concave points     0.261
mean concavity          0.258
concave points error    0.254
mean compactness        0.239
worst concave points    0.236
PCA komponentalari tushuntirilmaydi

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 #

Python
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")
Natija
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 #

Python
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}")
PCA ni butun ma'lumotda fit qilmang
Python
# 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 #

Python
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%}")
Natija
Qayta tiklash xatosi: 0.0481
Saqlangan ma'lumot:   95.2%
Anomaliyani aniqlash

Qayta tiklash xatosi katta bo'lgan namunalar - odatiy bo'lmagan nuqtalar:

Python
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.

Python
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()
PCAt-SNEUMAP
TuriChiziqliChiziqsizChiziqsiz
TezlikJuda tezSekinTez
Yangi ma'lumotgatransform borYo'qBor
Global tuzilmaSaqlanadiSaqlanmaydiQisman
Lokal tuzilmaQismanJuda yaxshiJuda yaxshi
Asosiy maqsadSiqish + vizualFaqat vizualVizual + siqish
t-SNE grafigidagi masofalarga ishonmang

t-SNE da:

  • Klasterlar orasidagi masofa ma'noga ega emas
  • Klaster o'lchami ma'noga ega emas
  • perplexity o'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 #

Python
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)
Matn uchun TruncatedSVD

TfidfVectorizer 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? #

PCA har doim foydali emas
VaziyatSabab
Belgilar kam (10 dan kam)Foydasi yo'q
Tushuntirish muhimKomponentalar tushunarsiz
Belgilar mustaqilSiqiladigan narsa yo'q
Daraxtga asoslangan modelUlar allaqachon belgi tanlaydi
Toifali belgilar ko'pPCA uzluksiz sonlar uchun

PCA - vosita, majburiy qadam emas. Uni faqat aniq sabab bo'lganda ishlating.

Alternativa - belgilarni tanlash #

Python
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 yoki belgilarni tanlash?
PCABelgi tanlash
NatijaYangi belgilarAsl belgilarning qismi
TushuntirishQiyinOson
Ma'lumot yo'qolishiKamKo'proq
Yangi ma'lumot yig'ishHamma belgi kerakFaqat tanlanganlar

Amaliy loyihada belgi tanlash ko'pincha afzalroq: kelajakda faqat 10 ta belgini yig'ish 30 tasidan arzonroq.

Amaliy topshiriq
  1. load_breast_cancer ma'lumotini yuklang va masshtablang.
  2. PCA(n_components=2) bilan siqing.
  3. Ikki sinfni turli rangda chizing - ular ajraladimi?
  4. Jamlanuvchi tarqoqlik grafigini chizing.
  5. 95% uchun nechta komponenta kerakligini aniqlang.
  6. PCA siz va PCA bilan SVM aniqligi va vaqtini solishtiring.
  7. inverse_transform bilan ma'lumotni tiklang va xatoni o'lchang.
  8. Eng katta qayta tiklash xatoli 10 ta namunani toping.
  9. t-SNE bilan ham chizing va PCA bilan solishtiring.
  10. SelectKBest bilan 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.95 kerakli sonni avtomatik tanlaydi.
  • PCA komponentalari tushuntirilmaydi - bu asosiy kamchilik.
  • PCA ni faqat o'qitish to'plamida fit qiling - Pipeline buni avtomatik qiladi.
  • inverse_transform anomaliya aniqlash uchun ishlatiladi.
  • t-SNE faqat vizuallashtirish uchun; undagi masofalarga ishonmang.
  • Matn uchun TruncatedSVD ishlating.
  • Tushuntirish muhim bo'lsa - PCA o'rniga belgilarni tanlang.

Keyingi bo'limda kross-validatsiya va qayta o'qitishni chuqurroq ko'ramiz.

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.