Decision tree pada chapter sebelumnya meninggalkan satu kekhawatiran: satu pohon yang dilatih ulang dengan data sedikit berbeda bisa menghasilkan aturan yang berubah total. Random forest menjawab kekhawatiran itu dengan strategi jumlah — daripada memercayai satu pohon, latih ratusan pohon di atas salinan-salinan acak data dan ambil suara mayoritasnya. Model ini menjadi praktik standar bertahun-tahun karena hasilnya yang kuat tanpa perlu penyetelan rumit. Pada chapter ini kita memakainya untuk menyaring risiko diabetes ringan dari data pemeriksaan sederhana puskesmas, lalu membedah dua hal yang membuatnya istimewa: mekanisme bagging dan cara membaca feature_importances_ tanpa tertipu.

Ensemble: Kekuatan dari Banyak Pohon #

Random forest adalah ensemble — gabungan banyak model yang bekerja bersama. Bahan bakunya decision tree persis seperti chapter sebelumnya, tetapi setiap pohon mendapat dua suntikan acak:

KomponenMekanismeEfeknya
Bootstrap samplingTiap pohon dilatih pada sampel acak dengan penggantian dari data latihTiap pohon melihat sudut data yang sedikit berbeda
Pemilihan fitur acakTiap percabangan hanya boleh memakai sebagian fitur terpilih acakPohon-pohon tidak seragam; kekuatan kolektifnya naik
Voting mayoritasPrediksi akhir = kelas terbanyak dari seluruh pohonKesalahan pohon tunggal saling meniadakan

Poin terakhir itulah inti gagasannya. Satu pohon yang menghafal derau akan meleset, tetapi ratusan pohon yang masing-masing meleset ke arah berbeda cenderung saling mengoreksi saat hasilnya dijumlahkan — kesalahan acak meniadakan sesamanya, sinyal sejati bertahan. Ukuran ini dikenal sebagai bagging (bootstrap aggregating); ia menurunkan variansi model tanpa menaikkan bias, persis obat untuk decision tree yang berfungsi normal tetapi tidak stabil.

Melatih Hutan pada Data Pemeriksaan #

Kasus kita: 34 pasien puskesmas dengan empat fitur gaya hidup dan kondisi tubuh — umur (tahun), bmi, olahraga_per_pekan (kali), makan_manis_per_pekan (kali) — serta status diabetes hasil pemeriksaan: 1 berarti terdeteksi diabetes ringan, 0 sehat. Pola umumnya: bmi tinggi, jarang bergerak, dan sering jajan manis berkumpul di kelompok positif, dengan beberapa pasien perbatasan yang membingungkan:

python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

pasien = pd.DataFrame({
    "umur": [33, 38, 28, 39, 40, 26, 35, 61, 58, 24, 31, 55, 42, 47, 59, 63, 29,
             65, 57, 53, 45, 36, 52, 51, 49, 27, 48, 44, 41, 46, 37, 50, 43, 34],
    "bmi": [22, 25, 22, 27, 23, 20, 24, 29, 34, 19, 21, 36, 22, 32, 35, 30, 23,
            33, 37, 26, 24, 21, 31, 28, 33, 20, 23, 31, 26, 28, 26, 27, 25, 25],
    "olahraga_per_pekan": [6, 4, 5, 1, 3, 5, 4, 0, 1, 6, 6, 0, 3, 2, 0, 1, 4,
                           1, 2, 5, 5, 7, 0, 3, 2, 5, 4, 0, 2, 2, 3, 4, 1, 2],
    "makan_manis_per_pekan": [1, 2, 2, 5, 2, 3, 3, 5, 7, 2, 1, 6, 2, 7, 6, 5, 2,
                              4, 6, 2, 3, 1, 6, 5, 8, 1, 3, 8, 4, 5, 3, 3, 4, 3],
    "diabetes": [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0,
                 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0],
})

fitur = ["umur", "bmi", "olahraga_per_pekan", "makan_manis_per_pekan"]
X = pasien[fitur]
y = pasien["diabetes"]

X_latih, X_uji, y_latih, y_uji = train_test_split(X, y, test_size=0.3,
                                                   stratify=y, random_state=42)
model = RandomForestClassifier(n_estimators=200, random_state=42)
model.fit(X_latih, y_latih)

