Lewati ke konten utama

Uji Eksak Fisher: Mengambil Keputusan dengan Sampel Kecil

Pelajari cara menganalisis hubungan kategorikal saat ukuran sampel Anda kecil.
· 9 mnt Baca

Jelajahi bersama AI

Organisasi membuat keputusan setiap hari berdasarkan perilaku pelanggan, performa produk, dan fluktuasi operasional. Agar keputusan ini didasarkan pada hubungan dan pola yang benar-benar ada dalam data, analis sering menggunakan uji statistik. 

Meskipun uji statistik umum bekerja dengan baik untuk dataset besar, bisnis tidak selalu memiliki kemewahan tersebut. Faktanya, banyak keputusan harus dibuat dengan ukuran sampel kecil, segmen pelanggan yang sempit, atau kejadian langka. Dalam situasi seperti ini, uji tradisional seperti chi-square bisa tidak memadai, entah menghasilkan hasil yang menyesatkan atau tidak memiliki ketelitian yang diperlukan untuk bertindak dengan percaya diri berdasarkan temuan tersebut. 

Di sinilah uji eksak Fisher menjadi bernilai. Teruskan membaca dan saya akan menunjukkan caranya.

Apa Itu Uji Eksak Fisher?

Uji eksak Fisher digunakan untuk mengevaluasi asosiasi antara variabel kategorikal ketika data terbatas. Uji ini paling sering diterapkan pada tabel kontingensi 2×2, dan menghitung probabilitas eksak untuk mengamati data setajam yang dikumpulkan, dengan asumsi hipotesis nol tentang independensi adalah benar.

Seorang analis mungkin menggunakan uji eksak Fisher, misalnya, saat mengevaluasi efektivitas kampanye pemasaran terarah. Jika, misalnya, analis menguji efektivitas kampanye email vs. media sosial, dan ini untuk kelompok pelanggan khusus dengan ukuran sampel kecil, ia dapat membuat tabel kontingensi dan menjalankan uji eksak Fisher. Atau, dalam konteks pengendalian mutu, seorang analis dapat menggunakan uji ini untuk mengatasi tantangan dalam pelaporan insiden dan pelacakan cacat. Ketika jenis kegagalan tertentu hanya terjadi beberapa kali, uji eksak Fisher dapat menilai apakah faktor seperti jenis mesin benar-benar terkait dengan terjadinya cacat.

Teori Statistik dan Landasan Matematis

Setelah memiliki pemahaman intuitif mengapa uji ini penting, kini kita dapat memformalkannya. Pada intinya, uji eksak Fisher adalah metode statistik untuk menentukan apakah ada asosiasi non-acak antara dua variabel kategorikal. Ini paling umum diterapkan pada tabel kontingensi 2×2 untuk membandingkan dua kelompok pada dua luaran, misalnya, “perlakuan versus kontrol” terhadap “membaik versus tidak membaik.”

Menariknya, asal-usulnya berakar pada salah satu kisah paling terkenal dalam statistik, dikenal sebagai eksperimen “lady tasting tea”. Sir Ronald A. Fisher merancang eksperimen untuk mengevaluasi klaim Dr. Muriel Bristol bahwa ia dapat membedakan apakah susu atau teh yang dituangkan terlebih dahulu hanya dari rasa. Sebagai bagian dari eksperimen, Fisher menyiapkan delapan cangkir dan memintanya mengidentifikasi mana yang “susu-dulu” versus “teh-dulu”. Karena ukuran sampel yang kecil, Fisher mengembangkan metode eksak untuk menentukan apakah pola tebakan yang benar bisa terjadi secara kebetulan, meletakkan dasar bagi apa yang kini kita kenal sebagai uji eksak Fisher.

Dalam situasi di mana data terbatas, tidak seimbang, atau sulit diperoleh, seperti dalam riset klinis, uji Fisher membantu menentukan apakah perlakuan dan luaran terkait secara bermakna. Ekologi, epidemiologi, genetika, dan pengendalian mutu adalah beberapa bidang yang melibatkan data jarang dan bergantung pada uji ini.

