# 1. Data Observasi (E) - Jumlah H dan T per set (sumber: 5, 49)
# Tiap set terdiri dari 10 pelemparan (n = 10)
obs_data <- data.frame(
set = 1:5,
H = c(5, 9, 8, 4, 7),
T = c(5, 1, 2, 6, 3)
)
# Fungsi EM Iteration
em_coin_flip <- function(theta_A, theta_B, max_iter = 10, tol = 1e-4) {
df_results <- data.frame(iter = 0, theta_A = theta_A, theta_B = theta_B, change = NA)
for (i in 1:max_iter) {
curr_A <- df_results$theta_A[i]
curr_B <- df_results$theta_B[i]
# --- E-STEP ---
# Menghitung probabilitas binomial untuk tiap set (sumber: 33, 41)
# P(E | Z) = (n! / (h!(n-h)!)) * theta^h * (1-theta)^(n-h)
p_E_given_A <- choose(10, obs_data$H) * (curr_A^obs_data$H) * ((1-curr_A)^obs_data$T)
p_E_given_B <- choose(10, obs_data$H) * (curr_B^obs_data$H) * ((1-curr_B)^obs_data$T)
# Menghitung rasio/bobot koin (Responsibility) (sumber: 44, 45)
weight_A <- p_E_given_A / (p_E_given_A + p_E_given_B)
weight_B <- p_E_given_B / (p_E_given_A + p_E_given_B)
# Estimasi jumlah H untuk tiap koin (sumber: 52, 53)
est_H_A <- obs_data$H * weight_A
est_H_B <- obs_data$H * weight_B
# --- M-STEP ---
# Menghitung ulang parameter theta baru (sumber: 11, 54, 55)
new_theta_A <- sum(est_H_A) / sum(weight_A * 10)
new_theta_B <- sum(est_H_B) / sum(weight_B * 10)
# Hitung Perubahan (Euclidean Distance) (sumber: 61, 62)
change <- sqrt((new_theta_A - curr_A)^2 + (new_theta_B - curr_B)^2)
df_results <- rbind(df_results, data.frame(iter = i, theta_A = new_theta_A, theta_B = new_theta_B, change = change))
if (change < tol) break # Batas Konvergensi (sumber: 58, 59)
}
return(df_results)
}
# --- MENGERJAKAN TUGAS: KOMBINASI PARAMETER BERBEDA ---
# Skenario 1: Parameter awal dari materi (thetaA=0.6, thetaB=0.5) (sumber: 30)
skenario_1 <- em_coin_flip(0.6, 0.5)
# Skenario 2: Parameter awal kontras (thetaA=0.9, thetaB=0.1)
skenario_2 <- em_coin_flip(0.9, 0.1)
# Skenario 3: Parameter awal terbalik (thetaA=0.4, thetaB=0.7)
skenario_3 <- em_coin_flip(0.4, 0.7)
print("Hasil Skenario 1 (Awal: 0.6, 0.5):")
## [1] "Hasil Skenario 1 (Awal: 0.6, 0.5):"
print(tail(skenario_1, 1))
## iter theta_A theta_B change
## 11 10 0.7967441 0.5196587 0.0001350369
print("Hasil Skenario 2 (Awal: 0.9, 0.1):")
## [1] "Hasil Skenario 2 (Awal: 0.9, 0.1):"
print(tail(skenario_2, 1))
## iter theta_A theta_B change
## 11 10 0.796779 0.5195549 4.319236e-05
print("Hasil Skenario 3 (Awal: 0.4, 0.7):")
## [1] "Hasil Skenario 3 (Awal: 0.4, 0.7):"
print(tail(skenario_3, 1))
## iter theta_A theta_B change
## 10 9 0.5195484 0.7967691 5.843652e-05
Berdasarkan percobaan dengan berbagai parameter awal di atas, diperoleh beberapa insight penting mengenai cara kerja algoritma EM:
Meskipun kita memulai dengan nilai tebakan awal yang berbeda (misalnya \(\theta_A=0.6\) atau \(\theta_A=0.9\)), algoritma EM cenderung konvergen ke titik optimal yang sama. Dalam data ini, hasil akhirnya selalu mendekati \(\theta \approx 0.796\) dan \(\theta \approx 0.520\).
Parameter awal yang lebih dekat dengan kenyataan data akan membuat algoritma mencapai konvergensi lebih cepat (jumlah iterasi lebih sedikit). Sebaliknya, jika tebakan awal sangat jauh, algoritma membutuhkan lebih banyak langkah E-M untuk “memperbaiki” nilai parameter.
Jika kita memberikan nilai awal yang terbalik (misal \(\theta_A\) lebih kecil dari \(\theta_B\)), algoritma EM tetap akan menemukan dua probabilitas tersebut, namun identitas koinnya akan tertukar.
Algoritma ini sangat bergantung pada threshold atau batas minimum perubahan. Ketika perubahan nilai antar-iterasi sudah sangat kecil (mendekati 0.0000), maka algoritma dianggap telah menemukan solusi optimal untuk variabel laten (identitas koin) tersebut.