import streamlit as st import pandas as pd import os from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression, LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor from sklearn.svm import SVC, SVR from sklearn.naive_bayes import GaussianNB from sklearn.metrics import accuracy_score, mean_squared_error, classification_report import numpy as np import io, zipfile, pickle x_cols = [] y_col = None st.title("ML Workbench") #-------------------------------------------- # Sidebar - About App st.sidebar.title("About App") st.sidebar.info( "**ML Workbench** is an enterprise-grade data analysis and machine learning platform designed to democratize AI. " "It empowers users to seamlessly upload datasets, perform robust preprocessing, train state-of-the-art models, " "and derive actionable insights through an intuitive, code-free interface." ) st.sidebar.markdown("---") st.sidebar.link_button("View on GitHub", "https://github.com/sowmiyan-s/ML-WorkBench") st.sidebar.markdown("Created by [Sowmiyan S](https://github.com/sowmiyan-s)") #-------------------------------------------- # Upload Dataset # Upload Dataset st.header("Step 1: Upload Your Data") st.markdown("Start by uploading your CSV file. This is the data we will use to train the model.") uploaded_file = st.file_uploader("Choose a CSV file", type=["csv"]) if uploaded_file: df = pd.read_csv(uploaded_file) st.write("Preview of dataset") st.write(df.head()) st.write("Shape:", df.shape) #-------------------------------------------- # Preprocessing # Preprocessing if uploaded_file: st.header("Step 2: Clean and Prepare Data") st.markdown("Data often needs cleaning before it can be used. Use the options below to fix common issues.") # Drop missing values if st.checkbox("Drop rows with missing values"): df.dropna(inplace=True) st.write("After dropping NA:", df.shape) # Identify numeric and categorical columns num_cols = df.select_dtypes(include=["number"]).columns.tolist() cat_cols = df.select_dtypes(include=["object", "category"]).columns.tolist() st.markdown("### Data Overview") col1, col2 = st.columns(2) with col1: st.markdown(f"**Numeric Columns** ({len(num_cols)})") st.caption("Columns containing numbers.") st.write(num_cols) with col2: st.markdown(f"**Categorical Columns** ({len(cat_cols)})") st.caption("Columns containing text or categories.") st.write(cat_cols) with st.expander("View Detailed Statistics"): col_info = pd.DataFrame({ 'Column': df.columns, 'Type': df.dtypes.astype(str), 'Missing Values': df.isnull().sum(), 'Unique Values': df.nunique() }) st.dataframe(col_info, use_container_width=True) # Normalize numeric columns normalize = st.multiselect("Scale Numbers (Optional)", num_cols, help="Adjusts numeric values to a common scale. Useful for some algorithms.") if normalize: from sklearn.preprocessing import StandardScaler df[normalize] = StandardScaler().fit_transform(df[normalize]) #-------------------------------------------- # Select Features and Target if uploaded_file: all_cols = df.columns.tolist() st.header("Step 3: Choose What to Predict") st.markdown("Select the columns you want the model to learn from (Inputs) and the column you want to predict (Target).") x_cols = st.multiselect("Select Input Columns (Features)", all_cols, help="Choose the columns the model should learn from.") y_col = st.selectbox("Select Target Column (Prediction)", all_cols, help="Choose the column you want to predict.") #-------------------------------------------- # Select Algorithm and Test Size if x_cols and y_col: st.header("Step 4: Choose a Learning Method") st.markdown("Select an algorithm to train your model. If you're unsure, try **Random Forest**.") algo = st.selectbox("Select Method", [ "Linear Regression", "Random Forest Regressor", "KNN Regressor", "SVR", "Logistic Regression", "Decision Tree", "Random Forest Classifier", "KNN Classifier", "SVM", "Naive Bayes" ]) st.caption("Note: Regressors are for predicting numbers (e.g., price), Classifiers are for predicting categories (e.g., yes/no).") test_size = st.slider("Test Data Size (Fraction)", 0.1, 0.5, 0.2, help="How much data should be kept aside for testing? 0.2 means 20%.") #-------------------------------------------- # Train Model if st.button("Start Training", type="primary"): X = df[x_cols].values y = df[y_col].values X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42) # Select model task = None if algo == "Linear Regression": model = LinearRegression(); task = "regression" elif algo == "Random Forest Regressor": model = RandomForestRegressor(); task = "regression" elif algo == "KNN Regressor": model = KNeighborsRegressor(); task = "regression" elif algo == "SVR": model = SVR(); task = "regression" elif algo == "Logistic Regression": model = LogisticRegression(max_iter=1000); task = "classification" elif algo == "Decision Tree": model = DecisionTreeClassifier(); task = "classification" elif algo == "Random Forest Classifier": model = RandomForestClassifier(); task = "classification" elif algo == "KNN Classifier": model = KNeighborsClassifier(); task = "classification" elif algo == "SVM": model = SVC(); task = "classification" elif algo == "Naive Bayes": model = GaussianNB(); task = "classification" model.fit(X_train, y_train) y_pred = model.predict(X_test) st.success("Model trained!") if task == "regression": st.write("MSE:", mean_squared_error(y_test, y_pred)) else: st.write("Accuracy:", accuracy_score(y_test, y_pred)) st.text(classification_report(y_test, y_pred)) # Save model in session st.session_state.model = model st.session_state.x_cols = x_cols st.session_state.y_col = y_col st.session_state.task = task #-------------------------------------------- # Test Model with Custom Input if "model" in st.session_state: st.subheader("Test Model with Custom Input") # Create input fields for all features user_input = [] st.write("Enter values for features:") for col in st.session_state.x_cols: val = st.text_input(f"{col}", "") if val != "": try: val = float(val) except: st.warning(f"Invalid input for {col}, using 0") val = 0 else: val = 0 user_input.append(val) user_input_array = np.array(user_input).reshape(1, -1) # Predict button if st.button("Predict"): try: prediction = st.session_state.model.predict(user_input_array) if st.session_state.task == "regression": st.success(f"Predicted value: {prediction[0]:.4f}") else: st.success(f"Predicted class: {prediction[0]}") except Exception as e: st.error(f"Prediction failed: {e}") # Optional: prediction history if "pred_history" not in st.session_state: st.session_state.pred_history = [] if st.button("Add to History"): try: prediction = st.session_state.model.predict(user_input_array) st.session_state.pred_history.append(prediction[0]) st.write("Prediction history:", st.session_state.pred_history) except: st.error("Cannot add to history, prediction failed.") #-------------------------------------------- # Export Model if "model" in st.session_state: st.header("Step 5: Download Model") st.markdown("Download your trained model to use it in other applications.") # Create in-memory buffer zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, "w") as zf: # Save model model_bytes = io.BytesIO() pickle.dump(st.session_state.model, model_bytes) zf.writestr("model.pkl", model_bytes.getvalue()) # Save metadata info = f"X columns: {st.session_state.x_cols}\nY column: {st.session_state.y_col}\nTask: {st.session_state.task}" zf.writestr("model_info.txt", info) zip_buffer.seek(0) st.download_button( label="Download Trained Model (ZIP)", data=zip_buffer, file_name="trained_model.zip", mime="application/zip" )