Uji eksak Fisher mengevaluasi independensi dengan menghitung probabilitas hipergeometrik eksak. Untuk tabel 2×2:

 

Grup B1

Grup B2

Total

Grup A1

a

b

a+b

Grup A2

c

d

c+d

Total

a+c

b+d

n

Probabilitas untuk mengamati konfigurasi eksak tersebut di bawah hipotesis nol (tidak ada asosiasi) dihitung dengan distribusi hipergeometrik:

Uji dapat satu arah, seperti menjawab “Apakah A1 lebih mungkin terjadi pada B1 daripada B2?” atau dua arah: “Apakah ada asosiasi sama sekali?” Tidak seperti pendekatan perkiraan untuk sampel besar (misalnya, chi-square), metode Fisher memastikan akurasi bahkan saat frekuensi harapan rendah.

Asumsi dan Prasyarat

Untuk menerapkan uji eksak Fisher, kita memerlukan kondisi berikut.

  • Data harus kategorikal
  • Disajikan dalam tabel kontingensi 2×2
  • Observasi saling independen
  • Margin (total baris & kolom) tetap di bawah hipotesis nol

Uji Fisher lebih disukai saat nilai harapan di kisi sangat rendah (kurang dari 5), atau hasilnya jarang atau sangat tidak seimbang.

Uji Eksak Fisher di Python

Misalkan kita menguji apakah suatu obat meningkatkan pemulihan:

 

Sembuh

Tidak Sembuh

Total

Perlakuan

8

2

10

Kontrol

4

11

15

Total

12

13

25

Berikut hipotesisnya:

  • H₀: Perlakuan dan pemulihan saling independen
  • H₁: Perlakuan meningkatkan pemulihan (satu arah)

Dan berikut cara saya mempertimbangkannya di Python:

from scipy.stats import fisher_exact

# Construct contingency table
table = [[8, 2],
         [4, 11]]

oddsratio, p_value = fisher_exact(table, alternative='two-sided')
print("Odds Ratio:", oddsratio)
print("Two-sided p-value:", round(p_value, 2))

# One-sided test (treatment better)
_, p_value_one = fisher_exact(table, alternative='greater')
print("One-sided p-value:", round(p_value_one, 2))
Odds Ratio: 11.0
Two-sided p-value: 0.02
One-sided p-value: 0.01

Nilai p yang kecil sebesar 0.02 menunjukkan adanya asosiasi nyata antara perlakuan dan pemulihan.

Sekarang, mari pilih contoh nyata menggunakan data publik NHANES 2017–2018 untuk meneliti asosiasi antara “status merokok saat ini” dan “pernah diberi tahu bahwa Anda menderita asma” pada orang dewasa.

Berkas yang digunakan (semuanya dari situs resmi NHANES):

  • DEMO_J.XPT — Demografi (usia, jenis kelamin, bobot, dll.)

  • SMQ_J.XPT — Merokok - Penggunaan Rokok (riwayat merokok & penggunaan saat ini)

  • MCQ_J.XPT — Kondisi Medis (termasuk "pernah diberi tahu Anda menderita asma")

Berikut langkah-langkah yang akan kita ikuti:

  1. Unduh dan muat dataset

  2. Buat variabel biner:

    1. current_smoker (ya/tidak)

    2. asthma_ever (ya/tidak)

  3. Buat tabel kontingensi 2×2

  4. Jalankan uji eksak Fisher (dua arah dan satu arah)

  5. Hitung interval kepercayaan 95% untuk odds ratio

  6. Interpretasikan hasil

Catatan: Analisis NHANES yang tepat memerlukan bobot survei dan desain kompleks.

Di sini, kami mengabaikan bobot untuk tujuan didaktik. Mari impor pustaka yang diperlukan.

# %% Imports
import pandas as pd
import numpy as np
from scipy.stats import fisher_exact
from statsmodels.stats.contingency_tables import Table2x2

