farwew commited on
Commit
b2ffd6d
·
verified ·
1 Parent(s): 3b6a480

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +691 -19
  3. prompts.txt +0 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Proba Le
3
- emoji: 🦀
4
- colorFrom: purple
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: proba-le
3
+ emoji: 🐳
4
+ colorFrom: green
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,691 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ML Prediction Probability Visualizer</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
11
+ <style>
12
+ .dropzone {
13
+ border: 2px dashed #3b82f6;
14
+ transition: all 0.3s ease;
15
+ }
16
+ .dropzone.active {
17
+ border-color: #10b981;
18
+ background-color: #f0f9ff;
19
+ }
20
+ .probability-bar {
21
+ transition: width 0.5s ease;
22
+ }
23
+ .glow {
24
+ box-shadow: 0 0 15px rgba(59, 130, 246, 0.5);
25
+ }
26
+ .card-hover:hover {
27
+ transform: translateY(-5px);
28
+ transition: all 0.3s ease;
29
+ }
30
+ .fade-in {
31
+ animation: fadeIn 0.5s ease-in;
32
+ }
33
+ @keyframes fadeIn {
34
+ from { opacity: 0; }
35
+ to { opacity: 1; }
36
+ }
37
+ </style>
38
+ </head>
39
+ <body class="bg-gray-50 min-h-screen">
40
+ <div class="container mx-auto px-4 py-8">
41
+ <!-- Header -->
42
+ <header class="text-center mb-12">
43
+ <h1 class="text-4xl font-bold text-blue-600 mb-2">ML Prediction Probability Visualizer</h1>
44
+ <p class="text-gray-600 max-w-2xl mx-auto">Upload your prediction results and visualize the probability distributions with interactive charts and insights.</p>
45
+ </header>
46
+
47
+ <!-- Main Content -->
48
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
49
+ <!-- Upload Section -->
50
+ <div class="bg-white rounded-xl shadow-md p-6 lg:col-span-1 card-hover">
51
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
52
+ <i class="fas fa-upload mr-2 text-blue-500"></i> Upload Data
53
+ </h2>
54
+
55
+ <div id="dropzone" class="dropzone rounded-lg p-8 text-center cursor-pointer mb-4">
56
+ <i class="fas fa-file-csv text-4xl text-blue-400 mb-3"></i>
57
+ <p class="text-gray-600 mb-2">Drag & drop your CSV/JSON file here</p>
58
+ <p class="text-sm text-gray-500">or</p>
59
+ <input type="file" id="fileInput" class="hidden" accept=".csv,.json,.txt">
60
+ <button id="selectFileBtn" class="mt-3 bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition">
61
+ Select File
62
+ </button>
63
+ </div>
64
+
65
+ <div class="mt-4">
66
+ <label for="fileType" class="block text-sm font-medium text-gray-700 mb-1">File Type</label>
67
+ <select id="fileType" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
68
+ <option value="csv">CSV</option>
69
+ <option value="json">JSON</option>
70
+ </select>
71
+ </div>
72
+
73
+ <div class="mt-4">
74
+ <label for="probabilityColumn" class="block text-sm font-medium text-gray-700 mb-1">Probability Column (CSV)</label>
75
+ <input type="text" id="probabilityColumn" placeholder="e.g., coppaRisk" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
76
+ </div>
77
+
78
+ <button id="visualizeBtn" class="mt-6 w-full bg-green-500 hover:bg-green-600 text-white px-4 py-3 rounded-lg font-medium transition flex items-center justify-center disabled:opacity-50" disabled>
79
+ <i class="fas fa-chart-bar mr-2"></i> Visualize Probabilities
80
+ </button>
81
+ </div>
82
+
83
+ <!-- Visualization Section -->
84
+ <div class="bg-white rounded-xl shadow-md p-6 lg:col-span-2 card-hover">
85
+ <div class="flex justify-between items-center mb-6">
86
+ <h2 class="text-xl font-semibold text-gray-800 flex items-center">
87
+ <i class="fas fa-chart-pie mr-2 text-blue-500"></i> Probability Distribution
88
+ </h2>
89
+ <div class="flex space-x-2">
90
+ <button id="barChartBtn" class="px-3 py-1 bg-blue-100 text-blue-600 rounded-md text-sm">
91
+ <i class="fas fa-chart-bar mr-1"></i> Bar
92
+ </button>
93
+ <button id="pieChartBtn" class="px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm">
94
+ <i class="fas fa-chart-pie mr-1"></i> Pie
95
+ </button>
96
+ <button id="histogramBtn" class="px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm">
97
+ <i class="fas fa-chart-line mr-1"></i> Histogram
98
+ </button>
99
+ </div>
100
+ </div>
101
+
102
+ <div id="chartContainer" class="h-80 flex items-center justify-center bg-gray-50 rounded-lg mb-6">
103
+ <p class="text-gray-400">Upload a file to visualize prediction probabilities</p>
104
+ </div>
105
+
106
+ <div id="statsContainer" class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
107
+ <!-- Stats will be populated here -->
108
+ </div>
109
+
110
+ <div id="probabilityBars" class="space-y-3">
111
+ <!-- Probability bars will be populated here -->
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <!-- Data Table Section (hidden by default) -->
117
+ <div id="dataTableSection" class="mt-8 bg-white rounded-xl shadow-md p-6 hidden fade-in">
118
+ <div class="flex justify-between items-center mb-4">
119
+ <h2 class="text-xl font-semibold text-gray-800 flex items-center">
120
+ <i class="fas fa-table mr-2 text-blue-500"></i> Raw Data Preview
121
+ </h2>
122
+ <button id="toggleTableBtn" class="text-blue-500 hover:text-blue-700 text-sm">
123
+ <i class="fas fa-eye-slash mr-1"></i> Hide Table
124
+ </button>
125
+ </div>
126
+ <div class="overflow-x-auto">
127
+ <table id="dataTable" class="min-w-full divide-y divide-gray-200">
128
+ <thead class="bg-gray-50">
129
+ <tr>
130
+ <!-- Table headers will be populated here -->
131
+ </tr>
132
+ </thead>
133
+ <tbody class="bg-white divide-y divide-gray-200">
134
+ <!-- Table rows will be populated here -->
135
+ </tbody>
136
+ </table>
137
+ </div>
138
+ </div>
139
+
140
+ <!-- Insights Section (hidden by default) -->
141
+ <div id="insightsSection" class="mt-8 bg-white rounded-xl shadow-md p-6 hidden fade-in">
142
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
143
+ <i class="fas fa-lightbulb mr-2 text-yellow-500"></i> Model Insights
144
+ </h2>
145
+ <div id="insightsContent" class="grid grid-cols-1 md:grid-cols-2 gap-4">
146
+ <!-- Insights will be populated here -->
147
+ </div>
148
+ </div>
149
+ </div>
150
+
151
+ <script>
152
+ document.addEventListener('DOMContentLoaded', function() {
153
+ // DOM Elements
154
+ const dropzone = document.getElementById('dropzone');
155
+ const fileInput = document.getElementById('fileInput');
156
+ const selectFileBtn = document.getElementById('selectFileBtn');
157
+ const visualizeBtn = document.getElementById('visualizeBtn');
158
+ const chartContainer = document.getElementById('chartContainer');
159
+ const statsContainer = document.getElementById('statsContainer');
160
+ const probabilityBars = document.getElementById('probabilityBars');
161
+ const dataTableSection = document.getElementById('dataTableSection');
162
+ const dataTable = document.getElementById('dataTable');
163
+ const insightsSection = document.getElementById('insightsSection');
164
+ const toggleTableBtn = document.getElementById('toggleTableBtn');
165
+ const barChartBtn = document.getElementById('barChartBtn');
166
+ const pieChartBtn = document.getElementById('pieChartBtn');
167
+ const histogramBtn = document.getElementById('histogramBtn');
168
+
169
+ // Variables
170
+ let uploadedData = null;
171
+ let chart = null;
172
+ let currentChartType = 'bar';
173
+
174
+ // Event Listeners
175
+ selectFileBtn.addEventListener('click', () => fileInput.click());
176
+
177
+ fileInput.addEventListener('change', handleFileSelect);
178
+
179
+ dropzone.addEventListener('dragover', (e) => {
180
+ e.preventDefault();
181
+ dropzone.classList.add('active');
182
+ });
183
+
184
+ dropzone.addEventListener('dragleave', () => {
185
+ dropzone.classList.remove('active');
186
+ });
187
+
188
+ dropzone.addEventListener('drop', (e) => {
189
+ e.preventDefault();
190
+ dropzone.classList.remove('active');
191
+ if (e.dataTransfer.files.length) {
192
+ fileInput.files = e.dataTransfer.files;
193
+ handleFileSelect({ target: fileInput });
194
+ }
195
+ });
196
+
197
+ visualizeBtn.addEventListener('click', visualizeData);
198
+
199
+ toggleTableBtn.addEventListener('click', () => {
200
+ dataTableSection.classList.toggle('hidden');
201
+ toggleTableBtn.innerHTML = dataTableSection.classList.contains('hidden') ?
202
+ '<i class="fas fa-eye mr-1"></i> Show Table' :
203
+ '<i class="fas fa-eye-slash mr-1"></i> Hide Table';
204
+ });
205
+
206
+ barChartBtn.addEventListener('click', () => switchChartType('bar'));
207
+ pieChartBtn.addEventListener('click', () => switchChartType('pie'));
208
+ histogramBtn.addEventListener('click', () => switchChartType('histogram'));
209
+
210
+ // Functions
211
+ function handleFileSelect(event) {
212
+ const file = event.target.files[0];
213
+ if (!file) return;
214
+
215
+ const fileType = document.getElementById('fileType').value;
216
+ const reader = new FileReader();
217
+
218
+ reader.onload = function(e) {
219
+ try {
220
+ if (fileType === 'csv') {
221
+ Papa.parse(e.target.result, {
222
+ header: true,
223
+ skipEmptyLines: true,
224
+ complete: function(results) {
225
+ uploadedData = results.data;
226
+ visualizeBtn.disabled = false;
227
+ showSuccess('File uploaded successfully!');
228
+ },
229
+ error: function(error) {
230
+ showError('Error parsing CSV file: ' + error.message);
231
+ }
232
+ });
233
+ } else if (fileType === 'json') {
234
+ uploadedData = JSON.parse(e.target.result);
235
+ visualizeBtn.disabled = false;
236
+ showSuccess('File uploaded successfully!');
237
+ }
238
+ } catch (error) {
239
+ showError('Error parsing file: ' + error.message);
240
+ }
241
+ };
242
+
243
+ reader.onerror = function() {
244
+ showError('Error reading file');
245
+ };
246
+
247
+ reader.readAsText(file);
248
+ }
249
+
250
+ function visualizeData() {
251
+ if (!uploadedData || uploadedData.length === 0) {
252
+ showError('No data to visualize');
253
+ return;
254
+ }
255
+
256
+ const probabilityColumn = document.getElementById('probabilityColumn').value;
257
+
258
+ // Process data based on file type
259
+ let probabilities = [];
260
+ let labels = [];
261
+
262
+ if (document.getElementById('fileType').value === 'csv') {
263
+ if (!probabilityColumn) {
264
+ showError('Please specify the probability column name for CSV files');
265
+ return;
266
+ }
267
+
268
+ // Process CSV data
269
+ uploadedData.forEach((row, index) => {
270
+ if (row[probabilityColumn]) {
271
+ probabilities.push(parseFloat(row[probabilityColumn]));
272
+ labels.push(`Prediction ${index + 1}`);
273
+ }
274
+ });
275
+ } else {
276
+ // Process JSON data (assuming array of numbers or array of objects with probability property)
277
+ if (Array.isArray(uploadedData)) {
278
+ if (typeof uploadedData[0] === 'number') {
279
+ probabilities = uploadedData;
280
+ labels = uploadedData.map((_, index) => `Prediction ${index + 1}`);
281
+ } else if (typeof uploadedData[0] === 'object') {
282
+ probabilities = uploadedData.map(item => item.probability || item.prediction || item.value || 0);
283
+ labels = uploadedData.map((item, index) => item.label || `Prediction ${index + 1}`);
284
+ }
285
+ }
286
+ }
287
+
288
+ if (probabilities.length === 0) {
289
+ showError('No valid probability data found');
290
+ return;
291
+ }
292
+
293
+ // Update UI
294
+ updateStats(probabilities);
295
+ updateProbabilityBars(probabilities, labels);
296
+ renderChart(probabilities, labels, currentChartType);
297
+ renderDataTable(uploadedData);
298
+ generateInsights(probabilities);
299
+
300
+ // Show sections
301
+ dataTableSection.classList.remove('hidden');
302
+ insightsSection.classList.remove('hidden');
303
+ }
304
+
305
+ function updateStats(probabilities) {
306
+ const mean = probabilities.reduce((a, b) => a + b, 0) / probabilities.length;
307
+ const sorted = [...probabilities].sort((a, b) => a - b);
308
+ const median = sorted[Math.floor(sorted.length / 2)];
309
+ const min = Math.min(...probabilities);
310
+ const max = Math.max(...probabilities);
311
+ const stdDev = Math.sqrt(probabilities.reduce((sq, n) => sq + Math.pow(n - mean, 2), 0) / probabilities.length);
312
+
313
+ statsContainer.innerHTML = `
314
+ <div class="bg-blue-50 p-4 rounded-lg">
315
+ <p class="text-sm text-blue-500 font-medium">Mean Probability</p>
316
+ <p class="text-2xl font-bold text-blue-600">${mean.toFixed(4)}</p>
317
+ </div>
318
+ <div class="bg-green-50 p-4 rounded-lg">
319
+ <p class="text-sm text-green-500 font-medium">Median Probability</p>
320
+ <p class="text-2xl font-bold text-green-600">${median.toFixed(4)}</p>
321
+ </div>
322
+ <div class="bg-purple-50 p-4 rounded-lg">
323
+ <p class="text-sm text-purple-500 font-medium">Standard Deviation</p>
324
+ <p class="text-2xl font-bold text-purple-600">${stdDev.toFixed(4)}</p>
325
+ </div>
326
+ <div class="bg-yellow-50 p-4 rounded-lg">
327
+ <p class="text-sm text-yellow-500 font-medium">Range</p>
328
+ <p class="text-2xl font-bold text-yellow-600">${min.toFixed(4)} - ${max.toFixed(4)}</p>
329
+ </div>
330
+ `;
331
+ }
332
+
333
+ function updateProbabilityBars(probabilities, labels) {
334
+ probabilityBars.innerHTML = '';
335
+
336
+ probabilities.forEach((prob, index) => {
337
+ const percentage = Math.round(prob * 100);
338
+ const barColor = prob > 0.7 ? 'bg-green-500' : prob > 0.3 ? 'bg-yellow-500' : 'bg-red-500';
339
+
340
+ const bar = document.createElement('div');
341
+ bar.className = 'probability-bar';
342
+ bar.innerHTML = `
343
+ <div class="flex justify-between mb-1">
344
+ <span class="text-sm font-medium text-gray-700">${labels[index] || `Prediction ${index + 1}`}</span>
345
+ <span class="text-sm font-medium ${prob > 0.7 ? 'text-green-600' : prob > 0.3 ? 'text-yellow-600' : 'text-red-600'}">${prob.toFixed(4)}</span>
346
+ </div>
347
+ <div class="w-full bg-gray-200 rounded-full h-2.5">
348
+ <div class="h-2.5 rounded-full ${barColor}" style="width: ${percentage}%"></div>
349
+ </div>
350
+ `;
351
+
352
+ probabilityBars.appendChild(bar);
353
+
354
+ // Trigger animation
355
+ setTimeout(() => {
356
+ bar.querySelector(`.${barColor}`).classList.add('glow');
357
+ }, index * 100);
358
+ });
359
+ }
360
+
361
+ function renderChart(probabilities, labels, type = 'bar') {
362
+ // Destroy previous chart if exists
363
+ if (chart) {
364
+ chart.destroy();
365
+ }
366
+
367
+ const ctx = document.createElement('canvas');
368
+ chartContainer.innerHTML = '';
369
+ chartContainer.appendChild(ctx);
370
+
371
+ const backgroundColors = probabilities.map(prob => {
372
+ const opacity = 0.7;
373
+ return prob > 0.7 ? `rgba(16, 185, 129, ${opacity})` :
374
+ prob > 0.3 ? `rgba(234, 179, 8, ${opacity})` :
375
+ `rgba(239, 68, 68, ${opacity})`;
376
+ });
377
+
378
+ const borderColors = probabilities.map(prob => {
379
+ return prob > 0.7 ? 'rgba(16, 185, 129, 1)' :
380
+ prob > 0.3 ? 'rgba(234, 179, 8, 1)' :
381
+ 'rgba(239, 68, 68, 1)';
382
+ });
383
+
384
+ const chartData = {
385
+ labels: labels,
386
+ datasets: [{
387
+ label: 'Prediction Probability',
388
+ data: probabilities,
389
+ backgroundColor: backgroundColors,
390
+ borderColor: borderColors,
391
+ borderWidth: 1
392
+ }]
393
+ };
394
+
395
+ const chartOptions = {
396
+ responsive: true,
397
+ maintainAspectRatio: false,
398
+ scales: {
399
+ y: {
400
+ beginAtZero: true,
401
+ max: 1,
402
+ ticks: {
403
+ callback: function(value) {
404
+ return value.toFixed(2);
405
+ }
406
+ }
407
+ }
408
+ },
409
+ plugins: {
410
+ tooltip: {
411
+ callbacks: {
412
+ label: function(context) {
413
+ return `Probability: ${context.raw.toFixed(4)}`;
414
+ }
415
+ }
416
+ }
417
+ }
418
+ };
419
+
420
+ switch (type) {
421
+ case 'bar':
422
+ chart = new Chart(ctx, {
423
+ type: 'bar',
424
+ data: chartData,
425
+ options: chartOptions
426
+ });
427
+ barChartBtn.className = 'px-3 py-1 bg-blue-100 text-blue-600 rounded-md text-sm';
428
+ pieChartBtn.className = 'px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm';
429
+ histogramBtn.className = 'px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm';
430
+ break;
431
+
432
+ case 'pie':
433
+ chart = new Chart(ctx, {
434
+ type: 'pie',
435
+ data: chartData,
436
+ options: {
437
+ ...chartOptions,
438
+ plugins: {
439
+ legend: {
440
+ position: 'right',
441
+ },
442
+ tooltip: {
443
+ callbacks: {
444
+ label: function(context) {
445
+ const label = context.label || '';
446
+ const value = context.raw || 0;
447
+ const percentage = Math.round(value * 100);
448
+ return `${label}: ${value.toFixed(4)} (${percentage}%)`;
449
+ }
450
+ }
451
+ }
452
+ }
453
+ }
454
+ });
455
+ barChartBtn.className = 'px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm';
456
+ pieChartBtn.className = 'px-3 py-1 bg-blue-100 text-blue-600 rounded-md text-sm';
457
+ histogramBtn.className = 'px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm';
458
+ break;
459
+
460
+ case 'histogram':
461
+ // For histogram, we'll bin the probabilities
462
+ const binCount = Math.min(10, Math.floor(probabilities.length / 5));
463
+ const histogramData = Array(binCount).fill(0);
464
+ const step = 1 / binCount;
465
+
466
+ probabilities.forEach(prob => {
467
+ const binIndex = Math.min(Math.floor(prob / step), binCount - 1);
468
+ histogramData[binIndex]++;
469
+ });
470
+
471
+ const histogramLabels = Array.from({length: binCount}, (_, i) => {
472
+ const start = (i * step).toFixed(2);
473
+ const end = ((i + 1) * step).toFixed(2);
474
+ return `${start}-${end}`;
475
+ });
476
+
477
+ chart = new Chart(ctx, {
478
+ type: 'bar',
479
+ data: {
480
+ labels: histogramLabels,
481
+ datasets: [{
482
+ label: 'Count of Predictions',
483
+ data: histogramData,
484
+ backgroundColor: 'rgba(59, 130, 246, 0.7)',
485
+ borderColor: 'rgba(59, 130, 246, 1)',
486
+ borderWidth: 1
487
+ }]
488
+ },
489
+ options: {
490
+ ...chartOptions,
491
+ scales: {
492
+ y: {
493
+ beginAtZero: true,
494
+ title: {
495
+ display: true,
496
+ text: 'Count'
497
+ }
498
+ },
499
+ x: {
500
+ title: {
501
+ display: true,
502
+ text: 'Probability Range'
503
+ }
504
+ }
505
+ }
506
+ }
507
+ });
508
+ barChartBtn.className = 'px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm';
509
+ pieChartBtn.className = 'px-3 py-1 bg-gray-100 text-gray-600 rounded-md text-sm';
510
+ histogramBtn.className = 'px-3 py-1 bg-blue-100 text-blue-600 rounded-md text-sm';
511
+ break;
512
+ }
513
+
514
+ currentChartType = type;
515
+ }
516
+
517
+ function renderDataTable(data) {
518
+ if (!data || data.length === 0) return;
519
+
520
+ // Clear previous table
521
+ dataTable.querySelector('thead tr').innerHTML = '';
522
+ dataTable.querySelector('tbody').innerHTML = '';
523
+
524
+ // Get headers from first object
525
+ const headers = Object.keys(data[0]);
526
+
527
+ // Add headers
528
+ headers.forEach(header => {
529
+ const th = document.createElement('th');
530
+ th.className = 'px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider';
531
+ th.textContent = header;
532
+ dataTable.querySelector('thead tr').appendChild(th);
533
+ });
534
+
535
+ // Add rows (limit to 10 for performance)
536
+ const rowsToShow = Math.min(10, data.length);
537
+ for (let i = 0; i < rowsToShow; i++) {
538
+ const row = document.createElement('tr');
539
+ row.className = i % 2 === 0 ? 'bg-white' : 'bg-gray-50';
540
+
541
+ headers.forEach(header => {
542
+ const td = document.createElement('td');
543
+ td.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500';
544
+ td.textContent = data[i][header] !== undefined ? data[i][header] : '';
545
+ row.appendChild(td);
546
+ });
547
+
548
+ dataTable.querySelector('tbody').appendChild(row);
549
+ }
550
+ }
551
+
552
+ function generateInsights(probabilities) {
553
+ const highConfidence = probabilities.filter(p => p > 0.7).length;
554
+ const lowConfidence = probabilities.filter(p => p < 0.3).length;
555
+ const midConfidence = probabilities.length - highConfidence - lowConfidence;
556
+
557
+ const mean = probabilities.reduce((a, b) => a + b, 0) / probabilities.length;
558
+ const sorted = [...probabilities].sort((a, b) => a - b);
559
+ const median = sorted[Math.floor(sorted.length / 2)];
560
+
561
+ insightsSection.innerHTML = `
562
+ <div class="bg-white p-4 rounded-lg border border-gray-200">
563
+ <h3 class="font-medium text-gray-800 mb-2 flex items-center">
564
+ <i class="fas fa-chart-line mr-2 text-blue-500"></i> Confidence Distribution
565
+ </h3>
566
+ <div class="space-y-2">
567
+ <div class="flex justify-between">
568
+ <span class="text-sm text-green-600">High Confidence (>70%)</span>
569
+ <span class="text-sm font-medium">${highConfidence} (${Math.round(highConfidence/probabilities.length*100)}%)</span>
570
+ </div>
571
+ <div class="flex justify-between">
572
+ <span class="text-sm text-yellow-600">Medium Confidence (30-70%)</span>
573
+ <span class="text-sm font-medium">${midConfidence} (${Math.round(midConfidence/probabilities.length*100)}%)</span>
574
+ </div>
575
+ <div class="flex justify-between">
576
+ <span class="text-sm text-red-600">Low Confidence (<30%)</span>
577
+ <span class="text-sm font-medium">${lowConfidence} (${Math.round(lowConfidence/probabilities.length*100)}%)</span>
578
+ </div>
579
+ </div>
580
+ </div>
581
+
582
+ <div class="bg-white p-4 rounded-lg border border-gray-200">
583
+ <h3 class="font-medium text-gray-800 mb-2 flex items-center">
584
+ <i class="fas fa-balance-scale mr-2 text-purple-500"></i> Central Tendency
585
+ </h3>
586
+ <div class="space-y-2">
587
+ <div class="flex justify-between">
588
+ <span class="text-sm">Mean Probability</span>
589
+ <span class="text-sm font-medium">${mean.toFixed(4)}</span>
590
+ </div>
591
+ <div class="flex justify-between">
592
+ <span class="text-sm">Median Probability</span>
593
+ <span class="text-sm font-medium">${median.toFixed(4)}</span>
594
+ </div>
595
+ <div class="flex justify-between">
596
+ <span class="text-sm">Difference</span>
597
+ <span class="text-sm font-medium">${Math.abs(mean - median).toFixed(4)}</span>
598
+ </div>
599
+ </div>
600
+ </div>
601
+
602
+ <div class="bg-white p-4 rounded-lg border border-gray-200">
603
+ <h3 class="font-medium text-gray-800 mb-2 flex items-center">
604
+ <i class="fas fa-exclamation-triangle mr-2 text-red-500"></i> Potential Issues
605
+ </h3>
606
+ <div class="space-y-2 text-sm">
607
+ ${lowConfidence > probabilities.length * 0.5 ?
608
+ '<p class="text-red-500"><i class="fas fa-exclamation-circle mr-1"></i> Over 50% of predictions have low confidence (<30%)</p>' :
609
+ '<p class="text-green-500"><i class="fas fa-check-circle mr-1"></i> Low confidence predictions are in acceptable range</p>'}
610
+
611
+ ${Math.abs(mean - median) > 0.2 ?
612
+ '<p class="text-yellow-500"><i class="fas fa-exclamation-circle mr-1"></i> Significant difference between mean and median probabilities</p>' :
613
+ '<p class="fas fa-check-circle mr-1"></i> Mean and median probabilities are close</p>'}
614
+ </div>
615
+ </div>
616
+
617
+ <div class="bg-white p-4 rounded-lg border border-gray-200">
618
+ <h3 class="font-medium text-gray-800 mb-2 flex items-center">
619
+ <i class="fas fa-lightbulb mr-2 text-yellow-500"></i> Recommendations
620
+ </h3>
621
+ <div class="space-y-2 text-sm">
622
+ <p><i class="fas fa-check-circle text-blue-500 mr-1"></i> Review low confidence predictions for potential errors</p>
623
+ <p><i class="fas fa-check-circle text-blue-500 mr-1"></i> Consider model retraining if confidence is consistently low</p>
624
+ <p><i class="fas fa-check-circle text-blue-500 mr-1"></i> Examine features influencing high confidence predictions</p>
625
+ </div>
626
+ </div>
627
+ `;
628
+ }
629
+
630
+ function switchChartType(type) {
631
+ if (!uploadedData) return;
632
+
633
+ const probabilityColumn = document.getElementById('probabilityColumn').value;
634
+ let probabilities = [];
635
+ let labels = [];
636
+
637
+ if (document.getElementById('fileType').value === 'csv') {
638
+ uploadedData.forEach((row, index) => {
639
+ if (row[probabilityColumn]) {
640
+ probabilities.push(parseFloat(row[probabilityColumn]));
641
+ labels.push(`Prediction ${index + 1}`);
642
+ }
643
+ });
644
+ } else {
645
+ if (Array.isArray(uploadedData)) {
646
+ if (typeof uploadedData[0] === 'number') {
647
+ probabilities = uploadedData;
648
+ labels = uploadedData.map((_, index) => `Prediction ${index + 1}`);
649
+ } else if (typeof uploadedData[0] === 'object') {
650
+ probabilities = uploadedData.map(item => item.probability || item.prediction || item.value || 0);
651
+ labels = uploadedData.map((item, index) => item.label || `Prediction ${index + 1}`);
652
+ }
653
+ }
654
+ }
655
+
656
+ renderChart(probabilities, labels, type);
657
+ }
658
+
659
+ function showSuccess(message) {
660
+ const alert = document.createElement('div');
661
+ alert.className = 'fixed top-4 right-4 bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded shadow-lg z-50 flex items-center';
662
+ alert.innerHTML = `
663
+ <i class="fas fa-check-circle mr-2"></i>
664
+ <span>${message}</span>
665
+ `;
666
+ document.body.appendChild(alert);
667
+
668
+ setTimeout(() => {
669
+ alert.classList.add('opacity-0', 'transition-opacity', 'duration-500');
670
+ setTimeout(() => alert.remove(), 500);
671
+ }, 3000);
672
+ }
673
+
674
+ function showError(message) {
675
+ const alert = document.createElement('div');
676
+ alert.className = 'fixed top-4 right-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded shadow-lg z-50 flex items-center';
677
+ alert.innerHTML = `
678
+ <i class="fas fa-exclamation-circle mr-2"></i>
679
+ <span>${message}</span>
680
+ `;
681
+ document.body.appendChild(alert);
682
+
683
+ setTimeout(() => {
684
+ alert.classList.add('opacity-0', 'transition-opacity', 'duration-500');
685
+ setTimeout(() => alert.remove(), 500);
686
+ }, 3000);
687
+ }
688
+ });
689
+ </script>
690
+ <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=farwew/proba-le" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
691
+ </html>
prompts.txt ADDED
File without changes