zainulabedin949's picture
Update app.py
2e96626 verified
raw
history blame
4.44 kB
import pandas as pd
import numpy as np
from momentfm import MOMENTPipeline
from io import StringIO
# Initialize model globally
model = MOMENTPipeline.from_pretrained(
"AutonLab/MOMENT-1-large",
model_kwargs={"task_name": "reconstruction"},
)
model.init()
def generate_analysis_report(data_input, sensitivity=3.0):
"""Generate a comprehensive textual analysis report"""
try:
# Process and validate data
df = pd.read_csv(StringIO(data_input))
# Validate columns
if 'timestamp' not in df.columns or 'value' not in df.columns:
return "Error: CSV must contain 'timestamp' and 'value' columns"
# Convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], errors='coerce')
df['value'] = pd.to_numeric(df['value'], errors='coerce')
# Check for invalid data
if df.isnull().any().any():
return "Error: Invalid data format (check timestamp/value formats)"
df = df.sort_values('timestamp')
# Prepare data for model
values = df['value'].values.astype(np.float32).reshape(1, -1, 1)
# Get reconstruction
reconstructed = model.reconstruct(values)
errors = np.abs(df['value'].values - reconstructed[0,:,0])
# Calculate threshold (modified z-score)
median = np.median(errors)
mad = np.median(np.abs(errors - median))
threshold = median + sensitivity * (1.4826 * mad)
# Identify anomalies
anomalies = df[errors > threshold].copy()
anomalies['anomaly_score'] = errors[errors > threshold]
anomalies = anomalies.sort_values('anomaly_score', ascending=False)
normal_points = df[errors <= threshold]
# Generate report
report = f"""
EQUIPMENT ANALYSIS REPORT
========================
Generated at: {pd.Timestamp.now()}
Detection sensitivity: {sensitivity} (z-score)
DATA OVERVIEW
-------------
Time period: {df['timestamp'].min()} to {df['timestamp'].max()}
Total observations: {len(df)}
Value range: {df['value'].min():.2f} to {df['value'].max():.2f}
Median value: {df['value'].median():.2f}
Mean value: {df['value'].mean():.2f}
ANOMALY DETECTION RESULTS
-------------------------
Detection threshold: {threshold:.2f}
Anomalies detected: {len(anomalies)} ({len(anomalies)/len(df):.1%} of data)
Strongest anomaly: {errors.max():.2f} at {df.loc[errors.argmax(), 'timestamp']}
TOP ANOMALIES
-------------
{anomalies[['timestamp', 'value', 'anomaly_score']].head(15).to_string(index=False, float_format='%.2f')}
NORMAL OPERATION SUMMARY
------------------------
Typical value range: {normal_points['value'].min():.2f} to {normal_points['value'].max():.2f}
Stable period duration: {pd.Timedelta(normal_points['timestamp'].max() - normal_points['timestamp'].min())}
RECOMMENDATIONS
---------------
1. Investigate top {min(3, len(anomalies))} anomalous readings
2. Check equipment around {anomalies['timestamp'].iloc[0]} for potential issues
3. Consider recalibration if anomalies cluster in specific time periods
4. Review maintenance logs around detected anomalies
"""
return report.strip()
except Exception as e:
return f"ANALYSIS ERROR: {str(e)}"
# Gradio Interface for the report-only version
import gradio as gr
with gr.Blocks() as demo:
gr.Markdown("## πŸ“„ Equipment Analysis Report Generator")
with gr.Row():
with gr.Column():
data_input = gr.Textbox(label="Paste CSV Data", lines=10, 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""")
sensitivity = gr.Slider(1.0, 5.0, value=3.0, label="Detection Sensitivity")
submit_btn = gr.Button("Generate Report", variant="primary")
with gr.Column():
report_output = gr.Textbox(label="Analysis Report", lines=20, interactive=False)
submit_btn.click(
generate_analysis_report,
inputs=[data_input, sensitivity],
outputs=report_output
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)