Ionosphere / app.py
nafees369's picture
Upload app.py
518c2b0 verified
# -*- 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