Asosiy qismga o'tish

Heatmap va correlation

18-bob 34 kod bloki 8331 so'z

Oldingi boblardagi har bir plot long (tidy) DataFrame ni olib, guruhlashni seaborn ning o'ziga topshirar edi. Bu bob o'sha odatni buzadi. sns.heatmap() va sns.clustermap() — seaborn ning ikkita matrix function i: ular hech narsani guruhlamaydi, x=, y= yoki hue= ni qabul qilmaydi va tidy jadvalni o'qiy olmaydi. Ular sonlardan iborat to'rtburchakni olib, har bir cell ni rang bilan bo'yaydi.

Aynan mana shu struktura farqi ko'pchilik boshlovchini to'xtatib qo'yadi, shuning uchun unga jiddiy vaqt ajratamiz: oddiy ma'lumotni pivot, pivot_table, crosstab va corr yordamida matrix shakliga qanday o'zgartirish kerak. Keyin eng ko'p uchraydigan matrix — correlation matrix — bilan tanishamiz va, undan ham muhimi, uni o'zingizni aldamasdan qanday o'qish kerakligini o'rganamiz.

🧩 O'xshatish

Tidy DataFrame — bu cheklar ro'yxati: har bir tranzaksiyaga bitta row. Matrix esa jadval to'ri: chetida oylar, yuqorisida yillar, har bir cell da bitta son. heatmap — siz allaqachon tuzib qo'ygan to'rni bo'yab beradigan nusxa ko'chirgich; u siz uchun to'rni qura olmaydi. Sizning vazifangiz — unga cheklarni emas, tayyor jadvalni uzatish.

Heatmap asoslari va u talab qiladigan ma'lumot shakli

Heatmap sonli qiymatni rang orqali ifodalaydi. Row index y o'qiga, column index x o'qiga aylanadi, har bir cell ning qiymati esa colormap dan olingan rangga aylanadi. Butun g'oya shundan iborat.

Eng sodda chaqiruv

python19 qator
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

sns.set_theme(style="white")

# flights long/tidy shaklda: har bir (year, month) uchun bitta row va yo'lovchilar soni
flights = sns.load_dataset("flights")
print(flights.head())
#    year month  passengers
# 0  1949   Jan         112
# 1  1949   Feb         118

# long -> wide ga o'tkazamiz: rows = month, columns = year, cells = passengers
matrix = flights.pivot(index="month", columns="year", values="passengers")

sns.heatmap(matrix)
plt.show()
Chiqish
   year month  passengers
0  1949   Jan         112
1  1949   Feb         118
2  1949   Mar         132
3  1949   Apr         129
4  1949   May         121

Klassik heatmap: flights oy × yil ko‘rinishiga pivot qilingan. Ikkita pattern darrov ko‘zga tashlanadi — qatnov har yili o‘sadi va har yozda cho‘qqiga chiqadi.

Klassik flights heatmap i 144 ta sondan iborat jadval yashiradigan ikkita narsani bir zumda ko'rsatadi: havo qatnovi 1949 dan 1960 gacha barqaror o'sgan (rang chapdan o'ngga yorishib boradi) va har bir yilda iyul–avgustda yozgi cho'qqi bor (yorqin gorizontal chiziq). Ko'z bilan pattern ni ilg'ash — heatmap ning asosiy maqsadi.

"Matrix shakli" aniq nimani anglatadi

QOIDAheatmap ga sonlardan iborat 2 o'lchamli to'rtburchak blok kerak. Row yorliqlari df.index dan, column yorliqlari df.columns dan, ranglar df.values dan olinadi. Boshqa hech narsa tekshirilmaydi.
Shakl Misol heatmap bilan ishlaydimi?
Long / tidy year, month, passengers column lariga ega flights Yo'q — bu uchta column, to'r emas
Wide DataFrame flights.pivot(...), 12 row × 12 column Ha
Correlation matrix df.corr(numeric_only=True) Ha
Contingency table pd.crosstab(a, b) Ha
NumPy 2 o'lchamli array np.random.rand(5, 5) Ha, lekin yorliqlar 0,1,2,…
Series / 1 o'lchamli array df["x"] Yo'q — 2 o'lcham kerak

Agar oddiy NumPy array uzatsangiz, row va column nomlarini yo'qotasiz, chunki NumPy array da index yo'q. Tick yorliqlari ma'noli bo'lishi uchun DataFrame ni afzal ko'ring.

Qabul qilinadigan argumentlar, qisqacha

python15 qator
sns.heatmap(
    data,              # 2 o'lchamli DataFrame yoki ndarray - YAGONA pozitsion argument
    annot=False,       # cell lar ichiga sonlarni yozadi
    fmt=".2g",         # annotation lar uchun format qatori
    cmap=None,         # colormap nomi yoki obyekti
    center=None,       # diverging map ning o'rtasiga tushadigan qiymat
    vmin=None, vmax=None,   # rang shkalasini cheklaydi
    robust=False,      # min/max o'rniga 2 va 98-protsentillarni ishlatadi
    linewidths=0, linecolor="white",
    cbar=True, cbar_kws=None,
    square=False,      # cell larni kvadrat qilib majburlaydi
    xticklabels="auto", yticklabels="auto",
    mask=None,         # boolean array; True bo'lgan cell lar chizilmaydi
    ax=None,
)
📌 Bu yerda `hue` ham, `x=` ham, `data=` semantikasi ham yo'q

Seaborn dagi barcha figure-level va axes-level chizish function laridan farqli o'laroq, heatmap — matrix function i. sns.heatmap(data=df, x="year", y="month") degan narsa umuman mavjud emas va TypeError beradi. Shu bilan birga u axes-level, ya'ni joriy axes ga chizadi va plt.subplots() bilan bemalol birga ishlaydi.

Asosiy parametrlar: annot, fmt, cmap, vmin/vmax/center, linewidths, cbar

annot va fmt — sonlarni chiqarish

annot=True har bir cell ning qiymatini rang ustiga yozadi. Bu heatmap ni rangli jadvalga aylantiradi va hisobotlarda aynan shu ko'proq kerak bo'ladi. Muammo — o'qilishida: matrix kattalashgani sari matn kichrayadi.

python13 qator
flights = sns.load_dataset("flights")
matrix = flights.pivot(index="month", columns="year", values="passengers")

fig, ax = plt.subplots(figsize=(10, 6))
sns.heatmap(
    matrix,
    annot=True,
    fmt="d",              # butun sonlar, kasr nuqtasisiz
    cmap="viridis",
    linewidths=0.5,
    ax=ax,
)
plt.show()

fmt — bu har bir songa qo'llaniladigan standart Python format spetsifikatsiyasi. Uni noto'g'ri bersangiz, ValueError olasiz — eng ko'p uchraydigani float larga fmt="d" qo'llash.

fmt Ma'nosi 1234.5678 quyidagicha chiqadi
".2g" standart: 2 ta ma'noli raqam 1.2e+03
"d" butun son (float larda xato beradi) xato
".0f" kasr qismisiz 1235
".2f" 2 xona kasr — correlation lar uchun standart 1234.57
".1%" foiz, 1 xona kasr 123456.8%
",.0f" minglik ajratgich 1,235

Annotation matnining ko'rinishi annot_kws orqali sozlanadi:

python2 qator
sns.heatmap(matrix, annot=True, fmt="d",
            annot_kws={"size": 8, "weight": "bold"})

Rang beradigan qiymatlardan boshqa qiymatlar bilan annotation qilish ham mumkin — annot ga ikkinchi array uzating. Masalan, p-value bo'yicha rang berib, effect size ni yozib qo'yish shu tarzda qilinadi:

python2 qator
# correlation bo'yicha rang beramiz, lekin har bir cell ga sample size ni yozamiz
sns.heatmap(corr, annot=counts, fmt="d", cmap="coolwarm", center=0)

cmap — yolg'on gapirmaydigan colormap tanlash

Colormap tanlash bezak emas; u o'quvchi qanday xulosaga kelishini belgilaydi. Uchta oila muhim.

Oila Qachon ishlatiladi Misollar
Sequential Qiymatlar pastdan yuqoriga boradi va ma'noli o'rta nuqta yo'q (sanoqlar, narxlar, yo'lovchilar soni) viridis, rocket, mako, Blues, YlGnBu
Diverging Ma'noli markaz bor va chetlanishlar ikki tomonga ketadi (correlation lar, baseline dan farqlar, z-score lar) coolwarm, RdBu_r, vlag, icefire
Qualitative Tartibsiz kategoriyalar — sonlar heatmap ida deyarli hech qachon mos kelmaydi Set2, tab10
QARORNol (yoki biror baseline) alohida ma'noga egami? Unda diverging map + center=0. Aks holda sequential map. Rainbow hech qachon emas.

