count(); $riwayatTerakhir = HasilPengujian::latest('created_at')->whereNotNull('status_prediksi')->get(); if (session()->has('hasil_uji')) { $hasil = session('hasil_uji'); } if ($jumlahDataLatih <= 0) { return "Tidak ada data latih, silahkan input terlebih dahulu"; } // Tidak ada data uji karena belum diproses $jumlahDataUji = 0; $persentase_uji = 0; $persentase_latih = 100; $dataUji = []; // Tetap hitung atribut numerik sebagai persiapan visualisasi $atribut_numerik = $this->hitungAtributNumerik($dataLatih); // Untuk kategori tetap hitung juga $fitur_kategorik = ['faktor1', 'faktor2']; $kelas = ['Naik', 'Turun']; $atribut_kategorik = []; foreach ($fitur_kategorik as $fitur) { $kategori_unik = $dataLatih->pluck($fitur)->unique()->values()->all(); $atribut_kategorik[$fitur] = [ 'kategori' => $kategori_unik, 'status' => [] ]; foreach ($kelas as $label) { $group = $dataLatih->where('hipotesis', $label); $total_group = $group->count(); $prob_kategori = []; foreach ($kategori_unik as $kategori) { $jumlah_kategori = $group->where($fitur, $kategori)->count(); $prob = ($jumlah_kategori + 1) / ($total_group + count($kategori_unik)); $prob_kategori[] = $prob; } $atribut_kategorik[$fitur]['status'][strtolower($label)] = $prob_kategori; } } // Tidak ada hasil uji karena belum dilakukan $hasil = []; $akurasi = 0; $precision = 0; $recall = 0; $tp = $fp = $tn = $fn = 0; // Probabilitas kelas (sebagai info statistik) $jumlah_naik = $dataLatih->where('hipotesis', 'Naik')->count(); $jumlah_turun = $dataLatih->where('hipotesis', 'Turun')->count(); $total_data = $jumlah_naik + $jumlah_turun; $prob_naik = $total_data > 0 ? round(($jumlah_naik / $total_data) * 100, 2) : 0; $prob_turun = $total_data > 0 ? round(($jumlah_turun / $total_data) * 100, 2) : 0; // Data kategorik seperti di index() $fitur_kategorik = ['faktor1', 'faktor2']; $kelas = ['Naik', 'Turun']; $atribut_kategorik = []; // Cek apakah ada data hasil uji di session if (session()->has('hasil_uji')) { $hasil = session('hasil_uji'); $akurasi = session('akurasi_uji'); $precision = session('precision_uji'); $recall = session('recall_uji'); $tp = session('tp_uji'); $fp = session('fp_uji'); $tn = session('tn_uji'); $fn = session('fn_uji'); $persentase_uji = session('persentase_uji'); $persentase_latih = session('persentase_latih'); $jumlahDataUji = session('jumlah_data_uji'); $jumlahDataLatih = session('jumlah_data_latih'); $prob_turun = session('prob_turun', 0); $prob_naik = session('prob_naik', 0); $jumlah_turun = session('jumlah_turun', 0); $jumlah_naik = session('jumlah_naik', 0); $total_data = $jumlah_naik + $jumlah_turun; } else { // Default data kosong kalau belum ada pengujian $hasil = []; $akurasi = 0; $precision = 0; $recall = 0; $tp = $fp = $tn = $fn = 0; $persentase_uji = 0; $persentase_latih = 100; $jumlahDataUji = 0; $jumlah_naik = $dataLatih->where('hipotesis', 'Naik')->count(); $jumlah_turun = $dataLatih->where('hipotesis', 'Turun')->count(); $total_data = $jumlah_naik + $jumlah_turun; // Controller $prob_naik = $total_data > 0 ? ($jumlah_naik / $total_data) : 0; $prob_turun = $total_data > 0 ? ($jumlah_turun / $total_data) : 0; } foreach ($fitur_kategorik as $fitur) { $kategori_unik = $dataLatih->pluck($fitur)->unique()->values()->all(); $atribut_kategorik[$fitur] = [ 'kategori' => $kategori_unik, 'status' => [] ]; foreach ($kelas as $label) { $group = $dataLatih->where('hipotesis', $label); $total_group = $group->count(); $prob_kategori = []; foreach ($kategori_unik as $kategori) { $jumlah_kategori = $group->where($fitur, $kategori)->count(); $prob = ($jumlah_kategori + 1) / ($total_group + count($kategori_unik)); $prob_kategori[] = $prob; } $atribut_kategorik[$fitur]['status'][strtolower($label)] = $prob_kategori; } } return view('admin.uji-data', [ 'jumlah_data_latih' => $dataLatih->count(), 'persentase_latih' => $persentase_latih, 'persentase_uji' => $persentase_uji, 'jumlah_data_uji' => $jumlahDataUji, 'prob_turun' => $prob_turun, 'prob_naik' => $prob_naik, 'jumlah_turun' => $jumlah_turun, 'jumlah_naik' => $jumlah_naik, 'atribut_numerik' => $this->hitungAtributNumerik($dataLatih), 'atribut_kategorik' => $atribut_kategorik, 'dataUji' => $dataUji, 'data_uji' => $hasil, 'akurasi' => round($akurasi, 2), 'precision' => round($precision, 2), 'recall' => round($recall, 2), 'tp' => $tp, 'fp' => $fp, 'tn' => $tn, 'fn' => $fn, 'data_kasus' => $this->hitungAtributNumerik($dataLatih)['kasus_2023'] ?? [], 'jumlah_data' => $dataLatih->count(), 'total_data' => $total_data, 'riwayat_pengujian' => $riwayatTerakhir, 'from_excel' => false ]); } public function proses(Request $request) { $dataLatih = DataLatih::inRandomOrder()->get(); $persentase = (int) $request->input('persentase'); $total = $dataLatih->count(); if ($total === 0) { return back()->with('error', 'Data kosong'); } // Hitung jumlah data latih dan uji sesuai persentase $jumlahDataLatih = max(round($total * ($persentase / 100)), 1); $jumlahDataUji = $total - $jumlahDataLatih; $dataLatihUpdate = $dataLatih->slice(0, $jumlahDataLatih); $dataUji = $dataLatih->slice($jumlahDataLatih); // Hitung probabilitas kelas dari dataLatihUpdate $probabilitasKelas = $this->hitungProbabilitasKelas($dataLatihUpdate); if (empty($probabilitasKelas)) { return back()->with('error', 'Gagal hitung probabilitas kelas!'); } // Hitung jumlah hipotesis Naik dan Turun di data latih (opsional, bisa untuk info) $jumlah_naik = $dataLatihUpdate->where('hipotesis', 'Naik')->count(); $jumlah_turun = $dataLatihUpdate->where('hipotesis', 'Turun')->count(); $total_data = $jumlah_naik + $jumlah_turun; $hasil = []; $benar = 0; $tp = $fp = $tn = $fn = 0; $hasilSudahAda = HasilPengujian::count() > 0; foreach ($dataUji as $data) { $hipotesisAsli = ucfirst(strtolower($data->hipotesis)); $prediksi = $this->naiveBayes($data, $dataLatihUpdate); $prediksiTahun = ((int)$data->data_tahun <= 2024) ? 2025 : ((int)$data->data_tahun + 1); $status = $prediksi === $hipotesisAsli ? '✅ Benar' : '❌ Salah'; $hasil[] = [ 'id' => $data->id, 'kabupaten' => $data->kecamatan, 'data_tahun' => $data->data_tahun, 'phbs' => $data->phbs, 'imunisasi' => $data->imunisasi, 'merokok' => $data->merokok, 'kasus_2023' => $data->kasus_2023, 'latitude' => $data->latitude, 'longitude' => $data->longitude, 'prediksi_tahun' => $prediksiTahun, 'hipotesis_asli' => $hipotesisAsli, 'prediksi' => $prediksi, 'status' => $status, ]; // Simpan hasil pengujian ke database jika belum ada data if (!$hasilSudahAda) { HasilPengujian::create([ 'kecamatan' => $data->kecamatan, 'data_tahun' => $data->data_tahun, 'phbs' => $data->phbs, 'imunisasi' => $data->imunisasi, 'merokok' => $data->merokok, 'jumlah_kasus' => $data->kasus_2023 ?? 0, 'latitude' => $data->latitude, 'longitude' => $data->longitude, 'prediksi_tahun' => $prediksiTahun, 'status_asli' => $hipotesisAsli, 'status_prediksi' => $prediksi, ]); } // Hitung TP, FP, TN, FN untuk evaluasi if ($hipotesisAsli === 'Naik' && $prediksi === 'Naik') $tp++; if ($hipotesisAsli === 'Naik' && $prediksi === 'Turun') $fn++; if ($hipotesisAsli === 'Turun' && $prediksi === 'Naik') $fp++; if ($hipotesisAsli === 'Turun' && $prediksi === 'Turun') $tn++; if ($hipotesisAsli === $prediksi) $benar++; } $akurasi = $benar / $jumlahDataUji * 100; $precision = $tp + $fp > 0 ? ($tp / ($tp + $fp)) * 100 : 0; $recall = $tp + $fn > 0 ? ($tp / ($tp + $fn)) * 100 : 0; session([ 'hasil_uji' => $hasil, 'akurasi_uji' => round($akurasi, 2), 'precision_uji' => round($precision, 2), 'recall_uji' => round($recall, 2), 'tp_uji' => $tp, 'fp_uji' => $fp, 'tn_uji' => $tn, 'fn_uji' => $fn, 'persentase_uji' => 100 - $persentase, 'persentase_latih' => $persentase, 'jumlah_data_uji' => $dataUji->count(), 'jumlah_data_latih' => $dataLatihUpdate->count(), 'prob_turun' => $probabilitasKelas['Turun'], 'prob_naik' => $probabilitasKelas['Naik'], 'jumlah_turun' => $jumlah_turun, 'jumlah_naik' => $jumlah_naik, 'total_data' => $total_data, 'id_data_latih' => $dataLatihUpdate->pluck('id')->toArray(), 'id_data_uji' => $dataUji->pluck('id')->toArray(), ]); return view('admin.uji-data', [ 'hasil' => $hasil, 'benar' => $benar, 'total' => $jumlahDataUji, 'totalDataLatih' => $jumlahDataLatih, 'akurasi' => round($akurasi, 2), 'precision' => round($precision, 2), 'recall' => round($recall, 2), 'tp' => $tp, 'fp' => $fp, 'tn' => $tn, 'fn' => $fn, 'persentase' => $persentase, 'atribut_numerik' => $this->hitungAtributNumerik($dataLatih), 'jumlah_data' => $jumlahDataLatih, 'data_uji' => $hasil, 'jumlah_data_latih' => $dataLatihUpdate->count(), 'jumlah_data_uji' => $dataUji->count(), 'persentase_latih' => $persentase, 'persentase_uji' => 100 - $persentase, 'probabilitasKelas' => $probabilitasKelas, 'prob_naik' => $probabilitasKelas['Naik'], 'prob_turun' => $probabilitasKelas['Turun'], 'jumlah_naik' => $jumlah_naik, 'jumlah_turun' => $jumlah_turun, 'total_data' => $total_data, 'from_excel' => false ]); } public function naiveBayes($uji, $dataLatih) { $labels = ['Naik', 'Turun']; $fitur = ['phbs', 'imunisasi', 'merokok', 'kasus_2023']; $hasilLogProb = []; foreach ($labels as $label) { $group = $dataLatih->where('hipotesis', $label); $totalGroup = $group->count(); if ($totalGroup == 0) { $hasilLogProb[$label] = -INF; continue; } $prior = $totalGroup / $dataLatih->count(); $logProb = log($prior); foreach ($fitur as $f) { $mean = $group->avg($f); $variance = $group->reduce(function ($carry, $item) use ($f, $mean) { return $carry + pow($item[$f] - $mean, 2); }, 0) / $totalGroup; $variance = max($variance, 1e-6); // Hindari division by zero $prob = (1 / sqrt(2 * M_PI * $variance)) * exp(-pow($uji[$f] - $mean, 2) / (2 * $variance)); $logProb += log($prob); } $hasilLogProb[$label] = $logProb; } // Ambil label dengan logProb terbesar return array_keys($hasilLogProb, max($hasilLogProb))[0]; } private function hitungAtributNumerik($dataLatih) { $atribut_numerik = []; $fitur_numerik = ['phbs', 'imunisasi', 'merokok', 'kasus_2023']; $kelas = ['Naik', 'Turun']; // Mapping label nama atribut $nama_atribut_baru = [ 'phbs' => 'Perilaku Hidup Bersih dan Sehat', 'imunisasi' => 'Imunisasi', 'merokok' => 'Kebiasaan Merokok', 'kasus_2023' => 'Data Kasus', ]; foreach ($fitur_numerik as $fitur) { $atribut_numerik[$fitur] = [ 'label' => $nama_atribut_baru[$fitur] ?? ucfirst($fitur), 'mean' => [], 'std' => [], 'avg_prob' => [], ]; foreach ($kelas as $label) { $group = $dataLatih->where('hipotesis', $label); $mean = $group->avg($fitur) ?? 0; $variansi = $group->reduce(function ($carry, $item) use ($fitur, $mean) { return $carry + pow($item[$fitur] - $mean, 2); }, 0) / max($group->count() - 1, 1); $std = sqrt($variansi); $atribut_numerik[$fitur]['mean'][strtolower($label)] = $mean; $atribut_numerik[$fitur]['std'][strtolower($label)] = $std; $prob = (1 / sqrt(2 * M_PI * $variansi)) * exp(-pow($mean - $mean, 2) / (2 * $variansi)); $atribut_numerik[$fitur]['avg_prob'][strtolower($label)] = round($prob, 6); } } return $atribut_numerik; } public function reset() { // Hapus hasil pengujian dari session session()->forget([ 'hasil_uji', 'akurasi_uji', 'precision_uji', 'recall_uji', 'tp_uji', 'fp_uji', 'tn_uji', 'fn_uji', 'persentase_uji', 'persentase_latih', 'jumlah_data_uji', 'jumlah_data_latih', 'id_data_latih', 'id_data_uji' ]); // Hapus data hasil pengujian dari database jika perlu HasilPengujian::truncate(); // ini akan menghapus semua data dari tabel hasil_pengujian DataUji::truncate(); session()->flash('enable_radio', true); return redirect()->route('admin.uji-data')->with('success', 'Hasil pengujian telah direset.'); } public function upload(Request $request) { $request->validate([ 'file_excel' => 'required|file|mimes:xls,xlsx', ]); $data = \Excel::toArray([], $request->file('file_excel')); if (empty($data[0]) || count($data[0]) < 2) { return back()->withErrors(['file_excel' => 'File Excel kosong atau tidak sesuai format.']); } // Ambil statistik dari data latih $jumlah_naik = DataLatih::where('hipotesis', 'Naik')->count(); $jumlah_turun = DataLatih::where('hipotesis', 'Turun')->count(); $jumlah_data_latih = $jumlah_naik + $jumlah_turun; if ($jumlah_data_latih == 0) { return back()->withErrors(['file_excel' => 'Data latih tidak tersedia atau kosong.']); } $dataBaru = []; $jumlah_data_uji_total = DataUji::count(); // Jumlah data uji, misal 15 $total_datatest = $jumlah_data_latih + $jumlah_data_uji_total; // 17 + 15 = 32 $persentase_latih = $total_datatest > 0 ? round(($jumlah_data_latih / $total_datatest) * 100) : 0; // % data latih dari total $persentase_uji = $total_datatest > 0 ? round(($jumlah_data_uji_total / $total_datatest) * 100) : 0; // % data uji dari total $prob_naik = $jumlah_data_latih > 0 ? round($jumlah_naik / $jumlah_data_latih, 4) : 0; // probabilitas naik dari data latih $prob_turun = $jumlah_data_latih > 0 ? round($jumlah_turun / $jumlah_data_latih, 4) : 0; // probabilitas turun dari data latih $fitur_list = ['phbs', 'imunisasi', 'merokok', 'kasus_2023']; $atribut_numerik = []; $fitur_labels = [ 'phbs' => 'Perilaku Hidup Bersih dan Sehat', 'imunisasi' => 'Imunisasi', 'merokok' => 'Merokok', 'kasus_2023' => 'Jumlah Kasus', ]; foreach ($fitur_list as $fitur) { $data_naik = DataLatih::where('hipotesis', 'Naik')->pluck($fitur)->filter()->values(); $data_turun = DataLatih::where('hipotesis', 'Turun')->pluck($fitur)->filter()->values(); $mean_naik = $data_naik->avg(); $mean_turun = $data_turun->avg(); $std_naik = sqrt($data_naik->map(fn($x) => pow($x - $mean_naik, 2))->avg() ?: 0) ?: 1e-6; $std_turun = sqrt($data_turun->map(fn($x) => pow($x - $mean_turun, 2))->avg() ?: 0) ?: 1e-6; $atribut_numerik[$fitur] = [ 'label' => $fitur_labels[$fitur] ?? 'Tidak ada label', 'mean' => ['naik' => $mean_naik, 'turun' => $mean_turun], 'std' => ['naik' => $std_naik, 'turun' => $std_turun], ]; } $tp = $tn = $fp = $fn = 0; foreach ($data[0] as $index => $row) { if ($index == 0 || strtolower(trim($row[1] ?? '')) === 'kecamatan') continue; $kecamatan = trim($row[1] ?? ''); $jumlah_penduduk = intval($row[2] ?? 0); $data_tahun = intval($row[3] ?? 0); // jika perlu tahun $phbs = floatval(str_replace(',', '.', $row[4] ?? 0)); $imunisasi_pcv_1 = floatval(str_replace(',', '.', $row[5] ?? 0)); // jika kamu gunakan $imunisasi_pcv_2 = floatval(str_replace(',', '.', $row[6] ?? 0)); // jika kamu gunakan $imunisasi = floatval(str_replace(',', '.', $row[7] ?? 0)); $merokok = floatval(str_replace(',', '.', $row[8] ?? 0)); $jumlah_kasus = intval($row[9] ?? 0); $latitude = floatval(str_replace(',', '.', $row[10] ?? 0)); $longitude = floatval(str_replace(',', '.', $row[11] ?? 0)); $status = trim($row[12] ?? ''); if (!$kecamatan || $phbs === null || $imunisasi === null || $merokok === null) { continue; } $rasio = ($phbs + $imunisasi - $merokok) / ($jumlah_kasus ?: 1); $status_asli = $rasio > 1 ? 'Naik' : 'Turun'; $log_naik = log($prob_naik ?: 1e-10); $log_turun = log($prob_turun ?: 1e-10); $fitur_values = [ 'phbs' => $phbs, 'imunisasi' => $imunisasi, 'merokok' => $merokok, 'kasus_2023' => $jumlah_kasus, ]; foreach ($fitur_values as $fitur => $value) { $mean_naik = $atribut_numerik[$fitur]['mean']['naik']; $mean_turun = $atribut_numerik[$fitur]['mean']['turun']; $std_naik = $atribut_numerik[$fitur]['std']['naik']; $std_turun = $atribut_numerik[$fitur]['std']['turun']; $gauss_naik = (1 / ($std_naik * sqrt(2 * M_PI))) * exp(-pow($value - $mean_naik, 2) / (2 * pow($std_naik, 2))); $gauss_turun = (1 / ($std_turun * sqrt(2 * M_PI))) * exp(-pow($value - $mean_turun, 2) / (2 * pow($std_turun, 2))); $log_naik += log($gauss_naik ?: 1e-10); $log_turun += log($gauss_turun ?: 1e-10); } $prediksi = $log_naik > $log_turun ? 'Naik' : 'Turun'; if ($status_asli == 'Naik' && $prediksi == 'Naik') $tp++; elseif ($status_asli == 'Turun' && $prediksi == 'Turun') $tn++; elseif ($status_asli == 'Turun' && $prediksi == 'Naik') $fp++; elseif ($status_asli == 'Naik' && $prediksi == 'Turun') $fn++; $dataUji = new DataUji(); $dataUji->kecamatan = $kecamatan; $dataUji->jumlah_penduduk = $jumlah_penduduk; $dataUji->data_tahun = $data_tahun; $dataUji->phbs = $phbs; $dataUji->imunisasi_pcv_1 = $imunisasi_pcv_1; $dataUji->imunisasi_pcv_2 = $imunisasi_pcv_2; $dataUji->rata_rata_imunisasi = $imunisasi; $dataUji->perilaku_merokok = $merokok; $dataUji->data_kasus = $jumlah_kasus; $dataUji->latitude = $latitude; $dataUji->longitude = $longitude; $dataUji->status_prediksi = $prediksi; $dataUji->save(); // Cek apakah data uji untuk kecamatan ini sudah ada $dataUjiExist = DataUji::where('kecamatan', $kecamatan)->first(); if (!$dataUjiExist) { // Jika belum ada, simpan data baru $dataUji = new DataUji(); $dataUji->kecamatan = $kecamatan; $dataUji->jumlah_penduduk = $jumlah_penduduk; $dataUji->data_tahun = $data_tahun; $dataUji->phbs = $phbs; $dataUji->imunisasi_pcv_1 = $imunisasi_pcv_1; $dataUji->imunisasi_pcv_2 = $imunisasi_pcv_2; $dataUji->rata_rata_imunisasi = $imunisasi; $dataUji->perilaku_merokok = $merokok; $dataUji->data_kasus = $jumlah_kasus; $dataUji->latitude = $latitude; $dataUji->longitude = $longitude; $dataUji->status_prediksi = $prediksi; $dataUji->save(); } $dataBaru[] = [ 'id' => $dataUji->id, 'kabupaten' => $dataUji->kecamatan, 'jumlah_penduduk' => $dataUji->jumlah_penduduk, 'data_tahun' => $data_tahun, 'phbs' => $dataUji->phbs, 'pcv1' => $dataUji->imunisasi_pcv_1 ?? '-', 'pcv2' => $dataUji->imunisasi_pcv_2 ?? '-', 'imunisasi' => $dataUji->rata_rata_imunisasi, 'merokok' => $dataUji->perilaku_merokok, 'kasus_2023' => $dataUji->data_kasus, 'latitude' => $dataUji->latitude ?? '-', 'longitude' => $dataUji->longitude ?? '-', 'hipotesis_asli' => $status_asli, 'prediksi' => $dataUji->status_prediksi, ]; } $jumlah_data_uji_baru = count($dataBaru); $total = $tp + $tn + $fp + $fn; $akurasi = $total > 0 ? (($tp + $tn) / $total) * 100 : 0; $precision = ($tp + $fp) > 0 ? ($tp / ($tp + $fp)) * 100 : 0; $recall = ($tp + $fn) > 0 ? ($tp / ($tp + $fn)) * 100 : 0; session([ 'hasil_uji' => $dataBaru, 'akurasi_uji' => round($akurasi, 2), 'precision_uji' => round($precision, 2), 'recall_uji' => round($recall, 2), 'tp_uji' => $tp, 'fp_uji' => $fp, 'tn_uji' => $tn, 'fn_uji' => $fn, 'persentase_uji' => $persentase_uji, 'persentase_latih' => $persentase_latih, 'jumlah_data_uji' => $jumlah_data_uji_total + $jumlah_data_uji_baru, 'jumlah_data_latih' => $jumlah_data_latih, 'prob_turun' => $prob_turun, 'prob_naik' => $prob_naik, 'jumlah_turun' => $jumlah_turun, 'jumlah_naik' => $jumlah_naik, 'total_data' => $total_datatest + $jumlah_data_uji_baru, 'id_data_latih' => DataLatih::pluck('id')->toArray(), 'id_data_uji' => DataUji::pluck('id')->toArray(), ]); session()->flash('success', 'Data testing berhasil diupload dan diuji.'); $fileHash = md5_file($request->file('file_excel')->getRealPath()); if (session('last_upload_hash') === $fileHash) { return back()->with('message', 'File sudah diuji sebelumnya. Silakan upload file lain.'); } session(['last_upload_hash' => $fileHash]); return view('admin.uji-data', [ 'data_uji' => $dataBaru, 'persentase_latih' => $persentase_latih, 'persentase_uji' => $persentase_uji, 'jumlah_data_latih' => $jumlah_data_latih, 'jumlah_data_uji' => $jumlah_data_uji_total + $jumlah_data_uji_baru, 'jumlah_naik' => $jumlah_naik, 'jumlah_turun' => $jumlah_turun, 'prob_naik' => $prob_naik, 'prob_turun' => $prob_turun, 'atribut_numerik' => $atribut_numerik, 'akurasi' => $akurasi, 'precision' => $precision, 'recall' => $recall, 'tp' => $tp, 'tn' => $tn, 'fp' => $fp, 'fn' => $fn, 'total_data' => $total_datatest + $jumlah_data_uji_baru, 'from_excel' => true, ]); } private function hitungConfusionMatrix($dataUji) { $tp = $fp = $tn = $fn = 0; foreach ($dataUji as $data) { $actual = $data['hipotesis_asli']; $pred = $data['prediksi']; if ($actual === 'Naik' && $pred === 'Naik') $tp++; elseif ($actual === 'Naik' && $pred === 'Turun') $fn++; elseif ($actual === 'Turun' && $pred === 'Naik') $fp++; elseif ($actual === 'Turun' && $pred === 'Turun') $tn++; } return compact('tp', 'fp', 'tn', 'fn'); } // Fungsi untuk hitung probabilitas kelas dari data latih public function hitungProbabilitasKelas($dataLatih) { $jumlah_naik = 0; $jumlah_turun = 0; foreach ($dataLatih as $item) { if (!isset($item->hipotesis)) { continue; // skip kalau property hipotesis tidak ada } $hip = strtolower($item->hipotesis); if ($hip === 'naik') { $jumlah_naik++; } elseif ($hip === 'turun') { $jumlah_turun++; } } $total_data = count($dataLatih); $jumlah_kelas = 2; $prob_naik = ($jumlah_naik + 1) / ($total_data + $jumlah_kelas); $prob_turun = ($jumlah_turun + 1) / ($total_data + $jumlah_kelas); return [ 'Naik' => $prob_naik, 'Turun' => $prob_turun, 'jumlah_naik' => $jumlah_naik, 'jumlah_turun' => $jumlah_turun, 'total_data' => $total_data ]; } }