Pandas & NumPy Academy · درس

تحليل التباين واختبارات ما بعد التحليل

قارن المتوسطات بين ثلاث مجموعات أو أكثر باستخدام تحليل التباين أحادي الاتجاه، وأجرِ اختبار Tukey HSD لتحديد الأزواج المختلفة

الدرس 4 من 413 خطوة

تحليل التباين واختبارات ما بعد التحليل درس مجاني في Pandas & NumPy Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Pandas & NumPy Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

لماذا لا نستخدم اختبارات t متعددة؟

عند مقارنة المتوسطات بين ثلاث مجموعات أو أكثر، يؤدي إجراء اختبارات t متعددة إلى تضخيم معدل خطأ النوع الأول (معدل النتائج الإيجابية الكاذبة). فعند اختبار A مقابل B، وA مقابل C، وB مقابل C عند α=0.05 لكل اختبار، يصبح الاحتمال الإجمالي للنتيجة الإيجابية الكاذبة نحو 14%، وليس 5%. يحل تحليل التباين (ANOVA) هذه المشكلة باختبار جميع المجموعات في الوقت نفسه ضمن اختبار واحد، مع إبقاء معدل النتائج الإيجابية الكاذبة عند α تمامًا. ويحل اختبار ANOVA واحد محل جميع اختبارات t الثنائية للإجابة عن السؤال الشامل: «هل تختلف أي من المجموعات؟»

تحليل التباين أحادي الاتجاه: الصورة الشاملة

يختبر تحليل التباين أحادي الاتجاه ما إذا كانت متوسطات ثلاث مجموعات أو أكثر تختلف اختلافًا ذا دلالة إحصائية. وهو يفكك التباين الكلي إلى التباين بين المجموعات (الذي يفسره الانتماء إلى المجموعة) والتباين داخل المجموعات (الضوضاء العشوائية). وإحصائية F هي النسبة بينهما: F = (التباين بين المجموعات) / (التباين داخل المجموعات). وتشير قيمة F الكبيرة إلى أن الفروق بين المجموعات كبيرة مقارنةً بالضوضاء، ما يؤدي إلى قيمة p صغيرة. أما الفرضية الصفرية فهي H₀: جميع متوسطات المجموعات متساوية.

import numpy as np
from scipy import stats

np.random.seed(0)
# Three product variants with different conversion rates
group_a = np.random.normal(10.0, 2.0, 50)  # baseline
group_b = np.random.normal(11.5, 2.0, 50)  # slightly better
group_c = np.random.normal(13.0, 2.0, 50)  # clearly better

f_stat, p = stats.f_oneway(group_a, group_b, group_c)
print(f'F-statistic: {f_stat:.3f}')
print(f'p-value: {p:.6f}')
print('At least one group differs?', 'Yes' if p < 0.05 else 'No')

تحليل التباين باستخدام إطارات بيانات Pandas

عمليًا، تكون بياناتكم في إطار بيانات بتنسيق طويل، حيث يحتوي أحد الأعمدة على تسمية المجموعة ويحتوي عمود آخر على القياس. استخرجوا كل مجموعة بوصفها Series ومرروها إلى stats.f_oneway(). وبدلًا من ذلك، إذا كان لديكم إطار بيانات بتنسيق عريض (عمود لكل مجموعة)، فمرروا كل عمود مباشرةً. تقبل الدالة أي عدد من الوسائط الموضعية، ما يسهّل توسيع التحليل ليشمل 4 أو 5 مجموعات أو أكثر.

import pandas as pd
import numpy as np
from scipy import stats

np.random.seed(1)
df = pd.DataFrame({
    'group': ['A']*40 + ['B']*40 + ['C']*40 + ['D']*40,
    'score': np.concatenate([
        np.random.normal(70, 10, 40),
        np.random.normal(75, 10, 40),
        np.random.normal(80, 10, 40),
        np.random.normal(72, 10, 40)
    ])
})

groups = [group['score'].values
          for _, group in df.groupby('group')]

f, p = stats.f_oneway(*groups)
print(f'F={f:.3f}, p={p:.4f}')
print(df.groupby('group')['score'].mean().round(2))

افتراضات تحليل التباين

يفترض تحليل التباين أحادي الاتجاه ما يلي: (1) الاستقلالية — الملاحظات مستقلة بعضها عن بعض؛ (2) التوزيع الطبيعي — البواقي موزعة توزيعًا طبيعيًا تقريبًا داخل كل مجموعة (ويكون التحليل متينًا مع العينات الكبيرة بفضل مبرهنة الحد المركزي)؛ (3) تجانس التباين — تساوي التباينات بين المجموعات. اختبروا افتراض التباين باستخدام اختبار Levene (stats.levene(*groups)). وإذا كانت التباينات غير متساوية، فاستخدموا تحليل Welch للتباين، المتاح في مكتبة pingouin أو الذي يمكن حسابه عبر statsmodels.

