Spaces:
Sleeping
Sleeping
| # -*- 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 | |