zainulabedin949 commited on
Commit
9458d26
·
verified ·
1 Parent(s): 6646cc2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -42
app.py CHANGED
@@ -1,77 +1,112 @@
1
  import gradio as gr
2
  import pandas as pd
3
  import numpy as np
4
- from momentfm import MOMENTPipeline
5
  import matplotlib.pyplot as plt
6
  from io import StringIO
 
 
7
 
8
- # Initialize model
9
- model = MOMENTPipeline.from_pretrained(
10
- "AutonLab/MOMENT-1-large",
11
- model_kwargs={"task_name": "reconstruction"},
12
- )
13
- model.init()
14
 
15
- def detect_anomalies(data_input, threshold=0.1):
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  try:
17
  # Read data
18
  if isinstance(data_input, str):
19
  df = pd.read_csv(StringIO(data_input))
20
  else:
21
- return "Error: Please provide CSV data"
22
-
23
- # Validate columns
24
- if 'timestamp' not in df.columns or 'value' not in df.columns:
25
- return "Error: CSV must contain 'timestamp' and 'value' columns", None, None
26
-
27
- # Convert timestamp and sort
28
- df['timestamp'] = pd.to_datetime(df['timestamp'])
29
- df = df.sort_values('timestamp')
30
 
31
- # Get values as numpy array
32
- values = df['value'].values.astype(float)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- # Detect anomalies
35
  reconstruction = model.reconstruct(values)
36
  errors = np.abs(values - reconstruction)
37
 
38
- # Apply threshold (using relative error)
39
- threshold_value = threshold * np.max(errors)
40
  df['anomaly_score'] = errors
41
  df['is_anomaly'] = errors > threshold_value
42
 
43
  # Create plot
44
- fig, ax = plt.subplots(figsize=(10, 4))
45
- ax.plot(df['timestamp'], df['value'], label='Value', color='blue')
46
  ax.scatter(
47
  df.loc[df['is_anomaly'], 'timestamp'],
48
  df.loc[df['is_anomaly'], 'value'],
49
- color='red', label='Anomaly'
50
  )
51
- ax.set_title('Sensor Data with Anomalies')
52
  ax.legend()
 
53
 
54
- # Prepare results
55
  stats = {
56
- "total_points": len(df),
57
- "anomalies_detected": sum(df['is_anomaly']),
58
- "max_anomaly_score": float(np.max(errors)),
59
- "threshold_used": float(threshold_value)
60
  }
61
 
62
  return fig, stats, df.to_dict('records')
63
 
64
  except Exception as e:
65
- return f"Error: {str(e)}", None, None
 
66
 
67
- # Gradio interface
68
- with gr.Blocks() as demo:
69
- gr.Markdown("## 🛠️ Equipment Anomaly Detection")
70
 
71
  with gr.Row():
72
  with gr.Column():
73
  data_input = gr.Textbox(
74
- label="Paste CSV data (timestamp,value)",
75
  value="""timestamp,value
76
  2025-04-01 00:00:00,100
77
  2025-04-01 01:00:00,102
@@ -86,15 +121,15 @@ with gr.Blocks() as demo:
86
  2025-04-01 10:00:00,99
87
  2025-04-01 11:00:00,102
88
  2025-04-01 12:00:00,101""",
89
- lines=10
90
  )
91
- threshold = gr.Slider(0.01, 0.5, value=0.1, label="Anomaly Threshold")
92
- submit_btn = gr.Button("Detect Anomalies")
93
 
94
  with gr.Column():
95
- plot_output = gr.Plot()
96
  stats_output = gr.JSON(label="Statistics")
97
- data_output = gr.JSON(label="Detailed Results")
98
 
99
  submit_btn.click(
100
  detect_anomalies,
@@ -102,4 +137,5 @@ with gr.Blocks() as demo:
102
  outputs=[plot_output, stats_output, data_output]
103
  )
104
 
105
- demo.launch()
 
 
1
  import gradio as gr
2
  import pandas as pd
3
  import numpy as np
 
4
  import matplotlib.pyplot as plt
5
  from io import StringIO
6
+ import logging
7
+ from momentfm import MOMENTPipeline
8
 
9
+ # Set up logging
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
 
 
 
12
 
13
+ # Initialize model (with error handling)
14
+ try:
15
+ model = MOMENTPipeline.from_pretrained(
16
+ "AutonLab/MOMENT-1-large",
17
+ model_kwargs={"task_name": "reconstruction"},
18
+ )
19
+ model.init()
20
+ logger.info("Model loaded successfully")
21
+ except Exception as e:
22
+ logger.error(f"Model loading failed: {str(e)}")
23
+ raise
24
+
25
+ def validate_and_process_data(data_input):
26
+ """Handle all data validation and processing"""
27
  try:
28
  # Read data
29
  if isinstance(data_input, str):
30
  df = pd.read_csv(StringIO(data_input))
31
  else:
32
+ raise ValueError("Input must be CSV text")
33
+
34
+ # Check required columns
35
+ required = ['timestamp', 'value']
36
+ if not all(col in df.columns for col in required):
37
+ missing = [col for col in required if col not in df.columns]
38
+ raise ValueError(f"Missing columns: {missing}")
 
 
39
 
40
+ # Convert and validate timestamp
41
+ df['timestamp'] = pd.to_datetime(df['timestamp'], errors='coerce')
42
+ if df['timestamp'].isnull().any():
43
+ raise ValueError("Invalid timestamp format")
44
+
45
+ # Validate values
46
+ try:
47
+ df['value'] = pd.to_numeric(df['value'])
48
+ except:
49
+ raise ValueError("Non-numeric values found")
50
+
51
+ # Sort by timestamp
52
+ df = df.sort_values('timestamp').reset_index(drop=True)
53
+
54
+ return df
55
+
56
+ except Exception as e:
57
+ logger.error(f"Data processing error: {str(e)}")
58
+ raise
59
+
60
+ def detect_anomalies(data_input, threshold=0.1):
61
+ """Main anomaly detection function"""
62
+ try:
63
+ # Process input data
64
+ df = validate_and_process_data(data_input)
65
+ values = df['value'].values.astype(np.float32)
66
 
67
+ # Get reconstruction
68
  reconstruction = model.reconstruct(values)
69
  errors = np.abs(values - reconstruction)
70
 
71
+ # Dynamic threshold ( from mean)
72
+ threshold_value = np.mean(errors) + 3 * np.std(errors)
73
  df['anomaly_score'] = errors
74
  df['is_anomaly'] = errors > threshold_value
75
 
76
  # Create plot
77
+ fig, ax = plt.subplots(figsize=(12, 5))
78
+ ax.plot(df['timestamp'], df['value'], 'b-', label='Value')
79
  ax.scatter(
80
  df.loc[df['is_anomaly'], 'timestamp'],
81
  df.loc[df['is_anomaly'], 'value'],
82
+ color='red', s=100, label='Anomaly'
83
  )
84
+ ax.set_title(f'Anomaly Detection (Threshold: {threshold_value:.2f})')
85
  ax.legend()
86
+ plt.close(fig) # Prevents duplicate plots
87
 
88
+ # Prepare outputs
89
  stats = {
90
+ "data_points": len(df),
91
+ "anomalies": int(df['is_anomaly'].sum()),
92
+ "threshold_used": float(threshold_value),
93
+ "max_score": float(np.max(errors))
94
  }
95
 
96
  return fig, stats, df.to_dict('records')
97
 
98
  except Exception as e:
99
+ logger.error(f"Detection error: {str(e)}")
100
+ return None, {"error": str(e)}, None
101
 
102
+ # Gradio Interface
103
+ with gr.Blocks(title="Anomaly Detector") as demo:
104
+ gr.Markdown("# 🚨 Time-Series Anomaly Detection")
105
 
106
  with gr.Row():
107
  with gr.Column():
108
  data_input = gr.Textbox(
109
+ label="Paste CSV Data",
110
  value="""timestamp,value
111
  2025-04-01 00:00:00,100
112
  2025-04-01 01:00:00,102
 
121
  2025-04-01 10:00:00,99
122
  2025-04-01 11:00:00,102
123
  2025-04-01 12:00:00,101""",
124
+ lines=15
125
  )
126
+ threshold = gr.Slider(0.01, 1.0, value=0.3, label="Sensitivity (higher = stricter)")
127
+ submit_btn = gr.Button("Analyze", variant="primary")
128
 
129
  with gr.Column():
130
+ plot_output = gr.Plot(label="Results")
131
  stats_output = gr.JSON(label="Statistics")
132
+ data_output = gr.JSON(label="Detailed Data")
133
 
134
  submit_btn.click(
135
  detect_anomalies,
 
137
  outputs=[plot_output, stats_output, data_output]
138
  )
139
 
140
+ if __name__ == "__main__":
141
+ demo.launch(server_name="0.0.0.0", server_port=7860)