Perseptual bir xillik. Colormap perseptual jihatdan bir xil deyiladi, agar ma'lumotdagi teng qadamlar rangda ham teng ko'rinadigan qadamlarni bersa. viridis, rocket va mako aynan shunday loyihalangan. Eski jet/rainbow map esa bunday emas: unda yorqin siyan-sariq chiziq bor va ko'z uni ma'lumot silliq o'zgarayotgan bo'lsa ham keskin chegara deb o'qiydi, hamda to'q ko'kdan siyangacha bo'lgan qismda haqiqiy farqlar ko'rinmas holga siqiladi. Rainbow map lar ma'lumotda yo'q chegaralarni o'ylab topadi. Ularni ishlatmang.

Rang ko'rlikka bardoshlilik. Taxminan har 12 erkakdan biri qizil–yashil rang ko'rish buzilishining qandaydir shakliga ega. viridis, mako va cividis bunga bardosh beradi; qizil–yashil diverging map esa yo'q. Diverging ma'lumot uchun RdYlGn o'rniga RdBu_r yoki seaborn ning vlag (ko'k–qizil) ini afzal ko'ring. Yorqinlik bo'yicha ham o'zgaradigan sequential map kulrang shkalada va nusxa ko'chirilganda ham o'qilaveradi.

Istalgan matplotlib colormap nomiga _r qo'shsangiz, u teskari bo'ladi: "RdBu" qizil→ko'k, "RdBu_r" esa ko'k→qizil yo'nalishda boradi — correlation lar uchun aynan shu kerak, chunki musbat qiymat issiq rangda bo'lishi lozim.

vmin, vmax, center — shkalani boshqarish

Standart holatda rang shkalasi ma'lumotning minimumidan maksimumigacha cho'ziladi. Bu qulay, ammo xavfli.

python2 qator
# correlation lar: chartlar taqqoslanadigan bo'lishi uchun shkalani doim qotiring
sns.heatmap(corr, cmap="coolwarm", center=0, vmin=-1, vmax=1)

Bir-biriga bog'liq uchta murvat:

  • vmin / vmax — rang shkalasining qat'iy quyi va yuqori chegarasi. Chegaradan tashqaridagi qiymatlar chekka ranglarga qirqiladi.
  • center — diverging map ning o'rta rangiga tushadigan qiymat. Correlation lar uchun bu 0; foizli o'zgarish matrix i uchun ham 0; nisbatlar matrix i uchun esa 1 bo'lishi mumkin. Faqat center ni berish seaborn ning standart colormap ini ham diverging turiga o'zgartiradi.
  • robust=True — chegaralarni min/max o'rniga 2 va 98-protsentillardan oladi, shunda bitta ekstremal outlier butun rasmni yagona rangga aylantirib yubormaydi. Tadqiq qilish uchun foydali; ammo buni izohda aytib o'ting, chunki u ekstremal qiymatlarni yashiradi.
⚠️ Avtomatik shkala ikkita heatmap ni taqqoslab bo'lmaydigan qiladi

Agar A chart dagi correlation lar −0.2 dan 0.4 gacha, B chart dagilari esa −0.9 dan 0.95 gacha bo'lsa, avtomatik shkala ikkalasiga ham bir xil eng to'q qizil va bir xil eng to'q ko'k rangni beradi. Yonma-yon qo'yganda ular bir xil kuchli ko'rinadi. Bir xil kattalikning bittadan ortiq heatmap ini chizganingizda, hammasida vmin va vmax ni bir xil qiymatga qotiring.

linewidths, square, cbar

python14 qator
fig, ax = plt.subplots(figsize=(8, 6))
sns.heatmap(
    matrix,
    cmap="mako",
    linewidths=0.5,          # cell lar orasidagi ingichka oraliqlar
    linecolor="white",
    square=True,             # cell lar to'rtburchak emas, kvadrat bo'ladi
    cbar=True,
    cbar_kws={"label": "passengers", "shrink": 0.8},
    ax=ax,
)
ax.set_title("Air passengers by month and year")
plt.tight_layout()
plt.show()