print("Akurasi data latih : %.2f" % model.score(X_latih, y_latih))
print("Akurasi data uji   : %.2f" % model.score(X_uji, y_uji))
print()
print("Pentingnya fitur:")
for nama, skor in sorted(zip(fitur, model.feature_importances_), key=lambda t: -t[1]):
    print("  %-20s: %.2f" % (nama, skor))

Output yang Dihasilkan:

text
Akurasi data latih : 1.00
Akurasi data uji   : 1.00

Pentingnya fitur:
  makan_manis_per_pekan: 0.32
  bmi                 : 0.30
  olahraga_per_pekan  : 0.22
  umur                : 0.17

Mari kita telaah baris-baris kode di atas:

  1. RandomForestClassifier(n_estimators=200, random_state=42): n_estimators adalah jumlah pohon di hutan — 200 cukup untuk stabilitas tanpa membuat pelatihan lambat pada data sekecil ini. random_state tetap wajib karena seluruh kekuatan model ada pada dua sumber acak (bootstrap dan fitur); tanpa penguncian, hasil bisa bergeser tiap dijalankan.
  2. Akurasi uji 1,00 pada 11 pasien — hutan mengoreksi seluruh kesalahan yang biasanya dijumpai pohon tunggal di zona perbatasan bmi 25-28. Sebelum angka ini kita rayakan, ingat ukuran datanya: satu pasien bernilai 9 poin persen, dan penilaian yang layak pakai butuh ribuan baris dengan cross-validation di Section Evaluasi dan Validasi Model .
  3. model.feature_importances_ berupa larik yang sejajar dengan kolom X; sorted(..., key=lambda t: -t[1]) mengurutkannya mulai dari yang paling penting. Kita membacanya sekarang — dengan beberapa catatan penting.

Berapa Pohon yang Cukup #

Kalau 200 pohon bagus, apakah 2.000 lebih bagus? Kita ukur langsung akurasi uji hutan dengan jumlah pohon bertambah:

python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

pasien = pd.DataFrame({
    "umur": [33, 38, 28, 39, 40, 26, 35, 61, 58, 24, 31, 55, 42, 47, 59, 63, 29,
             65, 57, 53, 45, 36, 52, 51, 49, 27, 48, 44, 41, 46, 37, 50, 43, 34],
    "bmi": [22, 25, 22, 27, 23, 20, 24, 29, 34, 19, 21, 36, 22, 32, 35, 30, 23,
            33, 37, 26, 24, 21, 31, 28, 33, 20, 23, 31, 26, 28, 26, 27, 25, 25],
    "olahraga_per_pekan": [6, 4, 5, 1, 3, 5, 4, 0, 1, 6, 6, 0, 3, 2, 0, 1, 4,
                           1, 2, 5, 5, 7, 0, 3, 2, 5, 4, 0, 2, 2, 3, 4, 1, 2],
    "makan_manis_per_pekan": [1, 2, 2, 5, 2, 3, 3, 5, 7, 2, 1, 6, 2, 7, 6, 5, 2,
                              4, 6, 2, 3, 1, 6, 5, 8, 1, 3, 8, 4, 5, 3, 3, 4, 3],
    "diabetes": [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0,
                 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0],
})
X = pasien[["umur", "bmi", "olahraga_per_pekan", "makan_manis_per_pekan"]]
y = pasien["diabetes"]
X_latih, X_uji, y_latih, y_uji = train_test_split(X, y, test_size=0.3,
                                                   stratify=y, random_state=42)

print("n_estimators | akurasi uji")
for n in [1, 5, 25, 200]:
    model = RandomForestClassifier(n_estimators=n, random_state=42).fit(X_latih, y_latih)
    print("%12d | %11.2f" % (n, model.score(X_uji, y_uji)))

Output yang Dihasilkan:

text
n_estimators | akurasi uji
           1 |        0.91
           5 |        1.00
          25 |        1.00
         200 |        1.00

Pola pada tabel ini adalah watak bagging yang khas:

  1. n_estimators=1 berarti tanpa pengoreksi: akurasi 0,91 — satu pohon bootstrap tunggal meleset pada satu pasien perbatasan, persis kerapuhan pohon pada chapter sebelumnya.
  2. Lima pohon sudah cukup di sini: voting mayoritas menutup kesalahan pohon tunggal dan akurasi mentok di 1,00. Pada data 34 baris, kontribusi tiap pohon tambahan cepat jenuh.
  3. Menambah pohon hampir tak pernah memperburuk — paling buruk hasilnya mendatar — tetapi biaya waktu pelatihan dan prediksi tetap dibayar. Praktik umum: mulai dari 100-300 pohon, naikkan hanya bila kurva metrik pada validasi masih menanjak.

