|
import gradio as gr |
|
import pandas as pd |
|
import numpy as np |
|
from momentfm import MOMENTPipeline |
|
import matplotlib.pyplot as plt |
|
from io import StringIO |
|
|
|
|
|
model = MOMENTPipeline.from_pretrained( |
|
"AutonLab/MOMENT-1-large", |
|
model_kwargs={"task_name": "reconstruction"}, |
|
) |
|
model.init() |
|
|
|
def detect_anomalies(data_input, threshold=0.1): |
|
try: |
|
|
|
if isinstance(data_input, str): |
|
df = pd.read_csv(StringIO(data_input)) |
|
else: |
|
return "Error: Please provide CSV data" |
|
|
|
|
|
if 'timestamp' not in df.columns or 'value' not in df.columns: |
|
return "Error: CSV must contain 'timestamp' and 'value' columns", None, None |
|
|
|
|
|
df['timestamp'] = pd.to_datetime(df['timestamp']) |
|
df = df.sort_values('timestamp') |
|
|
|
|
|
values = df['value'].values.astype(float) |
|
|
|
|
|
reconstruction = model.reconstruct(values) |
|
errors = np.abs(values - reconstruction) |
|
|
|
|
|
threshold_value = threshold * np.max(errors) |
|
df['anomaly_score'] = errors |
|
df['is_anomaly'] = errors > threshold_value |
|
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 4)) |
|
ax.plot(df['timestamp'], df['value'], label='Value', color='blue') |
|
ax.scatter( |
|
df.loc[df['is_anomaly'], 'timestamp'], |
|
df.loc[df['is_anomaly'], 'value'], |
|
color='red', label='Anomaly' |
|
) |
|
ax.set_title('Sensor Data with Anomalies') |
|
ax.legend() |
|
|
|
|
|
stats = { |
|
"total_points": len(df), |
|
"anomalies_detected": sum(df['is_anomaly']), |
|
"max_anomaly_score": float(np.max(errors)), |
|
"threshold_used": float(threshold_value) |
|
} |
|
|
|
return fig, stats, df.to_dict('records') |
|
|
|
except Exception as e: |
|
return f"Error: {str(e)}", None, None |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("## ๐ ๏ธ Equipment Anomaly Detection") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
data_input = gr.Textbox( |
|
label="Paste CSV data (timestamp,value)", |
|
value="""timestamp,value |
|
2025-04-01 00:00:00,100 |
|
2025-04-01 01:00:00,102 |
|
2025-04-01 02:00:00,98 |
|
2025-04-01 03:00:00,105 |
|
2025-04-01 04:00:00,103 |
|
2025-04-01 05:00:00,107 |
|
2025-04-01 06:00:00,200 |
|
2025-04-01 07:00:00,108 |
|
2025-04-01 08:00:00,110 |
|
2025-04-01 09:00:00,98 |
|
2025-04-01 10:00:00,99 |
|
2025-04-01 11:00:00,102 |
|
2025-04-01 12:00:00,101""", |
|
lines=10 |
|
) |
|
threshold = gr.Slider(0.01, 0.5, value=0.1, label="Anomaly Threshold") |
|
submit_btn = gr.Button("Detect Anomalies") |
|
|
|
with gr.Column(): |
|
plot_output = gr.Plot() |
|
stats_output = gr.JSON(label="Statistics") |
|
data_output = gr.JSON(label="Detailed Results") |
|
|
|
submit_btn.click( |
|
detect_anomalies, |
|
inputs=[data_input, threshold], |
|
outputs=[plot_output, stats_output, data_output] |
|
) |
|
|
|
demo.launch() |
|
|