0Pricing
Pandas & NumPy Academy · Pelajaran

ANOVA dan Pengujian Pasca-Hoc

Bandingkan rata-rata pada tiga kelompok atau lebih dengan ANOVA satu arah, lalu jalankan Tukey HSD untuk mengidentifikasi pasangan yang berbeda.

ANOVA dan Pengujian Pasca-Hoc adalah pelajaran Pandas & NumPy Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Pandas & NumPy Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Pandas & NumPy Academy mencakup 4 pelajaran total.

Mengapa Tidak Menggunakan Banyak Uji-T?

Saat membandingkan rata-rata dari tiga kelompok atau lebih, menjalankan beberapa uji t akan meningkatkan tingkat kesalahan Tipe I (tingkat positif palsu). Menguji kelompok A vs B, A vs C, dan B vs C masing-masing pada α=0.05 menghasilkan peluang positif palsu keseluruhan sekitar 14%, bukan 5%. Analisis Varians (ANOVA) mengatasi hal ini dengan menguji semua kelompok secara bersamaan dalam satu uji, sehingga tingkat positif palsu tetap tepat pada α. Satu ANOVA menggantikan semua uji t berpasangan untuk pertanyaan omnibus: "Apakah ada kelompok yang berbeda?"

ANOVA Satu Arah: Gambaran Besar

ANOVA satu arah menguji apakah rata-rata dari tiga kelompok atau lebih berbeda secara signifikan. Metode ini menguraikan varians total menjadi varians antarkelompok (yang dijelaskan oleh keanggotaan kelompok) dan varians dalam kelompok (derau acak). Statistik F adalah rasio keduanya: F = (varians antarkelompok) / (varians dalam kelompok). Nilai F yang besar berarti perbedaan antarkelompok besar dibandingkan derau, sehingga menghasilkan nilai-p yang kecil. Hipotesis nolnya adalah H₀: semua rata-rata kelompok sama.

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')

ANOVA dengan Pandas DataFrames

Dalam praktiknya, data Anda berada dalam DataFrame berformat panjang, dengan satu kolom yang menyimpan label kelompok dan kolom lain yang menyimpan pengukuran. Ekstrak setiap kelompok sebagai Series dan teruskan ke stats.f_oneway(). Sebagai alternatif, jika Anda memiliki DataFrame berformat lebar (satu kolom untuk setiap kelompok), teruskan setiap kolom secara langsung. Fungsi ini menerima argumen posisi dalam jumlah berapa pun, sehingga mudah diperluas untuk 4, 5, atau lebih kelompok.

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))

Asumsi ANOVA

ANOVA satu arah mengasumsikan: (1) Independensi — observasi saling independen; (2) Normalitas — residual kira-kira berdistribusi normal dalam setiap kelompok (kukuh untuk sampel besar melalui CLT); (3) Homoskedastisitas — varians antarkelompok sama. Uji asumsi varians dengan uji Levene (stats.levene(*groups)). Jika varians tidak sama, gunakan ANOVA Welch, yang tersedia di pustaka pingouin atau dapat dihitung melalui 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: ANOVA Nonparametrik

Saat asumsi ANOVA dilanggar (distribusi tidak normal, sampel kecil, varians tidak sama), uji Kruskal-Wallis menjadi alternatif nonparametriknya. Uji ini memeriksa apakah distribusi kelompok berbeda dengan mengubah data menjadi peringkat dan membandingkan jumlah peringkat. Gunakan scipy.stats.kruskal(*groups). Hipotesis nolnya menyatakan bahwa semua kelompok memiliki distribusi yang sama (setara dengan menguji median yang sama jika distribusinya memiliki bentuk yang sama). Uji ini selalu valid, tetapi kurang kuat dibandingkan ANOVA ketika asumsi-asumsi terpenuhi.

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')

Uji Pascahoc: Mengapa Anda Membutuhkannya

ANOVA yang signifikan memberi tahu Anda bahwa setidaknya satu rata-rata kelompok berbeda, tetapi tidak memberi tahu pasangan mana yang berbeda. Uji pascahoc melakukan semua perbandingan berpasangan sekaligus mengoreksi perbandingan ganda. Uji yang paling populer adalah Honest Significant Difference Tukey (Tukey HSD), yang mengendalikan tingkat kesalahan berdasarkan keluarga tepat pada α. Uji ini tersedia di statsmodels.stats.multicomp.pairwise_tukeyhsd(). Jalankan uji pascahoc hanya setelah ANOVA yang signifikan — bukan sebagai pencarian acak pada hasil yang tidak signifikan.

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))

Membaca Keluaran Tukey HSD

Tabel Tukey HSD memiliki satu baris untuk setiap pasangan kelompok. Kolom yang perlu diperhatikan adalah: meandiff (perbedaan rata-rata antara pasangan), lower dan upper (interval kepercayaan 95% untuk perbedaan tersebut), serta reject (True jika pasangan berbeda secara signifikan pada α). Interval kepercayaan yang tidak mencakup nol berarti pasangan tersebut berbeda secara signifikan. Kelompok dengan interval kepercayaan yang saling tumpang tindih tidak berbeda secara signifikan satu sama lain.

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)

