Spaces:
Build error
Build error
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.preprocessing import LabelEncoder, StandardScaler, OneHotEncoder | |
| from sklearn.compose import ColumnTransformer | |
| from tensorflow.keras.models import Sequential | |
| from tensorflow.keras.layers import Input, Dense | |
| import matplotlib.pyplot as plt | |
| # Load dataset | |
| def load_data(): | |
| return pd.read_csv("f2.csv") | |
| df = load_data() | |
| st.title("Fertilizer Prediction with ANN - Interactive Demo") | |
| # Define target and features | |
| target = 'Fertilizer' | |
| cat_features = ['Soil_Type', 'Crop_Type'] | |
| num_features = ['Temparature', 'Humidity', 'Moisture', 'Nitrogen', 'Potassium', 'Phosphorous'] | |
| X = df.drop(columns=[target]) | |
| y = df[target] | |
| # Preprocessing pipeline | |
| preprocessor = ColumnTransformer( | |
| transformers=[ | |
| ('num', StandardScaler(), num_features), | |
| ('cat', OneHotEncoder(handle_unknown='ignore'), cat_features) | |
| ] | |
| ) | |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=27) | |
| X_train = preprocessor.fit_transform(X_train) | |
| X_test = preprocessor.transform(X_test) | |
| le = LabelEncoder() | |
| y_train = le.fit_transform(y_train) | |
| y_test = le.transform(y_test) | |
| # Sidebar params | |
| st.sidebar.header("Model Parameters") | |
| epochs = st.sidebar.slider("Epochs", 5, 100, 30) | |
| batch_size = st.sidebar.selectbox("Batch Size", [8, 16, 32, 64], index=1) | |
| # Build ANN model | |
| model = Sequential() | |
| model.add(Input(shape=(X_train.shape[1],))) | |
| model.add(Dense(16, activation='relu')) | |
| model.add(Dense(32, activation='relu')) | |
| model.add(Dense(len(np.unique(y_train)), activation='softmax')) | |
| model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy']) | |
| if st.button("Train Model"): | |
| history = model.fit(X_train, y_train, validation_split=0.2, epochs=epochs, batch_size=batch_size, verbose=0) | |
| st.success("Model training complete.") | |
| st.subheader("Model Summary") | |
| # Capture model summary into a list | |
| model_summary = [] | |
| model.summary(print_fn=lambda x: model_summary.append(x)) | |
| st.write("Model Summary") | |
| st.code("\n".join(model_summary)) | |
| # Extract table rows from the summary | |
| table_data = [] | |
| start_parsing = False | |
| for line in model_summary: | |
| if 'Layer' in line and 'Output' in line and 'Param' in line: | |
| start_parsing = True | |
| continue | |
| if start_parsing and all(char == '=' for char in line.strip()): | |
| continue | |
| if start_parsing and ('Total params' in line or 'Trainable params' in line or 'Non-trainable params' in line): | |
| break | |
| if start_parsing: | |
| # Try splitting by '|' first | |
| parts = [p.strip() for p in line.split('|')] | |
| parts = [p for p in parts if p] | |
| if len(parts) == 3: | |
| table_data.append(parts) | |
| continue # Move to the next line if successful | |
| # If '|' split fails, try splitting by multiple spaces | |
| parts = [p.strip() for p in line.split(' ') if p.strip()] | |
| if len(parts) >= 3: | |
| table_data.append(parts[:3]) | |
| # Display as a table if data is available | |
| if table_data: | |
| # Ensure the correct number of columns | |
| if table_data and len(table_data[0]) == 3: | |
| model_df = pd.DataFrame(table_data, columns=["Layer (type)", "Output Shape", "Param #"]) | |
| st.table(model_df) | |
| else: | |
| st.warning("Could not create table: Inconsistent number of columns found.") | |
| st.write("Extracted Data (for debugging):") | |
| st.write(table_data) | |
| else: | |
| st.warning("") | |
| # Plot training metrics | |
| st.subheader("Training and Validation Metrics") | |
| fig, ax = plt.subplots(2, 1, figsize=(8, 6)) | |
| ax[0].plot(history.history['loss'], label='Loss') | |
| ax[0].plot(history.history['val_loss'], label='Val Loss') | |
| ax[0].legend() | |
| ax[0].set_title("Loss vs Validation Loss") | |
| ax[1].plot(history.history['accuracy'], label='Accuracy') | |
| ax[1].plot(history.history['val_accuracy'], label='Val Accuracy') | |
| ax[1].legend() | |
| ax[1].set_title("Accuracy vs Validation Accuracy") | |
| st.pyplot(fig) | |
| # Show min val loss and best val accuracy | |
| st.write(f"**Minimum Validation Loss:** {min(history.history['val_loss']):.4f}") | |
| st.write(f"**Best Validation Accuracy:** {max(history.history['val_accuracy']):.4f}") | |
| # Save model and label encoder in session state for predictions | |
| st.session_state['model'] = model | |
| st.session_state['preprocessor'] = preprocessor | |
| st.session_state['label_encoder'] = le | |
| # Only show prediction UI if model is trained and saved | |
| if 'model' in st.session_state: | |
| st.subheader("🌾 Predict Fertilizer Type Based on Input Features") | |
| input_soil = st.selectbox("Select Soil Type", df["Soil_Type"].unique()) | |
| input_crop = st.selectbox("Select Crop Type", df["Crop_Type"].unique()) | |
| input_temp = st.slider("Temperature (°C)", float(df["Temparature"].min()), float(df["Temparature"].max()), float(df["Temparature"].mean())) | |
| input_humidity = st.slider("Humidity (%)", float(df["Humidity"].min()), float(df["Humidity"].max()), float(df["Humidity"].mean())) | |
| input_moisture = st.slider("Moisture (%)", float(df["Moisture"].min()), float(df["Moisture"].max()), float(df["Moisture"].mean())) | |
| input_nitrogen = st.slider("Nitrogen Level", float(df["Nitrogen"].min()), float(df["Nitrogen"].max()), float(df["Nitrogen"].mean())) | |
| input_potassium = st.slider("Potassium Level", float(df["Potassium"].min()), float(df["Potassium"].max()), float(df["Potassium"].mean())) | |
| input_phosphorous = st.slider("Phosphorous Level", float(df["Phosphorous"].min()), float(df["Phosphorous"].max()), float(df["Phosphorous"].mean())) | |
| # Prepare input data | |
| input_dict = { | |
| "Soil_Type": input_soil, | |
| "Crop_Type": input_crop, | |
| "Temparature": input_temp, | |
| "Humidity": input_humidity, | |
| "Moisture": input_moisture, | |
| "Nitrogen": input_nitrogen, | |
| "Potassium": input_potassium, | |
| "Phosphorous": input_phosphorous, | |
| } | |
| input_df = pd.DataFrame([input_dict]) | |
| X_input = st.session_state['preprocessor'].transform(input_df) | |
| # Predict | |
| probs = st.session_state['model'].predict(X_input)[0] | |
| pred_class_idx = np.argmax(probs) | |
| pred_label = st.session_state['label_encoder'].inverse_transform([pred_class_idx])[0] | |
| st.success(f"🌟 Predicted Fertilizer: **{pred_label}**") | |
| # Plot confidence | |
| fig, ax = plt.subplots() | |
| fertilizer_classes = st.session_state['label_encoder'].classes_ | |
| ax.bar(fertilizer_classes, probs) | |
| ax.set_ylabel("Prediction Probability") | |
| ax.set_title("Fertilizer Prediction Confidence") | |
| plt.xticks(rotation=45) | |
| st.pyplot(fig) | |