linewidths — kichik oraliqlar (0.5) cell larni ajratib, kichik matrix ni o'qishni osonlashtiradi. 200×200 matrix da uni 0 qiling: chiziqlar ma'lumotdan ko'ra ko'proq piksel egallab ketadi. square=True — 1:1 nisbatni majbur qiladi. Correlation matrix lari uchun to'g'ri (ular shakli bo'yicha ham, ma'nosi bo'yicha ham kvadrat); 12 row va 60 column bo'lganda esa noto'g'ri. cbar=False — colorbar ni olib tashlaydi. annot=True allaqachon har bir sonni chiqarayotgan bo'lsa yoki bir necha heatmap bitta bar ni baham ko'rishi kerak bo'lsa, mantiqli. cbar_kws — plt.colorbar ga uzatiladi: {"label": ...}, {"shrink": 0.5}, {"orientation": "horizontal"}, {"ticks": [-1, 0, 1]}. xticklabels / yticklabels — False ularni yashiradi, butun son n har n-chi yorliqni ko'rsatadi, ro'yxat esa o'zingiznikini beradi. Katta matrix lar uchun zarur.

Correlation matrix

Amaliyotda eng ko'p uchraydigan heatmap — bu correlation matrix: har bir sonli column boshqa har bir column bilan correlation qilinadi va kvadrat to'r ko'rinishida chiziladi. Yangi dataset ga birinchi nazar tashlashning standart usuli aynan shu.

Uni qurish

python6 qator
penguins = sns.load_dataset("penguins")

# penguins da species, island, sex bor - hammasi sonli emas
# pandas 2.x da numeric_only=True SHART
corr = penguins.corr(numeric_only=True)
print(corr.round(2))
Chiqish
                   bill_length_mm  ...  body_mass_g
bill_length_mm               1.00  ...         0.60
bill_depth_mm               -0.24  ...        -0.47
flipper_length_mm            0.66  ...         0.87
body_mass_g                  0.60  ...         1.00

[4 rows x 4 columns]

center=0 va diverging colormap bilan chizilgan correlation matrix. Qizil — musbat, ko‘k — manfiy, oqish — nolga yaqin. Diagonal doim 1.00 va hech qanday ma’lumot bermaydi.

penguins uchun natija (Pearson, ikki xonagacha yaxlitlangan):

bill_length bill_depth flipper_length body_mass
bill_length_mm 1.00 −0.24 0.66 0.60
bill_depth_mm −0.24 1.00 −0.58 −0.47
flipper_length_mm 0.66 −0.58 1.00 0.87
body_mass_g 0.60 −0.47 0.87 1.00

Bir nechta cell ni o'qib ko'raylik. Qanot uzunligi va tana massasi 0.87 da correlation qiladi — qanot uzunroq bo'lsa, qush og'irroq, va bu bog'liqlik kuchli. Tumshuq chuqurligi ikkalasi bilan ham manfiy correlation qiladi, −0.58 va −0.47 da, va bu quyida muhokama qilinadigan Simpson paradoksi tuzog'idir. Diagonalda hamma joyda 1.00 turadi, chunki har bir o'zgaruvchi o'zi bilan mukammal correlation qiladi, va matrix o'sha diagonalga nisbatan ko'zguga o'xshash simmetrikdir.

Standart plot

python18 qator
corr = penguins.corr(numeric_only=True)

fig, ax = plt.subplots(figsize=(7, 6))
sns.heatmap(
    corr,
    annot=True,
    fmt=".2f",
    cmap="coolwarm",     # diverging
    center=0,            # oq rang aniq r = 0 da turadi
    vmin=-1, vmax=1,     # qat'iy shkala, chartlar orasida taqqoslanadi
    square=True,
    linewidths=0.5,
    cbar_kws={"label": "Pearson r", "shrink": 0.8},
    ax=ax,
)
ax.set_title("Penguin measurements: correlation matrix")
plt.tight_layout()
plt.show()
YODLAB OLINGCorrelation heatmap retsepti: annot=True, fmt=".2f", cmap="coolwarm", center=0, vmin=-1, vmax=1, square=True. Bu oltita argument deyarli har doim to'g'ri va ularning yo'qligi deyarli har doim xato.

Method ni tanlash

corr_pearson = penguins.corr(numeric_only=True) # standart corr_spearman = penguins.corr(method="spearman", numeric_only=True) corr_kendall = penguins.corr(method="kendall", numeric_only=True)

DataFrame.corr yetishmayotgan qiymatlarni juftlik bo'yicha ishlaydi: har bir column juftligi uchun biri NaN bo'lgan row larni tashlab yuboradi. Shu sababli turli cell lar turli sondagi row lardan hisoblanishi mumkin — ma'lumotingizda ko'p va notekis yetishmovchilik bo'lsa, buni bilib qo'ygan ma'qul.

Bitta target ga nisbatan correlation

Modellashtirishda ko'pincha faqat bitta column qiziqtiradi. Uni saralab, bitta column li heatmap sifatida chizing:

python11 qator
corr = penguins.corr(numeric_only=True)
target = corr[["body_mass_g"]].drop(index="body_mass_g").sort_values(
    "body_mass_g", ascending=False
)

fig, ax = plt.subplots(figsize=(3, 4))
sns.heatmap(target, annot=True, fmt=".2f", cmap="coolwarm",
            center=0, vmin=-1, vmax=1, cbar=False, ax=ax)
ax.set_title("Correlation with body mass")
plt.tight_layout()
plt.show()

Ikki qavat kvadrat qavsga e'tibor bering: corr[["body_mass_g"]] bitta column li DataFrame qaytaradi (2 o'lchamli, ishlaydi), corr["body_mass_g"] esa Series qaytaradi (1 o'lchamli, xato beradi).

Kategorik o'zgaruvchilarni qo'shish

corr object va category column larni butunlay e'tiborsiz qoldiradi. Agar ular kerak bo'lsa, avval encode qiling — va halol encode qiling.

python11 qator
titanic = sns.load_dataset("titanic")

# ikkilik kategoriyalarni -> 0/1 ga o'tkazish o'rinli; natijadagi r point-biserial correlation bo'ladi
df = titanic[["survived", "pclass", "age", "fare", "sibsp", "parch"]].copy()
df["is_male"] = (titanic["sex"] == "male").astype(int)

corr = df.corr(numeric_only=True)
sns.heatmap(corr, annot=True, fmt=".2f", cmap="coolwarm",
            center=0, vmin=-1, vmax=1, square=True)
plt.tight_layout()
plt.show()
⚠️ Tartibsiz kategoriyaga label encoding qilmang

embark_town ni Cherbourg=0, Queenstown=1, Southampton=2 ga o'girib, so'ng correlation qilsangiz, son chiqadi, lekin bu son ma'nosiz: u butunlay siz tasodifan bergan alifbo tartibiga bog'liq. Ikkilik o'zgaruvchilar (0/1) esa yaxshi. Tartiblangan kategoriyalar (class 1 < 2 < 3) himoya qilinishi mumkin, ayniqsa Spearman bilan. Tartibsiz ko'p kategoriyali o'zgaruvchilarga one-hot encoding yoki Cramer V kabi boshqa statistika kerak bo'ladi.

Correlation matrix ni to'g'ri o'qish

Correlation koeffitsienti r — bu ikki o'zgaruvchi qanchalik birga harakatlanishini umumlashtiradigan, −1 va +1 orasidagi bitta son. Scatterplot ni bitta songa siqish juda ko'p narsani yo'qotadi, va nima yo'qotilganini aniq bilish — tahlil bilan xurofot orasidagi farqdir.

Pearson r faqat LINEAR bog'liqlikni o'lchaydi

Pearson r i — ikki o'zgaruvchining kovariatsiyasini ularning standart chetlanishlari ko'paytmasiga bo'lgani. U bitta savolga javob beradi: to'g'ri chiziq bu munosabatni qanchalik yaxshi tasvirlaydi? To'g'ri chiziq ilg'ay olmaydigan har qanday narsa uning uchun ko'rinmas.

python3 qator
x = np.linspace(-3, 3, 200)
y = x ** 2                       # mukammal parabola - tasodifiylik umuman yo'q
print(np.corrcoef(x, y)[0, 1])   # ~ 0.0
Chiqish
-1.9203276205777008e-16

Bu yerda y — x ning determinlashgan function i: x ni bilsangiz, y ni aniq bilasiz. Shunga qaramay r ≈ 0, chunki simmetrik parabola bo'ylab eng mos to'g'ri chiziq gorizontal bo'ladi. Nolga teng correlation "linear bog'liqlik yo'q" degani, hech qachon "bog'liqlik yo'q" degani emas.

⚠️ Scatterplot larga ham albatta qarang

Anscombe kvarteti — o'rtachalari, dispersiyalari va r = 0.816 qiymati bir xil, ammo shakllari butunlay boshqacha bo'lgan to'rtta dataset: biri linear, biri egri, biri bitta outlier li linear, yana birida esa butun correlation ni yolg'iz nuqta hosil qiladi. sns.load_dataset("anscombe") seaborn bilan birga keladi. Correlation heatmap — qaysi juftliklar scatterplot ga loyiq ekanini aniqlaydigan saralash vositasi, ko'z bilan ko'rishning o'rnini bosmaydi.

Correlation — sababiyat emas

Agar A va B correlation qilsa, kamida beshta izoh ochiq qoladi: A B ni keltirib chiqaradi; B A ni keltirib chiqaradi; uchinchi C o'zgaruvchisi ikkalasini ham keltirib chiqaradi (confounding); bog'liqlik namuna qanday tanlanganidan kelib chiqqan sun'iy natija (collider bias); yoki bu tasodif, va bir vaqtda ko'p juftlikni tekshirsangiz, tasodif ehtimoli oshadi. 10×10 matrix da 45 ta turli correlation bor, shuning uchun sof shovqinda ham bir nechta kattaroq qiymat paydo bo'ladi.

Penguins matrix i confounding ni to'g'ridan-to'g'ri ko'rsatadi. Butun dataset bo'yicha tumshuq chuqurligi qanot uzunligi bilan −0.58 correlation qiladi. Species bo'yicha ajratsangiz, ishora almashadi: har bir species ichida chuqurroq tumshuq uzunroq qanot bilan birga keladi. Umumiy manfiy ishora faqat shuning uchun mavjudki, Gentoo pingvinlari yirik tanali va sayoz tumshuqli bo'lib, diapazonning bir chekkasini egallaydi. Bu — Simpson paradoksi, va hech qanday heatmap sizni undan ogohlantira olmaydi — faqat guruhlovchi o'zgaruvchi bo'yicha shartlash yordam beradi.

python7 qator
for sp, g in penguins.groupby("species"):
    r = g["bill_depth_mm"].corr(g["flipper_length_mm"])
    print(sp, round(r, 2))
# Adelie     0.31
# Chinstrap  0.58
# Gentoo     0.71
# ... lekin umumiy holda: -0.58
Chiqish
Adelie 0.31
Chinstrap 0.58
Gentoo 0.71

Diagonal — shovqin

Asosiy diagonaldagi har bir cell ta'rifga ko'ra aynan 1.00 ga teng. U hech qanday ma'lumot bermaydi, ammo vmin=-1, vmax=1 shkalasida chartdagi eng to'yingan rang bo'lib, ko'zni darrov o'ziga tortadi. Uni mask qilish (keyingi bo'limga qarang) e'tiborni chalg'itadigan narsani olib tashlaydi va qolgan ranglarga shkalaning ko'proq qismidan foydalanish imkonini beradi.

Matrix simmetrik — yarmi ortiqcha

corr(A, B) = corr(B, A), shuning uchun yuqori uchburchak pastkisining ko'zgu aksi. k o'zgaruvchili matrix k² ta cell ko'rsatadi, lekin faqat k(k−1)/2 ta turli faktni saqlaydi. k = 10 uchun bu 100 ta cell da 45 ta ma'lumot — 55% vizual ortiqchalik. Bitta uchburchakni mask qilishning butun sababi ana shu.

Pearson, Spearman va Kendall

Method Nimani o'lchaydi Qachon ishlatiladi Kuchsiz tomoni
"pearson" (standart) Xom qiymatlar bo'yicha linear bog'liqlik Taxminan linear, taxminan simmetrik, uzluksiz ma'lumot Outlier larga sezgir; egri chiziqlarni ko'rmaydi
"spearman" Rank lar bo'yicha monotonic bog'liqlik Qiyshaygan ma'lumot, outlier lar, ordinal o'zgaruvchilar, egri lekin monotonic munosabatlar Qiymatlar orasidagi masofalar kattaligini tashlab yuboradi
"kendall" Mos va nomos juftliklar Kichik namunalar, ko'p teng qiymatlar; ehtiyotkorroq baho Katta ma'lumotda sekin (sodda shaklda O(n²)); qiymatlari Spearman nikidan kichikroq chiqadi

