File size: 3,264 Bytes
6f850cd
 
6646cc2
6f850cd
 
 
 
6646cc2
6f850cd
 
 
 
 
 
6646cc2
6f850cd
6646cc2
6f850cd
6646cc2
6f850cd
6646cc2
 
 
6f850cd
6646cc2
 
 
6f850cd
 
 
6646cc2
 
6f850cd
6646cc2
 
 
6f850cd
6646cc2
 
 
 
6f850cd
 
6646cc2
 
6f850cd
6646cc2
 
 
6f850cd
6646cc2
6f850cd
 
 
 
 
6646cc2
 
 
6f850cd
 
6646cc2
 
6f850cd
6646cc2
6f850cd
6646cc2
 
 
6f850cd
 
 
6646cc2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f850cd
6646cc2
 
 
6f850cd
6646cc2
 
 
6f850cd
 
 
6646cc2
6f850cd
 
 
6646cc2
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
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

# Initialize model
model = MOMENTPipeline.from_pretrained(
    "AutonLab/MOMENT-1-large",
    model_kwargs={"task_name": "reconstruction"},
)
model.init()

def detect_anomalies(data_input, threshold=0.1):
    try:
        # Read data
        if isinstance(data_input, str):
            df = pd.read_csv(StringIO(data_input))
        else:
            return "Error: Please provide CSV data"
            
        # Validate columns
        if 'timestamp' not in df.columns or 'value' not in df.columns:
            return "Error: CSV must contain 'timestamp' and 'value' columns", None, None
            
        # Convert timestamp and sort
        df['timestamp'] = pd.to_datetime(df['timestamp'])
        df = df.sort_values('timestamp')
        
        # Get values as numpy array
        values = df['value'].values.astype(float)
        
        # Detect anomalies
        reconstruction = model.reconstruct(values)
        errors = np.abs(values - reconstruction)
        
        # Apply threshold (using relative error)
        threshold_value = threshold * np.max(errors)
        df['anomaly_score'] = errors
        df['is_anomaly'] = errors > threshold_value
        
        # Create plot
        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()
        
        # Prepare results
        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

# Gradio interface
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()