201 lines
7.6 KiB
PHP
201 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use App\Models\DataAlumni;
|
|
use App\Models\Jabatan;
|
|
use App\Models\TahunAngkatan;
|
|
|
|
class ProsesKmeansController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$angkatan = TahunAngkatan::all();
|
|
$jabatanMap = Jabatan::pluck('Kategori_bidang_kerja', 'id_kategori')->toArray();
|
|
|
|
return view('proses_klasifikasi', compact('angkatan', 'jabatanMap'));
|
|
}
|
|
|
|
public function proses(Request $request)
|
|
{
|
|
$request->validate([
|
|
'id_angkatan' => 'required',
|
|
]);
|
|
|
|
$id_angkatan = $request->id_angkatan;
|
|
// Ambil list angkatan untuk dropdown di view
|
|
$angkatan = TahunAngkatan::all();
|
|
|
|
// Ambil data alumni sesuai angkatan
|
|
$data = DataAlumni::with(['jabatan', 'kualifikasiBidang', 'tahunAngkatan'])
|
|
->where('angkatan', $id_angkatan)
|
|
->get();
|
|
|
|
if ($data->isEmpty()) {
|
|
return redirect()->back()->with('error', 'Data alumni untuk angkatan tersebut tidak ditemukan.');
|
|
}
|
|
|
|
// Siapkan dataset numerik untuk K-Means
|
|
$dataset = $data->map(function ($item) {
|
|
return [
|
|
'id' => $item->id_alumni,
|
|
'nama' => $item->nama,
|
|
'nim' => $item->nim,
|
|
'angkatan' => optional($item->tahunAngkatan)->tahun,
|
|
'pekerjaan' => $item->pekerjaan,
|
|
// 'jabatan' => optional($item->jabatan)->nilai ?? 0,
|
|
'jabatan' => is_object($item->jabatan) ? $item->jabatan->nilai : (isset($item->jabatan) ? $item->jabatan : 0),
|
|
'kualifikasi' => optional($item->kualifikasiBidang)->nilai ?? 0,
|
|
];
|
|
})->toArray();
|
|
|
|
// Inisialisasi centroid awal (manual)
|
|
$centroids = [
|
|
['jabatan' => 1, 'kualifikasi' => 0], //C0
|
|
['jabatan' => 3, 'kualifikasi' => 3], //C1
|
|
['jabatan' => 6, 'kualifikasi' => 6], //C2
|
|
];
|
|
|
|
$centroid_awal = json_encode($centroids);
|
|
|
|
// Define cluster labels
|
|
$clusterLabels = [
|
|
0 => 'TIDAK SESUAI',
|
|
1 => 'KURANG SESUAI',
|
|
2 => 'SESUAI'
|
|
];
|
|
|
|
$maxIterasi = 10;
|
|
$hasil_iterasi = [];
|
|
|
|
// Proses iterasi
|
|
for ($iterasi = 1; $iterasi <= $maxIterasi; $iterasi++) {
|
|
$clusters = [];
|
|
// Assign ke cluster terdekat
|
|
foreach ($dataset as $item) {
|
|
$jarak = array_map(function ($cent) use ($item) {
|
|
return sqrt(
|
|
pow($item['jabatan'] - $cent['jabatan'], 2) +
|
|
pow($item['kualifikasi'] - $cent['kualifikasi'], 2)
|
|
);
|
|
}, $centroids);
|
|
$cluster_id = array_search(min($jarak), $jarak);
|
|
$clusters[$cluster_id][] = $item;
|
|
}
|
|
|
|
// Hitung centroid baru
|
|
$newCentroids = [];
|
|
foreach (range(0, count($centroids) - 1) as $ci) {
|
|
if (!empty($clusters[$ci])) {
|
|
$avgJabatan = collect($clusters[$ci])->avg('jabatan');
|
|
$avgKualifikasi = collect($clusters[$ci])->avg('kualifikasi');
|
|
$newCentroids[] = [
|
|
'jabatan' => round($avgJabatan, 4),
|
|
'kualifikasi' => round($avgKualifikasi, 4),
|
|
];
|
|
} else {
|
|
// Pertahankan centroid lama jika kosong
|
|
$newCentroids[] = $centroids[$ci];
|
|
}
|
|
}
|
|
|
|
// Kumpulkan data untuk tampilan iterasi ini
|
|
$iterData = [];
|
|
$timestamp = Carbon::now()->format('d-m-Y H:i');
|
|
foreach ($dataset as $item) {
|
|
$jarak = array_map(function ($cent) use ($item) {
|
|
return sqrt(
|
|
pow($item['jabatan'] - $cent['jabatan'], 2) +
|
|
pow($item['kualifikasi'] - $cent['kualifikasi'], 2)
|
|
);
|
|
}, $centroids);
|
|
$cluster_id = array_search(min($jarak), $jarak);
|
|
$iterData[] = [
|
|
'id' => $item['id'],
|
|
'nama' => $item['nama'],
|
|
'nim' => $item['nim'],
|
|
'angkatan' => $item['angkatan'],
|
|
'pekerjaan' => $item['pekerjaan'],
|
|
'jabatan' => $item['jabatan'],
|
|
'kualifikasi' => $item['kualifikasi'],
|
|
'cluster' => $cluster_id,
|
|
// 'klasifikasi' => 'Cluster ' . ($cluster_id + 1),
|
|
'klasifikasi' => 'Cluster ' . ($cluster_id) . ' - ' . $clusterLabels[$cluster_id],
|
|
'waktu_proses' => $timestamp,
|
|
];
|
|
|
|
// Simpan data hasil klasifikasi dari iterasi terakhir
|
|
if ($iterasi == $maxIterasi || $newCentroids === $centroids) {
|
|
$finalData[] = [
|
|
'id' => $item['id'],
|
|
'cluster' => $cluster_id
|
|
];
|
|
}
|
|
}
|
|
|
|
$hasil_iterasi[] = [
|
|
'iterasi' => $iterasi,
|
|
'centroids' => $centroids,
|
|
'data' => $iterData,
|
|
];
|
|
|
|
if ($newCentroids === $centroids) {
|
|
// Update finalData jika konvergen sebelum iterasi maksimum
|
|
$finalData = []; // Reset dulu
|
|
foreach ($iterData as $item) {
|
|
$finalData[] = [
|
|
'id' => $item['id'],
|
|
'cluster' => $item['cluster']
|
|
];
|
|
}
|
|
break;
|
|
}
|
|
$centroids = $newCentroids;
|
|
}
|
|
|
|
// Hasil centroid akhir
|
|
$centroid_akhir = $centroids;
|
|
// Jumlah iterasi yang dilakukan
|
|
$jumlah_iterasi = count($hasil_iterasi);
|
|
|
|
// Keterangan klasifikasi untuk tampilan
|
|
$keterangan_klasifikasi = [
|
|
'C0' => 'TIDAK SESUAI',
|
|
'C1' => 'KURANG SESUAI',
|
|
'C2' => 'SESUAI'
|
|
];
|
|
// Encode centroid akhir untuk disimpan ke database
|
|
// $centroid_akhir_json = json_encode($centroid_akhir);
|
|
|
|
// return view('proses_klasifikasi', [
|
|
// 'angkatan' => $angkatan,
|
|
// 'jabatanMap' => Jabatan::pluck('Kategori_bidang_kerja', 'id_kategori')->toArray(),
|
|
// 'hasil_iterasi' => $hasil_iterasi,
|
|
// 'centroid_awal' => $centroid_awal,
|
|
// 'centroid_akhir' => $centroid_akhir,
|
|
// 'centroid_akhir_json' => $centroid_akhir_json,
|
|
// 'id_angkatan' => $id_angkatan,
|
|
// 'keterangan_klasifikasi' => $keterangan_klasifikasi,
|
|
// 'jumlah_iterasi' => $jumlah_iterasi,
|
|
// 'finalData' => $finalData, // Data yang akan disimpan
|
|
|
|
$centroid_akhir_json = json_encode($centroid_akhir);
|
|
|
|
return view('proses_klasifikasi', [
|
|
'angkatan' => $angkatan,
|
|
'jabatanMap' => Jabatan::pluck('Kategori_bidang_kerja', 'id_kategori')->toArray(),
|
|
'hasil_iterasi' => $hasil_iterasi,
|
|
'centroid_awal' => $centroid_awal,
|
|
'centroid_akhir' => $centroid_akhir,
|
|
'centroid_akhir_json' => $centroid_akhir_json,
|
|
'id_angkatan' => $id_angkatan,
|
|
'keterangan_klasifikasi' => $keterangan_klasifikasi,
|
|
'jumlah_iterasi' => $jumlah_iterasi,
|
|
'finalData' => $finalData, // Data yang akan disimpan
|
|
]);
|
|
}
|
|
|
|
}
|