Mari unduh berkas XPT dari CDC secara manual dan letakkan di folder lokal data/:

  • Buka:

    • Demografi: Data Demografi 2017–2018 (DEMO_J)

    • Kondisi Medis: MCQ_J

    • Merokok - Penggunaan Rokok: SMQ_J

  • Unduh:

    • DEMO_J Data [XPT]

    • MCQ_J Data [XPT]

    • SMQ_J Data [XPT]

  • Simpan sebagai:

    • data/DEMO_J.XPT

    • data/MCQ_J.XPT

    • data/SMQ_J.XPT

# Set paths or URLs here.
# If you've downloaded locally, point to the local paths:
DEMO_PATH = "data/DEMO_J.XPT"
MCQ_PATH  = "data/MCQ_J.XPT"
SMQ_PATH  = "data/SMQ_J.XPT"

# If you prefer to read directly from URLs, uncomment these instead:
# DEMO_PATH = "https://wwwn.cdc.gov/Nchs/NHanes/2017-2018/DEMO_J.XPT"
# MCQ_PATH  = "https://wwwn.cdc.gov/Nchs/NHanes/2017-2018/MCQ_J.XPT"
# SMQ_PATH  = "https://wwwn.cdc.gov/Nchs/NHanes/2017-2018/SMQ_J.XPT"

# Read SAS transport (.XPT) files
demo = pd.read_sas(DEMO_PATH, format="xport")
mcq  = pd.read_sas(MCQ_PATH,  format="xport")
smq  = pd.read_sas(SMQ_PATH,  format="xport")
demo.head()

mcq.head()

smq.head()

Mari lihat beberapa variabel kunci dalam DataFrame ini. Di sini, SEQN adalah ID responden dan dapat digunakan sebagai kunci penggabung.

# %% Inspect key variables

# SEQN is the respondent ID present in all three files.
# Check columns and pick what we need:
print("DEMO columns (subset):", demo.columns[:10])
print("MCQ columns (subset):", mcq.columns[:10])
print("SMQ columns (subset):", smq.columns[:10])
DEMO columns (subset): Index(['SEQN', 'SDDSRVYR', 'RIDSTATR', 'RIAGENDR', 'RIDAGEYR', 'RIDAGEMN',
       'RIDRETH1', 'RIDRETH3', 'RIDEXMON', 'RIDEXAGM'],
      dtype='object')
MCQ columns (subset): Index(['SEQN', 'MCQ010', 'MCQ025', 'MCQ035', 'MCQ040', 'MCQ050', 'AGQ030',
       'MCQ053', 'MCQ080', 'MCQ092'],
      dtype='object')
SMQ columns (subset): Index(['SEQN', 'SMQ020', 'SMD030', 'SMQ040', 'SMQ050Q', 'SMQ050U', 'SMD057',
       'SMQ078', 'SMD641', 'SMD650'],
      dtype='object')

Mari kita saring kolom yang diperlukan dan juga saring berdasarkan usia (lebih dari 20). 

# %% Keep only necessary variables and filter adults

demo_sub = demo[["SEQN", "RIDAGEYR", "RIAGENDR"]].copy()
mcq_sub  = mcq[["SEQN", "MCQ010"]].copy()
smq_sub  = smq[["SEQN", "SMQ040"]].copy()

# Merge on SEQN (inner join: keep only participants present in all three files)
df = (
    demo_sub
    .merge(mcq_sub, on="SEQN", how="inner")
    .merge(smq_sub, on="SEQN", how="inner")
)
# Restrict to adults aged 20+
df = df[df["RIDAGEYR"] >= 20].copy()
df.head()

MCQ010 merepresentasikan pasien dengan kondisi Asma, di mana nilai 1 berarti Ya dan 2 berarti Tidak. Demikian pula, SMQ040 menunjukkan apakah responden seorang perokok atau bukan. 

# %% Recode variables into binary indicators

# 1. Asthma: MCQ010
#    1 = Yes, 2 = No, 7 = Refused, 9 = Don't know
#    We'll create asthma_ever: 1 = yes, 0 = no, NaN otherwise

