בדיקת השערות בחלל הצורות

שבוע 11 — סטטיסטיקה לא-פרמטרית

שי גורדין | אוניברסיטת אריאל

למה סטטיסטיקה?

גרף מרחב הצורות מראה דפוס. אבל:

“האם ההפרדה בין הקבוצות יכולה להיות מקרית?”

סטטיסטיקה אינה מוצאת אמת — היא מודדת כמה סביר שהדפוס מקרי.

מבחן מאן-וויטני — עקרון

  1. חשבו את ה-U בפועל בין שתי קבוצות
  2. ערבבו את השיוך לקבוצות אקראית (1000 פעם)
  3. בכל ערבוב — חשבו U מחדש
  4. p-value = אחוז הערבובים שנתנו U גדול יותר

הערה

זהו מבחן הרשאה (permutation test) — לא מניח התפלגות נורמלית.

מאן-וויטני ב-Python

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

מאן-וויטני — תוצאות אמיתיות (Ogame)

מבחן מאן-וויטני: כבשן לעומת קבורה

p < 0.001 — ההבדל מובהק מאוד. גודל האפקט?

גודל אפקט — Cohen’s d

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 d

p < 0.05 לא מספיק — צריך לדעת כמה גדול ההבדל!

השוואות מרובות — בעיה

  • בדקנו PC1 בלבד — מה אם PC2 מובהק?
  • בדקנו 10 מבחנים → בממוצע, 1 יהיה מובהק במקרה (p<0.05)
  • פתרון: תיקון בונפרוני — מחלקים סף המובהקות ב-N המבחנים
# תיקון בונפרוני
n_tests = 5  # בדקנו 5 רכיבים עיקריים
bonferroni_alpha = 0.05 / n_tests
print(f"סף מובהקות לאחר תיקון: {bonferroni_alpha:.4f}")

MANOVA — כל הממדים ביחד

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% = מקרי לשתי קבוצות)")

לשיעור האחרון

  • סיימו מטלה 5 (כלי חרס — הגשה השבוע)
  • התחילו לחשוב על פרויקט הגמר
  • קראו: מודול 12 — סינתזה