מודול 6: PCA — חקירת מרחב הצורות
שבוע 6 — ערכת הכלים
מ-12 ממדים ל-2
לאחר יישור פרוקרוסטס, כל מטבע קיים כנקודה במרחב צורות בן 12 ממדים. לא ניתן לדמיין 12 ממדים. ניתוח רכיבים עיקריים (PCA) פותר זאת.
PCA מוצא את הכיוונים במרחב הצורות שלוכדים את מירב השונות. הרכיב העיקרי הראשון (PC1) הוא הציר היחיד שמסביר את מירב שונות הצורה במאגר הנתונים. PC2 מסביר את מירב מה שנותר, וכן הלאה.
מהו PCA (מבחינה מושגית)
דמיינו את כל המטבעות שלכם כענן נקודות במרחב הצורות. PCA מוצא את הציר הארוך ביותר דרך הענן הזה (PC1), ואחר כך את הציר הארוך ביותר הניצב לו (PC2), וכן הלאה.
על ידי ציור PC1 לעומת PC2, אנחנו לוכדים את רוב שונות הצורה בשני ממדים שניתן לראות.
לכל פרט יש ציון על כל ציר PC. ציון חיובי גבוה על PC1 אומר שלפרט יש הרבה משונות הצורה המתוארת על ידי PC1 (בכיוון החיובי). ציון קרוב לאפס אומר שהפרט קרוב לצורה הממוצעת על ציר זה.
רשתות עיוות צורה
הכלי החזק ביותר לפרשנות תוצאות PCA הוא רשת עיוות לוח הדקיק (thin-plate spline).
רשת עיוות מראה כיצד הצורה הממוצעת צריכה להתעוות כדי לייצר את הצורה בכל נקודה במרחב הצורות. זוהי מפה ויזואלית של השינוי הגיאומטרי בין שתי צורות.
קריאת רשת עיוות: - אזורים שבהם הרשת דחוסה → התכווצות יחסית לכיוון הצורה המטרה - אזורים שבהם הרשת מתוחה → הרחבה יחסית לכיוון הצורה המטרה - קווי רשת מעוקלים בחדות → עיוות מקומי חזק
צינור PCA מלא ב-Colab
# תא 1: ייבוא והגדרה
!pip install python-bidi -q
from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from bidi.algorithm import get_display
rtl = get_display # תיקון כיוון טקסט עברי בגרפים של matplotlib
# נניח ש-'aligned' הוא תוצאת GPA משבוע 5
# שינוי צורה: כל פרט הופך לשורה אחת
n = aligned.shape[0]
X = aligned.reshape(n, -1) # צורה: (n_מטבעות, 16)
# PCA
pca = PCA()
scores = pca.fit_transform(X)
loadings = pca.components_ # צורה: (16, 16)
# שונות מוסברת
var_exp = pca.explained_variance_ratio_ * 100
print("שונות מוסברת על ידי 5 הרכיבים הראשונים:")
for i, v in enumerate(var_exp[:5]):
print(f" PC{i+1}: {v:.1f}%")# תא 2: גרף שדרה — כמה רכיבים עיקריים חשובים?
plt.figure(figsize=(8, 4))
plt.bar(range(1, 8), var_exp[:7], color='steelblue', edgecolor='black')
plt.plot(range(1, 8), np.cumsum(var_exp[:7]), 'ro-', label=rtl('מצטבר %'))
plt.xlabel(rtl("רכיב עיקרי"))
plt.ylabel(rtl("שונות מוסברת (%)"))
plt.title(rtl("גרף שדרה — מטבעות הדריאנוס"))
plt.legend()
plt.show()# תא 3: גרף פיזור PCA (PC1 לעומת PC2)
plt.figure(figsize=(8, 7))
plt.scatter(scores[:, 0], scores[:, 1],
s=60, alpha=0.8, color='steelblue', edgecolor='white')
# סימון חריגים (5% תחתון ועליון על PC1)
threshold = np.percentile(np.abs(scores[:, 0]), 95)
for i, (x, y) in enumerate(scores[:, :2]):
if abs(x) > threshold:
plt.annotate(rtl(f"מטבע {i+1}"), (x, y), fontsize=8,
xytext=(5, 5), textcoords='offset points')
plt.axhline(0, color='gray', linewidth=0.5, linestyle='--')
plt.axvline(0, color='gray', linewidth=0.5, linestyle='--')
plt.xlabel(rtl(f"PC1 ({var_exp[0]:.1f}% מהשונות)"))
plt.ylabel(rtl(f"PC2 ({var_exp[1]:.1f}% מהשונות)"))
plt.title(rtl("מרחב הצורות: דנריים של הדריאנוס"))
plt.tight_layout()
plt.show()פרשנות גרף PCA
הסתכלו בגרף הפיזור שלכם וענו על שאלות אלה:
פיזור: האם מטבעות מפוזרים יותר לאורך PC1 או PC2? מה זה אומר על הציר הדומיננטי של שונות הצורה?
אשכולות: האם אתם רואים קבוצות מובחנות, או שהשונות רציפה?
חריגים: האם יש מטבעות רחוקים מהענן הראשי? חזרו והסתכלו בתמונות המטבעות האלה — האם יש בהם משהו חריג ויזואלית?
מה אומר PC1? אנחנו זקוקים לרשת עיוות כדי לענות על זה כראוי — אבל עשו ניחוש ויזואלי בהתבסס על מטבעות בקצה החיובי לעומת השלילי של PC1.
עיוות צורה: מה PC1 אכן אומר
# תא 4: ויזואליזציה של צורה בערכי PC1 קיצוניים
mean_shape = aligned.mean(axis=0)
# שחזור צורה ב-2 SD מינוס ו-2 SD פלוס על PC1
pc1_vector = loadings[0].reshape(-1, 2) # PC1 כהזזות ציוני דרך (8, 2)
std1 = np.sqrt(pca.explained_variance_[0])
shape_minus = mean_shape - 2 * std1 * pc1_vector
shape_plus = mean_shape + 2 * std1 * pc1_vector
# ציור
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for ax, shape, title in zip(axes,
[shape_minus, mean_shape, shape_plus],
["PC1 מינימום (−2 SD)", "צורה ממוצעת", "PC1 מקסימום (+2 SD)"]):
ax.scatter(shape[:, 0], shape[:, 1], s=80, color='steelblue')
ax.set_title(title)
ax.set_aspect('equal')
ax.set_xlim(-0.4, 0.4)
ax.set_ylim(-0.4, 0.4)
plt.suptitle("שונות צורה לאורך PC1", fontsize=14)
plt.tight_layout()
plt.show()מה לחפש: כיצד מיקומי ציוני הדרך משתנים מהצורה המינימלית לצורה המרבית? אילו ציוני דרך זזים הכי הרבה? מה זה מתאים לו בתמונת המטבע?
מטלה 3 מחולקת השבוע
GPA + PCA מלא של מטבעות הדריאנוס לעומת אנטונינוס פיוס. צבעו את ה-PCA לפי קיסר, הריצו בדיקת השראה (permutation test), וכתבו פרשנות של 500 מילה.
ראו מטלה 3 לפרטים מלאים.