df["asthma_ever"] = np.nan
df.loc[df["MCQ010"] == 1, "asthma_ever"] = 1
df.loc[df["MCQ010"] == 2, "asthma_ever"] = 0

# 2. Current smoker: SMQ040
#    1 = Every day, 2 = Some days, 3 = Not at all, 7/9 = missing
#    We'll create current_smoker: 1 = yes (1 or 2), 0 = no (3), NaN otherwise

df["current_smoker"] = np.nan
df.loc[df["SMQ040"].isin([1, 2]), "current_smoker"] = 1
df.loc[df["SMQ040"] == 3, "current_smoker"] = 0

# Drop rows with missing recodes
df_clean = df.dropna(subset=["asthma_ever", "current_smoker"]).copy()
df_clean[["RIDAGEYR", "MCQ010", "asthma_ever", "SMQ040", "current_smoker"]].head()

Kita membuat kolom baru, asthma_ever dan current_smoker

Mari buat tabel kontingensi sehingga kita dapat menggunakan Uji Eksak Fisher.

# %% Build a 2×2 contingency table

# Ensure ints
df_clean["asthma_ever"] = df_clean["asthma_ever"].astype(int)
df_clean["current_smoker"] = df_clean["current_smoker"].astype(int)

contingency = pd.crosstab(
    df_clean["current_smoker"],
    df_clean["asthma_ever"],
    rownames=["Current smoker (1=yes,0=no)"],
    colnames=["Ever told asthma (1=yes,0=no)"]
)
contingency

Konversikan tabel kontingensi ke array NumPy.

# %% Fisher's Exact Test

# Convert to 2x2 numpy array with explicit ordering:
# rows: [non-smoker, smoker] ; cols: [no asthma, asthma]
table = np.array([
    [contingency.loc[0, 0], contingency.loc[0, 1]],
    [contingency.loc[1, 0], contingency.loc[1, 1]]
])

table
array([[1102,  226],
       [ 832,  172]])

Terakhir, jalankan Uji Eksak Fisher dua arah dan satu arah.

# Run Fisher's exact test (two-sided and one-sided)
oddsratio, p_two_sided = fisher_exact(table, alternative="two-sided")
_, p_smoker_higher_asthma = fisher_exact(table, alternative="greater")
_, p_smoker_lower_asthma  = fisher_exact(table, alternative="less")

print("2x2 table (rows: non-smoker, smoker; cols: no asthma, asthma)")
print(table)
print()
print(f"Odds ratio (Fisher): {oddsratio:.3f}")
print(f"Two-sided p-value: {p_two_sided:.5f}")
print(f"One-sided p-value (H1: smokers have higher asthma odds): {p_smoker_higher_asthma:.5f}")
print(f"One-sided p-value (H1: smokers have lower asthma odds): {p_smoker_lower_asthma:.5f}")
2x2 table (rows: non-smoker, smoker; cols: no asthma, asthma)
[[1102  226]
 [ 832  172]]

Odds ratio (Fisher): 1.008
Two-sided p-value: 0.95571
One-sided p-value (H1: smokers have higher asthma odds): 0.49274
One-sided p-value (H1: smokers have lower asthma odds): 0.55144

Nilai p yang tinggi menunjukkan tidak ada bukti asosiasi yang signifikan secara statistik antara kebiasaan merokok saat ini dan pernah didiagnosis asma dalam sampel ini.

Odds ratio ~1 berarti perokok saat ini memiliki peluang nyaris sama untuk melaporkan diagnosis asma seperti non-perokok. Perbedaan apa pun yang diamati masih dalam batas yang bisa terjadi secara acak.

Perbandingan dengan Metode Statistik Alternatif

Berbagai uji statistik digunakan untuk menganalisis hubungan dalam tabel kontingensi bergantung pada ukuran sampel, struktur data, dan asumsi:

Uji eksak Fisher

