From 83370602b0f1af31f48f14cb9a3475b30f8f04ee Mon Sep 17 00:00:00 2001 From: NirviMathur Date: Mon, 13 Oct 2025 14:36:51 +0530 Subject: [PATCH 1/4] 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/4] 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/4] 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 From b04990f3e6b33ce6538b70a7c866e814b5090a3e Mon Sep 17 00:00:00 2001 From: NirviMathur Date: Mon, 13 Oct 2025 15:00:09 +0530 Subject: [PATCH 4/4] Added KNN classifier/regressor with Streamlit visualization and adjustable k --- models/knn.py | 33 ++++++++++++++++++++++++++ pages/KNN.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 models/knn.py create mode 100644 pages/KNN.py diff --git a/models/knn.py b/models/knn.py new file mode 100644 index 0000000..de6171d --- /dev/null +++ b/models/knn.py @@ -0,0 +1,33 @@ +from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor +from sklearn.metrics import accuracy_score, mean_squared_error + +class KNNClassifier: + def __init__(self, n_neighbors=3): + self.n_neighbors = n_neighbors + self.model = KNeighborsClassifier(n_neighbors=self.n_neighbors) + + 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) + + +class KNNRegressor: + def __init__(self, n_neighbors=3): + self.n_neighbors = n_neighbors + self.model = KNeighborsRegressor(n_neighbors=self.n_neighbors) + + 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/KNN.py b/pages/KNN.py new file mode 100644 index 0000000..163d2de --- /dev/null +++ b/pages/KNN.py @@ -0,0 +1,66 @@ +import streamlit as st +import numpy as np +import matplotlib.pyplot as plt +from sklearn import datasets +from models.knn import KNNClassifier, KNNRegressor +from utils.plot_helpers import plot_confusion_matrix + +st.title("🧩 K-Nearest Neighbors (KNN) Simulator") + +mode = st.radio("Choose Mode", ["Classification", "Regression"]) + +if mode == "Classification": + st.subheader("KNN Classifier Visualization") + + # Load dataset + X, y = datasets.make_classification( + n_samples=150, n_features=2, n_informative=2, n_redundant=0, + n_clusters_per_class=1, random_state=42 + ) + + k = st.slider("Number of Neighbors (k)", 1, 15, 3) + model = KNNClassifier(n_neighbors=k) + model.train(X, y) + y_pred = model.predict(X) + + # 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.5) + plt.scatter(X[:, 0], X[:, 1], c=y, cmap="coolwarm", edgecolors="k") + plt.title(f"KNN Classifier (k={k})") + st.pyplot(plt) + + st.write(f"**Accuracy:** {model.evaluate(X, y):.2f}") + + # Confusion matrix + fig = plot_confusion_matrix(y, y_pred, labels=["Class 0", "Class 1"], cmap="Purples") + st.pyplot(fig) + +else: + st.subheader("KNN Regressor Visualization") + + # Generate regression dataset + X = np.linspace(0, 10, 100).reshape(-1, 1) + y = np.sin(X).ravel() + np.random.randn(100) * 0.1 + + k = st.slider("Number of Neighbors (k)", 1, 15, 3) + model = KNNRegressor(n_neighbors=k) + model.train(X, y) + y_pred = model.predict(X) + + # Plot regression + plt.figure(figsize=(8, 6)) + plt.scatter(X, y, color="blue", label="Data") + plt.plot(X, y_pred, color="red", label=f"KNN Prediction (k={k})") + plt.title("KNN Regression") + plt.legend() + st.pyplot(plt) + + st.write(f"**RMSE:** {model.evaluate(X, y):.3f}")