Spaces:
Sleeping
Sleeping
| 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" | |
| ) | |