שבוע 11 — סטטיסטיקה לא-פרמטרית
גרף מרחב הצורות מראה דפוס. אבל:
“האם ההפרדה בין הקבוצות יכולה להיות מקרית?”
סטטיסטיקה אינה מוצאת אמת — היא מודדת כמה סביר שהדפוס מקרי.
הערה
זהו מבחן הרשאה (permutation test) — לא מניח התפלגות נורמלית.
from scipy.stats import mannwhitneyu
import numpy as np
def compare_groups_pc1(scores, labels, g1, g2):
"""מבחן מאן-וויטני על PC1 בין שתי קבוצות."""
pc1_g1 = scores[np.array(labels) == g1, 0]
pc1_g2 = scores[np.array(labels) == g2, 0]
stat, p = mannwhitneyu(pc1_g1, pc1_g2,
alternative='two-sided')
print(f"קבוצה {g1}: n={len(pc1_g1)}, "
f"חציון PC1={np.median(pc1_g1):.4f}")
print(f"קבוצה {g2}: n={len(pc1_g2)}, "
f"חציון PC1={np.median(pc1_g2):.4f}")
print(f"U = {stat:.1f}, p = {p:.4f}")
if p < 0.05:
print(f"→ הבדל מובהק (p<0.05)")
else:
print(f"→ אין הבדל מובהק")
return stat, pמבחן מאן-וויטני: כבשן לעומת קבורה
p < 0.001 — ההבדל מובהק מאוד. גודל האפקט?
def cohens_d(group1, group2):
"""מחשב גודל אפקט Cohen's d."""
n1, n2 = len(group1), len(group2)
mean_diff = group1.mean() - group2.mean()
# סטיית תקן משולבת
pooled_std = np.sqrt(
((n1-1)*group1.std()**2 + (n2-1)*group2.std()**2)
/ (n1 + n2 - 2)
)
d = mean_diff / pooled_std
label = "קטן" if abs(d)<0.5 else "בינוני" if abs(d)<0.8 else "גדול"
print(f"Cohen's d = {d:.3f} ({label})")
return dp < 0.05 לא מספיק — צריך לדעת כמה גדול ההבדל!
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import LeaveOneOut
from sklearn.metrics import accuracy_score
# LDA עם Leave-One-Out cross-validation
lda = LinearDiscriminantAnalysis()
loo = LeaveOneOut()
y_true, y_pred = [], []
for train_idx, test_idx in loo.split(X):
lda.fit(X[train_idx], labels[train_idx])
y_true.append(labels[test_idx][0])
y_pred.append(lda.predict(X[test_idx])[0])
acc = accuracy_score(y_true, y_pred)
print(f"דיוק LOO-LDA: {acc*100:.1f}%")
print(f"(50% = מקרי לשתי קבוצות)")צורה בזמן — שי גורדין, אוניברסיטת אריאל