run_adaptive.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. """第三轮:自适应扩段 + 多特征确认。"""
  2. from __future__ import annotations
  3. import json
  4. import sys
  5. from pathlib import Path
  6. import pandas as pd
  7. ROOT = Path(__file__).resolve().parents[1]
  8. if str(ROOT) not in sys.path:
  9. sys.path.insert(0, str(ROOT))
  10. from _tmp_cylinder_vibration import adaptive, config, html_export, labels
  11. def main() -> None:
  12. features_path = config.OUTPUT_DIR / "vibration_features_refined.csv"
  13. points_path = config.OUTPUT_DIR / "vibration_labels_refined.csv"
  14. baseline_path = config.OUTPUT_DIR / "baseline.json"
  15. frame = labels.prepare_frame(pd.read_csv(features_path).to_dict("records"), 15)
  16. baseline = json.loads(baseline_path.read_text(encoding="utf-8"))
  17. frame, _, _ = labels.build_labels(frame, 15, baseline=baseline)
  18. frame = adaptive.add_ratios(frame, baseline)
  19. point_labels = pd.read_csv(points_path)
  20. point_labels["max_time"] = pd.to_datetime(point_labels["max_time"], errors="coerce")
  21. result = adaptive.build_intervals(frame, point_labels, baseline)
  22. result_path = config.OUTPUT_DIR / "vibration_intervals_adaptive.csv"
  23. result.to_csv(result_path, index=False, date_format="%Y-%m-%d %H:%M:%S")
  24. validation = adaptive.validate_events(result)
  25. validation_path = config.OUTPUT_DIR / "event_validation_adaptive.csv"
  26. validation.to_csv(validation_path, index=False, date_format="%Y-%m-%d %H:%M:%S")
  27. html_export.export_html(frame, result, validation)
  28. event_windows = []
  29. for event in config.EVENTS:
  30. center = pd.Timestamp(event["date"])
  31. event_windows.append((center - pd.Timedelta(days=7), center + pd.Timedelta(days=1)))
  32. if result.empty:
  33. false_all = false_conf = result
  34. else:
  35. related = result.apply(
  36. lambda row: any(row["start_time"] <= end and row["end_time"] >= start for start, end in event_windows),
  37. axis=1,
  38. )
  39. false_all = result[~related]
  40. false_conf = false_all[false_all["multi_feature_confirmed"]]
  41. summary = {
  42. "false_alarm_intervals": int(len(false_all)),
  43. "false_alarm_hours": round(float(false_all["duration_hours"].sum()), 2) if not false_all.empty else 0.0,
  44. "confirmed_false_alarm_intervals": int(len(false_conf)),
  45. "confirmed_false_alarm_hours": round(float(false_conf["duration_hours"].sum()), 2) if not false_conf.empty else 0.0,
  46. "intervals": len(result),
  47. "confirmed_intervals": int(result["multi_feature_confirmed"].sum()) if not result.empty else 0,
  48. "event_hits": int(validation["hit"].sum()) if not validation.empty else 0,
  49. "confirmed_event_hits": int(validation["confirmed"].sum()) if not validation.empty else 0,
  50. "validation": validation.to_dict("records"),
  51. }
  52. summary_path = config.OUTPUT_DIR / "adaptive_summary.json"
  53. summary_path.write_text(json.dumps(summary, ensure_ascii=False, indent=2, default=str), encoding="utf-8")
  54. print(result.to_string())
  55. print(json.dumps(summary, ensure_ascii=False, indent=2, default=str))
  56. if __name__ == "__main__":
  57. main()