Terbaik untuk sampel kecil dan ketika beberapa jumlah sel harapan rendah. Memberikan nilai p eksak, sehingga sangat andal, namun bisa menjadi lambat secara komputasional saat tabel membesar.

Uji chi-square

Pilihan standar untuk ukuran sampel besar. Cepat, umum, dan mudah diterapkan, tetapi menjadi tidak akurat ketika jumlah harapan turun di bawah 5 karena bergantung pada pendekatan perkiraan.

Uji eksak Barnard

Alternatif yang lebih kuat terhadap uji Fisher pada tabel 2×2. Tidak mengasumsikan margin tetap, yang dapat membuat hasil lebih sensitif, tetapi metode ini lebih jarang diimplementasikan dalam perangkat lunak.

Uji McNemar

Dirancang untuk data kategorikal berpasangan atau berpadanan (misalnya, sebelum vs. sesudah perlakuan pada subjek yang sama). Memperhitungkan ketergantungan antarobservasi, tetapi tidak dapat digunakan ketika titik data independen.

Metode

Kapan Digunakan

Kekuatan

Keterbatasan

Uji eksak Fisher

Sampel kecil, jumlah harapan rendah

Nilai p eksak

Konservatif, lambat untuk tabel besar

Uji chi-square

Ukuran sampel besar

Cepat, banyak digunakan

Bias saat jumlah harapan < 5

Uji eksak Barnard

Alternatif untuk Fisher, daya lebih tinggi

Tidak dibatasi margin tetap

Lebih jarang tersedia

Uji McNemar

Data kategorikal berpasangan

Menangani ketergantungan

Bukan untuk sampel independen

Pertimbangan Komputasional

Performa bisa menjadi perhatian pada uji eksak Fisher karena komputasi berskala buruk ketika melampaui tabel kontingensi 2×2 sederhana. Meskipun ekstensi Freeman–Halton memungkinkan uji ini diterapkan pada tabel 2×3 dan 3×3, biaya komputasi meningkat pesat seiring bertambahnya ukuran tabel. Akibatnya, algoritme dan optimasi yang efisien sangat penting di bidang seperti genetika dan riset klinis, di mana pengujian eksak mungkin perlu dilakukan berulang kali pada banyak dataset kecil namun kompleks.

Interpretasi & Pelaporan Statistik

Saat menafsirkan dan melaporkan hasil uji eksak Fisher, penting untuk menyertakan nilai p eksak, memberikan odds ratio beserta interval kepercayaan 95%, dan menyatakan dengan jelas apakah uji satu atau dua arah dilakukan. Hasil juga sebaiknya didukung konteks praktis untuk membantu pembaca memahami signifikansi temuan di dunia nyata. Misalnya, seseorang dapat menulis: “Uji eksak Fisher menunjukkan asosiasi signifikan antara perlakuan dan pemulihan (OR=11.0, p=0.02, dua arah).”

Ekstensi dan Aplikasi Lanjutan

Ekstensi dan aplikasi lanjutan dari uji eksak Fisher membantu menangani skenario data yang lebih kompleks dan meningkatkan akurasi saat berhadapan dengan dataset kecil atau jarang. Ekstensi Freeman–Halton memungkinkan uji diterapkan pada tabel kontingensi yang lebih besar di luar format standar 2×2, seperti tabel 2×3 atau 3×3. Uji mid-P eksak menawarkan alternatif yang kurang konservatif terhadap uji Fisher, meningkatkan daya statistik sekaligus tetap andal. Uji eksak Bayesian menggabungkan pengetahuan a priori ke dalam analisis, sehingga sangat berguna ketika data terbatas atau ketika pertimbangan pakar dapat memandu inferensi. Selain itu, metode koreksi bias untuk odds ratio memberikan estimasi ukuran efek yang lebih akurat dalam studi dengan ukuran sampel kecil atau jumlah nol, memastikan interpretasi yang lebih baik atas kekuatan dan arah asosiasi.

Keterbatasan dan Pertimbangan Metodologis

