| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Yahoo Webscope Anomaly Detection Dashboard</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .sidebar { |
| transition: all 0.3s ease; |
| } |
| .chart-container { |
| position: relative; |
| height: 300px; |
| width: 100%; |
| } |
| .anomaly-marker { |
| position: absolute; |
| width: 8px; |
| height: 8px; |
| border-radius: 50%; |
| background-color: #ef4444; |
| transform: translate(-50%, -50%); |
| z-index: 10; |
| } |
| .tooltip { |
| position: absolute; |
| background: rgba(0, 0, 0, 0.8); |
| color: white; |
| padding: 5px 10px; |
| border-radius: 4px; |
| font-size: 12px; |
| pointer-events: none; |
| z-index: 100; |
| opacity: 0; |
| transition: opacity 0.3s; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-100 font-sans"> |
| <div class="flex h-screen overflow-hidden"> |
| |
| <div class="sidebar bg-indigo-800 text-white w-64 flex-shrink-0"> |
| <div class="p-4 border-b border-indigo-700"> |
| <h1 class="text-xl font-bold flex items-center"> |
| <i class="fas fa-chart-line mr-2"></i> |
| AnomalyScope |
| </h1> |
| </div> |
| <nav class="p-4"> |
| <div class="mb-6"> |
| <h2 class="text-sm uppercase text-indigo-300 font-semibold mb-2">Datasets</h2> |
| <ul> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded bg-indigo-700"> |
| <i class="fas fa-server mr-3"></i> |
| A1 Benchmark |
| </a> |
| </li> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-700"> |
| <i class="fas fa-server mr-3"></i> |
| A2 Benchmark |
| </a> |
| </li> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-700"> |
| <i class="fas fa-server mr-3"></i> |
| A3 Benchmark |
| </a> |
| </li> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-700"> |
| <i class="fas fa-server mr-3"></i> |
| A4 Benchmark |
| </a> |
| </li> |
| </ul> |
| </div> |
| <div> |
| <h2 class="text-sm uppercase text-indigo-300 font-semibold mb-2">Analysis Tools</h2> |
| <ul> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-700"> |
| <i class="fas fa-search mr-3"></i> |
| Anomaly Detection |
| </a> |
| </li> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-700"> |
| <i class="fas fa-chart-bar mr-3"></i> |
| Time Series Analysis |
| </a> |
| </li> |
| <li class="mb-2"> |
| <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-700"> |
| <i class="fas fa-cogs mr-3"></i> |
| Model Settings |
| </a> |
| </li> |
| </ul> |
| </div> |
| </nav> |
| </div> |
|
|
| |
| <div class="flex-1 overflow-auto"> |
| |
| <header class="bg-white shadow-sm p-4 flex justify-between items-center"> |
| <div> |
| <h2 class="text-xl font-semibold text-gray-800">Yahoo Webscope Anomaly Detection</h2> |
| <p class="text-sm text-gray-500">Analyzing time series anomalies in real-world data</p> |
| </div> |
| <div class="flex items-center space-x-4"> |
| <div class="relative"> |
| <input type="text" placeholder="Search..." class="pl-10 pr-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"> |
| <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
| </div> |
| <div class="flex items-center space-x-2"> |
| <div class="w-8 h-8 rounded-full bg-indigo-500 flex items-center justify-center text-white"> |
| <i class="fas fa-user"></i> |
| </div> |
| <span class="text-sm font-medium">Analyst</span> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <main class="p-6"> |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6"> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Total Data Points</p> |
| <p class="text-2xl font-bold text-gray-800">67,000</p> |
| </div> |
| <div class="p-3 rounded-full bg-indigo-100 text-indigo-600"> |
| <i class="fas fa-database text-xl"></i> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Anomalies Detected</p> |
| <p class="text-2xl font-bold text-gray-800">1,450</p> |
| </div> |
| <div class="p-3 rounded-full bg-red-100 text-red-600"> |
| <i class="fas fa-exclamation-triangle text-xl"></i> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Detection Accuracy</p> |
| <p class="text-2xl font-bold text-gray-800">92.3%</p> |
| </div> |
| <div class="p-3 rounded-full bg-green-100 text-green-600"> |
| <i class="fas fa-check-circle text-xl"></i> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="flex items-center justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Processing Time</p> |
| <p class="text-2xl font-bold text-gray-800">1.2s</p> |
| </div> |
| <div class="p-3 rounded-full bg-blue-100 text-blue-600"> |
| <i class="fas fa-stopwatch text-xl"></i> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white rounded-lg shadow p-6 mb-6"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-lg font-semibold text-gray-800">Time Series with Anomaly Detection</h3> |
| <div class="flex space-x-2"> |
| <select class="border rounded-md px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"> |
| <option>Last 7 days</option> |
| <option>Last 30 days</option> |
| <option selected>Last 90 days</option> |
| <option>Last year</option> |
| </select> |
| <button class="bg-indigo-600 text-white px-3 py-1 rounded-md text-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500"> |
| <i class="fas fa-download mr-1"></i> Export |
| </button> |
| </div> |
| </div> |
| <div class="chart-container"> |
| <canvas id="mainChart"></canvas> |
| </div> |
| </div> |
|
|
| |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> |
| |
| <div class="bg-white rounded-lg shadow p-6 col-span-2"> |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">Recent Anomalies</h3> |
| <div class="overflow-x-auto"> |
| <table class="min-w-full divide-y divide-gray-200"> |
| <thead class="bg-gray-50"> |
| <tr> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Timestamp</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Value</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Expected</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Deviation</th> |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th> |
| </tr> |
| </thead> |
| <tbody class="bg-white divide-y divide-gray-200"> |
| <tr> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">2023-05-15 14:30</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">142.56</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">98.23</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-red-600 font-medium">+45.1%</td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Spike</span> |
| </td> |
| </tr> |
| <tr> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">2023-05-12 09:15</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">32.11</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">68.45</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-red-600 font-medium">-53.1%</td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Drop</span> |
| </td> |
| </tr> |
| <tr> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">2023-05-10 18:45</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">215.78</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">102.34</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-red-600 font-medium">+110.8%</td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Spike</span> |
| </td> |
| </tr> |
| <tr> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">2023-05-08 11:20</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">45.67</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">72.89</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-red-600 font-medium">-37.3%</td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Drop</span> |
| </td> |
| </tr> |
| <tr> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">2023-05-05 16:10</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">178.92</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">95.67</td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-red-600 font-medium">+87.0%</td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Spike</span> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white rounded-lg shadow p-6"> |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">Model Performance</h3> |
| <div class="space-y-4"> |
| <div> |
| <div class="flex justify-between mb-1"> |
| <span class="text-sm font-medium text-gray-700">Precision</span> |
| <span class="text-sm font-medium text-gray-700">89.2%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> |
| <div class="bg-blue-600 h-2.5 rounded-full" style="width: 89.2%"></div> |
| </div> |
| </div> |
| <div> |
| <div class="flex justify-between mb-1"> |
| <span class="text-sm font-medium text-gray-700">Recall</span> |
| <span class="text-sm font-medium text-gray-700">92.3%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> |
| <div class="bg-green-600 h-2.5 rounded-full" style="width: 92.3%"></div> |
| </div> |
| </div> |
| <div> |
| <div class="flex justify-between mb-1"> |
| <span class="text-sm font-medium text-gray-700">F1 Score</span> |
| <span class="text-sm font-medium text-gray-700">90.7%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> |
| <div class="bg-purple-600 h-2.5 rounded-full" style="width: 90.7%"></div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mt-6"> |
| <h4 class="text-md font-medium text-gray-700 mb-2">Confusion Matrix</h4> |
| <div class="grid grid-cols-3 gap-1 text-center text-xs"> |
| <div class="p-2"></div> |
| <div class="p-2 font-medium">Predicted Anomaly</div> |
| <div class="p-2 font-medium">Predicted Normal</div> |
| <div class="p-2 font-medium">Actual Anomaly</div> |
| <div class="p-2 bg-green-100 text-green-800 rounded">1,234 (TP)</div> |
| <div class="p-2 bg-red-100 text-red-800 rounded">102 (FN)</div> |
| <div class="p-2 font-medium">Actual Normal</div> |
| <div class="p-2 bg-red-100 text-red-800 rounded">114 (FP)</div> |
| <div class="p-2 bg-green-100 text-green-800 rounded">65,550 (TN)</div> |
| </div> |
| </div> |
| |
| <div class="mt-6"> |
| <button class="w-full bg-indigo-600 text-white py-2 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500"> |
| <i class="fas fa-cog mr-2"></i> Tune Model Parameters |
| </button> |
| </div> |
| </div> |
| </div> |
| </main> |
| </div> |
| </div> |
|
|
| <script> |
| |
| function generateTimeSeriesData() { |
| const data = []; |
| const anomalies = []; |
| let value = 100; |
| |
| for (let i = 0; i < 90; i++) { |
| |
| value = 100 + Math.sin(i / 5) * 30 + (Math.random() * 10 - 5); |
| |
| |
| if (i === 15 || i === 45 || i === 70) { |
| value += 60 + Math.random() * 40; |
| anomalies.push({x: i, y: value}); |
| } else if (i === 30 || i === 60) { |
| value -= 50 + Math.random() * 30; |
| anomalies.push({x: i, y: value}); |
| } |
| |
| data.push(value); |
| } |
| |
| return {data, anomalies}; |
| } |
| |
| |
| function initMainChart() { |
| const {data, anomalies} = generateTimeSeriesData(); |
| const ctx = document.getElementById('mainChart').getContext('2d'); |
| |
| const chart = new Chart(ctx, { |
| type: 'line', |
| data: { |
| labels: Array.from({length: 90}, (_, i) => `Day ${i+1}`), |
| datasets: [ |
| { |
| label: 'Time Series Data', |
| data: data, |
| borderColor: 'rgb(79, 70, 229)', |
| backgroundColor: 'rgba(79, 70, 229, 0.1)', |
| borderWidth: 2, |
| fill: true, |
| tension: 0.1 |
| }, |
| { |
| label: 'Anomalies', |
| data: data.map((val, idx) => { |
| const anomaly = anomalies.find(a => a.x === idx); |
| return anomaly ? anomaly.y : null; |
| }), |
| pointBackgroundColor: 'rgb(239, 68, 68)', |
| pointRadius: 5, |
| pointHoverRadius: 7, |
| showLine: false |
| } |
| ] |
| }, |
| options: { |
| responsive: true, |
| maintainAspectRatio: false, |
| plugins: { |
| tooltip: { |
| mode: 'index', |
| intersect: false, |
| }, |
| legend: { |
| position: 'top', |
| } |
| }, |
| scales: { |
| y: { |
| beginAtZero: false, |
| grid: { |
| color: 'rgba(0, 0, 0, 0.05)', |
| } |
| }, |
| x: { |
| grid: { |
| display: false |
| } |
| } |
| }, |
| interaction: { |
| mode: 'nearest', |
| axis: 'x', |
| intersect: false |
| } |
| } |
| }); |
| |
| |
| const chartContainer = document.querySelector('.chart-container'); |
| anomalies.forEach(anomaly => { |
| const marker = document.createElement('div'); |
| marker.className = 'anomaly-marker'; |
| marker.style.left = `${(anomaly.x / 89) * 100}%`; |
| marker.style.top = `${100 - ((anomaly.y - 50) / 200) * 100}%`; |
| |
| const tooltip = document.createElement('div'); |
| tooltip.className = 'tooltip'; |
| tooltip.innerHTML = ` |
| <div class="font-bold">Anomaly Detected</div> |
| <div>Value: ${anomaly.y.toFixed(2)}</div> |
| <div>Day ${anomaly.x + 1}</div> |
| `; |
| |
| marker.addEventListener('mouseover', () => { |
| tooltip.style.opacity = '1'; |
| tooltip.style.left = `${(anomaly.x / 89) * 100 + 2}%`; |
| tooltip.style.top = `${100 - ((anomaly.y - 50) / 200) * 100 - 10}%`; |
| }); |
| |
| marker.addEventListener('mouseout', () => { |
| tooltip.style.opacity = '0'; |
| }); |
| |
| chartContainer.appendChild(marker); |
| chartContainer.appendChild(tooltip); |
| }); |
| } |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| initMainChart(); |
| |
| |
| document.querySelectorAll('.sidebar a').forEach(link => { |
| link.addEventListener('click', function(e) { |
| e.preventDefault(); |
| document.querySelectorAll('.sidebar a').forEach(a => a.classList.remove('bg-indigo-700')); |
| this.classList.add('bg-indigo-700'); |
| }); |
| }); |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Daniela-C/yahoo-webscope-anomaly-detection-dataset" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |