251 lines
11 KiB
PHP
251 lines
11 KiB
PHP
<div class="space-y-6">
|
|
|
|
{{-- ================= HEADER ================= --}}
|
|
<div class="flex justify-between items-center">
|
|
<div>
|
|
<h2 class="text-2xl font-bold">Hasil Analisis Sentimen</h2>
|
|
<p class="text-gray-500 text-sm">
|
|
Berikut adalah hasil evaluasi model dan detail analisis sentimen terhadap ulasan wisata.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- ================= METRICS ================= --}}
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
|
|
<div class="bg-white p-5 rounded-xl shadow">
|
|
<p class="text-gray-500 text-sm">Precision</p>
|
|
<h3 class="text-2xl font-bold text-blue-600">
|
|
{{ number_format($evaluasi->precision ?? 0, 2) }}
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="bg-white p-5 rounded-xl shadow">
|
|
<p class="text-gray-500 text-sm">Recall</p>
|
|
<h3 class="text-2xl font-bold text-green-600">
|
|
{{ number_format($evaluasi->recall ?? 0, 2) }}
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="bg-white p-5 rounded-xl shadow">
|
|
<p class="text-gray-500 text-sm">F1 Score</p>
|
|
<h3 class="text-2xl font-bold text-purple-600">
|
|
{{ number_format($evaluasi->f1_score ?? 0, 2) }}
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="bg-white p-5 rounded-xl shadow">
|
|
<p class="text-gray-500 text-sm">Akurasi</p>
|
|
<h3 class="text-2xl font-bold text-indigo-600">
|
|
{{ number_format($evaluasi->accuracy ?? 0, 2) }}
|
|
</h3>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{-- ================= MATRIX + PERFORMA ================= --}}
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
|
|
{{-- CONFUSION MATRIX --}}
|
|
<div class="bg-white p-6 rounded-xl shadow">
|
|
<h3 class="font-semibold mb-4">Confusion Matrix</h3>
|
|
|
|
<table class="w-full text-center border rounded-lg overflow-hidden">
|
|
<thead class="bg-gray-100">
|
|
<tr>
|
|
<th></th>
|
|
<th>Positif</th>
|
|
<th>Negatif</th>
|
|
<th>Netral</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<th class="bg-gray-50">Positif</th>
|
|
<td class="bg-green-100">{{ $evaluasi->tp ?? 0 }}</td>
|
|
<td class="bg-red-100">{{ $evaluasi->fp ?? 0 }}</td>
|
|
<td class="bg-yellow-100">{{ $evaluasi->fn ?? 0 }}</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="bg-gray-50">Negatif</th>
|
|
<td class="bg-red-100">{{ $evaluasi->fp ?? 0 }}</td>
|
|
<td class="bg-green-100">{{ $evaluasi->tn ?? 0 }}</td>
|
|
<td class="bg-yellow-100">0</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="bg-gray-50">Netral</th>
|
|
<td class="bg-yellow-100">0</td>
|
|
<td class="bg-yellow-100">0</td>
|
|
<td class="bg-green-100">0</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{-- PERFORMA --}}
|
|
<div class="bg-white p-6 rounded-xl shadow">
|
|
<h3 class="font-semibold mb-4">Performa per Kelas</h3>
|
|
|
|
<table class="w-full text-sm border">
|
|
<thead class="bg-gray-100">
|
|
<tr>
|
|
<th>Kelas</th>
|
|
<th>Precision</th>
|
|
<th>Recall</th>
|
|
<th>F1</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="text-green-600 font-semibold">Positif</td>
|
|
<td>{{ number_format($evaluasi->precision ?? 0, 2) }}</td>
|
|
<td>{{ number_format($evaluasi->recall ?? 0, 2) }}</td>
|
|
<td>{{ number_format($evaluasi->f1_score ?? 0, 2) }}</td>
|
|
<td>-</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-red-600 font-semibold">Negatif</td>
|
|
<td>{{ number_format($evaluasi->precision ?? 0, 2) }}</td>
|
|
<td>{{ number_format($evaluasi->recall ?? 0, 2) }}</td>
|
|
<td>{{ number_format($evaluasi->f1_score ?? 0, 2) }}</td>
|
|
<td>-</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-yellow-600 font-semibold">Netral</td>
|
|
<td>{{ number_format($evaluasi->precision ?? 0, 2) }}</td>
|
|
<td>{{ number_format($evaluasi->recall ?? 0, 2) }}</td>
|
|
<td>{{ number_format($evaluasi->f1_score ?? 0, 2) }}</td>
|
|
<td>-</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{-- ================= FILTER ================= --}}
|
|
<form id="filter-form" class="flex items-center gap-3">
|
|
|
|
<input type="hidden" name="tab" value="analisis">
|
|
|
|
<select name="wisata" class="border rounded px-3 py-2">
|
|
<option value="">Semua Destinasi</option>
|
|
<option value="Pantai Papuma" {{ request('wisata') == 'Pantai Papuma' ? 'selected' : '' }}>Pantai Papuma</option>
|
|
<option value="Pantai Watu Ulo" {{ request('wisata') == 'Pantai Watu Ulo' ? 'selected' : '' }}>Pantai Watu Ulo</option>
|
|
<option value="Teluk Love" {{ request('wisata') == 'Teluk Love' ? 'selected' : '' }}>Teluk Love</option>
|
|
<option value="Wisata Kebun Teh Gunung Gambir" {{ request('wisata') == 'Wisata Kebun Teh Gunung Gambir' ? 'selected' : '' }}>Wisata Kebun Teh Gunung Gambir</option>
|
|
</select>
|
|
|
|
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded">
|
|
Filter
|
|
</button>
|
|
|
|
</form>
|
|
|
|
{{-- ================= TABLE ================= --}}
|
|
<div class="bg-white rounded-xl shadow p-4">
|
|
|
|
<h3 class="font-semibold mb-4">Detail Hasil Analisis Sentimen</h3>
|
|
|
|
<table class="w-full text-sm">
|
|
<thead class="border-b text-left">
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Wisata</th>
|
|
<th>Ulasan Asli</th>
|
|
<th>Ulasan Bersih</th>
|
|
<th>Sentimen</th>
|
|
<th>Probabilitas</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
@forelse($hasil as $item)
|
|
<tr class="border-b">
|
|
<td>{{ ($hasil->currentPage() - 1) * $hasil->perPage() + $loop->iteration }}</td>
|
|
<td>{{ $item->wisata }}</td>
|
|
<td class="text-gray-500">{{ Str::limit($item->ulasan_asli ?? '-', 80) }}</td>
|
|
<td>{{ Str::limit($item->hasil_preprocessing ?? '-', 80) }}</td>
|
|
<td>
|
|
<span class="px-2 py-1 rounded text-xs
|
|
{{ strtolower($item->sentimen) == 'positif' ? 'bg-green-100 text-green-600' : '' }}
|
|
{{ strtolower($item->sentimen) == 'negatif' ? 'bg-red-100 text-red-600' : '' }}
|
|
{{ strtolower($item->sentimen) == 'netral' ? 'bg-yellow-100 text-yellow-600' : '' }}
|
|
">
|
|
{{ ucfirst($item->sentimen) }}
|
|
</span>
|
|
</td>
|
|
<td>{{ number_format($item->probabilitas ?? 0, 2) }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="6" class="text-center py-4 text-gray-500">Tidak ada data</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
|
|
{{-- ================= PAGINATION ================= --}}
|
|
@if($hasil->hasPages())
|
|
@php
|
|
$current = $hasil->currentPage();
|
|
$last = $hasil->lastPage();
|
|
$query = http_build_query(request()->except('page'));
|
|
// Window 2 halaman kiri & kanan dari current
|
|
$window = collect(range(max(1, $current - 2), min($last, $current + 2)));
|
|
@endphp
|
|
|
|
<div class="mt-4 flex items-center justify-between text-sm text-gray-600">
|
|
|
|
{{-- Info --}}
|
|
<p>Menampilkan {{ $hasil->firstItem() }} - {{ $hasil->lastItem() }} dari {{ $hasil->total() }} data</p>
|
|
|
|
{{-- Tombol --}}
|
|
<div class="flex items-center gap-1">
|
|
|
|
{{-- « --}}
|
|
@if($hasil->onFirstPage())
|
|
<span class="px-3 py-1 rounded border bg-gray-100 text-gray-400 cursor-not-allowed">«</span>
|
|
@else
|
|
<a href="{{ $hasil->previousPageUrl() }}&{{ $query }}" class="px-3 py-1 rounded border hover:bg-blue-50 text-blue-600">«</a>
|
|
@endif
|
|
|
|
{{-- Halaman 1 (jika tidak ada di window) --}}
|
|
@if(!$window->contains(1))
|
|
<a href="{{ $hasil->url(1) }}&{{ $query }}" class="px-3 py-1 rounded border hover:bg-blue-50 text-blue-600">1</a>
|
|
@if($window->min() > 2)
|
|
<span class="px-2 py-1 text-gray-400">...</span>
|
|
@endif
|
|
@endif
|
|
|
|
{{-- Window --}}
|
|
@foreach($window as $page)
|
|
@if($page == $current)
|
|
<span class="px-3 py-1 rounded border bg-blue-600 text-white font-semibold">{{ $page }}</span>
|
|
@else
|
|
<a href="{{ $hasil->url($page) }}&{{ $query }}" class="px-3 py-1 rounded border hover:bg-blue-50 text-blue-600">{{ $page }}</a>
|
|
@endif
|
|
@endforeach
|
|
|
|
{{-- Halaman terakhir (jika tidak ada di window) --}}
|
|
@if(!$window->contains($last))
|
|
@if($window->max() < $last - 1)
|
|
<span class="px-2 py-1 text-gray-400">...</span>
|
|
@endif
|
|
<a href="{{ $hasil->url($last) }}&{{ $query }}" class="px-3 py-1 rounded border hover:bg-blue-50 text-blue-600">{{ $last }}</a>
|
|
@endif
|
|
|
|
{{-- » --}}
|
|
@if($hasil->hasMorePages())
|
|
<a href="{{ $hasil->nextPageUrl() }}&{{ $query }}" class="px-3 py-1 rounded border hover:bg-blue-50 text-blue-600">»</a>
|
|
@else
|
|
<span class="px-3 py-1 rounded border bg-gray-100 text-gray-400 cursor-not-allowed">»</span>
|
|
@endif
|
|
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
|
|
</div> |