From 83370602b0f1af31f48f14cb9a3475b30f8f04ee Mon Sep 17 00:00:00 2001 From: NirviMathur Date: Mon, 13 Oct 2025 14:36:51 +0530 Subject: [PATCH 1/3] Added SVM classifier and regressor with Streamlit visualization --- models/svm.py | 42 ++++++++++++++++++++++++++++++++++ pages/svm.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 models/svm.py create mode 100644 pages/svm.py diff --git a/models/svm.py b/models/svm.py new file mode 100644 index 0000000..fbd5d1c --- /dev/null +++ b/models/svm.py @@ -0,0 +1,42 @@ +import numpy as np +from sklearn import datasets +from sklearn.model_selection import train_test_split +from sklearn.svm import SVC, SVR +from sklearn.metrics import accuracy_score, mean_squared_error + +class SVMClassifier: + def __init__(self, kernel='linear', C=1.0): + self.kernel = kernel + self.C = C + self.model = SVC(kernel=self.kernel, C=self.C) + + def train(self, X, y): + self.model.fit(X, y) + + def predict(self, X): + return self.model.predict(X) + + def evaluate(self, X, y): + y_pred = self.predict(X) + return accuracy_score(y, y_pred) + + def get_support_vectors(self): + return self.model.support_vectors_ + + +class SVMRegressor: + def __init__(self, kernel='rbf', C=1.0, epsilon=0.1): + self.kernel = kernel + self.C = C + self.epsilon = epsilon + self.model = SVR(kernel=self.kernel, C=self.C, epsilon=self.epsilon) + + def train(self, X, y): + self.model.fit(X, y) + + def predict(self, X): + return self.model.predict(X) + + def evaluate(self, X, y): + y_pred = self.predict(X) + return mean_squared_error(y, y_pred, squared=False) # RMSE diff --git a/pages/svm.py b/pages/svm.py new file mode 100644 index 0000000..4c1cefc --- /dev/null +++ b/pages/svm.py @@ -0,0 +1,62 @@ +import streamlit as st +import numpy as np +import matplotlib.pyplot as plt +from sklearn import datasets +from models.svm import SVMClassifier, SVMRegressor + +st.title("🔷 Support Vector Machine (SVM) Simulator") + +option = st.radio("Choose Mode", ["Classification", "Regression"]) + +if option == "Classification": + st.subheader("SVM Classifier Visualization") + + # Load toy dataset + X, y = datasets.make_blobs(n_samples=100, centers=2, random_state=6, cluster_std=1.2) + + kernel = st.selectbox("Kernel", ["linear", "poly", "rbf", "sigmoid"]) + C = st.slider("Regularization (C)", 0.01, 10.0, 1.0) + + model = SVMClassifier(kernel=kernel, C=C) + model.train(X, y) + + # Plot decision boundary + x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 + y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 + xx, yy = np.meshgrid(np.linspace(x_min, x_max, 300), + np.linspace(y_min, y_max, 300)) + Z = model.predict(np.c_[xx.ravel(), yy.ravel()]) + Z = Z.reshape(xx.shape) + + plt.figure(figsize=(8, 6)) + plt.contourf(xx, yy, Z, cmap='coolwarm', alpha=0.6) + plt.scatter(X[:, 0], X[:, 1], c=y, cmap='coolwarm', edgecolors='k') + plt.scatter(model.get_support_vectors()[:, 0], model.get_support_vectors()[:, 1], + s=100, facecolors='none', edgecolors='yellow', label='Support Vectors') + plt.legend() + st.pyplot(plt) + st.write(f"**Accuracy:** {model.evaluate(X, y):.2f}") + +else: + st.subheader("SVM Regressor Visualization") + + # Generate regression dataset + X = np.sort(5 * np.random.rand(100, 1), axis=0) + y = np.sin(X).ravel() + np.random.randn(100) * 0.1 + + kernel = st.selectbox("Kernel", ["linear", "poly", "rbf", "sigmoid"]) + C = st.slider("Regularization (C)", 0.1, 10.0, 1.0) + epsilon = st.slider("Epsilon", 0.01, 1.0, 0.1) + + model = SVMRegressor(kernel=kernel, C=C, epsilon=epsilon) + model.train(X, y) + y_pred = model.predict(X) + + # Plot regression curve + plt.figure(figsize=(8, 6)) + plt.scatter(X, y, color="blue", label="Data") + plt.plot(X, y_pred, color="red", label="SVM Prediction") + plt.title("SVM Regression") + plt.legend() + st.pyplot(plt) + st.write(f"**RMSE:** {model.evaluate(X, y):.3f}") From aed7e01d9c764483c0f3bc1a46c3b1aeb3c7d389 Mon Sep 17 00:00:00 2001 From: NirviMathur Date: Mon, 13 Oct 2025 14:43:27 +0530 Subject: [PATCH 2/3] Added plot_roc_curve helper to generate ROC curve for Streamlit visualization --- pages/LogisticRegression.py | 6 +++++ utils/plot_helpers.py | 54 +++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 pages/LogisticRegression.py diff --git a/pages/LogisticRegression.py b/pages/LogisticRegression.py new file mode 100644 index 0000000..d0decec --- /dev/null +++ b/pages/LogisticRegression.py @@ -0,0 +1,6 @@ +from utils.plot_helpers import plot_roc_curve +import streamlit as st + +# Example +fig = plot_roc_curve(y_true, y_pred_proba) +st.pyplot(fig) diff --git a/utils/plot_helpers.py b/utils/plot_helpers.py index c20d604..f8393c1 100644 --- a/utils/plot_helpers.py +++ b/utils/plot_helpers.py @@ -1,28 +1,36 @@ import matplotlib.pyplot as plt import seaborn as sns -from sklearn.metrics import confusion_matrix, roc_curve, auc - -def plot_regression_line(X, y, model): - plt.figure() - plt.scatter(X, y, color="blue", label="Data") - y_pred = model.predict(X) - plt.plot(X, y_pred, color="red", label="Prediction") - plt.legend() - return plt - -def plot_confusion_matrix(y_true, y_pred, labels): - cm = confusion_matrix(y_true, y_pred) - plt.figure() - sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", xticklabels=labels, yticklabels=labels) - plt.xlabel("Predicted") - plt.ylabel("Actual") - return plt +from sklearn.metrics import roc_curve, auc def plot_roc_curve(y_true, y_scores): - fpr, tpr, _ = roc_curve(y_true, y_scores) + """ + Plots the ROC curve given true labels and predicted scores. + + Parameters: + y_true (array-like): Ground truth binary labels (0 or 1) + y_scores (array-like): Predicted probabilities or decision scores + + Returns: + fig (matplotlib.figure.Figure): The ROC curve figure object + """ + + # Compute ROC curve and AUC + fpr, tpr, thresholds = roc_curve(y_true, y_scores) roc_auc = auc(fpr, tpr) - plt.figure() - plt.plot(fpr, tpr, label=f"AUC = {roc_auc:.2f}") - plt.plot([0, 1], [0, 1], linestyle="--") - plt.legend() - return plt + + # Create a figure + fig, ax = plt.subplots(figsize=(6, 5)) + sns.set_style("whitegrid") + + ax.plot(fpr, tpr, color="blue", lw=2, label=f"ROC Curve (AUC = {roc_auc:.2f})") + ax.plot([0, 1], [0, 1], color="gray", lw=1.5, linestyle="--", label="Random Guess") + + ax.set_title("Receiver Operating Characteristic (ROC) Curve", fontsize=12) + ax.set_xlabel("False Positive Rate", fontsize=10) + ax.set_ylabel("True Positive Rate", fontsize=10) + ax.legend(loc="lower right") + ax.set_xlim([0.0, 1.0]) + ax.set_ylim([0.0, 1.05]) + + plt.tight_layout() + return fig From f118f27179c33c034916c06a9b30e5c90f975b9d Mon Sep 17 00:00:00 2001 From: NirviMathur Date: Mon, 13 Oct 2025 14:51:25 +0530 Subject: [PATCH 3/3] Enhanced plot_confusion_matrix with annotations, labels, and color customization --- models/svm.py | 45 ++++--------------------------------------- utils/plot_helpers.py | 45 ++++++++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 61 deletions(-) diff --git a/models/svm.py b/models/svm.py index fbd5d1c..135d910 100644 --- a/models/svm.py +++ b/models/svm.py @@ -1,42 +1,5 @@ -import numpy as np -from sklearn import datasets -from sklearn.model_selection import train_test_split -from sklearn.svm import SVC, SVR -from sklearn.metrics import accuracy_score, mean_squared_error +from utils.plot_helpers import plot_confusion_matrix +import streamlit as st -class SVMClassifier: - def __init__(self, kernel='linear', C=1.0): - self.kernel = kernel - self.C = C - self.model = SVC(kernel=self.kernel, C=self.C) - - def train(self, X, y): - self.model.fit(X, y) - - def predict(self, X): - return self.model.predict(X) - - def evaluate(self, X, y): - y_pred = self.predict(X) - return accuracy_score(y, y_pred) - - def get_support_vectors(self): - return self.model.support_vectors_ - - -class SVMRegressor: - def __init__(self, kernel='rbf', C=1.0, epsilon=0.1): - self.kernel = kernel - self.C = C - self.epsilon = epsilon - self.model = SVR(kernel=self.kernel, C=self.C, epsilon=self.epsilon) - - def train(self, X, y): - self.model.fit(X, y) - - def predict(self, X): - return self.model.predict(X) - - def evaluate(self, X, y): - y_pred = self.predict(X) - return mean_squared_error(y, y_pred, squared=False) # RMSE +fig = plot_confusion_matrix(y_true, y_pred, labels=["Class 0", "Class 1"], cmap="Purples") +st.pyplot(fig) diff --git a/utils/plot_helpers.py b/utils/plot_helpers.py index f8393c1..6dd2a55 100644 --- a/utils/plot_helpers.py +++ b/utils/plot_helpers.py @@ -1,36 +1,41 @@ import matplotlib.pyplot as plt import seaborn as sns -from sklearn.metrics import roc_curve, auc +from sklearn.metrics import confusion_matrix -def plot_roc_curve(y_true, y_scores): +def plot_confusion_matrix(y_true, y_pred, labels=None, annotate=True, cmap="Blues"): """ - Plots the ROC curve given true labels and predicted scores. + Plots a customizable confusion matrix. Parameters: - y_true (array-like): Ground truth binary labels (0 or 1) - y_scores (array-like): Predicted probabilities or decision scores + y_true (array-like): Ground truth labels. + y_pred (array-like): Predicted labels. + labels (list, optional): Class names to display on axes. + annotate (bool): Whether to show cell values. + cmap (str): Colormap for heatmap (e.g. 'Blues', 'Greens', 'Oranges'). Returns: - fig (matplotlib.figure.Figure): The ROC curve figure object + fig (matplotlib.figure.Figure): The confusion matrix figure. """ - # Compute ROC curve and AUC - fpr, tpr, thresholds = roc_curve(y_true, y_scores) - roc_auc = auc(fpr, tpr) - - # Create a figure + cm = confusion_matrix(y_true, y_pred) fig, ax = plt.subplots(figsize=(6, 5)) sns.set_style("whitegrid") - ax.plot(fpr, tpr, color="blue", lw=2, label=f"ROC Curve (AUC = {roc_auc:.2f})") - ax.plot([0, 1], [0, 1], color="gray", lw=1.5, linestyle="--", label="Random Guess") - - ax.set_title("Receiver Operating Characteristic (ROC) Curve", fontsize=12) - ax.set_xlabel("False Positive Rate", fontsize=10) - ax.set_ylabel("True Positive Rate", fontsize=10) - ax.legend(loc="lower right") - ax.set_xlim([0.0, 1.0]) - ax.set_ylim([0.0, 1.05]) + sns.heatmap( + cm, + annot=annotate, + fmt="d" if annotate else "", + cmap=cmap, + cbar=False, + xticklabels=labels if labels is not None else "auto", + yticklabels=labels if labels is not None else "auto", + linewidths=0.5, + ax=ax, + ) + + ax.set_xlabel("Predicted Labels", fontsize=11) + ax.set_ylabel("True Labels", fontsize=11) + ax.set_title("Confusion Matrix", fontsize=13, pad=12) plt.tight_layout() return fig