Spearman — bu rank larga qo'llangan Pearson. Rank lash masofalarni yo'q qilgani uchun bitta ekstremal outlier endi hukmronlik qila olmaydi va har qanday monotonic munosabat — jumladan y = x³ yoki y = ex — aynan 1.0 chiqadi.

python5 qator
x = np.arange(1, 101)
y = np.exp(x / 20)                      # monotonic, lekin kuchli egri
s = pd.Series(x); t = pd.Series(y)
print(s.corr(t))                        # pearson  ~ 0.79
print(s.corr(t, method="spearman"))     # spearman = 1.00
Chiqish
0.8581420519497872
0.9999999999999999
💡 Ikkalasini yonma-yon taqqoslang

Pearson va Spearman matrix larini ikkita panel qilib chizing. Ular sezilarli farq qiladigan juftliklar — aynan outlier, qiyshiqlik yoki egrilik bor juftliklar. Bu tez va bepul diagnostika.

python9 qator
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
for ax, method in zip(axes, ["pearson", "spearman"]):
    c = penguins.corr(method=method, numeric_only=True)
    sns.heatmap(c, annot=True, fmt=".2f", cmap="coolwarm",
                center=0, vmin=-1, vmax=1, square=True,
                cbar=False, ax=ax)
    ax.set_title(method.capitalize())
plt.tight_layout()
plt.show()

Qanchasi katta hisoblanadi? Taxminiy kattalik jadvali

|r|Odatiy nomr² (tushuntirilgan dispersiya)

0.0 – 0.3kuchsiz / ahamiyatsiz0 – 9% 0.3 – 0.7o'rtacha9 – 49% 0.7 – 0.9kuchli49 – 81% 0.9 – 1.0juda kuchli (leakage yoki takrorlanishni tekshiring)81 – 100%

⚠️ Bu chegaralar — kelishuv, qonun emas

Ular sohaga qarab o'zgaradigan shartli kesim nuqtalari. Fizikada r = 0.9 asbob buzilganini bildirishi mumkin; psixologiya yoki iqtisodda esa 0.3 bosh xulosa bo'lishi mumkin. Namuna hajmi ham muhim: n = 500 da r = 0.12 "statistik ahamiyatli", lekin amalda ma'nosiz; n = 10 da esa r = 0.6 shovqin bemalol hosil qila oladigan qiymat. n ni ayting, scatterplot ni ko'rsating va bu nomlarni hukm emas, shunchaki atama sifatida qabul qiling.

r ni kvadratga oshirish halolroq umumlashma beradi: r² — bir o'zgaruvchidagi dispersiyaning ikkinchisi tomonidan linear tushuntiriladigan ulushi. r = 0.5 "yarmi" degandek eshitiladi, lekin u dispersiyaning atigi 25% ini tushuntiradi.

Ishora va kattalik bir-biriga bog'liq emas. −0.85 — +0.30 dan kuchliroq munosabat. Talabalar odatda correlation larni absolyut qiymat bo'yicha emas, ishorali qiymat bo'yicha saralab yuboradi; saralaganda corr.abs() dan foydalaning.

Juda yuqori correlation — mukofot emas, ogohlantirish

Ikki feature orasidagi |r| taxminan 0.95 dan oshsa, bu odatda uchta narsadan birini anglatadi: column lar bir-birining nusxasi yoki birlik o'zgartirilgani (bo'y santimetrda va dyuymda); biri target ni oshkor qiladi (titanic["alive"] va titanic["survived"] — bir faktning ikki marta yozilgani); yoki ular deyarli kollinear bo'lib, linear model koeffitsientlarini beqaror qiladi. Correlation heatmap lari feature selection da aynan shularni topib, olib tashlash uchun ishlatiladi.

Yuqori uchburchakni mask qilish

mask ma'lumot bilan bir xil shakldagi boolean array ni qabul qiladi. Mask True bo'lgan joyda cell bo'sh qoldiriladi. Correlation matrix ning yarmi ortiqcha bo'lgani uchun bitta uchburchakni mask qilish ma'lumot zichligini taxminan ikki barobar oshiradi.

python16 qator
corr = penguins.corr(numeric_only=True)

# np.triu = yuqori uchburchak; k=1 diagonalni ko'rinadigan qoldiradi
mask = np.triu(np.ones_like(corr, dtype=bool), k=1)

fig, ax = plt.subplots(figsize=(7, 6))
sns.heatmap(
    corr, mask=mask,
    annot=True, fmt=".2f",
    cmap="coolwarm", center=0, vmin=-1, vmax=1,
    square=True, linewidths=0.5,
    cbar_kws={"shrink": 0.75},
    ax=ax,
)
plt.tight_layout()
plt.show()

Correlation matrix simmetrik, ya’ni uning yarmi takroriy. Yuqori uchburchakni yashirish takrorni ham, foydasiz diagonalni ham olib tashlaydi.

k siljishi diagonal saqlanadimi yoki yo'qmi shuni belgilaydi:

Ifoda Nimani yashiradi Diagonal
np.triu(ones, k=1) qat'iy yuqori uchburchak ko'rinadi (barchasi 1.00)
np.triu(ones, k=0) yuqori uchburchak + diagonal yashirin — odatda aynan shu kerak
np.tril(ones, k=0) pastki uchburchak + diagonal yashirin, yuqori yarmi qoladi

np.ones_like(corr, dtype=bool) bir xil shakldagi True array ini quradi; np.triu tanlangan diagonaldan pastdagi hamma narsani nolga aylantiradi va faqat siz bo'sh qoldirmoqchi bo'lgan joyda True qoldiradi. Mask ni corr ning o'zidan qurish shakllar mos kelishini kafolatlaydi.

💡 Bo'sh row va column ni qirqib tashlang

Mask qilingandan keyin birinchi row va oxirgi column butunlay bo'sh qoladi. Rasm ixchamroq bo'lishi uchun ularni olib tashlang: corr.iloc[1:, :-1] va mask ni ham o'sha qirqilgan frame dan quring.

Mask — faqat uchburchak uchun mo'ljallangan hiyla emas, umumiy mexanizm. Har qanday boolean shart ishlaydi — masalan, e'tiborga arzimaydigan darajada kuchsiz correlation larni yashirish:

python5 qator
# faqat |r| >= 0.3 ni va faqat pastki uchburchakni ko'rsatamiz
weak = corr.abs() < 0.3
upper = np.triu(np.ones_like(corr, dtype=bool), k=0)
sns.heatmap(corr, mask=(weak | upper), annot=True, fmt=".2f",
            cmap="coolwarm", center=0, vmin=-1, vmax=1, square=True)

Bu yetishmayotgan ma'lumotni ko'rsatishning ham standart usuli: mask=df.isna() NaN cell larni tasodifiy rang olishiga yo'l qo'ymay, bo'sh qoldiradi.

Ma'lumotni matrix shakliga keltirish

Heatmap ishlashdan bosh tortganda qayta o'qish kerak bo'lgan bo'lim — aynan shu. To'rtta vosita deyarli barcha holatni qoplaydi.

1. df.pivot() — faqat shaklni o'zgartiradi, aggregation yo'q

python4 qator
flights = sns.load_dataset("flights")

matrix = flights.pivot(index="month", columns="year", values="passengers")
print(matrix.shape)   # (12, 12)
Chiqish
(12, 12)