import numpy as np
from scipy import stats

np.random.seed(0)
g1 = np.random.normal(10, 2, 40)
g2 = np.random.normal(12, 2, 40)
g3 = np.random.normal(11, 8, 40)   # Much higher variance

# Test equal variances
stat_l, p_l = stats.levene(g1, g2, g3)
print(f'Levene\'s test: stat={stat_l:.3f}, p={p_l:.4f}')
if p_l < 0.05:
    print('Warning: Unequal variances! Standard ANOVA may be unreliable.')
    print('Consider Welch\'s ANOVA or Kruskal-Wallis.')

Kruskal-Wallis: تحليل التباين اللامعلمي

عند انتهاك افتراضات تحليل التباين (مثل التوزيعات غير الطبيعية، أو العينات الصغيرة، أو التباينات غير المتساوية)، يكون اختبار Kruskal-Wallis البديل اللامعلمي. فهو يختبر ما إذا كانت توزيعات المجموعات تختلف، وذلك بتحويل البيانات إلى رتب ومقارنة مجاميع الرتب. استخدموا scipy.stats.kruskal(*groups). وتتمثل الفرضية الصفرية في أن جميع المجموعات لها التوزيع نفسه (وهو مكافئ لاختبار تساوي الوسيطات عندما تكون التوزيعات متماثلة الشكل). ويكون الاختبار صالحًا دائمًا، لكنه أقل قدرة من تحليل التباين عندما تتحقق الافتراضات.

import numpy as np
from scipy import stats

np.random.seed(0)
# Non-normal data: customer satisfaction scores (1-10 scale)
g1 = np.random.choice(range(1, 11), 50, p=[0.05]*10)
g2 = np.random.choice(range(1, 11), 50, p=[0.02, 0.03, 0.05, 0.08, 0.12, 0.15, 0.20, 0.15, 0.12, 0.08])
g3 = np.random.choice(range(1, 11), 50, p=[0.15, 0.15, 0.15, 0.15, 0.10, 0.10, 0.08, 0.05, 0.04, 0.03])

stat, p = stats.kruskal(g1, g2, g3)
print(f'Kruskal-Wallis: H={stat:.3f}, p={p:.4f}')
print('Groups differ?', 'Yes' if p < 0.05 else 'No')

اختبارات ما بعد التحليل: لماذا تحتاجون إليها

يخبركم تحليل التباين ذو الدلالة الإحصائية بأن متوسط مجموعة واحدة على الأقل يختلف، لكنه لا يوضح أي الأزواج تختلف. تُجري اختبارات ما بعد التحليل جميع المقارنات الثنائية مع تصحيح مشكلة المقارنات المتعددة. وأكثرها شيوعًا هو فرق Tukey الصادق المعنوي (Tukey HSD)، الذي يضبط معدل خطأ العائلة عند α تمامًا. وهو متاح في statsmodels.stats.multicomp.pairwise_tukeyhsd(). أجروا اختبارات ما بعد التحليل فقط بعد الحصول على تحليل تباين ذي دلالة إحصائية، وليس لاستكشاف النتائج غير الدالة إحصائيًا عشوائيًا.

import numpy as np
import pandas as pd
from scipy import stats
from statsmodels.stats.multicomp import pairwise_tukeyhsd

np.random.seed(0)
data = np.concatenate([
    np.random.normal(70, 10, 40),
    np.random.normal(80, 10, 40),
    np.random.normal(75, 10, 40)
])
groups = ['A']*40 + ['B']*40 + ['C']*40

# First confirm ANOVA is significant
f, p = stats.f_oneway(*[data[i*40:(i+1)*40] for i in range(3)])
print(f'ANOVA p={p:.4f}')
if p < 0.05:
    print('Post-hoc Tukey HSD:')
    print(pairwise_tukeyhsd(data, groups, alpha=0.05))

قراءة مخرجات Tukey HSD

يحتوي جدول Tukey HSD على صف واحد لكل زوج من المجموعات. والأعمدة التي ينبغي التركيز عليها هي: meandiff (الفرق بين متوسطي الزوج)، وlower وupper (حدا فاصل الثقة بنسبة 95% للفرق)، وreject (تكون True إذا كان الزوج يختلف اختلافًا ذا دلالة إحصائية عند α). ويعني فاصل الثقة الذي لا يتضمن الصفر أن الزوج مختلف اختلافًا ذا دلالة إحصائية. أما المجموعات التي تتداخل فواصل الثقة الخاصة بها فلا تختلف اختلافًا ذا دلالة إحصائية عن بعضها.

