File size: 4,684 Bytes
6f850cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import gradio as gr
import numpy as np
import pandas as pd
from momentfm import MOMENTPipeline
import matplotlib.pyplot as plt
from io import StringIO
# Initialize the MOMENT model
model = MOMENTPipeline.from_pretrained(
"AutonLab/MOMENT-1-large",
model_kwargs={"task_name": "reconstruction"},
)
model.init()
def detect_anomalies(data_input, threshold=0.05):
"""
Process time-series data and detect anomalies using MOMENT model
"""
try:
# Handle different input types
if isinstance(data_input, str):
# Try to read as CSV
try:
df = pd.read_csv(StringIO(data_input))
except:
# Try to read as JSON
try:
df = pd.read_json(StringIO(data_input))
except:
return "Error: Could not parse input data. Please provide valid CSV or JSON."
elif isinstance(data_input, dict):
df = pd.DataFrame(data_input)
else:
return "Error: Unsupported input format"
# Check for required columns
if 'timestamp' not in df.columns or 'value' not in df.columns:
return "Error: Data must contain 'timestamp' and 'value' columns"
# Convert timestamp to datetime if needed
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.sort_values('timestamp')
# Prepare data for MOMENT model
time_series = df['value'].values.astype(float)
# Get reconstruction from the model
reconstruction = model.reconstruct(time_series)
# Calculate reconstruction error
error = np.abs(time_series - reconstruction)
# Detect anomalies based on threshold
df['anomaly_score'] = error
df['is_anomaly'] = error > threshold * np.max(error)
# Create plot
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(df['timestamp'], df['value'], label='Original', color='blue')
ax.scatter(
df[df['is_anomaly']]['timestamp'],
df[df['is_anomaly']]['value'],
color='red',
label='Anomaly'
)
ax.set_title('Time Series with Anomalies Detected')
ax.set_xlabel('Timestamp')
ax.set_ylabel('Value')
ax.legend()
ax.grid(True)
# Prepare results
anomalies = df[df['is_anomaly']]
stats = {
"total_points": len(df),
"anomalies_detected": len(anomalies),
"anomaly_percentage": f"{100 * len(anomalies)/len(df):.2f}%",
"max_anomaly_score": np.max(error),
"threshold_used": threshold
}
return fig, stats, df.to_dict(orient='records')
except Exception as e:
return f"Error processing data: {str(e)}"
# Create Gradio interface
with gr.Blocks(title="Equipment Anomaly Detection") as demo:
gr.Markdown("# 🛠️ Equipment Sensor Anomaly Detection")
gr.Markdown("""
**Detect anomalies in equipment sensor data using the MOMENT-1-large model**
- Upload CSV/JSON data with 'timestamp' and 'value' columns
- Adjust the sensitivity threshold as needed
- Get visual and statistical results
""")
with gr.Row():
with gr.Column():
input_data = gr.Textbox(
label="Paste your time-series data (CSV/JSON)",
placeholder="timestamp,value\n2023-01-01,1.2\n2023-01-02,1.5...",
lines=5
)
file_upload = gr.File(label="Or upload a file")
threshold = gr.Slider(
minimum=0.01,
maximum=0.2,
value=0.05,
step=0.01,
label="Anomaly Detection Sensitivity (lower = more sensitive)"
)
submit_btn = gr.Button("Detect Anomalies", variant="primary")
with gr.Column():
plot_output = gr.Plot(label="Anomaly Detection Results")
stats_output = gr.JSON(label="Detection Statistics")
data_output = gr.JSON(label="Processed Data with Anomaly Scores")
# Handle file upload
def process_file(file):
if file:
with open(file.name, 'r') as f:
return f.read()
return ""
file_upload.change(process_file, inputs=file_upload, outputs=input_data)
submit_btn.click(
detect_anomalies,
inputs=[input_data, threshold],
outputs=[plot_output, stats_output, data_output]
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)
|