IlmHamroh
Data Science va sun'iy intellekt/Nazoratsiz organish1/12-dars18 daqiqa
Mundarija (22)

16.1-dars: Nazoratsiz o'rganish nima

16-QISM — NAZORATSIZ O'RGANISH · 1-dars


1. Kirish va motivatsiya

Shu paytgacha barcha modellarimiz yorliq (y) bilan ishladi: narx, sinf, kechikish. Lekin real ma'lumotlarning katta qismida yorliq yo'q — mijozlar ro'yxati, sensor o'qishlari, hujjatlar arxivi, tranzaksiyalar oqimi. Ularni yorliqlash qimmat yoki umuman imkonsiz.

Nazoratsiz o'rganish shu vaziyat uchun: u y siz, faqat X dagi tuzilmani topadi. Uch asosiy vazifa: o'xshash obyektlarni guruhlash (klasterlash), belgilar sonini kamaytirish (PCA, t-SNE) va g'ayrioddiy kuzatuvlarni topish (anomaliya aniqlash).

Lekin bu erkinlikning narxi bor: to'g'ri javob yo'q. Klasterlash natijasini "aniqlik" bilan o'lchab bo'lmaydi va ikki algoritm butunlay boshqa, lekin bir xil darajada "to'g'ri" javob berishi mumkin. Baholash — nazoratsiz o'rganishning eng qiyin qismi.

Bu darsda: nazoratsiz o'rganish turlari, nazoratli o'rganishdan farqi, baholash muammosi, masofa va o'xshashlik, masshtablashning hal qiluvchi roli va amaliy qo'llanilishi.

Real vaziyat. Telekom kompaniyasi mijozlarni segmentlash uchun K-means ishlatdi va 5 ta "segment" oldi. Marketing bo'limi ular asosida 5 xil taklif tayyorladi — natija nolga teng bo'ldi. Sabab: belgilar masshtablanmagan edi va klasterlar faqat "oylik to'lov" bo'yicha bo'lingan edi. Masshtablashdan keyin segmentlar mazmunli bo'ldi va konversiya 2.3 barobar oshdi.

Bu darsda nazoratsiz o'rganish asoslarini o'rganamiz.

Bu darsda:

  • Uch asosiy vazifa
  • Baholash muammosi
  • Masofa va o'xshashlik
  • Masshtablash
  • Nazoratli bilan farq
  • Qo'llanilishi
  • Tuzoqlar
  • Amaliy: birinchi klasterlash

ℹ Misollar real numpy/pandas/sklearn bilan (Python 3.14).


2. Nazariya — chuqur tushuntirish

2.1. Uch asosiy vazifa

text
1. KLASTERLASH — o'xshash obyektlarni guruhlash
   K-means, ierarxik, DBSCAN, GMM
   "Mijozlarimiz qanday tabiiy guruhlarga bo'linadi?"

2. O'LCHAMNI KAMAYTIRISH — belgilar sonini kamaytirish
   PCA, t-SNE, UMAP, autoencoder
   "500 belgini 2 ta bilan ko'rsatish mumkinmi?"

3. ANOMALIYA ANIQLASH — g'ayrioddiy kuzatuvlarni topish
   Isolation Forest, LOF, One-Class SVM
   "Qaysi tranzaksiya shubhali?"

Qo'shimcha: zichlikni baholash, assotsiativ qoidalar, matritsani faktorlash

Uch vazifa bir-biriga bog'liq: o'lchamni kamaytirish ko'pincha klasterlashdan oldin bajariladi, anomaliya esa "hech bir klasterga tushmagan nuqta" sifatida ham aniqlanadi.

2.2. Baholash muammosi

text
Nazoratli:  aniqlik, ROC AUC, MSE - HAQIQIY javob bilan solishtiriladi
Nazoratsiz: haqiqiy javob YO'Q

