Neroml / Templates /ridge.html
deedrop1140's picture
Upload 69 files
6491927 verified
{% extends "layout.html" %}
{% block content %}
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='output.css') }}">
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.7.0/dist/chart.min.js"></script>
<div class="max-w-3xl mx-auto mt-12 p-8 bg-gray-100 rounded-2xl shadow-xl border border-gray-300 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-gray-200 to-gray-300 opacity-60 rounded-2xl -z-10 animate-pulse-light"></div>
<h1 class="text-4xl font-extrabold text-gray-900 mb-6 flex items-center">
<span class="mr-3 text-purple-600">⛰️</span> Ridge Regression Predictions
</h1>
<p class="text-lg text-gray-800 mb-8 leading-relaxed">
Explore the power of <strong>Ridge Regression (L2 Regularization)</strong> for robust predictions.
This technique is excellent for handling multicollinearity and preventing overfitting by shrinking coefficients, while still retaining all features.
</p>
<div class="bg-gray-200 p-6 rounded-xl shadow-inner border border-gray-300 mt-8">
<h2 class="text-2xl font-bold text-gray-900 mb-4">🎯 Input Features</h2>
<form method="POST" class="space-y-5" id="predictionForm">
{% for field in ['OverallQual', 'GrLivArea', 'GarageCars', 'TotalBsmtSF', 'YearBuilt'] %}
<div class="relative group">
<label for="{{ field }}" class="block text-md font-medium text-gray-800 mb-1">
{{ field | replace('OverallQual', 'Overall Quality') | replace('GrLivArea', 'Above Ground Living Area (sq ft)') | replace('GarageCars', 'Size of Garage (cars)') | replace('TotalBsmtSF', 'Total Basement Area (sq ft)') | replace('YearBuilt', 'Year Built') }}:
</label>
<input type="number" step="any" id="{{ field }}" name="{{ field }}" required
class="w-full border-gray-400 input-glow rounded-md shadow-sm focus:border-purple-500 focus:ring-purple-500 text-lg p-2.5 transition duration-200 ease-in-out hover:border-gray-500"
placeholder="Enter value for {{ field | replace('OverallQual', 'Overall Quality') | replace('GrLivArea', 'sq ft') | replace('GarageCars', 'cars') | replace('TotalBsmtSF', 'sq ft') | replace('YearBuilt', 'year') }}">
<span class="absolute inset-y-0 right-0 flex items-center pr-4 text-gray-500 text-sm pointer-events-none">
{% if field == 'GrLivArea' or field == 'TotalBsmtSF' %} sq ft
{% elif field == 'GarageCars' %} cars
{% elif field == 'YearBuilt' %} year
{% else %}
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path></svg>
{% endif %}
</span>
</div>
{% endfor %}
<button type="submit" class="w-full bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white font-bold py-3.5 px-4 rounded-lg shadow-lg transition duration-300 ease-in-out transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-opacity-75">
<span class="mr-2">🔍</span> Predict with Ridge
</button>
<div id="loadingSpinner" class="hidden text-center mt-4 text-gray-600">
<span class="loader border-purple-500 border-t-purple-500"></span> Processing...
</div>
</form>
</div>
{% if prediction %}
<div class="mt-8 bg-gradient-to-r from-purple-400 to-indigo-500 text-white font-extrabold text-3xl p-6 rounded-xl shadow-2xl flex items-center justify-center animate-pulse-purple transform scale-105">
<span class="mr-4 text-4xl">💰</span> Predicted Price: <span class="ml-3 text-shadow">${{ "%.2f" | format(prediction | float) }}</span>
</div>
{% elif error %}
<div class="mt-8 bg-red-500 text-white font-semibold text-lg p-5 rounded-lg shadow-lg flex items-center justify-center animate-shake">
<span class="mr-3">⚠️</span> Error: {{ error }} Please check your inputs.
</div>
{% endif %}
</div>
<div class="max-w-3xl mx-auto mt-12 p-8 bg-gray-100 rounded-2xl shadow-xl border border-gray-300">
<h2 class="text-3xl font-extrabold text-gray-900 mb-6 flex items-center">
<span class="mr-3 text-purple-600">📚</span> Deep Dive into Ridge Regression (L2 Regularization)
</h2>
<p class="text-gray-800 mb-4 leading-relaxed">
<strong>Ridge Regression</strong> helps make our prediction models more stable and less prone to errors on new data. It does this by adding a special "penalty" to its calculations. This penalty is called <strong>L2 Regularization</strong>.
</p>
<div class="bg-gray-200 p-5 rounded-lg mb-6 border border-gray-300">
<h3 class="text-xl font-semibold text-gray-900 mb-3">🎯 How Ridge Calculates (Objective Function):</h3>
<p class="text-gray-800 text-lg mb-2">
Ridge tries to find the best prediction rule by minimizing this formula:
</p>
<strong class="text-gray-900 text-xl bg-gray-300 px-4 py-3 rounded-md font-mono text-center mb-4 block">
$$ J(\theta) = \frac{1}{2n} \sum_{i=1}^{n} \left(h_{\theta}(x^{(i)}) - y^{(i)}\right)^2 + \lambda \sum_{j=1}^{p} \theta_j^2 $$
</strong>
<ul class="list-disc list-inside text-gray-800 mt-4 pl-6 space-y-3">
<li><strong>Prediction Error (First Part):</strong><br>
<strong class="text-gray-900 text-xl bg-gray-300 px-4 py-3 rounded-md font-mono text-center mb-2 inline-block">
$$ \frac{1}{2n} \sum_{i=1}^{n} \left(h_{\theta}(x^{(i)}) - y^{(i)}\right)^2 $$
</strong>
This is the standard part: How well did our model predict? We want our predictions ($h_{\theta}(x^{(i)})$) to be very close to the actual values ($y^{(i)}$).
</li>
<li><strong>Ridge's "Penalty" (Second Part):</strong><br>
<strong class="text-gray-900 text-xl bg-gray-300 px-4 py-3 rounded-md font-mono text-center mb-2 inline-block">
$$ \lambda \sum_{j=1}^{p} \theta_j^2 $$
</strong>
This is the L2 penalty. It adds a cost for making any feature's "importance" (called a coefficient, $\theta_j$) too big. If a coefficient is large, this term gets big, increasing the total cost. To keep the cost low, Ridge *forces* coefficients to be smaller.
</li>
</ul>
<p class="text-gray-800 mt-4">
The symbol $\lambda$ (lambda) is like a <strong>"Volume Knob"</strong> for this penalty.
<br><strong>Big $\lambda$:</strong> Turn up the volume knob, so coefficients are shrunk *a lot*.
<br><strong>Small $\lambda$:</strong> Turn down the volume knob, so coefficients are shrunk *less*.
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div class="bg-gray-200 p-5 rounded-lg border border-gray-300">
<h3 class="text-xl font-semibold text-gray-900 mb-3 flex items-center">
<span class="mr-2 text-purple-600"></span> Why Ridge is Useful
</h3>
<ul class="list-disc list-inside text-gray-800 space-y-2">
<li><strong>Prevents Over-Learning:</strong> Stops the model from memorizing the training data too much, so it performs better on new data.</li>
<li><strong>Handles Similar Features:</strong> If you have features that tell a similar story (e.g., house size and number of rooms), Ridge manages them well without favoring one too much.</li>
<li><strong>Keeps All Information:</strong> All features still contribute to the prediction, even if just a little bit.</li>
</ul>
</div>
<div class="bg-gray-200 p-5 rounded-lg border border-gray-300">
<h3 class="text-xl font-semibold text-gray-900 mb-3 flex items-center">
<span class="mr-2 text-purple-600">🆚</span> Ridge vs. Lasso (The Main Difference)
</h3>
<ul class="list-disc list-inside text-gray-800 space-y-2">
<li><strong>Ridge (L2):</strong> It *shrinks* the importance of features (their coefficients) towards zero. Think of it like a dimmer switch for a light: the light gets very dim, but it's never completely OFF.</li>
<li><strong>Lasso (L1):</strong> It can *force* the importance of some features (their coefficients) to become *exactly zero*. This is like turning some lights completely OFF, effectively ignoring those features.</li>
</ul>
</div>
</div>
<!-- Ridge Flow Visualization -->
<div class="bg-purple-50 mt-12 p-8 rounded-2xl shadow-lg border border-purple-300">
<h2 class="text-3xl font-extrabold text-purple-900 mb-6 flex items-center">
<span class="mr-3 text-purple-600">🔄</span> How Ridge Treats Your Data
</h2>
<p class="text-purple-800 mb-6 leading-relaxed">
Ridge uses <strong>L2 regularization</strong> to <u>shrink all feature weights</u>, but <strong>never drops any feature completely</strong>. This allows it to preserve all information while still controlling model complexity.
</p>
<div class="grid gap-8 md:grid-cols-5 items-center text-center text-purple-800 font-semibold text-sm">
<!-- Step 1: Input -->
<div class="p-4 bg-purple-100 border rounded-lg shadow">
<div class="text-4xl mb-2">📥</div>
<div>Input Features</div>
<div class="text-xs mt-1 text-purple-500">All provided</div>
</div>
<!-- Arrow -->
<div class="text-2xl text-purple-400 hidden md:block">➡️</div>
<!-- Step 2: Cost Function -->
<div class="p-4 bg-purple-100 border rounded-lg shadow">
<div class="text-4xl mb-2">⚙️</div>
<div>Cost Function</div>
<div class="text-xs mt-1 text-purple-500">MSE + λ × ∑θ²</div>
</div>
<!-- Arrow -->
<div class="text-2xl text-purple-400 hidden md:block">➡️</div>
<!-- Step 3: Shrink Coefficients -->
<div class="p-4 bg-yellow-100 border rounded-lg shadow">
<div class="text-4xl mb-2">📉</div>
<div>Shrinks All Coeffs</div>
<div class="text-xs mt-1 text-yellow-600">Closer to 0, but ≠ 0</div>
</div>
<!-- Arrow -->
<div class="text-2xl text-purple-400 hidden md:block">➡️</div>
<!-- Step 4: Stable Output -->
<div class="p-4 bg-green-100 border rounded-lg shadow">
<div class="text-4xl mb-2">🎯</div>
<div>Prediction Uses All</div>
<div class="text-xs mt-1 text-green-600">None are ignored</div>
</div>
</div>
<p class="text-purple-800 mt-6 leading-relaxed text-sm">
Unlike Lasso, <strong>Ridge Regression keeps all your features</strong>—just with smaller, regularized weights. It’s perfect when <u>all features have some predictive power</u>.
</p>
</div>
</div>
<p class="text-gray-800 mt-6 mb-6 leading-relaxed">
Ridge is a great choice when you believe all your features are somewhat useful and you want to **control how much influence they have** without completely throwing any away.
</p>
<div class="bg-white mt-12 p-8 rounded-2xl shadow-xl border border-purple-200">
<h2 class="text-3xl font-extrabold text-purple-900 mb-6 flex items-center">
<span class="mr-3">🧠</span> Ridge Regression Made Easy (Story Style)
</h2>
<p class="text-purple-800 leading-relaxed text-lg mb-6">
Imagine your house price is being predicted by a team of 5 friends (features):<br>
<strong>Quality, Living Area, Garage, Basement, and Year Built.</strong>
Each friend gives their opinion (a number), and we add them up to predict the price.
</p>
<div class="grid md:grid-cols-3 gap-6 text-center text-purple-800 text-base font-medium">
<div class="bg-purple-50 p-4 rounded-lg border border-purple-200 shadow hover:shadow-lg transition">
<div class="text-4xl mb-2">🔊</div>
<p><strong>Without Ridge</strong><br>Some friends shout too loudly! Their numbers dominate and cause mistakes.</p>
</div>
<div class="text-4xl text-purple-400 hidden md:block animate-pulse">➡️</div>
<div class="bg-purple-50 p-4 rounded-lg border border-purple-200 shadow hover:shadow-lg transition">
<div class="text-4xl mb-2">🔇</div>
<p><strong>With Ridge</strong><br>Everyone still speaks, but Ridge adds rules so no one can shout. Voices are balanced.</p>
</div>
<div class="text-4xl text-purple-400 hidden md:block animate-pulse">➡️</div>
<div class="bg-green-50 p-4 rounded-lg border border-green-200 shadow hover:shadow-lg transition">
<div class="text-4xl mb-2">📊</div>
<p><strong>Result</strong><br>The prediction is more stable, fair, and doesn’t overreact to any one person.</p>
</div>
</div>
<p class="mt-6 text-purple-700 leading-relaxed text-base">
✅ Ridge doesn’t remove anyone (like Lasso does).<br>
✅ It just turns down their microphone if they’re being too loud.<br>
✅ That’s how Ridge keeps all your data and prevents wild, unstable predictions.
</p>
<p class="mt-4 text-sm italic text-purple-500">
(This is especially helpful when features are similar or slightly redundant.)
</p>
</div>
<h3 class="text-2xl font-semibold text-gray-900 mt-8 mb-4 flex items-center">
<span class="mr-2 text-purple-600">📊</span> Suggested Visualizations (to see it in action!):
</h3>
<p class="text-gray-800 mb-6">
To really get a feel for how Ridge works, visual examples are best:
</p>
<ul class="list-disc list-inside text-gray-800 space-y-3 pl-4">
<li><strong>Coefficient Shrinkage Graph:</strong> See a graph where all feature "voices" (coefficients) start big and then get smaller as you increase $\lambda$ (the "Volume Knob"). Notice they don't hit zero!</li>
<li><strong>Prediction Quality Chart:</strong> Compare Ridge's predictions against actual values.</li>
<li><strong>Model Stability Over Time:</strong> How the model's performance holds up on different sets of data.</li>
</ul>
<p class="text-gray-800 mt-4 italic">
(These dynamic visualizations can be powered by Chart.js, D3.js, or by integrating server-side plots from libraries like Matplotlib/Seaborn in your Flask application.)
</p>
</div>
<style>
/* Custom animations for better user feedback */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fadeIn {
animation: fadeIn 0.5s ease-out forwards;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.animate-shake {
animation: shake 0.5s ease-in-out;
}
.loader {
border: 4px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top: 4px solid #8B5CF6; /* Tailwind purple-500 */
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
display: inline-block;
vertical-align: middle;
margin-right: 8px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Input field glow on focus/hover */
.input-glow:focus {
box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.4); /* Tailwind purple-500 with opacity */
}
/* Animated background pulse */
@keyframes pulse-light {
0% { opacity: 0.6; }
50% { opacity: 0.8; }
100% { opacity: 0.6; }
}
.animate-pulse-light {
animation: pulse-light 4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
/* Prediction highlight pulse (adjusted for purple theme) */
@keyframes pulse-purple {
0% { transform: scale(1.05); box-shadow: 0 25px 50px -12px rgba(139, 92, 246, 0.25); } /* purple-500 shadow */
50% { transform: scale(1.06); box-shadow: 0 25px 50px -12px rgba(139, 92, 246, 0.5); }
100% { transform: scale(1.05); box-shadow: 0 25px 50px -12px rgba(139, 92, 246, 0.25); } } .animate-pulse-purple { animation: pulse-purple 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } /* Text shadow for predicted price */ .text-shadow { text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); } /* Arrow animation */ @keyframes pulse-arrow { 0% { transform: translateX(0); opacity: 0.7; } 50% { transform: translateX(5px); opacity: 1; } 100% { transform: translateX(0); opacity: 0.7; } } .animate-pulse { animation: pulse-arrow 1.5s ease-in-out infinite; }
{% endblock %}