Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import gradio as gr | |
| from sklearn.preprocessing import StandardScaler | |
| from sklearn.svm import OneClassSVM | |
| # Function to detect theft and provide insights | |
| def detect_theft_from_file(uploaded_file): | |
| # Determine the file type and read it | |
| if uploaded_file.name.endswith('.csv'): | |
| df = pd.read_csv(uploaded_file.name) | |
| elif uploaded_file.name.endswith(('.xlsx', '.xls')): | |
| df = pd.read_excel(uploaded_file.name) | |
| else: | |
| return "Unsupported file format. Please upload a CSV or Excel file." | |
| # Ensure required format (Consumer ID + 12 months + optional Last Year) | |
| if len(df.columns) < 13: | |
| return "The file must have at least 13 columns: 'Consumer ID', 12 months (e.g., Jan-Dec), and optionally 'Last Year Avg'." | |
| feature_columns = df.columns[1:13] # 12 months | |
| data = df[feature_columns].values | |
| # Normalize the data | |
| scaler = StandardScaler() | |
| data_scaled = scaler.fit_transform(data) | |
| # One-Class SVM model | |
| model = OneClassSVM(nu=0.1, kernel='rbf', gamma='scale') | |
| model.fit(data_scaled) | |
| # Predict anomalies | |
| predictions = model.predict(data_scaled) | |
| # Add Reasons and Tips | |
| reasons = [] | |
| tips = [] | |
| for i, pred in enumerate(predictions): | |
| if pred == -1: # Theft detected | |
| current_pattern = data[i] | |
| if 'Last Year Avg' in df.columns: | |
| last_year_avg = df['Last Year Avg'].iloc[i] | |
| if current_pattern.mean() < 0.5 * last_year_avg: | |
| reasons.append("Unusual drop compared to last year's average.") | |
| elif current_pattern.mean() > 1.5 * last_year_avg: | |
| reasons.append("Unusual rise compared to last year's average.") | |
| else: | |
| reasons.append("Irregular monthly pattern detected.") | |
| else: | |
| reasons.append("Irregular monthly pattern detected.") | |
| tips.append( | |
| "1. Inspect the meter physically for tampering.\n" | |
| "2. Compare with neighborhood usage for similar consumption patterns.\n" | |
| "3. Check if there are bypass connections or rewiring." | |
| ) | |
| else: # No theft detected | |
| reasons.append("No irregularities detected.") | |
| tips.append("No action required.") | |
| # Results | |
| df['Anomaly'] = ['Theft' if pred == -1 else 'No Theft' for pred in predictions] | |
| df['Reason'] = reasons | |
| df['Tips'] = tips | |
| return df[['Consumer ID', 'Anomaly', 'Reason', 'Tips']] | |
| # Function for manual input detection | |
| def detect_theft_from_manual_input(consumer_id, *monthly_kwh): | |
| # Create a DataFrame from manual input | |
| df = pd.DataFrame( | |
| { | |
| 'Consumer ID': [consumer_id], | |
| **{f'Month {i+1}': [monthly_kwh[i]] for i in range(12)}, | |
| } | |
| ) | |
| # Normalize the data | |
| data = df.iloc[:, 1:].values # Select monthly data | |
| scaler = StandardScaler() | |
| data_scaled = scaler.fit_transform(data) | |
| # One-Class SVM model | |
| model = OneClassSVM(nu=0.1, kernel='rbf', gamma='scale') | |
| model.fit(data_scaled) | |
| # Predict anomaly | |
| prediction = model.predict(data_scaled) | |
| # Add Reason and Tips | |
| if prediction[0] == -1: # Theft detected | |
| reason = "Irregular monthly pattern detected." | |
| tips = ( | |
| "1. Inspect the meter physically for tampering.\n" | |
| "2. Compare with neighborhood usage for similar consumption patterns.\n" | |
| "3. Check if there are bypass connections or rewiring." | |
| ) | |
| else: | |
| reason = "No irregularities detected." | |
| tips = "No action required." | |
| df['Anomaly'] = ['Theft' if prediction[0] == -1 else 'No Theft'] | |
| df['Reason'] = [reason] | |
| df['Tips'] = [tips] | |
| return df[['Consumer ID', 'Anomaly', 'Reason', 'Tips']] | |
| # Gradio Interface | |
| file_interface = gr.Interface( | |
| fn=detect_theft_from_file, | |
| inputs=gr.File(label="Upload Meter Data File (CSV, XLSX, XLS)"), | |
| outputs=gr.Dataframe(label="Meter Theft Detection") | |
| ) | |
| manual_input_interface = gr.Interface( | |
| fn=detect_theft_from_manual_input, | |
| inputs=[ | |
| gr.Textbox(label="Consumer ID", placeholder="Enter Consumer ID"), | |
| *[gr.Number(label=f"Month {i+1} kWh") for i in range(12)], | |
| ], | |
| outputs=gr.Dataframe(label="Meter Theft Detection") | |
| ) | |
| # Combine interfaces | |
| iface = gr.TabbedInterface( | |
| interface_list=[file_interface, manual_input_interface], | |
| tab_names=["Upload File", "Manual Input"] | |
| ) | |
| # Launch the Gradio app | |
| iface.launch() | |