Uni shunday o'qing: index row larga (y o'qi) aylanadi, columns column larga (x o'qi) aylanadi, values esa cell larni to'ldiradi. pivot hech qanday arifmetika bajarmaydi — u faqat qayta joylashtiradi. Shuning uchun har bir (index, columns) juftligi aynan bir marta uchrashi shart. Agar juftlik takrorlansa, ValueError: Index contains duplicate entries, cannot reshape olasiz — bu pandas ning "takrorlangan qiymatlardan qaysi birini cell ga qo'yishni bilmayman" degani. Bu sizga pivot_table ga o'tish kerakligini bildiruvchi signal.

📌 pandas 2.0 dan boshlab keyword argumentlar

DataFrame.pivot endi index, columns va values ni faqat keyword argument sifatida qabul qiladi. Eski pozitsion shakl flights.pivot("month", "year", "passengers") 1.5 da eskirgan deb belgilangan va 2.0 da olib tashlangan — eski qo'llanmalarning ko'pi shu yerda ishlamay qoladi.

2. pd.pivot_table() — shaklni o'zgartiradi va aggregation qiladi

Bir nechta row bitta cell ga tushsa, ularni qanday birlashtirishni aytishingiz kerak. Buni aggfunc qiladi.

python21 qator
titanic = sns.load_dataset("titanic")

# class va sex bo'yicha o'rtacha omon qolish darajasi
rates = pd.pivot_table(
    titanic,
    index="class",
    columns="sex",
    values="survived",
    aggfunc="mean",         # standart qiymati "mean"
)
print(rates.round(3))
#         female   male
# First    0.968  0.369
# Second   0.921  0.157
# Third    0.500  0.135

sns.heatmap(rates, annot=True, fmt=".1%", cmap="RdYlBu",
            vmin=0, vmax=1, linewidths=0.5,
            cbar_kws={"label": "survival rate"})
plt.tight_layout()
plt.show()
Chiqish
sex     female   male
class                
First    0.968  0.369
Second   0.921  0.157
Third    0.500  0.135

Foydali pivot_table argumentlari:

Argument Ta'siri
aggfunc="mean" "mean", "median", "sum", "count", "size", "std" dan biri, yoki chaqiriladigan function / ularning ro'yxati
fill_value=0 Bo'sh cell larni (hech qachon uchramagan kombinatsiyalarni) NaN o'rniga qiymat bilan to'ldiradi
dropna=True To'liq NaN bo'lgan column larni olib tashlaydi
margins=True Jamini ko'rsatuvchi "All" row va column qo'shadi — chizishdan oldin olib tashlang, aks holda u rang shkalasini egallab oladi
observed=True Categorical column larda kuzatilmagan kategoriya kombinatsiyalarini o'tkazib yuboradi
python7 qator
# tips: kun va guruh hajmi bo'yicha o'rtacha hisob, yo'q kombinatsiyalar 0 sifatida
tips = sns.load_dataset("tips")
m = pd.pivot_table(tips, index="day", columns="size",
                   values="total_bill", aggfunc="mean", fill_value=0)
sns.heatmap(m, annot=True, fmt=".1f", cmap="rocket_r", linewidths=0.5)
plt.tight_layout()
plt.show()
⚠️ `fill_value=0` — bu dunyo haqidagi da'vo

0 bilan to'ldirish "bu birikma uchragan va uning qiymati nol bo'lgan" deydi. NaN qoldirish esa "bu yerda kuzatuvimiz yo'q" deydi. Sanoqlar matrix i uchun 0 odatda to'g'ri; o'rtacha narxlar matrix i uchun esa bu yolg'on bo'lib, bo'sh cell ni chartdagi eng arzon cell qilib ko'rsatadi. NaN ni qoldirib, cell bo'sh chizilishiga yo'l qo'ygan ma'qul.

3. pd.crosstab() — ikkita kategorik o'zgaruvchining sanoqlari va ulushlari

crosstab ikkita Series ni oladi (DataFrame va column nomlarini emas) va sanoqlardan iborat contingency table qaytaradi.

python11 qator
# xom sanoqlar
counts = pd.crosstab(titanic["class"], titanic["embark_town"])
print(counts)
#         Cherbourg  Queenstown  Southampton
# First          85           2          127
# Second         17           3          164
# Third          66          72          353

sns.heatmap(counts, annot=True, fmt="d", cmap="Blues", linewidths=0.5)
plt.tight_layout()
plt.show()
Chiqish
embark_town  Cherbourg  Queenstown  Southampton
class                                          
First               85           2          127
Second              17           3          164
Third               66          72          353

normalize sanoqlarni ulushlarga aylantiradi va tahliliy qiymatning katta qismi aynan shu yerda:

normalize= Har bir cell nimaga aylanadi Nima bo'yicha yig'indisi 1 bo'ladi
"index" o'z row i ichidagi ulush har bir row
"columns" o'z column i ichidagi ulush har bir column
"all" / True umumiy jamidagi ulush butun jadval
python5 qator
props = pd.crosstab(titanic["class"], titanic["embark_town"], normalize="index")
sns.heatmap(props, annot=True, fmt=".1%", cmap="Blues",
            vmin=0, vmax=1, linewidths=0.5)
plt.tight_layout()
plt.show()
⚠️ Xom sanoqlar va ulushlar turli savollarga javob beradi

Sanoqlar heatmap ida qaysi kategoriya shunchaki eng ko'p uchrasa, o'sha hukmronlik qiladi — Third class × Southampton yorqin ko'rinadi, chunki o'sha cell da 353 kishi bor, bog'liqlik qiziqarli bo'lgani uchun emas. Row bo'yicha normalization "shu class berilgan bo'lsa, ular qayerdan chiqqan?" deb so'raydi; column bo'yicha normalization esa "shu port berilgan bo'lsa, ular qaysi class da edi?" deb so'raydi. Bular javoblari ham har xil bo'lgan turli savollar va ularning hech biri "yagona to'g'ri" emas. Sarlavha yoki izohda qaysi normalization ni ishlatganingizni doim yozib qo'ying.

crosstab uchinchi o'zgaruvchini aggregation ham qila oladi, bu esa uni pivot_table ga ixcham muqobil qiladi:

python2 qator
pd.crosstab(titanic["class"], titanic["sex"],
            values=titanic["age"], aggfunc="mean").round(1)
  1. df.corr() — maxsus holat

Correlation matrix allaqachon kvadrat va ikkala o'q bo'yicha yorliqlangan, shuning uchun shaklni o'zgartirish shart emas. U ham qolgan uchtasi kabi matrix hosil qiluvchi function.

Teskari yo'nalish: melt va stack

Matrix dan long shaklga qaytish ham gohida kerak bo'ladi — scatterplot ga uzatish yoki eng kuchli juftliklarning saralangan jadvalini tuzish uchun.

python9 qator
long_again = matrix.reset_index().melt(
    id_vars="month", var_name="year", value_name="passengers"
)

# eng ko'p correlation qilgan juftliklar, o'z-o'ziga va takrorlarga tegmasdan
corr = penguins.corr(numeric_only=True)
mask = np.triu(np.ones_like(corr, dtype=bool), k=0)
pairs = corr.mask(mask).stack().sort_values(key=abs, ascending=False)
print(pairs.head())
Chiqish
body_mass_g        flipper_length_mm    0.871202
flipper_length_mm  bill_length_mm       0.656181
body_mass_g        bill_length_mm       0.595110
flipper_length_mm  bill_depth_mm       -0.583851
body_mass_g        bill_depth_mm       -0.471916
dtype: float64
XULOSAHar bir cell ga allaqachon bitta qiymat → pivot. Har bir cell ga ko'p qiymat → pivot_table(aggfunc=...). Ikkita kategorik o'zgaruvchi va sanoqlar kerak → crosstab. Sonli column larni bir-biriga nisbatan → corr(numeric_only=True).

clustermap

sns.clustermap() — bu heatmap ustiga ierarxik klasterlash qo'shilgani. U row lar orasidagi va column lar orasidagi masofalarni hisoblaydi, dendrogram lar quradi va so'ng matrix ni qayta tartiblaydi, shunda o'xshash row lar yonma-yon, o'xshash column lar ham yonma-yon turadi. Ixtiyoriy alifbo tartibi tufayli sochilib ketgan blokli struktura yaxlit dog'lar sifatida ko'rinadigan bo'ladi.

python10 qator
corr = penguins.corr(numeric_only=True)

g = sns.clustermap(
    corr,
    cmap="coolwarm", center=0, vmin=-1, vmax=1,
    annot=True, fmt=".2f",
    figsize=(8, 8),
    linewidths=0.5,
)
plt.show()

clustermap o‘xshash o‘zgaruvchilar yonma-yon tursin deb row va column larni qayta tartiblaydi va shu tartibni hosil qilgan dendrogram ni chizadi. E’tibor bering: o‘qlar tartibi siz bergan tartib emas.

heatmap dan ikkita struktura farqi:

  • U figure-level. U o'z figure ini yaratadi va unga egalik qiladi, shuning uchun ax= ni qabul qilmaydi va uni plt.subplots() to'ri ichiga joylashtirib bo'lmaydi. U ClusterGrid qaytaradi, uning qismlariga g.ax_heatmap, g.ax_row_dendrogram, g.ax_col_dendrogram va g.ax_cbar orqali murojaat qilasiz.
  • U NaN bilan ishlay olmaydi. Klasterlash bosqichi ValueError: The condensed distance matrix must contain only finite values xatosini beradi. Avval NaN larni tashlang yoki to'ldiring.

Muhim argumentlar

Argument Ma'nosi
method="average" Linkage: "single", "complete", "average", "ward". "ward" ixcham va muvozanatli klasterlar beradi hamda yaxshi standart tanlov (u Evklid metrikasini talab qiladi).
metric="euclidean" Masofa o'lchovi: "euclidean", "correlation", "cityblock", "cosine".
z_score=0 / 1 Klasterlashdan oldin row larni (0) yoki column larni (1) o'rtachasi 0, standart chetlanishi 1 bo'ladigan qilib standartlashtiradi. O'zgaruvchilar turli birlikda bo'lsa, zarur.
standard_scale=0 / 1 Buning o'rniga row/column larni 0–1 oralig'iga masshtablaydi.
row_cluster, col_cluster Birortasini False qilsangiz, o'sha o'q asl tartibida qoladi.
row_colors, col_colors O'q yonida chiziq sifatida chiziladigan ranglar Series i (yoki DataFrame i) — klasterlar ma'lum yorliq bilan mos kelishini tekshirishning standart usuli.
dendrogram_ratio Figure ning dendrogram larga ajratilgan ulushi, masalan (0.15, 0.15).
cbar_pos Colorbar joylashuvi (left, bottom, width, height) ko'rinishida; None uni olib tashlaydi.

Row ranglari bilan to'liq misol

python23 qator
penguins = sns.load_dataset("penguins").dropna()

# sonli o'lchovlar, har bir qushga bitta row
X = penguins[["bill_length_mm", "bill_depth_mm",
              "flipper_length_mm", "body_mass_g"]]

# klasterlarni tekshirish uchun species ni rangli chiziqqa moslaymiz
species = penguins["species"]
lut = dict(zip(species.unique(), sns.color_palette("Set2", 3)))
row_colors = species.map(lut)

g = sns.clustermap(
    X,
    z_score=1,              # har bir column ni standartlashtiramiz - birliklar juda farq qiladi
    cmap="vlag", center=0,
    method="ward", metric="euclidean",
    row_colors=row_colors,
    yticklabels=False,      # 333 ta row - yorliqlar o'qib bo'lmas holga keladi
    figsize=(8, 10),
    dendrogram_ratio=(0.12, 0.15),
)
g.ax_heatmap.set_xlabel("")
plt.show()

z_score=1 bo'lmasa bu plot ma'nosiz bo'lar edi: tana massasi minglab grammda o'lchanadi, tumshuq chuqurligi esa taxminan 15 mm, shuning uchun Evklid masofasi deyarli butunlay tana massasidan iborat bo'lib qolar edi. Standartlashtirish har bir column ni teng holatga keltiradi. Shundan keyin species rangli chizig'i asosiy savolga javob beradi — o'lchovlar bo'yicha olingan klasterlar species yorliqlarini tiklaydimi? Asosan ha, faqat Adelie va Chinstrap bir-birining ustiga tushadi.

⚠️ Chiqish tartibi kirish tartibi EMAS

Clustermap ning butun mohiyati shu, va ayni paytda bu uning eng ko'p uchraydigan noto'g'ri o'qilishi. Chizilgan figure dagi 1-row sizning DataFrame ingizdagi 1-row emas. Clustermap ni xuddi row lar mos kelayotgandek qilib, o'sha ma'lumotning heatmap i bilan yonma-yon taqqoslamang. Haqiqiy tartibni g.dendrogram_row.reordered_ind va g.dendrogram_col.reordered_ind orqali tiklang — ular asl frame dagi butun sonli pozitsiyalarni beradi.

python6 qator
order = g.dendrogram_row.reordered_ind
print(X.index[order][:10])          # chizilgan tartibdagi yorliqlar, yuqoridan pastga

# daraxtni k ta guruhga kesamiz
from scipy.cluster.hierarchy import fcluster
labels = fcluster(g.dendrogram_row.linkage, t=3, criterion="maxclust")
Chiqish
Index([226, 312, 238, 270, 252, 342, 308, 338, 241, 314], dtype='int64')

Qaysi birini qachon ishlatish kerak

heatmap ni qachonclustermap ni qachon

O'q tartibi ma'noli bo'lsa (oylar, yillar, tartiblangan class lar)O'q tartibi ixtiyoriy bo'lsa va strukturani topmoqchi bo'lsangiz Plot subplot to'ri ichida kerak bo'lsaMustaqil figure yetarli bo'lsa Ma'lumotda NaN bo'lsaMa'lumot to'liq bo'lsa Joylashuv ustidan maksimal nazorat kerak bo'lsaGuruhlash va dendrogram larni tekinga olmoqchi bo'lsangiz

Flights matrix ini klasterlash xato bo'lar edi: oylar va yillar tabiiy tartibga ega, va o'xshash oylarni yonma-yon qo'yish uchun ularni aralashtirib yuborish chartni chizishga arzigulik qiladigan mavsumiy o'qishni yo'q qiladi.

Ehtiyot bo'ling

1. pandas 2.x da numeric_only siz df.corr()

python4 qator
penguins = sns.load_dataset("penguins")

# corr = penguins.corr()                    # pandas 2.x da ValueError
corr = penguins.corr(numeric_only=True)     # to'g'ri

pandas 1.x da corr() sonli bo'lmagan column larni jimgina tashlab yuborar edi. pandas 1.5 buni FutureWarning bilan eskirgan deb belgiladi; pandas 2.0 esa standart qiymatni numeric_only=False ga o'zgartirdi, shuning uchun penguins.corr() endi matnli species column ini ham correlation qilishga urinadi va ValueError: could not convert string to float: 'Adelie' beradi. Xuddi shu narsa aralash DataFrame lardagi .mean(), .sum(), .median() va shu kabilarga ham taalluqli. 2023 yildan oldin yozilgan har qanday qo'llanma shu muammoga duch keladi.

Aniqroq muqobil variant, u nimani nazarda tutganingizni hujjatlashtirgani uchun ehtimol yaxshiroq amaliyot:

corr = penguins.select_dtypes(include="number").corr()

  1. Diverging map da center=0 ni unutish

Diverging colormap "o'rtadagi rang neytral qiymat" deb va'da beradi. Agar correlation laringiz −0.1 dan +0.9 gacha bo'lsa va center=0 ni qo'ymasangiz, seaborn oq rangni +0.4 ga qo'yadi, natijada haqiqatan musbat bo'lgan 0.2 ko'k, ya'ni "manfiy" diapazonda chiziladi. Chart ma'lumotga zid keladi. Correlation lar bilan ishlaganda doim center=0 ni, imkoni bo'lsa vmin=-1, vmax=1 ni ham qo'ying.

3. Katta matrix da annot=True

O'n ikkita o'zgaruvchi 144 ta cell beradi va matn allaqachon siqilib qoladi; o'ttizta o'zgaruvchi esa 900 ta o'qib bo'lmaydigan dog' beradi. Amaliy qoidalar: taxminan 15×15 gacha annotation qo'ying, undan kattasida annotation ni olib tashlab, ishni rangga qoldiring, hamda standart ".2g" o'rniga fmt=".2f" ni ishlating, shunda barcha sonlar bir xil kenglikda bo'lib, to'r vizual tekis qoladi.

python6 qator
# katta matrix: annotation yo'q, yorliqlar siyrak, cell chegaralari yo'q
fig, ax = plt.subplots(figsize=(12, 10))
sns.heatmap(big_corr, cmap="coolwarm", center=0, vmin=-1, vmax=1,
            annot=False, linewidths=0, square=True,
            xticklabels=2, yticklabels=2, ax=ax)   # har 2-chi yorliq
plt.tight_layout()
  1. Bir nechta chartda vmin/vmax ning yo'qligi

Bu parametrlar bo'limida allaqachon aytilgan, ammo takrorlashga arziydi, chunki u juda tez-tez code review dan o'tib ketadi: qat'iy chegarasiz har bir subplot o'ziga xos shkala o'ylab topadi va umumiy colorbar yolg'onga aylanadi. Har qanday facet li yoki "oldin/keyin" taqqoslashda vmin va vmax ni qotirish shart.

5. O'zgarmas column ning correlation i NaN bo'ladi

python6 qator
df = pd.DataFrame({"a": [1, 2, 3, 4], "b": [5, 5, 5, 5], "c": [2, 4, 6, 8]})
print(df.corr())
#      a   b    c
# a  1.0 NaN  1.0
# b  NaN NaN  NaN
# c  1.0 NaN  1.0
Chiqish
     a   b    c
a  1.0 NaN  1.0
b  NaN NaN  NaN
c  1.0 NaN  1.0

Pearson r i har bir o'zgaruvchining standart chetlanishiga bo'ladi. O'zgarmas column da sd = 0, ya'ni hisob 0/0 ga aylanadi. Natijada heatmap ingiz bo'ylab bo'sh chiziq bo'lib chiziladigan NaN row va column paydo bo'ladi. Yechim — correlation dan oldin dispersiyasi nol bo'lgan column larni olib tashlash; ular baribir hech qanday model uchun ma'lumot bermaydi:

num = df.select_dtypes("number") num = num.loc[:, num.std(numeric_only=True) > 0] corr = num.corr()

Xuddi shu narsa deyarli o'zgarmas column larda ham uchraydi (bitta qiymat va bir nechta istisno), u yerda r aniqlangan bo'ladi, lekin nihoyatda beqaror.

6. Sanoqlar va normalize qilingan ulushlar

Crosstab ogohlantirishini umumiy qoida sifatida takrorlaymiz: xom sanoqlar heatmap i hajm qayerdaligini ko'rsatadi, effekt qayerdaligini emas. Kam uchraydigan kategoriyalar eng kuchli signalni tashishi va shunga qaramay ko'rinmas bo'lib qolishi mumkin. O'quvchiga "qancha" kerakmi yoki "qaysi ulush" kerakmi — buni ongli ravishda hal qiling va colorbar ni shunga mos yorliqlang.

7. Clustermap qayta tartiblaydi — o'q tartibi sizniki emas

Yuqorida ko'rib chiqildi; bu yerda tekshiruv ro'yxatiga tegishli bo'lgani uchun keltirilgan. Agar clustermap ni tashqi yorliqlarni pozitsiya bo'yicha biriktirib annotation qilsangiz, noto'g'ri yorliqlarni noto'g'ri row larga yopishtirasiz.

8. Yuqori va quyi row lar yarmigacha qirqilishi

Matplotlib 3.1.0 va 3.1.1 versiyalarida heatmap ning birinchi va oxirgi row larini yarim balandlikka qirqib qo'yadigan regressiya bo'lgan. O'sha davrning eng ko'p so'ralgan seaborn savoli aynan shu. Zamonaviy matplotlib da tuzatilgan, ammo vaqtinchalik yechim hamon hamma joyda uchraydi:

python5 qator
ax = sns.heatmap(corr, annot=True, fmt=".2f", cmap="coolwarm", center=0)

# faqat matplotlib 3.1.0 / 3.1.1 da kerak
bottom, top = ax.get_ylim()
ax.set_ylim(bottom + 0.5, top - 0.5)

Bunga bog'liq va hozir ham dolzarb muammo — yorliqlarning kanvasdan chiqib ketishi. Har doim plt.tight_layout() bilan yakunlang va uzun tick yorliqlarini burang:

python3 qator
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha="right")
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)
plt.tight_layout()
  1. sns.load_dataset() ga internet kerak

