# -*- coding: utf-8 -*- """app.ipynb Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/1oMJ02G_2BU5UAUhlQvk2s3Uvbu2YgDSG """ import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, LabelEncoder from sklearn.neural_network import MLPClassifier from sklearn.metrics import accuracy_score, confusion_matrix import gradio as gr # ========================================== # (A) Data Loading & Preprocessing # ========================================== # 1. Load the dataset # Using the URL directly from the quiz url = "https://archive.ics.uci.edu/ml/machine-learning-databases/ionosphere/ionosphere.data" # The dataset has 34 numerical features and 1 class label at the end. # It does not have a header row, so we use header=None. df = pd.read_csv(url, header=None) # Separate Features (X) and Target (y) X = df.iloc[:, :-1] # All columns except the last one y = df.iloc[:, -1] # The last column (labels: 'g' or 'b') # Encode the labels: 'g' (Good) -> 1, 'b' (Bad) -> 0 le = LabelEncoder() y_encoded = le.fit_transform(y) # 2. Split the dataset (80% train, 20% test, random_state=42) X_train, X_test, y_train, y_test = train_test_split( X, y_encoded, test_size=0.20, random_state=42 ) # 3. Standardize the features scaler = StandardScaler() # Fit on training set only to prevent data leakage, then transform both X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) print("Data loaded and preprocessed successfully.") print(f"Training shape: {X_train_scaled.shape}") print(f"Testing shape: {X_test_scaled.shape}") print("-" * 30) # ========================================== # (B) Build an ANN in scikit-learn # ========================================== # 4. Build the ANN (MLPClassifier) [cite: 15, 16, 17, 19] # Architecture: Hidden layers (32, 16), Activation 'relu', Solver 'adam' ann_model = MLPClassifier( hidden_layer_sizes=(32, 16), activation='relu', solver='adam', max_iter=500, # Setting > 300 as requested random_state=42 ) # 5. Train the model [cite: 20] ann_model.fit(X_train_scaled, y_train) # 6. Evaluate the model [cite: 21, 22, 23] y_pred = ann_model.predict(X_test_scaled) accuracy = accuracy_score(y_test, y_pred) conf_matrix = confusion_matrix(y_test, y_pred) print(f"Model Accuracy on Test Set: {accuracy:.4f}") print("Confusion Matrix:") print(conf_matrix) print("-" * 30) # ========================================== # (C) Build a GUI with Gradio # ========================================== def predict_radar_signal(input_str): """ Function to process input from Gradio and return prediction. Expects a comma-separated string of 34 numbers. """ try: # Convert string input to numpy array # This handles the user pasting a row of data input_list = [float(x.strip()) for x in input_str.split(',')] if len(input_list) != 34: return f"Error: Expected 34 values, but got {len(input_list)}." # Reshape for a single sample (1, 34) input_data = np.array(input_list).reshape(1, -1) # IMPORTANT: Scale the input using the SAME scaler trained above input_scaled = scaler.transform(input_data) # Predict class and probability prediction_idx = ann_model.predict(input_scaled)[0] prediction_prob = ann_model.predict_proba(input_scaled)[0] # Decode prediction back to 'Good' or 'Bad' # Since we know 'g' is usually 1 and 'b' is 0, but let's use the encoder classes # le.classes_ usually ['b', 'g']. So 0 -> 'b', 1 -> 'g' predicted_label_code = le.inverse_transform([prediction_idx])[0] label_text = "Good" if predicted_label_code == 'g' else "Bad" # Get probability of the predicted class # prob array is [prob_class_0, prob_class_1] confidence = prediction_prob[prediction_idx] # Format output as requested [cite: 28, 29] return f"Prediction: {label_text}\nProbability of {label_text}: {confidence:.4f}" except Exception as e: return f"Error processing input: {str(e)}" # Define the Gradio Interface [cite: 25, 30] # We use a Textbox for input to handle the large number of features (34) easily. iface = gr.Interface( fn=predict_radar_signal, inputs=gr.Textbox( label="Input Features", placeholder="Paste 34 comma-separated values here (e.g., 1,0,0.9,...)", lines=3 ), outputs=gr.Textbox(label="Result"), title="Ionosphere Radar Signal Predictor", description="Enter the 34 features of the radar signal to predict if it is Good or Bad." ) # Launch the app print("Launching Gradio Interface...") iface.launch(share=True) # Set share=True to create a public link