Koreksi Bonferroni dan Benjamini-Hochberg

Sebagai alternatif untuk Tukey HSD, Anda dapat menerapkan koreksi Bonferroni pada uji t berpasangan: jalankan semua uji t, lalu sesuaikan ambang batas menjadi α/k, dengan k sebagai jumlah perbandingan. Metode ini konservatif — perbedaan yang nyata mungkin tidak terdeteksi. Koreksi Benjamini-Hochberg False Discovery Rate (FDR) lebih tidak konservatif: metode ini mengendalikan proporsi temuan palsu yang diharapkan, sehingga memungkinkan lebih banyak positif benar dengan konsekuensi sedikit lebih banyak positif palsu. Gunakan 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}')

Ukuran Efek untuk ANOVA: Eta Kuadrat

Untuk ANOVA, ukuran yang sepadan dengan Cohen's d adalah eta kuadrat (η²): proporsi varians total yang dijelaskan oleh keanggotaan kelompok. η² = SS_between / SS_total. Nilai: < 0.01 kecil, 0.06 sedang, dan > 0.14 besar. Eta kuadrat parsial (η²_p) lebih umum digunakan dalam penelitian yang dipublikasikan: ukurannya hanya dibagi dengan varians kelompok ditambah varians kesalahan, bukan varians total. Selalu hitung η² bersama nilai-p ANOVA untuk menunjukkan apakah efek tersebut bermakna secara praktis, bukan sekadar terdeteksi secara statistik.

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)')

Ikhtisar ANOVA Dua Arah

ANOVA dua arah memperluas ANOVA satu arah untuk dua faktor kategoris secara bersamaan. Contohnya, menguji apakah nilai ujian berbeda berdasarkan metode pengajaran dan tingkat pengalaman siswa secara bersamaan. Uji ini juga menguji efek interaksi: apakah pengaruh metode pengajaran bergantung pada tingkat pengalaman? ANOVA dua arah diimplementasikan dalam statsmodels melalui ols('score ~ C(method) + C(level) + C(method):C(level)', data=df).fit() dan anova_lm(model). Ini menjadi dasar untuk desain eksperimen yang lebih lanjut.

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))

ANOVA Pengukuran Berulang

ANOVA pengukuran berulang digunakan ketika subjek yang sama diukur beberapa kali — misalnya, menguji waktu reaksi pada titik waktu 0, 30, dan 60 menit setelah perlakuan. Metode ini merupakan generalisasi multi-kelompok dari uji t berpasangan. Dengan memperhitungkan perbedaan individu, metode ini memiliki daya lebih besar daripada ANOVA satu arah. Dalam Python, gunakan pingouin.rm_anova() atau pg.pairwise_tests() untuk analisis pascahoc. Jika sferisitas dilanggar (diuji dengan uji Mauchly), gunakan nilai-p yang dikoreksi 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')

Pemeriksaan Singkat

Uji pemahaman Anda tentang konsep Analisis Data dari pelajaran ini.

Rangkuman Pelajaran

Dalam pelajaran ini Anda telah mempelajari: scipy.stats.f_oneway() menguji apakah ada kelompok yang berbeda dalam rata-rata sekaligus mengendalikan tingkat kesalahan Tipe I keseluruhan, uji pascahoc (Tukey HSD) mengidentifikasi pasangan tertentu yang berbeda setelah ANOVA yang signifikan, dan Kruskal-Wallis adalah pilihan nonparametrik ketika asumsi normalitas atau varians yang sama dilanggar. Selanjutnya kita akan memulai proyek akhir, yang mengintegrasikan semua keterampilan ke dalam pipeline data menyeluruh.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “ANOVA dan Pengujian Pasca-Hoc” gratis?

Ya — teks lengkap “ANOVA dan Pengujian Pasca-Hoc” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Pandas & NumPy Academy, upgrade ke CoddyKit PRO. Kursus Pandas & NumPy Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “ANOVA dan Pengujian Pasca-Hoc”?

Bandingkan rata-rata pada tiga kelompok atau lebih dengan ANOVA satu arah, lalu jalankan Tukey HSD untuk mengidentifikasi pasangan yang berbeda. Kamu berlatih Pandas & NumPy Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Pandas & NumPy Academy?

Tidak diperlukan pengalaman sebelumnya. Pandas & NumPy Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “ANOVA dan Pengujian Pasca-Hoc” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Pandas & NumPy Academy ini?

Ya. Setiap pelajaran Pandas & NumPy Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Statistik Deskriptif dan Pengujian Normalitas
  2. Pengujian-t untuk Membandingkan Rata-Rata
  3. Pengujian Chi-Kuadrat untuk Independensi
  4. ANOVA dan Pengujian Pasca-Hoc
← Kembali ke Pandas & NumPy Academy