MIF_E31222663/app/Http/Controllers/UjiController.php

684 lines
25 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\DataUji;
use App\Models\Prediksi;
use App\Models\DataLatih;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\HasilPengujian;
class UjiController extends Controller
{
public function index()
{
$dataLatih = DataLatih::all();
$dataUji = session('data_uji', []);
$jumlahDataLatih = $dataLatih->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
];
}
}