load->helper('url'); $this->load->model('M_pelayanan'); $this->load->model('M_pengunjung'); if ($this->session->userdata('status') != "login") { redirect(base_url("Auth")); } } public function index() { $id_pelayanan = $this->input->get('id_pelayanan'); $bulan = $this->input->get('bulan'); $tahun = $this->input->get('tahun'); $data['pelayanan'] = $this->M_pelayanan->get_all()->result(); $data['alpha'] = $this->M_pelayanan->alpha()->row_array(); if ($bulan != "" && $tahun != "") { $data['detail_pelayanan'] = $this->M_pelayanan->get_detail($id_pelayanan)->row_array(); $ft = $this->get_peramalan($id_pelayanan, $bulan, $tahun); $data['data'] = $ft['hasilRamal']; $data['MAD'] = $ft['MAD']; $data['MSE'] = $ft['MSE']; $data['MAPE'] = $ft['MAPE']; $data['ratarataKesalahan'] = $ft['ratarataKesalahan']; } else { $data['detail_pelayanan'] = null; $data['data'] = []; $data['MAD'] = null; $data['MSE'] = null; $data['MAPE'] = null; $data['ratarataKesalahan'] = null; } $this->load->view('peramalan', $data); } public function update_alpha() { $alpha = $this->input->post('alpha'); $beta = $this->input->post('beta'); $gamma = $this->input->post('gamma'); $data = array( 'alpha' => $alpha, 'beta' => $beta, 'gamma' => $gamma ); $where = array( 'id_alpha' => '1' ); $this->M_pelayanan->update($where, $data, 'alpha'); $response['success'] = true; $response['message'] = "Alpha Berhasil Diubah !"; echo json_encode($response); } public function get_peramalan($id_pelayanan, $bulan, $tahun) { $hasilRamal = array(); $awal = $this->M_pengunjung->tgl_kunjungan($id_pelayanan, 'asc')->row_array(); $akhir = $this->M_pengunjung->tgl_kunjungan($id_pelayanan, 'desc')->row_array(); $params = $this->M_pelayanan->alpha()->row_array(); $alpha = $params['alpha']; $beta = $params['beta']; $gamma = $params['gamma']; $L = $params['periode']; $dataAktual = []; $blnRamal = $tahun . '-' . $bulan . '-01'; $blnAwal = isset($awal['tanggal']) ? $awal['tanggal'] : date('Y-m-d'); $blnAkhir = isset($akhir['tanggal']) ? $akhir['tanggal'] : date('Y-m-d'); // mengambil data rekap pengunjung if ($id_pelayanan!="") { $srs = $this->M_pengunjung->get_rekap_pengunjung($id_pelayanan)->result_array(); } else { $srs = $this->M_pengunjung->get_rekap_total_pengunjung()->result_array(); } // Mengambil nilai data aktual foreach ($srs as $row) { $dataAktual[] = $row['jumlah']; } $starter = 0; $lb = 0; // generate list bulan dan jumlah data aktual, dari awal hingga akhir bulan kunjungan pada setiap pelayanan for ($t = date("Y", strtotime($blnAkhir)); $t <= date("Y", strtotime($blnRamal)); $t++) { if ($starter == 0) { $lb = date("m", strtotime($blnAkhir)) + 1; } else { $lb = 1; } for ($b = $lb; $b <= 13; $b++) { if ($b > 12) { $starter = 1; break; } else { if ($t == date("Y", strtotime($blnRamal)) && $b > date("m", strtotime($blnRamal))) { break; } else { // proses menambahkan / menggabungkan data series bulanan dengan bulan selanjutnya $bulanStr = sprintf("%02d", $b) . "-" . $t; $srs[] = array( 'bulan' => $bulanStr, 'jumlah' => null ); } } } } // Jika data rekap pengunjung sebelumnya kosong maka akan mengembalikan nilai dengan data peramalan null if (count($dataAktual) == 0) { for ($i = 0; $i < count($srs); $i++) { $hasilRamal[] = array( 'bulan' => $srs[$i]['bulan'], 'jumlah' => isset($srs[$i]['jumlah']) ? $srs[$i]['jumlah'] : 0, 'lt' => null, 'bt' => null, 'st' => null, 'ft' => null, 'xt_ft' => null, 'xt_ft2' => null, 'error' => null, ); } $result['hasilRamal'] = $hasilRamal; $result['MAD'] = null; $result['MSE'] = null; $result['MAPE'] = null; $result['ratarataKesalahan'] = null; return $result; } // Fungsi metode triple exponential smoothing $h = new ExponentialSmoothing($alpha, $beta, $gamma, $L, $dataAktual); $dataForecast = $h->get_forecast(); // Perhitungan error // rumus PE : ABS(xt-ft/xt)x100 $arrPE = array(); $arrPE2 = array(); $PE = array(); $MAD = 0; $MSE = 0; $MAPE = 0; for ($i = 0; $i < count($dataForecast); $i++) { if (isset($dataForecast[$i])) { // | xt-ft | $xtFt = $dataAktual[$i] - $dataForecast[$i]; $arrPE[] = ABS($xtFt); // (xt-ft)^2 $xtFt2 = pow($xtFt, 2); $arrPE2[] = $xtFt2; // ABS(xt-ft/xt)x100 $APE = ABS($xtFt / $dataAktual[$i]) * 100; $PE[] = $APE; // Total $MAD += ABS($xtFt); $MSE += $xtFt2; $MAPE += $APE; } else { $arrPE[] = null; $arrPE2[] = null; $PE[] = null; } }; $jmlAktual = count($dataForecast) - $L; $hasilMAD = $MAD / $jmlAktual; $hasilMSE = $MSE / $jmlAktual; $hasilMAPE = $MAPE / $jmlAktual; $hasilKeseluruhan = $hasilMAD + $hasilMSE + $hasilMAPE; $ratarataKesalahan = $hasilKeseluruhan / 3; // proses merge data ramal aktual dengan bulan selanjutnya for ($i = count($dataAktual); $i < count($srs); $i++) { $dataForecast[] = $h->forecast($i); } // Peramalan $levels = $h->get_levels(); $trens = $h->get_trens(); $seasonals = $h->get_seasonals(); for ($i = 0; $i < count($srs); $i++) { $hasilRamal[] = array( 'bulan' => $srs[$i]['bulan'], 'jumlah' => $srs[$i]['jumlah'], 'lt' => (isset($levels[$i])) ? round($levels[$i], 5) : null, 'bt' => (isset($trens[$i])) ? round($trens[$i], 5) : null, 'st' => (isset($seasonals[$i])) ? round($seasonals[$i], 5) : null, 'ft' => (isset($dataForecast[$i])) ? round($dataForecast[$i], 5) : null, 'xt_ft' => (isset($arrPE[$i])) ? round($arrPE[$i], 5) : null, 'xt_ft2' => (isset($arrPE2[$i])) ? round($arrPE2[$i], 5) : null, 'error' => (isset($PE[$i])) ? round($PE[$i], 5) : null, ); } $result['hasilRamal'] = $hasilRamal; $result['MAD'] = round($hasilMAD, 4); $result['MSE'] = round($hasilMSE, 4); $result['MAPE'] = round($hasilMAPE, 4); $result['ratarataKesalahan'] = round($ratarataKesalahan, 4); return $result; } // Fungsi untuk testing perhitungan development public function forecast() { $starter = 0; $lb = 0; $dataAktual = []; $blnAwal = '2023-04-01'; $blnAkhir = '2024-03-01'; $blnRamal = '2024-05-01'; $srs = array( array( 'bulan' => '04-2023', 'jumlah' => 32 ), array( 'bulan' => '05-2023', 'jumlah' => 32 ), array( 'bulan' => '06-2023', 'jumlah' => 33 ), array( 'bulan' => '07-2023', 'jumlah' => 35 ), array( 'bulan' => '08-2023', 'jumlah' => 38 ), array( 'bulan' => '09-2023', 'jumlah' => 36 ), array( 'bulan' => '10-2023', 'jumlah' => 36 ), array( 'bulan' => '11-2023', 'jumlah' => 32 ), array( 'bulan' => '12-2023', 'jumlah' => 33 ), array( 'bulan' => '01-2024', 'jumlah' => 31 ), array( 'bulan' => '02-2024', 'jumlah' => 33 ), array( 'bulan' => '03-2024', 'jumlah' => 34 ), ); // Mengambil nilai data aktual foreach ($srs as $row) { $dataAktual[] = $row['jumlah']; } // generate list bulan dan jumlah data aktual, dari awal hingga akhir bulan kunjungan pada setiap pelayanan for ($t = date("Y", strtotime($blnAkhir)); $t <= date("Y", strtotime($blnRamal)); $t++) { if ($starter == 0) { $lb = date("m", strtotime($blnAkhir)) + 1; } else { $lb = 1; } for ($b = $lb; $b <= 13; $b++) { if ($b > 12) { $starter = 1; break; } else { if ($t == date("Y", strtotime($blnRamal)) && $b > date("m", strtotime($blnRamal))) { break; } else { // proses menambahkan / menggabungkan data series bulanan dengan bulan selanjutnya $bulanStr = sprintf("%02d", $b) . "-" . $t; $srs[] = array( 'bulan' => $bulanStr, 'jumlah' => null ); } } } } $alpha = 0.5; $beta = 0.5; $gamma = 0.5; $L = 4; // $series = array( // 32, // 32, // 33, // 35, // 38, // 36, // 36, // 32, // 33, // 31, // 33, // 34 // ); // Fungsi metode triple exponential smoothing $h = new ExponentialSmoothing($alpha, $beta, $gamma, $L, $dataAktual); $dataForecast = $h->get_forecast(); echo '
'; // print_r($srs); print_r($dataAktual); // print_r($h); echo ''; return $hasilRamal; } }
Result forecast ori :
'; print_r($dataForecast); echo '
Result forecast future :
'; // Perhitungan error // rumus PE : ABS(xt-ft/xt)x100 $arrPE = array(); $arrPE2 = array(); $PE = array(); $MAD = 0; $MSE = 0; $MAPE = 0; for ($i = 0; $i < count($dataForecast); $i++) { if (isset($dataForecast[$i])) { // | xt-ft | $xtFt = $dataAktual[$i] - $dataForecast[$i]; $arrPE[] = ABS($xtFt); // (xt-ft)^2 $xtFt2 = pow($xtFt, 2); $arrPE2[] = $xtFt2; // ABS(xt-ft/xt)x100 $APE = ABS($xtFt / $dataAktual[$i]) * 100; $PE[] = $APE; // Total $MAD += ABS($xtFt); $MSE += $xtFt2; $MAPE += $APE; } else { $arrPE[] = null; $arrPE2[] = null; $PE[] = null; } }; $jmlAktual = count($dataForecast) - $L; echo '
xt-ft :
'; print_r($arrPE); print_r($arrPE2); print_r($PE); echo '
SUM MAD :'; print_r($MAD); echo '
SUM MSE :'; print_r($MSE); echo '
SUM PE :'; print_r($MAPE); echo '
JML DATA AKTUAL :'; print_r($jmlAktual); $hasilMAD = $MAD / $jmlAktual; $hasilMSE = $MSE / $jmlAktual; $hasilMAPE = $MAPE / $jmlAktual; echo '
MAD :'; print_r($hasilMAD); echo '
MSE :'; print_r($hasilMSE); echo '
MAPE :'; print_r($hasilMAPE); echo '
'; // proses merge data ramal aktual dengan bulan selanjutnya for ($i = count($dataAktual); $i < count($srs); $i++) { echo '[' . $i . '] ' . $h->forecast($i); echo '
'; $dataForecast[] = $h->forecast($i); } print_r($dataForecast); // Peramalan $hasilRamal = array(); $levels = $h->get_levels(); $trens = $h->get_trens(); $seasonals = $h->get_seasonals(); for ($i = 0; $i < count($srs); $i++) { $hasilRamal[] = array( 'bulan' => $srs[$i]['bulan'], 'jumlah' => $srs[$i]['jumlah'], 'lt' => (isset($levels[$i])) ? $levels[$i] : null, 'bt' => (isset($trens[$i])) ? $trens[$i] : null, 'st' => (isset($seasonals[$i])) ? $seasonals[$i] : null, 'ft' => $dataForecast[$i], 'xt_ft' => (isset($arrPE[$i])) ? $arrPE[$i] : null, 'xt_ft2' => (isset($arrPE2[$i])) ? $arrPE2[$i] : null, 'error' => (isset($PE[$i])) ? $PE[$i] : null, ); } print_r($hasilRamal); echo '