瀏覽代碼

1. 删除冗余代码

zhanghao 2 周之前
父節點
當前提交
e8801b9713

+ 0 - 627
models/anomaly_detection/README.md

@@ -1,627 +0,0 @@
-# 异常检测模块 (Anomaly Detection)
-
-> **版本**: 1.0.0  
-> **最后更新**: 2025-11-04  
-> **功能**: 对双膜系统(UF超滤 + RO反渗透)关键运行指标进行实时异常检测
-
----
-
-## 模块概述
-
-异常检测模块用于监测双膜水处理系统的关键运行指标,及时发现设备异常、性能退化等问题。
-
-### 主要特性
-
-- **多模型融合**: 支持孤立森林(Isolation Forest)、3σ统计、One-Class SVM三种检测方法
-- **逐列检测**: 对每个指标独立建模,精准定位异常来源
-- **无需标注**: 基于无监督学习,不需要人工标注异常样本
-- **实时检测**: 支持在线预测,快速识别异常点
-- **批量处理**: 自动读取和合并多批次历史数据
-
-### 应用场景
-
-1. **设备异常预警**: 膜组件堵塞、泵压异常、流量突变
-2. **性能监控**: 膜渗透率下降、产水量异常
-3. **维护决策**: 基于异常频率制定清洗/更换计划
-4. **质量控制**: 确保系统稳定运行
-
----
-
-## 目录结构
-
-```
-models/anomaly_detection/
-├── detection.py                    # 主程序(训练+预测)
-├── README.md                        # 本文档
-├── scaler.pkl                       # 数据归一化器(训练产物)
-├── isolation_forest_models.pkl      # 孤立森林模型(训练产物)
-├── three_sigma_model.pkl            # 3σ统计模型(训练产物)
-└── datasets_export_xishan/          # 数据目录(需自行准备)
-    ├── data_export5_1.csv           # UF渗透率数据
-    ├── data_export8_1.csv           # RO1/RO2压差数据
-    ├── data_export9_1.csv           # RO3/RO4压差数据
-    ├── data_export11_1.csv          # RO产水流量数据
-    └── ... (data_export*_2.csv ~ data_export*_26.csv)
-```
-
----
-
-## 核心功能
-
-### 1. 数据加载与合并
-
-- 批量读取 26 批次历史数据(`data_export*_1.csv ~ data_export*_26.csv`)
-- 自动提取关键指标列并纵向合并
-- 容错处理:文件缺失时跳过并记录日志
-
-### 2. 数据预处理
-
-- **MinMax归一化**: 将所有指标缩放至 [0, 1] 区间
-- **逐列处理**: 每个指标独立归一化,避免量纲影响
-- **保存scaler**: 归一化器保存为 `scaler.pkl`,用于在线预测
-
-### 3. 模型训练
-
-#### 孤立森林 (Isolation Forest)
-- 基于树结构随机分割,异常点更容易被孤立
-- 参数:`n_estimators=100`, `contamination='auto'`
-- 适用场景:单变量离群点检测
-
-#### 3σ统计法 (Three Sigma)
-- 基于正态分布假设,超出 μ±3σ 视为异常
-- 参数:`n_sigma=3`(可调)
-- 适用场景:稳态数据、可解释性要求高
-
-#### One-Class SVM (可选)
-- 基于核函数学习正常数据边界
-- 参数:`nu=0.05`, `kernel='rbf'`
-- 适用场景:复杂边界、非线性分布
-
-### 4. 异常预测
-
-- 输入归一化后的数据
-- 输出预测标签:`-1=异常`, `1=正常`
-- 支持批量预测和实时检测
-
----
-
-## 监测指标
-
-### UF(超滤)指标
-
-| 指标名称 | 含义 | 单位 | 正常范围 |
-|---------|------|------|---------|
-| UF1Per  | UF1膜渗透率 | - | 根据历史数据确定 |
-| UF2Per  | UF2膜渗透率 | - | 根据历史数据确定 |
-| UF3Per  | UF3膜渗透率 | - | 根据历史数据确定 |
-| UF4Per  | UF4膜渗透率 | - | 根据历史数据确定 |
-
-### RO(反渗透)指标
-
-| 指标名称 | 含义 | 单位 | 异常情况 |
-|---------|------|------|---------|
-| C.M.RO1_DB@DPT_1 | RO1一段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO1_DB@DPT_2 | RO1二段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO2_DB@DPT_1 | RO2一段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO2_DB@DPT_2 | RO2二段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO3_DB@DPT_1 | RO3一段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO3_DB@DPT_2 | RO3二段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO4_DB@DPT_1 | RO4一段压差 | kPa | 压差过高→膜污堵 |
-| C.M.RO4_DB@DPT_2 | RO4二段压差 | kPa | 压差过高→膜污堵 |
-| RO1_CSFlow | RO1产水流量 | m³/h | 流量异常→泵/阀问题 |
-| RO2_CSFlow | RO2产水流量 | m³/h | 流量异常→泵/阀问题 |
-| RO3_CSFlow | RO3产水流量 | m³/h | 流量异常→泵/阀问题 |
-| RO4_CSFlow | RO4产水流量 | m³/h | 流量异常→泵/阀问题 |
-
-**共16个监测指标**
-
----
-
-## 技术架构
-
-### 整体流程图
-
-```mermaid
-graph TB
-    subgraph 数据加载阶段
-        A[开始] --> B1[读取data_export5_*.csv]
-        A --> B2[读取data_export8_*.csv]
-        A --> B3[读取data_export9_*.csv]
-        A --> B4[读取data_export11_*.csv]
-        B1 --> C[提取UF1Per/UF2Per/UF3Per/UF4Per]
-        B2 --> D[提取RO1/RO2的DPT_1和DPT_2]
-        B3 --> E[提取RO3/RO4的DPT_1和DPT_2]
-        B4 --> F[提取RO1~RO4的CSFlow]
-        C --> G[纵向合并所有批次数据]
-        D --> G
-        E --> G
-        F --> G
-    end
-    
-    subgraph 数据预处理阶段
-        G --> H[DataFrame: 16个监测指标列]
-        H --> I[MinMaxScaler归一化到0-1区间]
-        I --> J[保存scaler.pkl]
-    end
-    
-    subgraph 模型训练阶段
-        J --> K{逐列训练}
-        K --> L1[孤立森林训练]
-        K --> L2[3σ统计计算]
-        K --> L3[One-Class SVM训练可选]
-        
-        L1 --> M1[遍历16个指标列]
-        M1 --> N1[每列fit一个IsolationForest模型]
-        N1 --> O1[保存isolation_forest_models.pkl]
-        
-        L2 --> M2[遍历16个指标列]
-        M2 --> N2[每列计算mean和std]
-        N2 --> O2[保存three_sigma_model.pkl]
-        
-        L3 --> M3[遍历16个指标列]
-        M3 --> N3[每列fit一个OneClassSVM模型]
-        N3 --> O3[保存one_class_svm_models.pkl]
-    end
-    
-    subgraph 异常检测阶段
-        O1 --> P[加载新数据]
-        O2 --> P
-        O3 --> P
-        P --> Q[使用scaler归一化新数据]
-        Q --> R{选择模型预测}
-        R --> S1[孤立森林预测]
-        R --> S2[3σ预测]
-        R --> S3[One-Class SVM预测]
-        S1 --> T[结果融合可选]
-        S2 --> T
-        S3 --> T
-        T --> U[输出预测结果: -1异常/1正常]
-        U --> V[结束]
-    end
-```
-
-### 详细训练与预测流程
-
-```mermaid
-sequenceDiagram
-    participant User as 用户
-    participant Script as detection.py
-    participant Data as 数据文件
-    participant Model as 模型
-    participant Result as 预测结果
-    
-    Note over User,Result: 训练阶段
-    User->>Script: 运行python detection.py
-    Script->>Data: 批量读取26批次CSV
-    Data-->>Script: 返回DataFrame(N行×16列)
-    Script->>Script: MinMaxScaler归一化
-    Script->>Script: 保存scaler.pkl
-    
-    loop 对每个指标列
-        Script->>Model: 训练IsolationForest
-        Script->>Model: 计算3σ统计量
-        Script->>Model: 训练OneClassSVM(可选)
-    end
-    
-    Script->>Script: 保存所有模型.pkl
-    Script-->>User: 训练完成
-    
-    Note over User,Result: 预测阶段
-    User->>Script: 提供新数据DataFrame
-    Script->>Script: 加载scaler.pkl和模型
-    Script->>Script: 归一化新数据
-    
-    loop 对每个指标列
-        Script->>Model: 调用predict()
-        Model-->>Script: 返回-1或1
-    end
-    
-    Script->>Result: 生成预测DataFrame
-    Result-->>User: 返回异常检测结果
-```
-
-### 关键技术
-
-- **sklearn.ensemble.IsolationForest**: 孤立森林实现
-- **sklearn.svm.OneClassSVM**: 单类SVM实现
-- **sklearn.preprocessing.MinMaxScaler**: 数据归一化
-- **pandas**: 数据处理
-- **joblib**: 模型序列化
-
----
-
-## 数据来源
-
-### 文件命名规则
-
-| 文件模板 | 包含指标 | 数量 |
-|---------|---------|------|
-| `data_export5_{i}.csv` | UF1Per, UF2Per, UF3Per, UF4Per | 4列 |
-| `data_export8_{i}.csv` | RO1/RO2的DPT_1和DPT_2 | 4列 |
-| `data_export9_{i}.csv` | RO3/RO4的DPT_1和DPT_2 | 4列 |
-| `data_export11_{i}.csv` | RO1~RO4的CSFlow | 4列 |
-
-其中 `{i}` 为批次号,范围 `1~26`
-
-### 数据格式要求
-
-```csv
-UF1Per,UF2Per,UF3Per,UF4Per
-0.85,0.87,0.83,0.86
-0.84,0.86,0.82,0.85
-...
-```
-
-- CSV格式,逗号分隔
-- 第一行为列名(必须与代码中定义的列名一致)
-- 数值型数据,缺失值用空或NaN表示
-
----
-
-## 使用指南
-
-### 1. 环境准备
-
-```bash
-# 安装依赖
-pip install numpy pandas scikit-learn joblib matplotlib
-
-# 确认目录结构
-cd models/anomaly_detection/
-ls datasets_export_xishan/  # 确认数据文件存在
-```
-
-### 2. 训练模型
-
-```bash
-# 运行主程序
-python detection.py
-```
-
-**输出示例**:
-```
-开始加载数据...
-成功读取: data_export5_1.csv
-成功读取: data_export8_1.csv
-...
-数据合并完成,总样本数: 125680
-
-开始数据归一化...
-归一化器已保存为 scaler.pkl
-
-开始训练孤立森林模型...
-已训练 UF1Per 的孤立森林模型
-已训练 UF2Per 的孤立森林模型
-...
-孤立森林模型已保存为 isolation_forest_models.pkl
-
-开始训练3σ模型...
-已计算 UF1Per 的3σ统计量
-...
-3σ模型已保存为 three_sigma_model.pkl
-
-所有模型训练和保存完成!
-```
-
-### 3. 使用模型预测(示例代码)
-
-```python
-import pandas as pd
-import joblib
-
-# 加载模型和归一化器
-scaler = joblib.load("scaler.pkl")
-if_model = joblib.load("isolation_forest_models.pkl")
-ts_model = joblib.load("three_sigma_model.pkl")
-
-# 准备新数据(需包含所有16个指标列)
-new_data = pd.DataFrame({
-    'UF1Per': [0.85, 0.82],
-    'UF2Per': [0.87, 0.84],
-    # ... 其他14个指标
-})
-
-# 归一化
-normalized_data = scaler.transform(new_data)
-normalized_df = pd.DataFrame(normalized_data, columns=new_data.columns)
-
-# 孤立森林预测
-if_predictions = if_model.predict(normalized_df)
-print("孤立森林预测:", if_predictions)
-
-# 3σ预测
-ts_predictions = ts_model.predict(normalized_df, n_sigma=3)
-print("3σ预测:", ts_predictions)
-
-# 结果融合(投票法)
-# -1=异常, 1=正常
-final_predictions = (if_predictions + ts_predictions) // 2
-```
-
----
-
-## 模型说明
-
-### 1. 孤立森林 (Isolation Forest)
-
-**原理**: 
-- 通过随机选择特征和分割点构建多棵树
-- 异常点更容易被孤立(需要更少的分割次数)
-- 路径长度越短,异常性越高
-
-**优点**:
-- 无需标注数据
-- 对高维数据有效
-- 计算效率高
-
-**缺点**:
-- 对正常数据密度不均匀的情况敏感
-- contamination参数需要先验知识
-
-**参数说明**:
-
-| 参数 | 值 | 说明 |
-|-----|-----|------|
-| n_estimators | 100 | 树的数量 |
-| contamination | 'auto' | 异常比例(自动估计) |
-| random_state | 42 | 随机种子 |
-
-### 2. 3σ统计法 (Three Sigma)
-
-**原理**:
-- 假设数据服从正态分布
-- 计算均值μ和标准差σ
-- 超出 [μ-3σ, μ+3σ] 范围视为异常(覆盖99.7%正常数据)
-
-**优点**:
-- 简单直观,易于理解和解释
-- 计算速度快
-- 可调整灵敏度(修改n_sigma)
-
-**缺点**:
-- 假设数据正态分布(偏态分布效果差)
-- 对极端异常值敏感
-
-**参数说明**:
-
-| 参数 | 值 | 说明 |
-|-----|-----|------|
-| n_sigma | 3 | 阈值系数(推荐2~4) |
-
-### 3. One-Class SVM (可选)
-
-**原理**:
-- 在高维空间寻找包含正常数据的最小超球面
-- 核函数将数据映射到高维空间
-- 边界外的点视为异常
-
-**优点**:
-- 适合复杂非线性边界
-- 理论基础扎实
-
-**缺点**:
-- 计算复杂度高(大数据集慢)
-- 参数调优困难(nu、gamma)
-- 对数据尺度敏感
-
-**参数说明**:
-
-| 参数 | 值 | 说明 |
-|-----|-----|------|
-| nu | 0.05 | 异常比例上界(5%) |
-| kernel | 'rbf' | 径向基核函数 |
-| gamma | 'scale' | 核系数(自动) |
-
-**启用方法**:
-1. 在 `detection.py` 中取消 `OneClassSVMModel` 类的注释(第166-203行)
-2. 取消 `main()` 函数中相关代码的注释(第227-250行)
-
----
-
-## 配置参数
-
-### 数据路径配置
-
-```python
-# detection.py 第14行
-data_folder = "datasets_export_xishan"
-```
-
-### 文件模板配置
-
-```python
-# detection.py 第22-29行
-file_info = {
-    "data_export5_{}.csv": ["UF1Per", "UF2Per", "UF3Per", "UF4Per"],
-    "data_export8_{}.csv": ["C.M.RO1_DB@DPT_1", "C.M.RO1_DB@DPT_2", 
-                           "C.M.RO2_DB@DPT_1", "C.M.RO2_DB@DPT_2"],
-    "data_export9_{}.csv": ["C.M.RO3_DB@DPT_1", "C.M.RO3_DB@DPT_2", 
-                           "C.M.RO4_DB@DPT_1", "C.M.RO4_DB@DPT_2"],
-    "data_export11_{}.csv": ["RO1_CSFlow", "RO2_CSFlow", "RO3_CSFlow", "RO4_CSFlow"]
-}
-```
-
-### 模型参数调整
-
-**孤立森林**:
-```python
-# detection.py 第98行
-model = IsolationForest(
-    n_estimators=100,        # 增大→更稳定,但训练慢
-    contamination='auto',    # 或设置具体值如0.05
-    random_state=42
-)
-```
-
-**3σ统计**:
-```python
-# 预测时调整
-ts_predictions = ts_model.predict(normalized_df, n_sigma=3)
-# n_sigma=2 → 更敏感(95%覆盖)
-# n_sigma=4 → 更宽松(99.99%覆盖)
-```
-
----
-
-## 输出结果
-
-### 1. 训练产物
-
-| 文件名 | 大小 | 说明 |
-|--------|------|------|
-| scaler.pkl | ~2KB | MinMax归一化器 |
-| isolation_forest_models.pkl | ~500KB | 孤立森林模型(16个) |
-| three_sigma_model.pkl | ~1KB | 3σ统计量(16个指标的μ和σ) |
-
-### 2. 预测结果格式
-
-**DataFrame示例**:
-
-| UF1Per | UF2Per | C.M.RO1_DB@DPT_1 | ... |
-|--------|--------|------------------|-----|
-| 1      | 1      | -1               | ... |
-| 1      | -1     | 1                | ... |
-| 1      | 1      | 1                | ... |
-
-- `1`: 正常
-- `-1`: 异常
-
-### 3. 结果分析
-
-#### 单指标异常统计
-```python
-# 统计每个指标的异常率
-anomaly_rate = (predictions == -1).sum() / len(predictions)
-print(f"异常率: {anomaly_rate * 100:.2f}%")
-```
-
-#### 多模型融合
-```python
-# 投票法:两个模型都判定为异常才认为异常
-consensus = ((if_pred == -1) & (ts_pred == -1)).astype(int)
-consensus = np.where(consensus, -1, 1)
-```
-
-#### 异常时段定位
-```python
-# 找出连续异常的时间段(需要时间戳列)
-anomaly_indices = np.where(predictions == -1)[0]
-print(f"异常点索引: {anomaly_indices}")
-```
-
----
-
-## 常见问题
-
-### Q1: 读取数据时报错"未找到文件"
-
-**原因**: `datasets_export_xishan/` 目录不存在或文件命名不符合规则
-
-**解决**:
-```bash
-# 检查目录
-ls datasets_export_xishan/
-
-# 确认文件命名格式
-# 正确: data_export5_1.csv, data_export8_2.csv
-# 错误: data_export5-1.csv, export5_1.csv
-```
-
-### Q2: One-Class SVM 报错 `NameError: name 'OneClassSVMModel' is not defined`
-
-**原因**: One-Class SVM 默认被注释
-
-**解决**:
-1. 打开 `detection.py`
-2. 取消第166-203行的注释(类定义)
-3. 取消第227-250行的注释(训练和预测代码)
-
-### Q3: 训练时内存不足
-
-**原因**: 数据量过大(26批次 × 数万样本)
-
-**解决**:
-```python
-# detection.py 第208行后添加下采样
-merged_data = load_and_merge_data()
-# 随机采样50%数据
-merged_data = merged_data.sample(frac=0.5, random_state=42)
-```
-
-### Q4: 预测结果全是异常或全是正常
-
-**原因**: 
-- 数据分布与训练数据差异大
-- contamination参数不合理
-
-**解决**:
-```python
-# 调整contamination参数
-model = IsolationForest(
-    n_estimators=100,
-    contamination=0.05,  # 假设5%为异常
-    random_state=42
-)
-```
-
-### Q5: 3σ方法对某些指标效果差
-
-**原因**: 数据不服从正态分布(偏态、双峰)
-
-**解决**:
-```python
-# 查看数据分布
-import matplotlib.pyplot as plt
-df['UF1Per'].hist(bins=50)
-plt.show()
-
-# 考虑数据变换(如log变换)或使用孤立森林
-```
-
-### Q6: 如何评估模型效果?
-
-**方法**:
-1. **人工标注部分样本**: 构建测试集计算准确率、召回率
-2. **业务反馈**: 结合实际异常事件验证
-3. **多模型对比**: 比较IF、3σ、OCSVM的一致性
-
-```python
-from sklearn.metrics import classification_report
-
-# 需要人工标注的真实标签
-y_true = [1, 1, -1, 1, -1, ...]
-y_pred = if_model.predict(test_data)
-
-print(classification_report(y_true, y_pred))
-```
-
-### Q7: 如何集成到在线系统?
-
-**方案**:
-```python
-# 1. 封装为函数
-def detect_anomaly(new_data):
-    """
-    参数: new_data - DataFrame,包含16个指标列
-    返回: predictions - DataFrame,-1=异常, 1=正常
-    """
-    scaler = joblib.load("scaler.pkl")
-    if_model = joblib.load("isolation_forest_models.pkl")
-    
-    normalized = scaler.transform(new_data)
-    normalized_df = pd.DataFrame(normalized, columns=new_data.columns)
-    
-    return if_model.predict(normalized_df)
-
-# 2. 构建API(FastAPI示例)
-from fastapi import FastAPI
-app = FastAPI()
-
-@app.post("/detect")
-def detect(data: dict):
-    df = pd.DataFrame([data])
-    result = detect_anomaly(df)
-    return {"prediction": result.tolist()}
-```
-
-