load_dataset har chaqiruvda seaborn-data GitHub repozitoriyasidan CSV yuklab oladi, agar u cache da bo'lmasa. Offline holatda — imtihon xonasida, cheklangan kompyuterda, proxy orqasida — u URLError yoki timeout beradi. Ikkita yechim:

python6 qator
# A) seaborn ni CSV lar joylashgan lokal papkaga yo'naltiring
#    https://github.com/mwaskom/seaborn-data ni bir marta clone qiling, so'ng:
flights = sns.load_dataset("flights", data_home="C:/data/seaborn-data", cache=True)

# B) seaborn ni umuman chetlab, CSV ni o'zingiz o'qing
flights = pd.read_csv("C:/data/seaborn-data/flights.csv")

Standart holatda seaborn yuklamalarni ~/seaborn-data ostida cache qiladi, shuning uchun dataset bir marta kompyuterga yuklab olingach, u offline ham ishlayveradi. O'qitish uchun kerak bo'lgan bir nechta dataset ni oldindan yuklab qo'yish o'sha ikki daqiqaga arziydi.

10. Kategoriya tartibi siz aytmasangiz alifbo bo'yicha bo'ladi

Pivot dan keyin index va column lar saralanadi — shuning uchun flights.pivot(...) tasodifan kalendar tartibida chiqadi (uning month column i tartiblangan Categorical), oddiy matn column i esa April, August, December tartibida chiqar edi. Tartib muhim bo'lsa, aniq reindex qiling:

order = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] matrix = matrix.reindex(order)

  1. Ko'rinmayotgan cell lar nolga teng emas

Pivot dagi bo'sh birikma NaN ga aylanadi va bo'sh chiziladi (yoki axes ning facecolor i qanday bo'lsa, shunday). O'quvchi bo'shlikni bemalol nol deb tushunishi mumkin. Buni izohda ayting yoki nol haqiqatan to'g'ri javob bo'lgan holatda fill_value ni ongli ravishda ishlating.

Amaliy mashqlar

python43 qator
# ---------------------------------------------------------------
# 18-bob mashqlari - heatmap, correlation, clustermap
# sns.load_dataset(...) bilan yuklang. Har bir plot ostida izohda
# savolga javob bering: chart aslida nimani ko'rsatyapti?
# ---------------------------------------------------------------

# 1. flights: month x year ga pivot qiling va cmap="viridis" hamda
#    yorliqlangan colorbar bilan klassik heatmap chizing. So'ng uni
#    annot=True, fmt="d" bilan qayta chizing. Qaysi versiya osonroq o'qiladi va nega?

# 2. penguins: numeric_only=True bilan Pearson correlation matrix ini
#    quring. Uni annot=True, fmt=".2f", cmap="coolwarm", center=0,
#    vmin=-1, vmax=1, square=True bilan chizing.
#    Eng kuchli musbat va eng kuchli manfiy juftlikni ayting.

# 3. 2-mashqni yuqori uchburchak VA diagonal mask qilingan holda
#    takrorlang (np.triu, k=0). Nechta turli correlation qolganini
#    sanang va u k*(k-1)/2 ga tengligini tekshiring.

# 4. penguins: Pearson va Spearman matrix larini bitta figure ning ikki
#    paneli sifatida umumiy vmin/vmax bilan chizing. Qaysi juftlik eng ko'p
#    o'zgaradi va o'sha juftlikning scatterplot i qanday ko'rinadi?

# 5. titanic: pd.pivot_table bilan class va sex bo'yicha o'rtacha omon
#    qolishni oling, so'ng fmt=".1%", vmin=0, vmax=1 bilan heatmap chizing.
#    Chart class va sex haqida nimani ko'rsatishini bitta jumlada yozing.

# 6. titanic: class va embark_town uchun pd.crosstab. Uchta heatmap chizing -
#    xom sanoqlar, normalize="index", normalize="columns". Har biri qanday
#    turli savolga javob berishini izohda tushuntiring.

# 7. tips: kun va vaqt bo'yicha o'rtacha tip foizining (tip / total_bill)
#    pivot_table i. Bo'sh cell larni aniq hal qiling va fill_value=0 ni
#    NaN qoldirishga nisbatan tanlaganingizni asoslang.

# 8. penguins: to'rtta sonli o'lchov bo'yicha clustermap, z_score=1,
#    method="ward" va species uchun row_colors chizig'i bilan.
#    So'ng g.dendrogram_row.reordered_ind ni chiqaring va chizilgan row
#    tartibi DataFrame tartibidan farq qilishiga ishonch hosil qiling.

# Bonus: x = linspace(-3, 3, 200), y = x**2 quring, Pearson va Spearman
#        correlation larini chiqaring, so'ng juftlikni scatterplot qiling.
#        Nega ikkala koeffitsient ham aniq determinlashgan munosabatni sezmaydi?

Intervyu savollari

S: Nega tidy DataFrame ni to'g'ridan-to'g'ri sns.heatmap() ga uzatib bo'lmaydi?

Chunki heatmap — statistik function emas, matrix function i. Unda x, y yoki hue parametrlari yo'q va u hech narsani guruhlamaydi. U df.index ni y o'qi, df.columns ni x o'qi va df.values ni ranglar sifatida o'qiydi, shuning uchun ma'lumot allaqachon 2 o'lchamli to'r bo'lishi kerak. Unga pivot, pivot_table, crosstab yoki corr orqali erishasiz.

S: df.pivot() va pd.pivot_table() orasidagi farq nima?

pivot faqat shaklni o'zgartiradi: u har bir (index, columns) juftligi uchun aynan bitta qiymat talab qiladi, aks holda ValueError: Index contains duplicate entries beradi. pivot_table esa takrorlarni aggfunc (standart holatda mean) yordamida aggregation qiladi va qo'shimcha ravishda fill_value, margins hamda bir nechta aggregation function ini qo'llab-quvvatlaydi. Agar pivot takrorlarda xato bersa, o'sha xato sizga ularni qanday birlashtirishni hal qilish kerakligini aytayotgan bo'ladi.

S: Correlation 0 ga teng — bu ikki o'zgaruvchi bog'liq emas degani-mi?

Yo'q. Pearson r i faqat linear bog'liqlikni o'lchaydi. Simmetrik diapazonda y = x² r ≈ 0 beradi, garchi y x ning determinlashgan function i bo'lsa ham. Nolga teng correlation linear munosabat yo'qligini bildiradi; egri yoki shartli munosabatlar haqida hech narsa demaydi. Xulosa chiqarishdan oldin juftlikni scatterplot qiling va munosabat monotonic lekin egri bo'lishi mumkin bo'lsa, Spearman ni ko'rib chiqing.

S: Pearson o'rniga Spearman ni qachon ishlatasiz?

Munosabat monotonic bo'lib, to'g'ri chiziqli bo'lmaganda; ma'lumot qiyshaygan yoki outlier larga boy bo'lganda; yoki o'zgaruvchi interval emas, ordinal bo'lganda. Spearman rank larni correlation qiladi, shuning uchun u har qanday monotonic o'zgartirishga nisbatan invariant va bitta ekstremal nuqtaga ancha kam sezgir. Evaziga u qiymatlar orasidagi masofalar kattaligini tashlab yuboradi. Pearson va Spearman matrix larini taqqoslash — outlier yoki egrilik ta'sir qilgan juftliklarni topishning arzon usuli.

S: Nega correlation heatmap ining yuqori uchburchagini mask qilish kerak?

Chunki corr(A, B) = corr(B, A), ya'ni matrix simmetrik: k o'zgaruvchili matrix k² ta cell chizadi, lekin faqat k(k−1)/2 ta turli son saqlaydi. Diagonal esa yana k ta sof shovqinli cell qo'shadi — doim 1.00, doim chartdagi eng to'yingan rang. np.triu(np.ones_like(corr, dtype=bool), k=0) bilan mask qilish takrorlanishni ham, chalg'ituvchi elementni ham olib tashlaydi.

S: Correlation matrix uchun qaysi colormap ni tanlaysiz va nega jet emas?

Diverging map — coolwarm, RdBu_r yoki vlag — center=0 va vmin=-1, vmax=1 bilan, shunda oq rang haqiqiy nolni belgilaydi, ikki yo'nalish vizual ajralib turadi va shkala chartlar orasida taqqoslanadigan bo'ladi. jet va boshqa rainbow map lar perseptual jihatdan bir xil emas: ular ma'lumotda mavjud bo'lmagan chegaralarni ko'z ilg'aydigan yorqin chiziqlar sifatida yaratadi va to'q ko'k sohada haqiqiy farqlarni siqib yuboradi. Ular rang ko'rmaydigan o'quvchilar uchun ham, kulrang shkalada ham juda yomon ishlaydi.

S: pandas 2.x da df.corr() nega haqiqiy dataset da xato beradi?

Chunki standart qiymat numeric_only=False ga o'zgargan, shuning uchun pandas endi matnli column larni ham correlation qilishga urinadi va ValueError: could not convert string to float beradi. pandas 1.x ularni jimgina tashlab yuborar edi; 1.5 bu xatti-harakatni eskirgan deb belgiladi. Yechim — df.corr(numeric_only=True) yoki df.select_dtypes("number").corr(). Xuddi shu o'zgarish aralash DataFrame lardagi mean, sum va boshqa reduksiyalarga ham ta'sir qiladi.

S: clustermap heatmap dan nimasi bilan farq qiladi va asosiy tuzoq nima?

clustermap row va column lar bo'yicha ierarxik klasterlash bajaradi, dendrogram lar chizadi va matrix ni o'xshash row va column lar yonma-yon turadigan qilib qayta tartiblaydi. U figure-level (ax= yo'q), NaN bilan ishlay olmaydi va column lar turli birlikda bo'lganda odatda z_score yoki standard_scale talab qiladi. Asosiy tuzoq shuki, ko'rsatilgan tartib kirish tartibi emas — tashqi yorliqlarni pozitsiya bo'yicha biriktirishdan oldin uni g.dendrogram_row.reordered_ind orqali tiklang. O'q tartibi ma'noli bo'lgan har qanday holatda, masalan oylar va yillarda, oddiy heatmap ni ishlating.

S: Ikki feature orasida r = 0.98 ko'rdingiz. Yaxshi xabarmi?

Deyarli hech qachon. Bu odatda column lar takrorlangani yoki birlik o'zgartirilgani, target leakage (bir faktning ikki marta yozilgani) yoki linear model koeffitsientlarini beqaror qiladigan deyarli kollinearlikni bildiradi. Juftlikni tekshiring, so'ng bittasini olib tashlang yoki birlashtiring. Juda yuqori correlation — avvalo ma'lumot sifati signali, keyin esa topilma.

Xulosa

  • heatmap va clustermap — matrix function lari: ular tidy ma'lumotni emas, 2 o'lchamli to'rni oladi. Row lar y o'qiga, column lar x o'qiga, qiymatlar ranglarga aylanadi. x=, y= yoki hue= mavjud emas.
  • Matrix shakliga df.pivot() (har bir cell ga bitta qiymat), pd.pivot_table(aggfunc=...) (har bir cell ga ko'p qiymat), pd.crosstab() (ikkita kategorik o'zgaruvchi) yoki df.corr() (sonli column lar) orqali yeting. pandas 2.0 dan boshlab pivot faqat keyword argument qabul qiladi.
  • Correlation retsepti: corr = df.corr(numeric_only=True), so'ng annot=True, fmt=".2f", cmap="coolwarm", center=0, vmin=-1, vmax=1, square=True. pandas 2.x da numeric_only=True majburiy.
  • Pearson r i faqat linear bog'liqlikni o'lchaydi — mukammal parabola ≈ 0 beradi. Correlation hech qachon sababiyat emas; confounding, tanlov effektlari va ko'p taqqoslashlar uni sun'iy hosil qiladi. Qiziqarli juftliklarni doim scatterplot qiling.
  • Diagonal doim 1.0 va hech qanday ma'lumot bermaydi; matrix simmetrik, ya'ni uning yarmi ortiqcha. Bitta uchburchakni np.triu(np.ones_like(corr, dtype=bool), k=0) bilan mask qiling.
  • Monotonic, rank langan, qiyshaygan yoki outlier ga boy ma'lumot uchun method="spearman" ni ishlating. Kattalik bo'yicha kelishuvlar (kuchsiz < 0.3, o'rtacha 0.3–0.7, kuchli > 0.7) — sohaga bog'liq amaliy qoidalar, haqiqat chegarasi emas — n ni ayting va r² halolroq umumlashma ekanini unutmang.
  • Colormap lar: ishorali ma'lumot uchun center=0 bilan diverging, kattaliklar uchun sequential (viridis, rocket, mako), rainbow esa hech qachon. Ikki chart taqqoslanishi kerak bo'lgan har qanday holatda vmin/vmax ni qotiring va rang ko'rlikka bardoshli map larni afzal ko'ring.
  • Ko'p uchraydigan muammolar: taxminan 15×15 dan keyin annot=True o'qib bo'lmas holga keladi; o'zgarmas column lar NaN chiziqlarini hosil qiladi; xom sanoqlar ulushlar ochib beradigan effektlarni yashiradi; bo'sh cell lar nol deb o'qiladi; matplotlib 3.1.x da yuqori va quyi row lar qirqiladi, buni plt.tight_layout() yoki aniq ylim tuzatishi hal qiladi.
  • clustermap row va column larni qayta tartiblaydi hamda NaN ni ham, ax= ni ham qabul qilmaydi; birliklar farq qilganda z_score bilan standartlashtiring va mavjud o'q tartibi o'zi ma'noli bo'lsa, oddiy heatmap ni ishlating.

Keyingi: 19-bob regression plot larni — regplot, lmplot va residplot ni ko'rib chiqadi.

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar