statmining-automl / index.html
mathurinacheisoft's picture
Add 3 files
ae0b104 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bolt AutoML - Solution intuitive</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
.file-upload {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem;
border: 2px dashed #cbd5e0;
border-radius: 1rem;
transition: all 0.3s ease;
}
.file-upload:hover {
border-color: #4f46e5;
background-color: #f8fafc;
}
.data-preview {
max-height: 300px;
overflow-y: auto;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
}
.dashboard-card {
transition: all 0.3s ease;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
border-radius: 0.75rem;
}
.model-table {
width: 100%;
border-collapse: collapse;
}
.model-table th, .model-table td {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid #e5e7eb;
}
.model-table th {
background-color: #f9fafb;
font-weight: 600;
color: #4b5563;
}
@media (max-width: 768px) {
.dashboard-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<div class="container mx-auto px-4 py-8 max-w-6xl">
<!-- Header -->
<header class="mb-8 text-center">
<div class="flex justify-center items-center mb-4">
<i class="fas fa-bolt text-4xl text-indigo-600 mr-3"></i>
<h1 class="text-3xl font-bold text-gray-800">Statmining AutoML</h1>
</div>
<p class="text-gray-600 max-w-3xl mx-auto">
Solution intuitive de Machine Learning sans code pour vos analyses de données
</p>
</header>
<!-- Main Card -->
<div class="bg-white rounded-xl shadow-sm overflow-hidden mb-8">
<div class="p-6">
<div class="flex items-center mb-6">
<div class="bg-indigo-100 p-3 rounded-full mr-4">
<i class="fas fa-play-circle text-indigo-600 text-xl"></i>
</div>
<h2 class="text-xl font-semibold text-gray-800">Démarrer une nouvelle expérimentation AutoML</h2>
</div>
<!-- Step 1: File Upload -->
<div class="mb-8">
<h3 class="text-lg font-medium text-gray-700 mb-4 flex items-center">
<span class="bg-indigo-100 text-indigo-800 rounded-full w-6 h-6 flex items-center justify-center text-sm mr-2">1</span>
Importez votre jeu de données
</h3>
<div class="file-upload" id="fileUploadArea">
<input type="file" id="fileInput" class="hidden" accept=".csv, .xlsx">
<i class="fas fa-file-csv text-4xl text-gray-400 mb-3"></i>
<p class="text-gray-500 mb-4">Glissez-déposez votre fichier .csv ou .xlsx ici</p>
<button id="uploadBtn" class="px-6 py-2 bg-indigo-600 text-white rounded-full hover:bg-indigo-700 transition-colors">
<i class="fas fa-upload mr-2"></i> Sélectionner un fichier
</button>
</div>
<!-- Data Preview -->
<div id="dataPreview" class="hidden mt-6">
<h4 class="text-md font-medium text-gray-700 mb-3">Aperçu des données</h4>
<div class="data-preview">
<table class="w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr id="previewHeader"></tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200" id="previewBody"></tbody>
</table>
</div>
</div>
</div>
<!-- Step 2: Target Selection -->
<div class="mb-8" id="targetSection" style="display: none;">
<h3 class="text-lg font-medium text-gray-700 mb-4 flex items-center">
<span class="bg-indigo-100 text-indigo-800 rounded-full w-6 h-6 flex items-center justify-center text-sm mr-2">2</span>
Sélectionnez la variable cible
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<select id="targetSelect" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500">
<option value="" disabled selected>Choisissez une colonne</option>
</select>
<p class="text-sm text-gray-500 mt-2">Cette variable sera celle que le modèle tentera de prédire.</p>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<canvas id="targetChart"></canvas>
</div>
</div>
</div>
<!-- Step 3: Objectives -->
<div class="mb-8" id="objectivesSection" style="display: none;">
<h3 class="text-lg font-medium text-gray-700 mb-4 flex items-center">
<span class="bg-indigo-100 text-indigo-800 rounded-full w-6 h-6 flex items-center justify-center text-sm mr-2">3</span>
Définissez vos objectifs
</h3>
<div class="space-y-3">
<div class="flex items-center">
<input type="checkbox" id="objective1" class="h-5 w-5 text-indigo-600 rounded focus:ring-indigo-500">
<label for="objective1" class="ml-3 text-gray-700">Obtenir un résultat très rapidement</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="objective2" class="h-5 w-5 text-indigo-600 rounded focus:ring-indigo-500">
<label for="objective2" class="ml-3 text-gray-700">Obtenir un modèle très performant</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="objective3" class="h-5 w-5 text-indigo-600 rounded focus:ring-indigo-500">
<label for="objective3" class="ml-3 text-gray-700">Obtenir un modèle interprétable</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="objective4" class="h-5 w-5 text-indigo-600 rounded focus:ring-indigo-500">
<label for="objective4" class="ml-3 text-gray-700">Utiliser le modèle en temps réel</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="objective5" class="h-5 w-5 text-indigo-600 rounded focus:ring-indigo-500">
<label for="objective5" class="ml-3 text-gray-700">Avoir un modèle simple</label>
</div>
</div>
</div>
<!-- Step 4: Launch -->
<div class="text-center pt-4">
<button id="launchBtn" class="px-8 py-3 bg-indigo-600 text-white rounded-full hover:bg-indigo-700 transition-colors font-medium flex items-center mx-auto">
<i class="fas fa-rocket mr-2"></i> Lancer l'entraînement AutoML
</button>
</div>
</div>
</div>
<!-- Results Dashboard (Initially Hidden) -->
<div id="resultsDashboard" class="hidden bg-white rounded-xl shadow-sm overflow-hidden mb-8">
<div class="p-6">
<div class="flex items-center mb-6">
<div class="bg-green-100 p-3 rounded-full mr-4">
<i class="fas fa-chart-line text-green-600 text-xl"></i>
</div>
<h2 class="text-xl font-semibold text-gray-800">Résultats de l'expérimentation AutoML</h2>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<!-- Top Left: Models Table -->
<div class="dashboard-card bg-white p-6 rounded-lg border border-gray-200">
<h3 class="text-lg font-medium text-gray-700 mb-4">
<i class="fas fa-table text-blue-500 mr-2"></i> Modèles testés
</h3>
<div class="overflow-x-auto">
<table class="model-table">
<thead>
<tr>
<th>Modèle</th>
<th>Score</th>
<th>Temps</th>
</tr>
</thead>
<tbody id="modelsTableBody">
<!-- Filled by JavaScript -->
</tbody>
</table>
</div>
</div>
<!-- Top Right: Feature Importance -->
<div class="dashboard-card bg-white p-6 rounded-lg border border-gray-200">
<h3 class="text-lg font-medium text-gray-700 mb-4">
<i class="fas fa-star text-yellow-500 mr-2"></i> Importance des variables
</h3>
<div class="h-64">
<canvas id="featureImportanceChart"></canvas>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Bottom Left: Apply Model -->
<div class="dashboard-card bg-white p-6 rounded-lg border border-gray-200">
<h3 class="text-lg font-medium text-gray-700 mb-4">
<i class="fas fa-file-import text-purple-500 mr-2"></i> Appliquer le modèle
</h3>
<p class="text-gray-600 mb-4">Téléchargez un nouveau jeu de données pour obtenir des prédictions.</p>
<div class="file-upload" id="newFileUploadArea">
<input type="file" id="newFileInput" class="hidden" accept=".csv, .xlsx">
<button id="newUploadBtn" class="px-6 py-2 bg-purple-600 text-white rounded-full hover:bg-purple-700 transition-colors">
<i class="fas fa-upload mr-2"></i> Sélectionner un fichier
</button>
</div>
</div>
<!-- Bottom Right: Summary -->
<div class="dashboard-card bg-white p-6 rounded-lg border border-gray-200">
<h3 class="text-lg font-medium text-gray-700 mb-4">
<i class="fas fa-info-circle text-green-500 mr-2"></i> Résumé
</h3>
<div class="space-y-3">
<div class="flex">
<span class="text-gray-500 font-medium w-32">Fichier:</span>
<span id="expFilename" class="text-gray-700">donnees.csv</span>
</div>
<div class="flex">
<span class="text-gray-500 font-medium w-32">Cible:</span>
<span id="expTarget" class="text-gray-700">prix</span>
</div>
<div class="flex">
<span class="text-gray-500 font-medium w-32">Objectifs:</span>
<span id="expObjectives" class="text-gray-700">Performance, Rapidité</span>
</div>
<div class="flex">
<span class="text-gray-500 font-medium w-32">Modèle:</span>
<span id="expModel" class="text-gray-700">H2O AutoML</span>
</div>
<div class="flex">
<span class="text-gray-500 font-medium w-32">Score:</span>
<span id="expScore" class="text-gray-700">0.92 (AUC)</span>
</div>
<div class="flex">
<span class="text-gray-500 font-medium w-32">Durée:</span>
<span id="expTime" class="text-gray-700">2 min 34 sec</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Sample data for demonstration
const sampleData = {
headers: ['ID', 'Age', 'Salaire', 'Département', 'Expérience', 'Poste'],
rows: [
[1, 32, 75000, 'Marketing', 5, 'Manager'],
[2, 28, 65000, 'Ventes', 3, 'Associé'],
[3, 45, 95000, 'IT', 15, 'Directeur'],
[4, 36, 82000, 'RH', 8, 'Manager'],
[5, 29, 68000, 'Ventes', 4, 'Associé'],
[6, 41, 88000, 'IT', 10, 'Chef de projet'],
[7, 35, 78000, 'Marketing', 7, 'Manager'],
[8, 27, 62000, 'RH', 2, 'Associé']
]
};
// Mock models data
const mockModels = [
{ name: 'H2O AutoML', score: 0.92, time: '1:45', type: 'Ensemble' },
{ name: 'LightAutoML', score: 0.91, time: '1:12', type: 'Gradient Boosting' },
{ name: 'MLJAR', score: 0.89, time: '2:03', type: 'Random Forest' },
{ name: 'Khiops', score: 0.88, time: '1:56', type: 'Decision Tree' },
{ name: 'StatMining', score: 0.85, time: '0:45', type: 'Logistic Regression' }
];
// Mock feature importance
const mockFeatures = [
{ name: 'Expérience', importance: 0.45 },
{ name: 'Age', importance: 0.32 },
{ name: 'Département', importance: 0.25 },
{ name: 'Formation', importance: 0.18 },
{ name: 'Localisation', importance: 0.12 },
{ name: 'Certifications', importance: 0.09 },
{ name: 'Compétences', importance: 0.07 },
{ name: 'Ancienneté', importance: 0.05 },
{ name: 'Projets', importance: 0.04 },
{ name: 'Langues', importance: 0.02 }
];
// DOM Elements
const fileInput = document.getElementById('fileInput');
const uploadBtn = document.getElementById('uploadBtn');
const fileUploadArea = document.getElementById('fileUploadArea');
const dataPreview = document.getElementById('dataPreview');
const previewHeader = document.getElementById('previewHeader');
const previewBody = document.getElementById('previewBody');
const targetSection = document.getElementById('targetSection');
const targetSelect = document.getElementById('targetSelect');
const objectivesSection = document.getElementById('objectivesSection');
const launchBtn = document.getElementById('launchBtn');
const resultsDashboard = document.getElementById('resultsDashboard');
const modelsTableBody = document.getElementById('modelsTableBody');
const newFileInput = document.getElementById('newFileInput');
const newUploadBtn = document.getElementById('newUploadBtn');
const newFileUploadArea = document.getElementById('newFileUploadArea');
// Charts
let targetChart = null;
let featureImportanceChart = null;
// Event Listeners
uploadBtn.addEventListener('click', () => fileInput.click());
newUploadBtn.addEventListener('click', () => newFileInput.click());
fileInput.addEventListener('change', handleFileUpload);
newFileInput.addEventListener('change', handleNewFileUpload);
fileUploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
fileUploadArea.classList.add('border-indigo-500', 'bg-indigo-50');
});
fileUploadArea.addEventListener('dragleave', () => {
fileUploadArea.classList.remove('border-indigo-500', 'bg-indigo-50');
});
fileUploadArea.addEventListener('drop', (e) => {
e.preventDefault();
fileUploadArea.classList.remove('border-indigo-500', 'bg-indigo-50');
fileInput.files = e.dataTransfer.files;
handleFileUpload();
});
targetSelect.addEventListener('change', updateTargetChart);
launchBtn.addEventListener('click', launchTraining);
// Functions
function handleFileUpload() {
// In a real app, you would parse the actual file here
// For this demo, we'll use sample data
// Show preview
displayDataPreview(sampleData.headers, sampleData.rows);
dataPreview.classList.remove('hidden');
// Populate target select
populateTargetSelect(sampleData.headers);
targetSection.style.display = 'block';
objectivesSection.style.display = 'block';
}
function handleNewFileUpload() {
alert('Nouveau fichier sélectionné pour les prédictions. Dans une application réelle, ce fichier serait envoyé au serveur pour traitement.');
}
function displayDataPreview(headers, rows) {
// Clear previous content
previewHeader.innerHTML = '';
previewBody.innerHTML = '';
// Add headers
headers.forEach(header => {
const th = document.createElement('th');
th.className = 'px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider';
th.textContent = header;
previewHeader.appendChild(th);
});
// Add rows
rows.forEach(row => {
const tr = document.createElement('tr');
row.forEach(cell => {
const td = document.createElement('td');
td.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500';
td.textContent = cell;
tr.appendChild(td);
});
previewBody.appendChild(tr);
});
}
function populateTargetSelect(headers) {
targetSelect.innerHTML = '<option value="" disabled selected>Choisissez une colonne</option>';
headers.forEach(header => {
const option = document.createElement('option');
option.value = header;
option.textContent = header;
targetSelect.appendChild(option);
});
}
function updateTargetChart() {
const selectedColumn = targetSelect.value;
const columnIndex = sampleData.headers.indexOf(selectedColumn);
// Get values for the selected column
const values = sampleData.rows.map(row => row[columnIndex]);
// Determine if the column is categorical or numerical
const isCategorical = typeof values[0] === 'string';
// Destroy previous chart if exists
if (targetChart) {
targetChart.destroy();
}
const ctx = document.getElementById('targetChart').getContext('2d');
if (isCategorical) {
// For categorical data, create a bar chart
const valueCounts = {};
values.forEach(value => {
valueCounts[value] = (valueCounts[value] || 0) + 1;
});
targetChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Object.keys(valueCounts),
datasets: [{
label: `Distribution de ${selectedColumn}`,
data: Object.values(valueCounts),
backgroundColor: 'rgba(79, 70, 229, 0.6)',
borderColor: 'rgba(79, 70, 229, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Nombre'
}
},
x: {
title: {
display: true,
text: selectedColumn
}
}
}
}
});
} else {
// For numerical data, create a box plot (simulated with bar chart)
// In a real app, you would use a proper box plot library
const sortedValues = [...values].sort((a, b) => a - b);
const q1 = sortedValues[Math.floor(sortedValues.length * 0.25)];
const median = sortedValues[Math.floor(sortedValues.length * 0.5)];
const q3 = sortedValues[Math.floor(sortedValues.length * 0.75)];
const iqr = q3 - q1;
const min = Math.max(sortedValues[0], q1 - 1.5 * iqr);
const max = Math.min(sortedValues[sortedValues.length - 1], q3 + 1.5 * iqr);
targetChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [selectedColumn],
datasets: [{
label: 'Distribution',
data: [{
min: min,
q1: q1,
median: median,
q3: q3,
max: max
}],
backgroundColor: 'rgba(79, 70, 229, 0.2)',
borderColor: 'rgba(79, 70, 229, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: function(context) {
const value = context.raw;
return [
`Min: ${value.min}`,
`Q1: ${value.q1}`,
`Médiane: ${value.median}`,
`Q3: ${value.q3}`,
`Max: ${value.max}`
];
}
}
}
},
scales: {
y: {
beginAtZero: false,
title: {
display: true,
text: 'Valeur'
}
}
}
}
});
}
}
function launchTraining() {
// Show loading state
launchBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Entraînement en cours...';
launchBtn.disabled = true;
// Simulate training delay
setTimeout(() => {
// Display results
displayResults();
// Reset button
launchBtn.innerHTML = '<i class="fas fa-rocket mr-2"></i> Lancer l\'entraînement AutoML';
launchBtn.disabled = false;
}, 2000);
}
function displayResults() {
// Populate models table
modelsTableBody.innerHTML = '';
mockModels.forEach(model => {
const tr = document.createElement('tr');
const tdName = document.createElement('td');
tdName.className = 'text-sm text-gray-900';
tdName.textContent = model.name;
const tdScore = document.createElement('td');
tdScore.className = 'text-sm text-gray-900 font-medium';
tdScore.textContent = model.score;
const tdTime = document.createElement('td');
tdTime.className = 'text-sm text-gray-500';
tdTime.textContent = model.time;
tr.appendChild(tdName);
tr.appendChild(tdScore);
tr.appendChild(tdTime);
modelsTableBody.appendChild(tr);
});
// Create feature importance chart
const ctx = document.getElementById('featureImportanceChart').getContext('2d');
if (featureImportanceChart) {
featureImportanceChart.destroy();
}
featureImportanceChart = new Chart(ctx, {
type: 'bar',
data: {
labels: mockFeatures.map(f => f.name),
datasets: [{
label: 'Importance',
data: mockFeatures.map(f => f.importance),
backgroundColor: 'rgba(79, 70, 229, 0.6)',
borderColor: 'rgba(79, 70, 229, 1)',
borderWidth: 1
}]
},
options: {
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
x: {
beginAtZero: true,
title: {
display: true,
text: 'Importance relative'
}
}
}
}
});
// Update summary
document.getElementById('expFilename').textContent = 'donnees.csv';
document.getElementById('expTarget').textContent = targetSelect.value;
const selectedObjectives = [];
if (document.getElementById('objective1').checked) selectedObjectives.push('Rapidité');
if (document.getElementById('objective2').checked) selectedObjectives.push('Performance');
if (document.getElementById('objective3').checked) selectedObjectives.push('Interprétabilité');
if (document.getElementById('objective4').checked) selectedObjectives.push('Temps réel');
if (document.getElementById('objective5').checked) selectedObjectives.push('Simplicité');
document.getElementById('expObjectives').textContent = selectedObjectives.join(', ') || 'Aucun';
document.getElementById('expModel').textContent = mockModels[0].name;
document.getElementById('expScore').textContent = `${mockModels[0].score} (AUC)`;
document.getElementById('expTime').textContent = mockModels[0].time;
// Show results dashboard
resultsDashboard.classList.remove('hidden');
// Scroll to results
resultsDashboard.scrollIntoView({ behavior: 'smooth' });
}
</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=mathurinacheisoft/statmining-automl" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>