import numpy as np
from statsmodels.stats.multicomp import pairwise_tukeyhsd

np.random.seed(42)
data = np.concatenate([
    np.random.normal(10, 2, 60),  # Group A
    np.random.normal(13, 2, 60),  # Group B (clearly higher)
    np.random.normal(10.5, 2, 60) # Group C (barely different from A)
])
groups = ['A']*60 + ['B']*60 + ['C']*60

result = pairwise_tukeyhsd(data, groups, alpha=0.05)
print(result)
# A-B: reject=True (B is higher)
# A-C: reject=False (barely different)
# B-C: reject=True (B is higher)

تصحيحات Bonferroni وBenjamini-Hochberg

كبديل عن Tukey HSD، يمكنكم تطبيق تصحيح Bonferroni على اختبارات t الثنائية: أجروا جميع اختبارات t، ثم عدّلوا العتبة إلى α/k، حيث k هو عدد المقارنات. ويُعد هذا التصحيح محافظًا، وقد يؤدي إلى عدم اكتشاف فروق حقيقية. أما تصحيح معدل الاكتشافات الكاذبة (FDR) لـ Benjamini-Hochberg فهو أقل تحفظًا؛ إذ يضبط النسبة المتوقعة للاكتشافات الكاذبة، ما يتيح عددًا أكبر من النتائج الإيجابية الحقيقية مقابل زيادة طفيفة في النتائج الإيجابية الكاذبة. استخدموا statsmodels.stats.multitest.multipletests(p_values, method='fdr_bh').

import numpy as np
from scipy import stats
from statsmodels.stats.multitest import multipletests

np.random.seed(0)
groups = [np.random.normal(10 + i*1.5, 2, 40) for i in range(4)]
names = ['A', 'B', 'C', 'D']

# All pairwise t-tests
p_values = []
pairs = []
for i in range(len(groups)):
    for j in range(i+1, len(groups)):
        _, p = stats.ttest_ind(groups[i], groups[j])
        p_values.append(p)
        pairs.append(f'{names[i]}-{names[j]}')

# Benjamini-Hochberg correction
reject, adj_p, _, _ = multipletests(p_values, method='fdr_bh')
for pair, p, ap, r in zip(pairs, p_values, adj_p, reject):
    print(f'{pair}: raw_p={p:.4f}, adj_p={ap:.4f}, significant={r}')

حجم الأثر في تحليل التباين: إيتا تربيع

في تحليل التباين، يكون المقياس المناظر لـ Cohen's d هو إيتا تربيع (η²)، أي نسبة التباين الكلي التي يفسرها الانتماء إلى المجموعة. η² = SS_between / SS_total. وتكون القيم التالية شائعة التفسير: < 0.01 أثر صغير، و0.06 أثر متوسط، و> 0.14 أثر كبير. ويُعد إيتا تربيع الجزئي (η²_p) أكثر شيوعًا في الأبحاث المنشورة؛ إذ يقسم التباين على تباين المجموعة مضافًا إليه تباين الخطأ فقط، وليس على التباين الكلي. احسبوا دائمًا η² إلى جانب قيمة p لتحليل التباين، لإظهار ما إذا كان الأثر ذا أهمية عملية، وليس قابلًا للكشف إحصائيًا فحسب.

import numpy as np
from scipy import stats

np.random.seed(0)
groups = [
    np.random.normal(10, 2, 50),
    np.random.normal(12, 2, 50),
    np.random.normal(14, 2, 50)
]

all_data = np.concatenate(groups)
grand_mean = all_data.mean()

ss_between = sum(len(g) * (g.mean() - grand_mean)**2 for g in groups)
ss_total = sum((x - grand_mean)**2 for g in groups for x in g)
eta_sq = ss_between / ss_total

f, p = stats.f_oneway(*groups)
print(f'F={f:.3f}, p={p:.4f}')
print(f'Eta-squared: {eta_sq:.4f} ({eta_sq:.1%} of variance explained)')

نظرة عامة على تحليل التباين ثنائي الاتجاه