+ 0 - 255
models/anomaly_detection/detection.py

@@ -1,255 +0,0 @@
-import os
-import pandas as pd
-import numpy as np
-import joblib
-from sklearn.preprocessing import MinMaxScaler
-from sklearn.ensemble import IsolationForest
-from sklearn.svm import OneClassSVM  
-
-# 设置中文字体显示(用于本地可视化时中文不乱码)
-import matplotlib.pyplot as plt
-plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
-
-# 数据文件夹路径(批量 CSV 存放目录)
-data_folder = "datasets_export_xishan"
-
-# 定义要读取的文件模板与对应列名(逐批次 data_exportX_{i}.csv, i=1..26)
-# 关键字段含义(业务约定):
-# - UF1Per:UF1膜渗透率(UF1Per)
-# - C.M.RO1_DB@DPT_1:RO1一段压差
-# - C.M.RO1_DB@DPT_2:RO1二段压差
-# - RO1_CSFlow:RO1产水流量
-file_info = {
-    "data_export5_{}.csv": ["UF1Per", "UF2Per", "UF3Per", "UF4Per"],
-    "data_export8_{}.csv": ["C.M.RO1_DB@DPT_1", "C.M.RO1_DB@DPT_2", 
-                           "C.M.RO2_DB@DPT_1", "C.M.RO2_DB@DPT_2"],
-    "data_export9_{}.csv": ["C.M.RO3_DB@DPT_1", "C.M.RO3_DB@DPT_2", 
-                           "C.M.RO4_DB@DPT_1", "C.M.RO4_DB@DPT_2"],
-    "data_export11_{}.csv": ["RO1_CSFlow", "RO2_CSFlow", "RO3_CSFlow", "RO4_CSFlow"]
-}
-
-def load_and_merge_data():
-    """加载并合并所有数据文件
-
-    - 按 file_info 中的模板逐列读取各批 CSV(i=1..26),仅选取关心的指标列
-    - 将成功读取的数据 DataFrame 纵向拼接(ignore_index=True)
-    - 返回合并后的 DataFrame;若无任何成功数据则报错
-    """
-    all_data = []
-    
-    # 循环读取每个文件模板和对应的编号1-26
-    for file_template, columns in file_info.items():
-        for i in range(1, 27):
-            # 构建完整的文件路径
-            filename = file_template.format(i)
-            file_path = os.path.join(data_folder, filename)
-            
-            try:
-                # 读取CSV文件的指定列(仅保留关心指标,减小内存开销)
-                df = pd.read_csv(file_path, usecols=columns)
-                all_data.append(df)
-                print(f"成功读取: {filename}")
-            except Exception as e:
-                print(f"读取文件 {filename} 时出错: {e}")
-    
-    # 合并所有数据(纵向堆叠)
-    if not all_data:
-        raise ValueError("没有成功读取任何数据文件")
-    
-    merged_df = pd.concat(all_data, ignore_index=True)
-    print(f"数据合并完成,总样本数: {len(merged_df)}")
-    return merged_df
-
-def normalize_data(df):
-    """对数据进行归一化处理(逐列 Min-Max 到 [0,1])
-
-    - 拟合并转换每一列;保存 scaler 至 `scaler.pkl`
-    - 返回归一化后的 DataFrame 以及 scaler(便于线上/后续反归一化)
-    """
-    scaler = MinMaxScaler()
-    scaled_data = scaler.fit_transform(df)
-    scaled_df = pd.DataFrame(scaled_data, columns=df.columns)
-    
-    # 保存归一化器
-    joblib.dump(scaler, "scaler.pkl")
-    print("归一化器已保存为 scaler.pkl")
-    
-    return scaled_df, scaler
-
-class IsolationForestModel:
-    """孤立森林异常检测模型(逐列一维检测)
-
-    - 特点:无需标注,适合检测孤立点;contamination='auto' 自动估计比例
-    - 输出:predict → -1 表示异常,1 表示正常
-    """
-    def __init__(self):
-        self.models = {}  # 存储每列的模型
-    
-    def fit(self, df):
-        """逐列训练孤立森林模型
-
-        参数:
-        - df: 归一化后的 DataFrame(每列为一个监测指标)
-        """
-        for column in df.columns:
-            # 准备数据(sklearn 需要二维输入)
-            X = df[column].values.reshape(-1, 1)
-            # 训练模型
-            model = IsolationForest(n_estimators=100, contamination='auto', random_state=42)
-            model.fit(X)
-            self.models[column] = model
-            print(f"已训练 {column} 的孤立森林模型")
-        return self
-    
-    def predict(self, df):
-        """预测异常值,-1 表示异常,1 表示正常(逐列)"""
-        results = pd.DataFrame()
-        for column in df.columns:
-            if column not in self.models:
-                raise ValueError(f"没有 {column} 的模型,请先训练")
-            
-            X = df[column].values.reshape(-1, 1)
-            results[column] = self.models[column].predict(X)
-        return results
-    
-    def save(self, filename="isolation_forest_models.pkl"):
-        """保存模型"""
-        joblib.dump(self, filename)
-        print(f"孤立森林模型已保存为 {filename}")
-
-class ThreeSigmaModel:
-    """3σ 异常检测模型(逐列基于均值±nσ 的阈值法)
-
-    - 特点:简单、可解释;可调 n_sigma(默认 3)
-    - 输出:-1 表示异常,1 表示正常
-    """
-    def __init__(self):
-        self.stats = {}  # 存储每列的均值和标准差
-    
-    def fit(self, df):
-        """计算每列的均值和标准差,并缓存统计量"""
-        for column in df.columns:
-            mean = df[column].mean()
-            std = df[column].std()
-            self.stats[column] = (mean, std)
-            print(f"已计算 {column} 的3σ统计量")
-        return self
-    
-    def predict(self, df, n_sigma=3):
-        """预测异常值(-1=异常,1=正常)
-
-        参数:
-        - df: 归一化后的 DataFrame
-        - n_sigma: 阈值宽度因子,默认 3,即 mean ± 3*std
-        """
-        results = pd.DataFrame()
-        for column in df.columns:
-            if column not in self.stats:
-                raise ValueError(f"没有 {column} 的统计量,请先训练")
-            
-            mean, std = self.stats[column]
-            # 计算上下限
-            lower_bound = mean - n_sigma * std
-            upper_bound = mean + n_sigma * std
-            
-            # 判断异常值
-            is_outlier = (df[column] < lower_bound) | (df[column] > upper_bound)
-            # 转换为-1(异常)和1(正常)
-            results[column] = np.where(is_outlier, -1, 1)
-        return results
-    
-    def save(self, filename="three_sigma_model.pkl"):
-        """保存模型"""
-        joblib.dump(self, filename)
-        print(f"3σ模型已保存为 {filename}")
-
-'''
-class OneClassSVMModel:
-    """One-Class SVM 异常检测模型(可选)
-
-    - 对复杂边界更有表达力,但对参数与尺度敏感
-    - 启用前请确保样本量与特征尺度合适
-    """
-    def __init__(self):
-        self.models = {}  # 存储每列的模型
-    
-    def fit(self, df):
-        """逐列训练 One-Class SVM 模型"""
-        for column in df.columns:
-            # 准备数据(需要二维数组)
-            X = df[column].values.reshape(-1, 1)
-            # 训练模型
-            model = OneClassSVM(nu=0.05, kernel='rbf', gamma='scale')
-            model.fit(X)
-            self.models[column] = model
-            print(f"已训练 {column} 的One-Class SVM模型")
-        return self
-    
-    def predict(self, df):
-        """预测异常值,-1 表示异常,1 表示正常"""
-        results = pd.DataFrame()
-        for column in df.columns:
-            if column not in self.models:
-                raise ValueError(f"没有 {column} 的模型,请先训练")
-            
-            X = df[column].values.reshape(-1, 1)
-            results[column] = self.models[column].predict(X)
-        return results
-    
-    def save(self, filename="one_class_svm_models.pkl"):
-        """保存模型"""
-        joblib.dump(self, filename)
-        print(f"One-Class SVM模型已保存为 {filename}")
-'''
-
-def main():
-    # 1. 加载并合并数据(仅读取关心指标列)
-    print("开始加载数据...")
-    merged_data = load_and_merge_data()
-    
-    # 2. 数据归一化(逐列 Min-Max 到 [0,1] 并保存 scaler)
-    print("\n开始数据归一化...")
-    normalized_data, scaler = normalize_data(merged_data)
-    
-    # 3. 训练并保存孤立森林模型(逐列训练)
-    print("\n开始训练孤立森林模型...")
-    if_model = IsolationForestModel()
-    if_model.fit(normalized_data)
-    if_model.save()
-    
-    # 4. 训练并保存3σ模型(逐列计算统计量)
-    print("\n开始训练3σ模型...")
-    ts_model = ThreeSigmaModel()
-    ts_model.fit(normalized_data)
-    ts_model.save()
-    
-    # 5. 训练并保存 One-Class SVM 模型(可选,默认已注释)
-    # 如需启用,请取消下方注释和类定义(第166-203行)的注释
-    # print("\n开始训练One-Class SVM模型...")
-    # ocsvm_model = OneClassSVMModel()
-    # ocsvm_model.fit(normalized_data)
-    # ocsvm_model.save()
-    
-    print("\n所有模型训练和保存完成!")
-    
-    # 使用模型进行预测(示例:随机抽样 100 条)
-    sample_data = normalized_data.sample(min(100, len(normalized_data)))  # 随机取100个样本或全部样本(如果不足100个)
-    
-    # 孤立森林预测
-    if_predictions = if_model.predict(sample_data)
-    print("\n孤立森林预测结果(-1表示异常,1表示正常):")
-    print(if_predictions)
-    
-    # 3σ预测
-    ts_predictions = ts_model.predict(sample_data)
-    print("\n3σ预测结果(-1表示异常,1表示正常):")
-    print(ts_predictions)
-    
-    # One-Class SVM预测(可选,默认已注释)
-    # 如需启用,请取消下方注释
-    # ocsvm_predictions = ocsvm_model.predict(sample_data)
-    # print("\nOne-Class SVM预测结果(-1表示异常,1表示正常):")
-    # print(ocsvm_predictions)
-
-if __name__ == "__main__":
-    main()

二進制
models/anomaly_detection/isolation_forest_models.pkl


二進制
models/anomaly_detection/scaler.pkl


二進制
models/anomaly_detection/three_sigma_model.pkl