Ikki yo'l:
  ICHKI metrikalar (yorliqsiz):
    silhouette, Davies-Bouldin, Calinski-Harabasz, inersiya
    -> faqat GEOMETRIYAni o'lchaydi, mazmunni emas

  TASHQI metrikalar (yorliq bo'lsa):
    ARI, NMI, homojenlik/to'liqlik
    -> faqat tekshirish uchun (yorliq bo'lsa nazoratli o'rganing)

  AMALIY baho (eng muhim):
    natija biznes uchun foydalimi? segmentlar tushunarli va harakatga yaroqlimi?

Ichki metrikalar algoritmning o'z taxminini tekshiradi: silhouette sferik klasterlarni afzal ko'radi, shuning uchun u K-means ni DBSCAN dan "yaxshiroq" deb baholashi mumkin — hatto DBSCAN to'g'ri shaklni topgan bo'lsa ham. Ularni mutlaq haqiqat deb qabul qilmang.

2.3. Masofa va o'xshashlik

text
Evklid:    sqrt(sum((a-b)^2))      - eng keng tarqalgan, masshtablash SHART
Manhetten: sum(|a-b|)              - chetlanishlarga chidamliroq
Kosinus:   1 - (a.b)/(|a||b|)      - yo'nalish muhim (matn, tavsiya)
Jaccard:   ikkilik belgilar uchun
Gower:     aralash turdagi belgilar uchun

O'lchamlar la'nati 14.2-bob: p katta bo'lganda barcha masofalar TENGLASHADI
  -> avval o'lchamni kamaytiring (PCA) yoki mos masofani tanlang

Kosinus masofasi matn va tavsiya tizimlarida standart: u vektorning uzunligini e'tiborsiz qoldiradi va faqat yo'nalishga qaraydi — uzun hujjat qisqasidan "kattaroq" bo'lmaydi.

2.4. Masshtablash

text
Nazoratsiz o'rganishda masshtablash DARAXTLARDAGIDAN muhimroq:

  daromad (0 .. 50 000 000)  va  yosh (18 .. 70)
  -> Evklid masofasi deyarli faqat daromadga bog'liq
  -> klasterlar faqat daromad bo'yicha bo'linadi

StandardScaler  - odatiy tanlov
RobustScaler    - chetlanishlar bo'lsa
MinMaxScaler    - chegaralangan diapazon kerak bo'lsa
PowerTransformer - kuchli qiyshiq taqsimot

Istisnolar: daraxtga asoslangan anomaliya (Isolation Forest) masshtabsiz ishlaydi

Masshtablash — nazoratsiz o'rganishdagi 1-raqamli xato manbai. Klasterlash natijasi mazmunsiz chiqsa, birinchi tekshiriladigan narsa aynan shu.

2.5. Nazoratli bilan farq

text
                    Nazoratli              Nazoratsiz
kirish              X va y                 faqat X
maqsad              y ni bashorat qilish   X dagi tuzilmani topish
baholash            aniq metrika           noaniq, ko'p mezon
to'g'ri javob       bor                    yo'q
overfitting         aniq o'lchanadi        o'lchash qiyin
natija barqarorligi o'rtacha               ko'pincha past
sozlash             CV bilan               ko'proq mulohaza bilan

Oraliq: yarim nazoratli (ozgina yorliq), o'z-o'zini nazorat (self-supervised)

Natija barqarorligi past — nazoratsiz o'rganishning yashirin muammosi: random_state yoki ma'lumotning kichik o'zgarishi klasterlarni sezilarli o'zgartirishi mumkin (15.3 dagi beqarorlikka o'xshash). Barqarorlikni albatta tekshiring.

2.6. Qo'llanilishi

text
Klasterlash:
  mijoz segmentatsiyasi, hujjatlarni guruhlash, tasvir siqish,
  genlarni tahlil qilish, shahar hududlarini tasniflash

O'lchamni kamaytirish:
  vizualizatsiya, shovqinni kamaytirish, modelni tezlashtirish,
  ko'p kollinearlikni bartaraf etish 13.2-bob

Anomaliya:
  firibgarlik, uskunaning ishdan chiqishi, tarmoq hujumlari,
  ma'lumot sifati nazorati (6-qism)

Amaliyotda eng ko'p qo'llaniladigan uchta: segmentatsiya, vizualizatsiya va anomaliya. Ularning har biri boshqa mezon bilan baholanadi — umumiy "eng yaxshi algoritm" yo'q.

2.7. Tuzoqlar

Asosiy tuzoqlar: masshtablamaslik; ichki metrikani mutlaq haqiqat deb qabul qilish; klasterlar sonini bitta usul bilan tanlash; natijaning barqarorligini tekshirmaslik; klasterlarga darhol "ma'no" berish (aslida shovqin bo'lishi mumkin); yorliq bor bo'lsa ham nazoratsiz usul ishlatish; aralash turdagi belgilarga Evklid masofasini qo'llash; random_state ni qo'ymaslik.

2.8. Tuzilmani topish

Nazoratsiz o'rganish yorliqsiz ma'lumotdagi tuzilmani topadi: klasterlash, o'lchamni kamaytirish va anomaliya aniqlash. Asosiy qiyinchilik — to'g'ri javob yo'qligi: ichki metrikalar (silhouette) faqat geometriyani o'lchaydi, shuning uchun yakuniy mezon amaliy foyda bo'ladi. Masshtablash bu yerda hal qiluvchi, natija barqarorligini esa albatta tekshirish kerak. Keyingi dars — K-means.


3. Tez ma'lumotnoma

python
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.decomposition import PCA
from sklearn.ensemble import IsolationForest
from sklearn.metrics import silhouette_score, adjusted_rand_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

quvur = Pipeline([("sc", StandardScaler()),
                  ("k", KMeans(n_clusters=4, n_init=10, random_state=0))])
yorliq = quvur.fit_predict(X)
silhouette_score(quvur[:-1].transform(X), yorliq)     # masshtablangan fazoda

PCA(n_components=2).fit_transform(Xs)
IsolationForest(contamination=0.02, random_state=0).fit_predict(X)
QOIDA: masshtabla · bir necha metrika · barqarorlikni tekshir ·
       random_state qo'y

Nazoratsiz o'rganish xulosasi

Uch vazifa: klasterlash, o'lchamni kamaytirish, anomaliya
To'g'ri javob yo'q -> ichki metrika + amaliy foyda
Masshtablash majburiy (Evklid masofasi uchun)
Natija beqaror bo'lishi mumkin - barqarorlikni tekshiring

4. Batafsil misollar

Misollar real numpy/pandas/sklearn bilan (Python 3.14).

Misol 1 — Masshtablashning hal qiluvchi roli

python
"""Bir xil ma'lumot, ikki xil natija (real numpy/pandas/sklearn)."""

import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
from sklearn.preprocessing import StandardScaler


def yarat(seed: int = 5, n: int = 1200) -> pd.DataFrame:
    """Uch haqiqiy segment; belgilar birliklari juda har xil."""
    rng = np.random.default_rng(seed)
    segment = rng.integers(0, 3, n)
    markaz_daromad = np.array([2.0e6, 4.5e6, 9.0e6])
    markaz_yosh = np.array([26.0, 45.0, 38.0])
    markaz_xarid = np.array([2.0, 8.0, 4.0])
    daromad = markaz_daromad[segment] + rng.normal(0, 0.6e6, n)
    yosh = markaz_yosh[segment] + rng.normal(0, 5.0, n)
    xarid = np.clip(markaz_xarid[segment] + rng.normal(0, 1.2, n), 0, None)
    return pd.DataFrame({"daromad": daromad, "yosh": yosh,
                         "xaridlar": xarid, "segment": segment})


def main() -> None:
    df = yarat()
    nomlar = ["daromad", "yosh", "xaridlar"]
    X = df[nomlar].to_numpy()
    haqiqiy = df["segment"].to_numpy()

    print("=== 1. Belgilarning diapazonlari ===")
    for i, nom in enumerate(nomlar):
        print(f"  {nom:<10}: {X[:, i].min():>12.1f} .. {X[:, i].max():>12.1f}, "
              f"std {X[:, i].std():>10.1f}")

    print("\n=== 2. Masshtablashsiz K-means ===")
    k1 = KMeans(n_clusters=3, n_init=10, random_state=0).fit(X)
    print(f"  ARI (haqiqiy segment bilan): "
          f"{adjusted_rand_score(haqiqiy, k1.labels_):.4f}")
    print(f"  {'klaster':>8} {'n':>6} {'daromad':>12} {'yosh':>8} "
          f"{'xaridlar':>10}")
    for k in range(3):
        m = k1.labels_ == k
        print(f"  {k:>8} {int(m.sum()):>6} {X[m, 0].mean():>12.0f} "
              f"{X[m, 1].mean():>8.1f} {X[m, 2].mean():>10.2f}")

    print("\n=== 3. Masshtablash bilan ===")
    Xs = StandardScaler().fit_transform(X)
    k2 = KMeans(n_clusters=3, n_init=10, random_state=0).fit(Xs)
    print(f"  ARI: {adjusted_rand_score(haqiqiy, k2.labels_):.4f}")
    print(f"  {'klaster':>8} {'n':>6} {'daromad':>12} {'yosh':>8} "
          f"{'xaridlar':>10}")
    for k in range(3):
        m = k2.labels_ == k
        print(f"  {k:>8} {int(m.sum()):>6} {X[m, 0].mean():>12.0f} "
              f"{X[m, 1].mean():>8.1f} {X[m, 2].mean():>10.2f}")

    print("\n=== 4. Nega shunday: belgilarning hissasi ===")
    print("  Masshtablanmagan fazoda har belgining dispersiyasi:")
    for i, nom in enumerate(nomlar):
        ulush = X[:, i].var() / X.var(axis=0).sum()
        print(f"    {nom:<10}: {ulush:>7.4%}")
    print("  Masshtablangan fazoda:")
    for i, nom in enumerate(nomlar):
        ulush = Xs[:, i].var() / Xs.var(axis=0).sum()
        print(f"    {nom:<10}: {ulush:>7.4%}")
    print("  ⭐ Masshtablanmagan fazoda faqat bitta belgi ahamiyatli")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Belgilarning diapazonlari ===
  daromad   :     357739.2 ..   10838774.4, std  2919919.8
  yosh      :         12.8 ..         60.8, std        9.2
  xaridlar  :          0.0 ..         11.3, std        2.8

=== 2. Masshtablashsiz K-means ===
  ARI (haqiqiy segment bilan): 0.9600
   klaster      n      daromad     yosh   xaridlar
         0    386      9030568     37.6       4.04
         1    399      2036340     26.9       2.21
         2    415      4527351     44.7       7.93

=== 3. Masshtablash bilan ===
  ARI: 0.9975
   klaster      n      daromad     yosh   xaridlar
         0    386      9030568     37.6       4.04
         1    400      2050701     26.6       2.08
         2    414      4519492     45.0       8.07

=== 4. Nega shunday: belgilarning hissasi ===
  Masshtablanmagan fazoda har belgining dispersiyasi:
    daromad   : 100.0000%
    yosh      : 0.0000%
    xaridlar  : 0.0000%
  Masshtablangan fazoda:
    daromad   : 33.3333%
    yosh      : 33.3333%
    xaridlar  : 33.3333%
  ⭐ Masshtablanmagan fazoda faqat bitta belgi ahamiyatli

Nima ko'rsatdi: 2.4-bo'lim.

Misol 2 — Baholash muammosi

python
"""Ichki va tashqi metrikalar nimani o'lchaydi (real numpy/sklearn)."""

import numpy as np
from sklearn.cluster import DBSCAN, KMeans
from sklearn.datasets import make_blobs, make_moons
from sklearn.metrics import (adjusted_rand_score, calinski_harabasz_score,
                             davies_bouldin_score, normalized_mutual_info_score,
                             silhouette_score)
from sklearn.preprocessing import StandardScaler


def main() -> None:
    print("=== 1. Ikki shakl: sferik va yarim oy ===")
    Xb, yb = make_blobs(n_samples=800, centers=3, cluster_std=1.1,
                        random_state=0)
    Xm, ym = make_moons(n_samples=800, noise=0.06, random_state=0)
    Xb, Xm = StandardScaler().fit_transform(Xb), StandardScaler().fit_transform(Xm)
    print(f"  sferik: {len(Xb)} nuqta, {len(np.unique(yb))} klaster")
    print(f"  yarim oy: {len(Xm)} nuqta, {len(np.unique(ym))} klaster")

    print("\n=== 2. Sferik ma'lumotda ===")
    print(f"  {'algoritm':<12} {'silhouette':>11} {'DB':>8} {'CH':>9} "
          f"{'ARI':>8} {'NMI':>8}")
    for nom, model in [("KMeans(3)", KMeans(3, n_init=10, random_state=0)),
                       ("DBSCAN", DBSCAN(eps=0.35, min_samples=8))]:
        yorliq = model.fit_predict(Xb)
        k = len(set(yorliq) - {-1})
        if k < 2:
            print(f"  {nom:<12} (bitta klaster topildi)")
            continue
        print(f"  {nom:<12} {silhouette_score(Xb, yorliq):>11.4f} "
              f"{davies_bouldin_score(Xb, yorliq):>8.4f} "
              f"{calinski_harabasz_score(Xb, yorliq):>9.1f} "
              f"{adjusted_rand_score(yb, yorliq):>8.4f} "
              f"{normalized_mutual_info_score(yb, yorliq):>8.4f}")

    print("\n=== 3. Yarim oy shaklida ===")
    print(f"  {'algoritm':<12} {'silhouette':>11} {'DB':>8} {'CH':>9} "
          f"{'ARI':>8} {'NMI':>8}")
    for nom, model in [("KMeans(2)", KMeans(2, n_init=10, random_state=0)),
                       ("DBSCAN", DBSCAN(eps=0.3, min_samples=8))]:
        yorliq = model.fit_predict(Xm)
        print(f"  {nom:<12} {silhouette_score(Xm, yorliq):>11.4f} "
              f"{davies_bouldin_score(Xm, yorliq):>8.4f} "
              f"{calinski_harabasz_score(Xm, yorliq):>9.1f} "
              f"{adjusted_rand_score(ym, yorliq):>8.4f} "
              f"{normalized_mutual_info_score(ym, yorliq):>8.4f}")
    print("  (silhouette KMeans ni afzal ko'radi, ARI esa DBSCAN ni)")

    print("\n=== 4. Tuzilmasiz ma'lumotda ===")
    rng = np.random.default_rng(0)
    Xr = rng.normal(0, 1, (800, 2))          # hech qanday klaster yo'q
    print(f"  {'k':>3} {'silhouette':>11} {'DB':>8} {'CH':>9}")
    for k in [2, 3, 4, 6]:
        yorliq = KMeans(k, n_init=10, random_state=0).fit_predict(Xr)
        print(f"  {k:>3} {silhouette_score(Xr, yorliq):>11.4f} "
              f"{davies_bouldin_score(Xr, yorliq):>8.4f} "
              f"{calinski_harabasz_score(Xr, yorliq):>9.1f}")
    print("  (metrikalar baribir 'eng yaxshi' k ni ko'rsatadi - ehtiyot bo'ling)")
    print("  ⭐ Ichki metrika geometriyani o'lchaydi, mazmunni emas")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ikki shakl: sferik va yarim oy ===
  sferik: 800 nuqta, 3 klaster
  yarim oy: 800 nuqta, 2 klaster

=== 2. Sferik ma'lumotda ===
  algoritm      silhouette       DB        CH      ARI      NMI
  KMeans(3)         0.4437   0.8043     887.5   0.7253   0.6648
  DBSCAN       (bitta klaster topildi)

=== 3. Yarim oy shaklida ===
  algoritm      silhouette       DB        CH      ARI      NMI
  KMeans(2)         0.4964   0.8084    1119.9   0.4754   0.3779
  DBSCAN            0.3869   1.0242     692.9   1.0000   1.0000
  (silhouette KMeans ni afzal ko'radi, ARI esa DBSCAN ni)

=== 4. Tuzilmasiz ma'lumotda ===
    k  silhouette       DB        CH
    2      0.3093   1.2529     389.1
    3      0.3300   0.9426     473.4
    4      0.3165   0.9305     480.8
    6      0.3302   0.8458     485.4
  (metrikalar baribir 'eng yaxshi' k ni ko'rsatadi - ehtiyot bo'ling)
  ⭐ Ichki metrika geometriyani o'lchaydi, mazmunni emas

Nima ko'rsatdi: 2.2-bo'lim.

Misol 3 — Masofa tanlash

python
"""Qaysi masofa qaysi vazifaga mos (real numpy/sklearn)."""

import numpy as np
from sklearn.cluster import AgglomerativeClustering, KMeans
from sklearn.metrics import adjusted_rand_score
from sklearn.metrics.pairwise import cosine_distances, euclidean_distances
from sklearn.preprocessing import StandardScaler, normalize


def matn_yarat(seed: int = 3, n: int = 600):
    """Uch mavzu; hujjat UZUNLIGI mavzuga bog'liq emas."""
    rng = np.random.default_rng(seed)
    mavzu = rng.integers(0, 3, n)
    lugat = 40
    naqsh = rng.random((3, lugat)) ** 3            # har mavzuda o'z so'zlari
    naqsh = naqsh / naqsh.sum(axis=1, keepdims=True)
    uzunlik = rng.integers(20, 400, n)             # juda har xil uzunlik
    X = np.array([rng.multinomial(u, naqsh[m])
                  for u, m in zip(uzunlik, mavzu)], dtype=float)
    return X, mavzu, uzunlik


def main() -> None:
    X, mavzu, uzunlik = matn_yarat()

    print("=== 1. Hujjatlar ===")
    print(f"  {len(X)} hujjat, {X.shape[1]} so'z")
    print(f"  uzunlik: {uzunlik.min()} .. {uzunlik.max()} so'z")
    print(f"  mavzular: {np.bincount(mavzu).tolist()}")

    print("\n=== 2. Evklid va kosinus masofalari ===")
    # bir mavzudagi qisqa va uzun hujjat
    qisqa = int(np.argmin(np.where(mavzu == 0, uzunlik, 10 ** 9)))
    uzun = int(np.argmax(np.where(mavzu == 0, uzunlik, -1)))
    boshqa = int(np.argmax(np.where(mavzu == 1, uzunlik, -1)))
    e_ich = float(euclidean_distances(X[[qisqa]], X[[uzun]])[0, 0])
    e_tash = float(euclidean_distances(X[[uzun]], X[[boshqa]])[0, 0])
    k_ich = float(cosine_distances(X[[qisqa]], X[[uzun]])[0, 0])
    k_tash = float(cosine_distances(X[[uzun]], X[[boshqa]])[0, 0])
    print(f"  bir mavzu (uz. {uzunlik[qisqa]} va {uzunlik[uzun]}):")
    print(f"    Evklid {e_ich:>8.2f}, kosinus {k_ich:.4f}")
    print(f"  turli mavzu (uz. {uzunlik[uzun]} va {uzunlik[boshqa]}):")
    print(f"    Evklid {e_tash:>8.2f}, kosinus {k_tash:.4f}")
    print(f"  Evklid to'g'ri tartiblaydimi: {e_ich < e_tash}")
    print(f"  kosinus to'g'ri tartiblaydimi: {k_ich < k_tash}")

    print("\n=== 3. Klasterlash natijasi ===")
    variantlar = {
        "KMeans (xom)": KMeans(3, n_init=10, random_state=0).fit_predict(X),
        "KMeans (normallashgan)": KMeans(3, n_init=10,
                                         random_state=0).fit_predict(
                                             normalize(X)),
        "Agglomerative (kosinus)": AgglomerativeClustering(
            3, metric="cosine", linkage="average").fit_predict(X),
    }
    for nom, yorliq in variantlar.items():
        print(f"  {nom:<24}: ARI {adjusted_rand_score(mavzu, yorliq):.4f}")

    print("\n=== 4. Uzunlik ta'siri ===")
    for nom, yorliq in variantlar.items():
        ortacha = [uzunlik[yorliq == k].mean() for k in np.unique(yorliq)]
        tarqoq = float(np.std(ortacha))
        print(f"  {nom:<24}: klaster o'rtacha uzunliklari "
              f"{[round(v) for v in ortacha]}, std {tarqoq:.1f}")
    print("  (xom Evklid klasterlari uzunlik bo'yicha bo'linadi)")
    print("  ⭐ Masofa tanlovi vazifaga bog'liq")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Hujjatlar ===
  600 hujjat, 40 so'z
  uzunlik: 20 .. 399 so'z
  mavzular: [197, 215, 188]

=== 2. Evklid va kosinus masofalari ===
  bir mavzu (uz. 24 va 399):
    Evklid    95.59, kosinus 0.1963
  turli mavzu (uz. 399 va 399):
    Evklid   124.68, kosinus 0.7734
  Evklid to'g'ri tartiblaydimi: True
  kosinus to'g'ri tartiblaydimi: True

=== 3. Klasterlash natijasi ===
  KMeans (xom)            : ARI 0.3827
  KMeans (normallashgan)  : ARI 1.0000
  Agglomerative (kosinus) : ARI 1.0000

=== 4. Uzunlik ta'siri ===
  KMeans (xom)            : klaster o'rtacha uzunliklari [147, 280, 241], std 56.1
  KMeans (normallashgan)  : klaster o'rtacha uzunliklari [204, 186, 201], std 7.7
  Agglomerative (kosinus) : klaster o'rtacha uzunliklari [201, 186, 204], std 7.7
  (xom Evklid klasterlari uzunlik bo'yicha bo'linadi)
  ⭐ Masofa tanlovi vazifaga bog'liq

Nima ko'rsatdi: 2.3-bo'lim.

Misol 4 — Uch vazifa bir ma'lumotda

python
"""Klasterlash, o'lchamni kamaytirish va anomaliya (real numpy/sklearn)."""

import numpy as np
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.ensemble import IsolationForest
from sklearn.metrics import adjusted_rand_score, silhouette_score
from sklearn.preprocessing import StandardScaler


def yarat(seed: int = 11, n: int = 1500, p: int = 12, anomaliya: float = 0.03):
    """4 ta guruh, ko'p ortiqcha belgi, bir nechta anomaliya."""
    rng = np.random.default_rng(seed)
    guruh = rng.integers(0, 4, n)
    markazlar = rng.normal(0, 3.0, (4, 3))
    asos = markazlar[guruh] + rng.normal(0, 0.8, (n, 3))
    # qolgan belgilar - asosning chiziqli aralashmasi + shovqin
    A = rng.normal(0, 1, (3, p - 3))
    qolgan = asos @ A + rng.normal(0, 0.5, (n, p - 3))
    X = np.column_stack([asos, qolgan])
    buzuq = rng.random(n) < anomaliya
    X[buzuq] += rng.normal(0, 8.0, (int(buzuq.sum()), p))
    return X, guruh, buzuq


def main() -> None:
    X, guruh, buzuq = yarat()
    Xs = StandardScaler().fit_transform(X)

    print("=== 1. Ma'lumot ===")
    print(f"  {len(X)} nuqta, {X.shape[1]} belgi")
    print(f"  haqiqiy guruhlar: {np.bincount(guruh).tolist()}")
    print(f"  anomaliyalar: {int(buzuq.sum())} ta ({buzuq.mean():.1%})")

    print("\n=== 2. O'lchamni kamaytirish (PCA) ===")
    p = PCA().fit(Xs)
    jamlangan = np.cumsum(p.explained_variance_ratio_)
    print(f"  {'komponent':>10} {'dispersiya':>12} {'jamlangan':>11}")
    for i in range(5):
        print(f"  {i + 1:>10} {p.explained_variance_ratio_[i]:>12.4f} "
              f"{jamlangan[i]:>11.4f}")
    kerakli = int(np.searchsorted(jamlangan, 0.90) + 1)
    print(f"  90% dispersiya uchun: {kerakli} ta komponent "
          f"({X.shape[1]} o'rniga)")

    print("\n=== 3. Klasterlash: to'liq va PCA fazoda ===")
    X3 = PCA(n_components=kerakli, random_state=0).fit_transform(Xs)
    for nom, Xa in [("to'liq (12 belgi)", Xs), (f"PCA ({kerakli} belgi)", X3)]:
        k = KMeans(4, n_init=10, random_state=0).fit_predict(Xa)
        print(f"  {nom:<20}: ARI {adjusted_rand_score(guruh, k):.4f}, "
              f"silhouette {silhouette_score(Xa, k):.4f}")

    print("\n=== 4. Anomaliya aniqlash ===")
    izo = IsolationForest(contamination=0.03, random_state=0, n_jobs=1)
    bashorat = izo.fit_predict(Xs) == -1
    topildi = int((bashorat & buzuq).sum())
    print(f"  belgilangan: {int(bashorat.sum())} ta")
    print(f"  haqiqiy anomaliyalardan topildi: {topildi} / "
          f"{int(buzuq.sum())} ({topildi / max(buzuq.sum(), 1):.1%})")
    print(f"  noto'g'ri belgilangan: {int((bashorat & ~buzuq).sum())} ta")
    # anomaliyalarni olib tashlash klasterlashga qanday ta'sir qiladi
    toza = ~bashorat
    k_toza = KMeans(4, n_init=10, random_state=0).fit_predict(Xs[toza])
    print(f"  anomaliyasiz klasterlash: ARI "
          f"{adjusted_rand_score(guruh[toza], k_toza):.4f}")
    k_hammasi = KMeans(4, n_init=10, random_state=0).fit_predict(Xs)
    print(f"  hammasi bilan:              ARI "
          f"{adjusted_rand_score(guruh, k_hammasi):.4f}")
    print("  ⭐ Uch vazifa bir-birini to'ldiradi")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ma'lumot ===
  1500 nuqta, 12 belgi
  haqiqiy guruhlar: [403, 363, 371, 363]
  anomaliyalar: 44 ta (2.9%)

=== 2. O'lchamni kamaytirish (PCA) ===
   komponent   dispersiya   jamlangan
           1       0.5248      0.5248
           2       0.2053      0.7302
           3       0.1004      0.8305
           4       0.0670      0.8975
           5       0.0251      0.9227
  90% dispersiya uchun: 5 ta komponent (12 o'rniga)

=== 3. Klasterlash: to'liq va PCA fazoda ===
  to'liq (12 belgi)   : ARI 0.9699, silhouette 0.5315
  PCA (5 belgi)       : ARI 0.9699, silhouette 0.5506

=== 4. Anomaliya aniqlash ===
  belgilangan: 45 ta
  haqiqiy anomaliyalardan topildi: 44 / 44 (100.0%)
  noto'g'ri belgilangan: 1 ta
  anomaliyasiz klasterlash: ARI 1.0000
  hammasi bilan:              ARI 0.9699
  ⭐ Uch vazifa bir-birini to'ldiradi

Nima ko'rsatdi: 2.1, 2.6-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Klasterlash 'to'g'ri' javob beradi" To'g'ri javob yo'q
"Silhouette yuqori — yaxshi klaster" Faqat geometriya
"Masshtablash ixtiyoriy" Ko'pincha hal qiluvchi
"Evklid har doim mos" Matnda kosinus
"Klasterlar barqaror" Ko'pincha beqaror
"Metrika k ni aniq tanlaydi" Tuzilmasiz ma'lumotda ham javob beradi
"Yorliq bo'lsa ham klasterlash foydali" Nazoratli o'rganing
"PCA har doim yordam beradi" Ba'zan signalni yo'qotadi

6. Keng tarqalgan xatolar va yechimlari

1. Masshtablamaslik

python
KMeans(4).fit(df[["daromad", "yosh"]])                            # ⚠️
Pipeline([("sc", StandardScaler()), ("k", KMeans(4))])            # ✅

2. Bitta metrikaga tayanish

python
# faqat silhouette bo'yicha k tanlash                             # ⚠️
# silhouette + DB + CH + barqarorlik + mazmun                     # ✅

3. random_state ni qo'ymaslik

python
KMeans(n_clusters=4)                                              # ⚠️
KMeans(n_clusters=4, n_init=10, random_state=0)                   # ✅

4. Matnda Evklid

python
KMeans(5).fit(tfidf_matritsa)                                     # ⚠️
KMeans(5).fit(normalize(tfidf_matritsa))    # ~ kosinus           # ✅

5. Klasterlarga darhol ma'no berish

python
# "0-klaster — sodiq mijozlar"                                    # ⚠️
# avval barqarorlik va mazmunni tekshiring                        # ✅

6. Yorliq bor bo'lsa ham klasterlash

python
KMeans(2).fit(X)   # y bor edi                                    # ⚠️
RandomForestClassifier().fit(X, y)                                # ✅

7. Aralash turdagi belgilarga Evklid

python
KMeans(4).fit(pd.get_dummies(df))   # sonli + kategoriya          # ⚠️
# Gower masofasi yoki K-prototypes, yoki alohida qarash           # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 16.2-dars: K-means
  • 16.8-dars: PCA
  • 16.10-dars: Anomaliya aniqlash
  • 14.2-dars (o'tilgan): Masofa va o'lchamlar la'nati
  • 06-qism (o'tilgan): Ma'lumotni tozalash

8. Eng yaxshi amaliyotlar

  1. Har doim masshtablang.

  2. Bir necha metrikani ko'ring.

  3. Barqarorlikni tekshiring.

  4. Masofani vazifaga moslang.

  5. random_state qo'ying.

  6. Natijani domen bilimi bilan tekshiring.

  7. Yorliq bo'lsa nazoratli o'rganing.

  8. Amaliy foydani mezon qiling.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # nazoratsiz o'rganishning uch vazifasi?
2.  # nazoratlidan asosiy farqi?
3.  # baholashning asosiy muammosi?
4.  # ichki metrikalar?
5.  # tashqi metrikalar?
6.  # silhouette nimani afzal ko'radi?
7.  # eng keng tarqalgan xato?
8.  # matn uchun qaysi masofa?
9.  # o'lchamlar la'nati nima qiladi?
10. # natija barqarormi?
11. # yorliq bo'lsa nima qilish kerak?
12. # yakuniy mezon nima?
Javoblar
  1. Klasterlash, o'lchamni kamaytirish, anomaliya
  2. y yo'q
  3. To'g'ri javob yo'q
  4. Silhouette, DB, CH, inersiya
  5. ARI, NMI
  6. Sferik klasterlarni
  7. Masshtablamaslik
  8. Kosinus
  9. Masofalarni tenglashtiradi
  10. Ko'pincha yo'q
  11. Nazoratli o'rganish
  12. Amaliy foyda

Vazifa 2: Xatolarni tuzating

python
1.  KMeans(4).fit(df[["daromad", "yosh"]])

2.  KMeans(n_clusters=4)   # takrorlanmaydi

3.  KMeans(5).fit(tfidf_matritsa)

4.  # faqat silhouette bo'yicha k tanlash

5.  KMeans(2).fit(X)   # y ustuni bor edi
Javoblar
python
1.  Pipeline([("sc", StandardScaler()), ("k", KMeans(4))])

2.  KMeans(n_clusters=4, n_init=10, random_state=0)

3.  KMeans(5).fit(normalize(tfidf_matritsa))

4.  # bir necha metrika + barqarorlik + mazmun

5.  RandomForestClassifier().fit(X, y)

Vazifa 3: Masshtablash

Modellang:

  1. Diapazonlar
  2. Masshtablashsiz
  3. Masshtab bilan
  4. Dispersiya hissasi

Vazifa 4: Baholash

Modellang:

  1. Ikki shakl
  2. Sferik ma'lumot
  3. Yarim oy
  4. Tuzilmasiz ma'lumot

Vazifa 5: Masofa

Modellang:

  1. Hujjatlar
  2. Ikki masofa
  3. Klasterlash
  4. Uzunlik ta'siri

Vazifa 6: Uch vazifa

Modellang:

  1. Ma'lumot
  2. PCA
  3. Klasterlash
  4. Anomaliya

Vazifa 7: O'ylash

Klasterlash natijasini "to'g'ri" yoki "noto'g'ri" deb baholab bo'lmasa, uni qanday qilib biznesga topshirish mumkin?

Javob

Qisqa javob: klasterlash natijasi gipoteza, xulosa emas. Uni topshirishdan oldin uch narsani ko'rsatish kerak: barqarorlik, tushunarlilik va harakatga yaroqlilik — va yakuniy tasdiq eksperiment orqali olinadi.

1. Barqarorlik tekshiruvi

Usul Nima ko'rsatadi
Bootstrap namunalar Klasterlar ma'lumot o'zgarishiga chidamlimi
Turli random_state Algoritm tasodifiga bog'liqmi
Ma'lumotni ikkiga bo'lish Ikki yarimda o'xshash segmentlar chiqadimi
Turli algoritmlar K-means va GMM bir xil naqshni topadimi

Agar segmentlar har safar boshqacha chiqsa — ular yo'q degani.

2. Tushunarlilik

  1. Har klasterni 3-5 belgi bilan ta'riflang ("yosh, yuqori daromadli, kam xarid qiladigan")
  2. Domen mutaxassisiga ko'rsating: "bu guruh tanishmi?"
  3. Klaster o'lchamlari mantiqiymi (1% lik segment amaliy emas)
  4. Klasterlar orasidagi farq statistik va amaliy jihatdan ahamiyatlimi

3. Harakatga yaroqlilik

  • Har segment uchun boshqa harakat mumkinmi?
  • Agar hamma segmentga bir xil taklif borsa — segmentatsiya keraksiz
  • Segmentga yangi mijozni joylashtirish mumkinmi (bashorat modeli)

4. Yakuniy tasdiq: eksperiment

Eng ishonchli baho — A/B test: segmentlashgan yondashuv segmentsizdan yaxshiroq natija beradimi. Bu klasterlashni nazoratli masalaga aylantiradi va aniq javob beradi.

5. Xulosa

  1. Klasterlash — gipoteza generatori
  2. Barqarorlik birinchi tekshiruv
  3. Tushunarlilik va harakatga yaroqlilik — ikkinchisi
  4. Yakuniy javobni eksperiment beradi

Nimani mustahkamlaydi: 2.2, 2.5-bo'limlar.


Xulosa

Bu darsda nazoratsiz o'rganish asoslarini o'rgandik.

Eng muhim uch fikr:

  1. Uch vazifa, bitta g'oya. Klasterlash (o'xshashlarni guruhlash), o'lchamni kamaytirish (belgilarni siqish) va anomaliya aniqlash (g'ayrioddiylarni topish) — hammasi yorliqsiz ma'lumotdagi tuzilmani izlaydi. Ular bir-birini to'ldiradi: PCA klasterlashdan oldin, anomaliyalarni olib tashlash esa klasterlarni tozalaydi.

  2. To'g'ri javob yo'q. Ichki metrikalar (silhouette, Davies-Bouldin) faqat geometriyani o'lchaydi va o'z taxminlarini tekshiradi — silhouette sferik klasterlarni afzal ko'radi, shuning uchun u yarim oy shaklida noto'g'ri algoritmni tanlaydi. Bundan tashqari, ular tuzilmasiz ma'lumotda ham "eng yaxshi k" ni ko'rsatadi. Yakuniy mezon — amaliy foyda.

  3. Masshtablash — 1-raqamli xato manbai. Daromad (0-50 mln) va yosh (18-70) bir fazoda bo'lsa, Evklid masofasi deyarli faqat daromadga bog'liq bo'ladi va klasterlar mazmunsiz chiqadi. Natija g'alati ko'ringanda birinchi tekshiriladigan narsa aynan shu. Masofani ham vazifaga moslang: matnda kosinus, aralash belgilarda Gower.

Keyingi darsda K-meansni o'rganamiz: eng keng tarqalgan klasterlash algoritmi, uning mexanizmi, taxminlari va cheklovlari.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
16.1-dars: Nazoratsiz o'rganish nima — IlmHamroh