Uji eksak Fisher dapat bersifat konservatif, yang dapat mengurangi daya statistik dan menyulitkan untuk mendeteksi efek nyata, terutama dalam studi kecil. Ketika data sangat jarang, interpretasi hasil bisa menantang karena interval kepercayaan melebar dan estimasi menjadi tidak stabil. Selain itu, menerapkan uji berulang pada banyak variabel meningkatkan risiko temuan positif palsu, sehingga pengendalian cermat terhadap pengujian berganda menjadi penting.

Memvisualisasikan Tabel Kontingensi

Opsi visualisasi yang baik untuk menyajikan hasil tabel kontingensi mencakup diagram batang bertumpuk, diagram batang berdampingan, dan plot mosaik. Visual ini membantu mengkomunikasikan hubungan antara variabel kategorikal dengan jelas dan mempermudah interpretasi pola atau perbedaan antar kelompok.

Berikut contoh Python:

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({
    "Outcome": ["Recovered", "Not Recovered"] * 2,
    "Count": [8, 2, 4, 11],
    "Group": ["Treatment"] * 2 + ["Control"] * 2
})

sns.barplot(data=df, x="Outcome", y="Count", hue="Group")
plt.title("Treatment Outcomes")
plt.show()

Kesimpulan

Uji eksak Fisher tetap menjadi standar emas untuk menganalisis dataset kategorikal kecil. Lahir dari secangkir teh di taman, uji ini telah berkembang menjadi alat penting dan banyak digunakan dalam kedokteran, genetika, riset subjek manusia, dan eksperimen bisnis.

Daftar di jalur keterampilan Dasar-dasar Statistik di Python kami untuk terus belajar yang, selain pengujian hipotesis, akan membantu Anda berlatih membangun model statistik dengan regresi linear dan logistik.

Vidhi Chugh

Penulis

Vidhi Chugh

Saya adalah Penasihat dan Etikus AI yang bekerja di persimpangan ilmu data, produk, dan rekayasa untuk membangun sistem pembelajaran mesin yang dapat diskalakan. Masuk dalam daftar "200 Inovator Bisnis dan Teknologi Teratas" di dunia, saya memiliki misi untuk mendemokratisasi pembelajaran mesin dan menyederhanakan jargon agar semua orang dapat menjadi bagian dari transformasi ini.

FAQs

Bagaimana perbedaan uji eksak Fisher dengan uji chi-square?

Uji eksak Fisher menghitung probabilitas eksak dan ideal untuk ukuran sampel kecil atau jumlah harapan sel yang rendah, sedangkan uji chi-square menggunakan pendekatan sampel besar yang bisa menjadi tidak akurat ketika jumlah harapan turun di bawah 5.

Apa aplikasi praktis uji eksak Fisher dalam riset medis?

Uji ini umum digunakan untuk mengevaluasi efektivitas perlakuan, menganalisis hasil uji klinis, menyelidiki asosiasi penyakit, dan mempelajari faktor risiko genetik — terutama saat ukuran sampel pasien kecil.

Apakah uji eksak Fisher dapat digunakan untuk tabel kontingensi lebih besar dari 2×2?

Ya, uji eksak Fisher dapat diperluas ke tabel yang lebih besar menggunakan metode seperti ekstensi Freeman–Halton, meskipun komputasinya menjadi lebih menuntut seiring bertambahnya ukuran tabel.

Apa saja asumsi yang diperlukan untuk menggunakan uji eksak Fisher?

Data harus kategorikal, terorganisasi dalam tabel kontingensi, dengan observasi independen dan total baris serta kolom yang tetap di bawah hipotesis nol.

Bagaimana hubungan distribusi hipergeometrik dengan uji eksak Fisher?

Uji eksak Fisher mendasarkan perhitungan probabilitasnya pada distribusi hipergeometrik, yang memodelkan kemungkinan mengamati susunan jumlah tertentu dengan total marginal yang tetap.

Topik

Terkait

blogs

Tutorial Korelasi di R

blogs

Spaghetti Plot dan Jalur Badai

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026