Spaces:
Running
Running
| | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Algoline</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| <script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script> | |
| <link rel="stylesheet" href="/static/css/style.css"> | |
| </head> | |
| <body> | |
| <!-- Theme Toggle --> | |
| <button class="theme-toggle" id="theme-toggle" onclick="toggleTheme()" title="Toggle theme"> | |
| <svg id="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg> | |
| <svg id="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg> | |
| </button> | |
| <!-- â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• | |
| SIDEBAR | |
| â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• --> | |
| <nav class="sidebar"> | |
| <div class="sidebar-logo"> | |
| <span>Algoline</span> | |
| </div> | |
| <div class="sidebar-nav"> | |
| <a class="nav-item active" onclick="showSection('data')" data-section="data"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/> | |
| </svg> | |
| <span>Data</span> | |
| </a> | |
| <a class="nav-item" onclick="showSection('explore')" data-section="explore"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/> | |
| </svg> | |
| <span>Explore</span> | |
| </a> | |
| <a class="nav-item" onclick="showSection('build')" data-section="build"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/> | |
| </svg> | |
| <span>Build</span> | |
| </a> | |
| <a class="nav-item" onclick="showSection('export')" data-section="export"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/> | |
| </svg> | |
| <span>Export</span> | |
| </a> | |
| </div> | |
| </nav> | |
| <!-- â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• | |
| MAIN CONTENT | |
| â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• --> | |
| <div class="main-content"> | |
| <!-- ──────── DATA SECTION ──────── --> | |
| <div id="sec-data" class="section active"> | |
| <h1 class="section-title">Data</h1> | |
| <p class="section-subtitle">Upload a dataset to begin your machine learning pipeline</p> | |
| <!-- Upload Area --> | |
| <input type="file" id="file-input" accept=".csv,.tsv,.xlsx,.xls" style="display:none"> | |
| <div class="upload-area" id="upload-area" onclick="document.getElementById('file-input').click()"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/> | |
| </svg> | |
| <div class="upload-area-title">Drop your dataset here or click to browse</div> | |
| <div class="upload-area-sub">Supports CSV, TSV, XLSX</div> | |
| </div> | |
| <!-- Metrics (hidden initially) --> | |
| <div id="data-metrics" class="metrics-grid" style="display:none"></div> | |
| <!-- Auto Insights (hidden initially) --> | |
| <div id="data-insights" style="display:none"></div> | |
| <!-- Target Selection --> | |
| <div id="target-section" style="display:none"> | |
| <div class="card"> | |
| <div class="target-row"> | |
| <div class="form-group" style="margin:0"> | |
| <label class="form-label">Target Column</label> | |
| <select class="form-select" id="target-select" onchange="setTarget(this.value)"> | |
| <option value="">Select target...</option> | |
| </select> | |
| </div> | |
| <div id="task-badge-wrap"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Data Tabs --> | |
| <div id="data-tabs-section" class="mt-md" style="display:none"> | |
| <div class="card"> | |
| <div class="tab-bar" id="data-tab-bar"> | |
| <button class="tab-btn active" onclick="switchDataTab('preview')">Preview</button> | |
| <button class="tab-btn" onclick="switchDataTab('types')">Types</button> | |
| <button class="tab-btn" onclick="switchDataTab('stats')">Stats</button> | |
| </div> | |
| <div id="data-tab-preview" class="tab-panel active"> | |
| <div class="table-wrap" style="max-height:400px;overflow-y:auto" id="preview-table"></div> | |
| </div> | |
| <div id="data-tab-types" class="tab-panel"> | |
| <div class="table-wrap" style="max-height:400px;overflow-y:auto" id="types-table"></div> | |
| </div> | |
| <div id="data-tab-stats" class="tab-panel"> | |
| <div class="table-wrap" style="max-height:400px;overflow-y:auto" id="stats-table"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ──────── EXPLORE SECTION ──────── --> | |
| <div id="sec-explore" class="section"> | |
| <h1 class="section-title">Explore</h1> | |
| <p class="section-subtitle">18 essential ML visualizations for data understanding and preprocessing</p> | |
| <div class="card"> | |
| <div class="tab-bar" id="explore-main-tabs"> | |
| <button class="tab-btn active" onclick="switchExploreMain('plots')">Visualizations</button> | |
| <button class="tab-btn" onclick="switchExploreMain('quality')">Data Quality</button> | |
| </div> | |
| <!-- Plots Panel --> | |
| <div id="explore-panel-plots" class="tab-panel active"> | |
| <div class="flex-row mb-md" style="gap:12px;flex-wrap:wrap;align-items:flex-end"> | |
| <div class="form-group" style="margin:0;min-width:240px;flex:1"> | |
| <label class="form-label">Plot Type</label> | |
| <select class="form-select" id="plot-type" onchange="onPlotTypeChange()"> | |
| <optgroup label="Distribution Analysis"> | |
| <option value="histogram">Histogram</option> | |
| <option value="kde">KDE Plot</option> | |
| <option value="boxplot">Box Plot</option> | |
| <option value="violin">Violin Plot</option> | |
| </optgroup> | |
| <optgroup label="Missing Data"> | |
| <option value="missing_bar">Missing Value Bar Chart</option> | |
| <option value="missing_heatmap">Missing Value Heatmap</option> | |
| </optgroup> | |
| <optgroup label="Correlation and Relationships"> | |
| <option value="correlation">Correlation Heatmap</option> | |
| <option value="pairplot">Pair Plot</option> | |
| <option value="scatter">Scatter Plot</option> | |
| <option value="jointplot">Joint Plot</option> | |
| </optgroup> | |
| <optgroup label="Target Analysis"> | |
| <option value="countplot">Count Plot</option> | |
| <option value="pie">Pie Chart</option> | |
| <option value="class_dist">Class Distribution</option> | |
| <option value="target_hist">Target Histogram</option> | |
| <option value="mean_target">Mean Target per Category</option> | |
| </optgroup> | |
| <optgroup label="Advanced"> | |
| <option value="scatter_index">Scatter vs Index</option> | |
| <option value="grouped_box">Grouped Box Plot</option> | |
| <option value="facetgrid">FacetGrid / Small Multiples</option> | |
| </optgroup> | |
| </select> | |
| </div> | |
| <div class="form-group" id="feat1-group" style="margin:0;min-width:180px;flex:0.7"> | |
| <label class="form-label">Feature</label> | |
| <select class="form-select" id="plot-feat1" onchange="generatePlot()"> | |
| <option value="">Select...</option> | |
| </select> | |
| </div> | |
| <div class="form-group" id="feat2-group" style="margin:0;min-width:180px;flex:0.7;display:none"> | |
| <label class="form-label">Feature 2</label> | |
| <select class="form-select" id="plot-feat2" onchange="generatePlot()"> | |
| <option value="">Select...</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="chart-container" id="explore-chart"></div> | |
| <div id="explore-msg" style="display:none;text-align:center;padding:40px 0;color:var(--text-muted)"></div> | |
| </div> | |
| <!-- Quality Panel --> | |
| <div id="explore-panel-quality" class="tab-panel"> | |
| <div class="table-wrap" id="quality-table"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ──────── BUILD SECTION ──────── --> | |
| <div id="sec-build" class="section"> | |
| <h1 class="section-title">Build</h1> | |
| <p class="section-subtitle">Configure preprocessing, train models, tune the best, and evaluate results</p> | |
| <!-- Configuration Card --> | |
| <div class="card relative" id="build-config-card"> | |
| <!-- Task --> | |
| <div class="form-group"> | |
| <label class="form-label">Task Type</label> | |
| <div class="radio-group" id="task-radio-group"> | |
| <label class="radio-item active" onclick="selectTask(this,'classification')"> | |
| <input type="radio" name="task" value="classification" checked> | |
| Classification | |
| </label> | |
| <label class="radio-item" onclick="selectTask(this,'regression')"> | |
| <input type="radio" name="task" value="regression"> | |
| Regression | |
| </label> | |
| </div> | |
| </div> | |
| <!-- Collapsible Preprocessing --> | |
| <div> | |
| <div class="collapsible-header open" onclick="toggleCollapsible(this)"> | |
| <span>Preprocessing Options</span> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg> | |
| </div> | |
| <div class="collapsible-body open"> | |
| <div class="checkbox-grid"> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="drop_duplicates" checked> Drop Duplicates</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="remove_outliers"> Remove Outliers</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="normalize" checked> Normalize</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="drop_multicollinear" checked> Drop Multicollinear</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="transform_skew"> Transform Skew</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="feature_selection"> Feature Selection</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="polynomial_features"> Polynomial Features</label> | |
| <label class="checkbox-item"><input type="checkbox" name="prep" value="fix_imbalance"> Fix Class Imbalance</label> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Sliders --> | |
| <div class="flex-row mt-md" style="gap:32px"> | |
| <div class="form-group" style="flex:1;margin:0"> | |
| <label class="form-label">Test Size</label> | |
| <div class="range-wrap"> | |
| <input type="range" id="test-size" min="0.1" max="0.4" step="0.05" value="0.2" oninput="document.getElementById('test-size-val').textContent=this.value"> | |
| <span class="range-val" id="test-size-val">0.2</span> | |
| </div> | |
| </div> | |
| <div class="form-group" style="flex:1;margin:0"> | |
| <label class="form-label">CV Folds</label> | |
| <div class="range-wrap"> | |
| <input type="range" id="cv-folds" min="2" max="10" step="1" value="5" oninput="document.getElementById('cv-folds-val').textContent=this.value"> | |
| <span class="range-val" id="cv-folds-val">5</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Train Button --> | |
| <div class="mt-md"> | |
| <button class="btn btn-primary" id="train-btn" onclick="trainModels()"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg> | |
| Train All Models | |
| </button> | |
| </div> | |
| <!-- Loading Overlay --> | |
| <div class="loading-overlay hidden" id="train-loading"> | |
| <div class="spinner"></div> | |
| <div class="loading-text" id="train-status">Initializing pipeline...</div> | |
| </div> | |
| </div> | |
| <!-- Results (hidden until training completes) --> | |
| <div id="build-results" style="display:none"> | |
| <!-- Training Summary Banner --> | |
| <div id="training-summary" style="display:none"></div> | |
| <!-- Best Model --> | |
| <div class="card mt-md" id="best-model-card" style="border-left: 3px solid #6366f1; background: linear-gradient(135deg, rgba(99,102,241,0.08) 0%, rgba(255,255,255,0.04) 100%); animation: glowPulse 3s ease-in-out infinite"> | |
| <div class="card-label">Best Model</div> | |
| <div style="display:flex;align-items:center;gap:10px"> | |
| <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color:var(--accent)"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg> | |
| <div class="card-value" id="best-model-name">--</div> | |
| </div> | |
| </div> | |
| <!-- Leaderboard --> | |
| <div class="card mt-md"> | |
| <div class="card-label">Leaderboard</div> | |
| <div class="table-wrap mt-sm" style="max-height:360px;overflow-y:auto" id="leaderboard-table"></div> | |
| </div> | |
| <!-- Metric Comparison --> | |
| <div class="card mt-md"> | |
| <div class="flex-row mb-md"> | |
| <div class="form-group" style="margin:0;min-width:200px"> | |
| <label class="form-label">Compare Metric</label> | |
| <select class="form-select" id="metric-select" onchange="renderMetricChart()"></select> | |
| </div> | |
| </div> | |
| <div class="chart-container" id="metric-chart"></div> | |
| </div> | |
| <!-- Tuning --> | |
| <div class="card mt-md relative" id="tune-card"> | |
| <div class="card-label">Hyperparameter Tuning</div> | |
| <div class="flex-row mt-sm" style="gap:16px;align-items:flex-end"> | |
| <div class="form-group" style="margin:0;min-width:160px"> | |
| <label class="form-label">Method</label> | |
| <select class="form-select" id="tune-method"> | |
| <option value="random">Random Search</option> | |
| <option value="optuna">Optuna (Bayesian)</option> | |
| <option value="grid">Grid Search</option> | |
| </select> | |
| </div> | |
| <div class="form-group" style="margin:0;min-width:180px"> | |
| <label class="form-label">Iterations</label> | |
| <div class="range-wrap"> | |
| <input type="range" id="tune-iter" min="5" max="50" step="5" value="10" oninput="document.getElementById('tune-iter-val').textContent=this.value"> | |
| <span class="range-val" id="tune-iter-val">10</span> | |
| </div> | |
| </div> | |
| <button class="btn btn-secondary btn-sm" id="tune-btn" onclick="tuneModel()">Tune</button> | |
| </div> | |
| <div id="tune-results" class="mt-md" style="display:none"> | |
| <div id="tune-improved" class="mb-md" style="font-size:13px;font-weight:500"></div> | |
| <div class="table-wrap" style="max-height:300px;overflow-y:auto" id="tune-table"></div> | |
| </div> | |
| <div class="loading-overlay hidden" id="tune-loading"> | |
| <div class="spinner"></div> | |
| <div class="loading-text">Tuning hyperparameters...</div> | |
| </div> | |
| </div> | |
| <!-- Evaluation Plots --> | |
| <div class="card mt-md"> | |
| <div class="card-label">Evaluation Plots</div> | |
| <div class="plot-grid mt-sm" id="eval-plots"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ──────── EXPORT SECTION ──────── --> | |
| <div id="sec-export" class="section"> | |
| <h1 class="section-title">Export</h1> | |
| <p class="section-subtitle">Download your trained pipeline, results, and predictions</p> | |
| <div class="card" id="export-summary-card"> | |
| <div class="card-label">Pipeline Summary</div> | |
| <div class="summary-grid mt-sm" id="export-summary"> | |
| <div class="card" style="padding:16px"> | |
| <div class="card-label">Model</div> | |
| <div class="card-value" style="font-size:16px" id="export-model">--</div> | |
| </div> | |
| <div class="card" style="padding:16px"> | |
| <div class="card-label">Task</div> | |
| <div class="card-value" style="font-size:16px" id="export-task">--</div> | |
| </div> | |
| <div class="card" style="padding:16px"> | |
| <div class="card-label">Predictions</div> | |
| <div class="card-value" style="font-size:16px" id="export-preds">--</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="card mt-md"> | |
| <div class="card-label">Downloads</div> | |
| <div class="download-row mt-sm"> | |
| <button class="btn btn-secondary" onclick="downloadExport('pipeline')"> | |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> | |
| Pipeline (.pkl) | |
| </button> | |
| <button class="btn btn-secondary" onclick="downloadExport('leaderboard')"> | |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg> | |
| Leaderboard (.csv) | |
| </button> | |
| <button class="btn btn-secondary" onclick="downloadExport('predictions')"> | |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg> | |
| Predictions (.csv) | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• | |
| JAVASCRIPT | |
| â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• --> | |
| <script src="/static/js/app.js"></script> | |
| </body> | |
| </html> | |