يوسّع تحليل التباين ثنائي الاتجاه تحليل التباين أحادي الاتجاه ليشمل عاملين فئويين في الوقت نفسه. فعلى سبيل المثال، يمكن اختبار ما إذا كانت درجات الاختبار تختلف باختلاف طريقة التدريس ومستوى خبرة الطالب في آن واحد. كما يختبر أثر التفاعل: هل يعتمد أثر طريقة التدريس على مستوى الخبرة؟ يُطبَّق تحليل التباين ثنائي الاتجاه في statsmodels باستخدام ols('score ~ C(method) + C(level) + C(method):C(level)', data=df).fit() وanova_lm(model). ويمثل هذا أساسًا لتصميم التجارب الأكثر تقدمًا.

import pandas as pd
import numpy as np
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm

np.random.seed(0)
df = pd.DataFrame({
    'method': ['trad']*60 + ['active']*60,
    'level': ['beginner']*30 + ['advanced']*30 + ['beginner']*30 + ['advanced']*30,
    'score': (np.random.normal(70, 8, 30).tolist() +
              np.random.normal(80, 8, 30).tolist() +
              np.random.normal(75, 8, 30).tolist() +
              np.random.normal(88, 8, 30).tolist())
})

model = ols('score ~ C(method) + C(level) + C(method):C(level)', data=df).fit()
print(anova_lm(model, typ=2)[['F', 'PR(>F)']].round(4))

تحليل التباين للقياسات المتكررة

يُستخدم تحليل التباين للقياسات المتكررة عندما تُقاس الوحدات نفسها عدة مرات، مثل اختبار زمن الاستجابة عند النقاط الزمنية 0 و30 و60 دقيقة بعد تلقي علاج. وهو التعميم متعدد المجموعات لاختبار t للعينات المزدوجة. وبأخذ الفروق الفردية في الحسبان، تكون قدرته أكبر من تحليل التباين أحادي الاتجاه. في Python، استخدموا pingouin.rm_anova() أو pg.pairwise_tests() لتحليل ما بعد التحليل. وعند انتهاك افتراض الكروية (الذي يُختبر باستخدام اختبار Mauchly)، استخدموا قيم p المصححة بطريقة Greenhouse-Geisser.

import pandas as pd
import numpy as np

# Example structure for repeated measures (pingouin library)
np.random.seed(0)
subjects = list(range(20)) * 3   # 20 subjects, 3 time points
timepoints = ['T0']*20 + ['T1']*20 + ['T2']*20
scores = np.concatenate([
    np.random.normal(50, 10, 20),   # baseline
    np.random.normal(55, 10, 20),   # improved
    np.random.normal(60, 10, 20)    # further improved
])

df_rm = pd.DataFrame({'subject': subjects, 'time': timepoints, 'score': scores})
print(df_rm.groupby('time')['score'].mean().round(2))
# Use pingouin.rm_anova(data=df_rm, dv='score', within='time', subject='subject')

تحقق سريع

اختبروا مدى فهمكم لمفاهيم تحليل البيانات التي تناولها هذا الدرس.

مراجعة الدرس

تعلمتم في هذا الدرس أن scipy.stats.f_oneway() يختبر ما إذا كانت أي مجموعات تختلف في المتوسط مع التحكم في معدل خطأ النوع الأول الكلي، وأن اختبارات ما بعد التحليل (Tukey HSD) تحدد الأزواج التي تختلف تحديدًا بعد الحصول على تحليل تباين ذي دلالة إحصائية، وأن Kruskal-Wallis هو البديل اللامعلمي عند انتهاك افتراضات التوزيع الطبيعي أو تساوي التباينات. سنبدأ بعد ذلك مشروع التخرج، الذي يدمج جميع المهارات في خط أنابيب بيانات متكامل من البداية إلى النهاية.

البدء مجانًا

تعلم Python مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
30
الدروس
120

الأسئلة الشائعة

هل درس «تحليل التباين واختبارات ما بعد التحليل» مجاني؟

نعم — نص درس «تحليل التباين واختبارات ما بعد التحليل» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Pandas & NumPy Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

ماذا ستتعلم في «تحليل التباين واختبارات ما بعد التحليل»؟

قارن المتوسطات بين ثلاث مجموعات أو أكثر باستخدام تحليل التباين أحادي الاتجاه، وأجرِ اختبار Tukey HSD لتحديد الأزواج المختلفة تتمرن على Pandas & NumPy Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Pandas & NumPy Academy؟

لا تُشترط خبرة سابقة. Pandas & NumPy Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تحليل التباين واختبارات ما بعد التحليل»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Pandas & NumPy Academy هذا؟

نعم. كل درس في Pandas & NumPy Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الإحصاءات الوصفية واختبار التوزيع الطبيعي
  2. اختبارات t لمقارنة المتوسطات
  3. اختبار كاي-تربيع للاستقلالية
  4. تحليل التباين واختبارات ما بعد التحليل
← العودة إلى Pandas & NumPy Academy