|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
console.log("lasso_charts.js loaded and DOM fully parsed.");
|
|
|
|
|
|
const form = document.getElementById('predictionForm');
|
|
|
const loadingSpinner = document.getElementById('loadingSpinner');
|
|
|
|
|
|
form.addEventListener('submit', function() {
|
|
|
loadingSpinner.classList.remove('hidden');
|
|
|
});
|
|
|
|
|
|
|
|
|
const alphaValues = [0.01, 0.1, 0.5, 1, 2, 5, 10];
|
|
|
const dummyCoefficients = {
|
|
|
'OverallQual': [0.8, 0.7, 0.5, 0.3, 0.1, 0, 0],
|
|
|
'GrLivArea': [1.2, 1.1, 0.9, 0.7, 0.5, 0.2, 0.1],
|
|
|
'GarageCars': [0.5, 0.4, 0.3, 0.1, 0, 0, 0],
|
|
|
'TotalBsmtSF': [0.6, 0.5, 0.4, 0.2, 0.1, 0.05, 0],
|
|
|
'YearBuilt': [0.3, 0.2, 0.1, 0.05, 0, 0, 0]
|
|
|
};
|
|
|
|
|
|
const ctxCoeff = document.getElementById('coefficientPathChart');
|
|
|
if (ctxCoeff) {
|
|
|
new Chart(ctxCoeff, {
|
|
|
type: 'line',
|
|
|
data: {
|
|
|
labels: alphaValues.map(a => `λ=${a}`),
|
|
|
datasets: Object.keys(dummyCoefficients).map(feature => ({
|
|
|
label: feature,
|
|
|
data: dummyCoefficients[feature],
|
|
|
borderColor: getRandomColor(),
|
|
|
fill: false,
|
|
|
tension: 0.1
|
|
|
}))
|
|
|
},
|
|
|
options: {
|
|
|
responsive: true,
|
|
|
maintainAspectRatio: false,
|
|
|
plugins: {
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Coefficient Path for Different Lambda (α) Values'
|
|
|
},
|
|
|
tooltip: {
|
|
|
mode: 'index',
|
|
|
intersect: false,
|
|
|
},
|
|
|
},
|
|
|
scales: {
|
|
|
x: {
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Regularization Strength (λ)'
|
|
|
}
|
|
|
},
|
|
|
y: {
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Coefficient Value'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
const finalCoefficients = {
|
|
|
'OverallQual': 0.65,
|
|
|
'GrLivArea': 0.82,
|
|
|
'GarageCars': 0.15,
|
|
|
'TotalBsmtSF': 0.38,
|
|
|
'YearBuilt': 0.07
|
|
|
};
|
|
|
const featureLabels = Object.keys(finalCoefficients);
|
|
|
const featureValues = Object.values(finalCoefficients).map(Math.abs);
|
|
|
|
|
|
const ctxFeature = document.getElementById('featureImportanceChart');
|
|
|
if (ctxFeature) {
|
|
|
new Chart(ctxFeature, {
|
|
|
type: 'bar',
|
|
|
data: {
|
|
|
labels: featureLabels,
|
|
|
datasets: [{
|
|
|
label: 'Absolute Coefficient Value',
|
|
|
data: featureValues,
|
|
|
backgroundColor: 'rgba(54, 162, 235, 0.7)',
|
|
|
borderColor: 'rgba(54, 162, 235, 1)',
|
|
|
borderWidth: 1
|
|
|
}]
|
|
|
},
|
|
|
options: {
|
|
|
responsive: true,
|
|
|
maintainAspectRatio: false,
|
|
|
plugins: {
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Feature Importance (Absolute Coefficients)'
|
|
|
},
|
|
|
legend: {
|
|
|
display: false
|
|
|
}
|
|
|
},
|
|
|
scales: {
|
|
|
y: {
|
|
|
beginAtZero: true,
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Absolute Coefficient Value'
|
|
|
}
|
|
|
},
|
|
|
x: {
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Features'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
const actualPrices = [200000, 250000, 180000, 300000, 220000, 270000, 190000, 310000];
|
|
|
const predictedPrices = [210000, 245000, 175000, 310000, 215000, 280000, 195000, 300000];
|
|
|
const dataPoints = actualPrices.map((actual, index) => ({
|
|
|
x: actual,
|
|
|
y: predictedPrices[index]
|
|
|
}));
|
|
|
|
|
|
const ctxPredActual = document.getElementById('predictionActualChart');
|
|
|
if (ctxPredActual) {
|
|
|
new Chart(ctxPredActual, {
|
|
|
type: 'scatter',
|
|
|
data: {
|
|
|
datasets: [{
|
|
|
label: 'Predicted vs. Actual',
|
|
|
data: dataPoints,
|
|
|
backgroundColor: 'rgba(75, 192, 192, 0.8)',
|
|
|
pointRadius: 5
|
|
|
}, {
|
|
|
label: 'Ideal Prediction',
|
|
|
data: [{x: Math.min(...actualPrices, ...predictedPrices), y: Math.min(...actualPrices, ...predictedPrices)},
|
|
|
{x: Math.max(...actualPrices, ...predictedPrices), y: Math.max(...actualPrices, ...predictedPrices)}],
|
|
|
borderColor: 'rgba(255, 99, 132, 0.8)',
|
|
|
borderWidth: 2,
|
|
|
pointRadius: 0,
|
|
|
type: 'line',
|
|
|
fill: false,
|
|
|
tension: 0
|
|
|
}]
|
|
|
},
|
|
|
options: {
|
|
|
responsive: true,
|
|
|
maintainAspectRatio: false,
|
|
|
plugins: {
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Predicted vs. Actual Prices'
|
|
|
},
|
|
|
tooltip: {
|
|
|
callbacks: {
|
|
|
label: function(context) {
|
|
|
return `Actual: $${context.parsed.x}, Predicted: $${context.parsed.y}`;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
scales: {
|
|
|
x: {
|
|
|
type: 'linear',
|
|
|
position: 'bottom',
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Actual Price ($)'
|
|
|
}
|
|
|
},
|
|
|
y: {
|
|
|
type: 'linear',
|
|
|
position: 'left',
|
|
|
title: {
|
|
|
display: true,
|
|
|
text: 'Predicted Price ($)'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
function getRandomColor() {
|
|
|
const letters = '0123456789ABCDEF';
|
|
|
let color = '#';
|
|
|
for (let i = 0; i < 6; i++) {
|
|
|
color += letters[Math.floor(Math.random() * 16)];
|
|
|
}
|
|
|
return color;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|