Membaca Kepentingan Fitur dengan Hati-hati #

Keluaran feature_importances_ kita menyampaikan cerita yang masuk akal secara medis — kebiasaan jajan manis (0,32) dan bmi (0,30) menempati posisi teratas, diikuti olahraga (0,22), dengan umur paling bawah (0,17). Namun angka-angka ini harus dibaca sebagai peringkat kontribusi dalam model ini, bukan ukuran pengaruh sebab-akibat di dunia nyata. Tiga jebakannya:

  • Fitur berkorelasi saling membagi nilai. Bmi dan kebiasaan jajan manis bergerak bersama pada data kita; pohon yang bisa memakai keduanya akan bergantian, sehingga kepentingan tiap fitur tampak lebih kecil daripada kontribusi gabungannya.
  • Fitur bernilai banyak unik disukai. Umur yang nyaris berbeda di tiap pasien menawarkan banyak titik belahan — kepentingannya bisa menggelembung bukan karena penting, melainkan karena sering dipakai.
  • Yang diukur adalah model, bukan kebenaran. Bila model kita lemah, kepentingan fiturnya pun sulit dipercaya.

Kekuatan dan Kelemahan Random Forest #

AspekKeterangan
Performa bawaan kuatSering langsung tampil baik pada percobaan pertama tanpa penyetelan rumit
Tahan overfittingVoting ratusan pohon meredam kecenderungan menghafal
Tanpa penskalaan fiturWarisan dari decision tree; bmi dan umur boleh beda satuan
Kepentingan fitur tersediaPeringkat kontribusi siap baca, dengan catatan hati-hati
Ukurannya besarRatusan pohon memakan memori dan waktu prediksi
Kurang transparanTidak ada satu aturan if-else yang bisa dipasang di dinding
Ekstrapolasi tak bisaSeperti pohon: hanya menjawab di dalam rentang data latih

Kapan Kita Memakainya #

Random forest adalah pilihan aman pertama untuk data tabular berlabel: pelanggan, pasien, transaksi, sensor. Ia menonjol saat fitur campur tipe satuan, saat hubungan antar fitur dan target tidak berbentuk garis, dan saat kita lebih menghargai akurasi stabil daripada satu rumus yang bisa dijelaskan. Jika akurasi hutan dirasa masih kurang dan kita rela menyetel lebih serius, keluarga ensemble berikutnya menawarkan pendekatan yang lebih halus: membangun pohon secara berurutan, satu koreksi demi satu koreksi.

Rangkuman #

  • Random forest = bagging: ratusan decision tree dilatih pada sampel bootstrap dengan fitur acak, lalu voting mayoritas; kesalahan acak saling meniadakan.
  • n_estimators mengatur jumlah pohon; lima pohon sudah menyembuhkan kesalahan pohon tunggal pada data kita (0,91 menjadi 1,00), dan 100-300 adalah wilayah praktis yang lazim.
  • feature_importances_ memberi peringkat kontribusi fitur (manis 0,32, bmi 0,30, olahraga 0,22, umur 0,17) — dibaca sebagai arah eksplorasi, bukan bukti sebab-akibat.
  • Fitur berkorelasi membagi nilai kepentingan; fitur bernilai banyak unik cenderung difavoritkan — permutation_importance adalah pemeriksaan silang yang lebih kokoh.
  • Akurasi sempurna pada data uji kecil bukan laporan akhir; validasi menyeluruh menunggu Section evaluasi.

Bagging melatih pohon-pohonnya berpasangan dan saling lepas — tiap pohon tidak tahu kesalahan pohon lain. Bagaimana kalau setiap pohon baru justru sengaja dilatih untuk mengoreksi kesalahan gabungan pohon-pohon sebelumnya? Mari kita lanjutkan ke mesin koreksi berantai pada chapter Gradient Boosting .

Referensi #

  1. scikit-learn — RandomForestClassifier
  2. scikit-learn — permutation_importance
  3. scikit-learn — FAQ