3. 水质数据采集与传感器基础

趋势预测的质量上限,在数据进入模型之前就已经被决定了。传感器选得不对、采样频率与水质变化的时间尺度不匹配、或者数据里混入了漂移和跳变,后续再精细的模型也只能在噪声上做拟合。本节围绕“采什么、多久采一次、数据会怎么坏、方案怎么设计”四个问题展开,为后续的清洗、特征工程与预测建模打好基础。

一、常见传感器类型与适用场景

水产养殖水质监测的核心参数通常包括溶解氧、水温、pH、氨氮、亚硝酸盐、浊度、电导率等。不同参数的测量原理差异很大,直接决定了它们的响应速度、维护周期和数据特性。

  • 溶解氧(DO):主流为荧光法(LDO)和极谱/原电池法。荧光法无需电解液、抗流速影响、维护周期长,适合长期在线监测;膜法成本低但对流速和污损敏感,需要定期更换膜和电解液。DO 是养殖中最关键的参数,通常要求 1~5 分钟一次的采样密度。
  • 水温:多用铂电阻(PT100/PT1000)或热敏电阻,稳定性好、响应快,可作为其他参数的温度补偿基准,采样频率可以较高(如 1 分钟)。
  • pH:玻璃电极法为主,存在零点漂移和参比电极老化问题,需要定期两点校准(如 pH 4.00 与 7.00 缓冲液)。
  • 氨氮、亚硝酸盐:在线监测多采用离子选择性电极或比色法,成本高、试剂消耗大,实际养殖场常以较低频率(如每小时或每天数次)采集,或采用实验室抽检补充。
  • 浊度、电导率:光学散射法与电极法,易受生物附着影响,需配合自动清洗或人工擦拭。

选型时应优先考虑“长期稳定性 + 抗污损能力”,而不是单纯追求精度指标。一个精度 0.1 mg/L 但两周就漂移的 DO 探头,实际价值低于精度 0.3 mg/L 但能稳定运行两个月的荧光探头。

二、数据采集频率的确定

采样频率不是越高越好,而应与被测量的变化时间尺度匹配。溶解氧在夏季高温、高密度养殖、夜间藻类呼吸作用下可能在几十分钟内快速下降,因此 DO 建议 1~5 分钟一次;水温变化缓慢,1~5 分钟足够;pH 受光合作用影响呈明显昼夜节律,5~10 分钟可捕捉到变化趋势;氨氮、亚硝酸盐日变化小,每小时一次甚至更低频率即可。

同时要考虑存储与传输成本。若 8 个参数均按 1 分钟采样,单点每天产生 11520 条记录,多池塘部署时数据量迅速上升。工程上常用“分层采样”策略:高频采集原始值,本地按 5 分钟或 15 分钟聚合(均值、最值、标准差)后上传,既保留趋势信息又降低传输压力。聚合时务必保留最小值与最大值,因为 DO 的夜间最低点往往比均值更有预警意义。

三、典型数据质量问题

真实养殖现场的数据几乎不可能“干净”,常见问题可归为以下几类:

  • 缺失:设备断电、网络中断、探头维护导致整段无数据。表现为时间戳不连续或值为空。
  • 异常跳变:DO 在 1 分钟内从 6 mg/L 跳到 0 或 20,多为探头污损、气泡、电磁干扰引起,属于物理上不可能的突变。
  • 漂移:传感器随生物附着和电极老化缓慢偏移,数据看起来“平滑”但整体偏离真值,最难被简单规则发现。
  • 冻结值:设备卡死后持续输出同一数值,表现为长时间方差为零。
  • 时间戳错乱:设备时钟未同步,导致数据顺序错位,影响趋势与滞后特征构造。
漂移和冻结值是最容易被忽视的两类问题。它们不会触发“超阈值”报警,却会系统性地污染训练数据。建议在采集端就记录设备状态码与校准时间,为后续判断提供依据。

四、采集方案设计与数据流

一个可落地的采集方案应包含传感器层、采集控制层、本地缓存与上传层、以及数据质量前置校验。下图展示了一个典型池塘监测点的数据流与质量控制节点:

池塘监测点数据采集与质量前置校验流程 传感器层 DO 荧光探头 水温 PT1000 pH 玻璃电极 氨氮/亚硝酸盐 浊度/电导率 采样:DO 1~5 min 采集控制层 定时触发采样 温度补偿计算 时间戳打标 设备状态码记录 5 min 聚合 均值/最小/最大/标准差 质量前置校验 量程与突变检查 冻结值检测 缺失标记 校准时间比对 异常标记入库 不删除,仅打标签 本地缓存与上传 断网续传 MQTT 上报 时序数据库 原始+聚合双存 供预测建模 关键原则:① 采样频率与参数变化尺度匹配;② 聚合保留最小值/最大值;③ 异常数据打标签而非直接删除;④ 记录校准时间以支撑漂移判断。 示例参数为教学假设,实际部署需结合池塘密度、季节与设备手册确定。

在实现层面,采集程序通常以固定周期读取各探头,先做温度补偿与单位统一,再写入带时间戳的记录。以下是一个简化的采集与聚合示例,展示如何按 5 分钟窗口聚合并保留关键统计量:

import time
from collections import defaultdict

# 假设 read_sensor() 返回 (do, temp, ph) 的原始读数
buffer = defaultdict(list)

def collect_once(ts):
    do, temp, ph = read_sensor()
    window = ts // 300 * 300          # 5 分钟对齐
    buffer[window].append((do, temp, ph))

def flush_window(window):
    rows = buffer.pop(window, [])
    if not rows:
        return None
    dos = [r[0] for r in rows]
    return {
        "ts": window,
        "do_mean": sum(dos) / len(dos),
        "do_min": min(dos),           # 夜间低氧预警关键
        "do_max": max(dos),
        "n": len(rows),               # 样本数,用于判断缺失
    }

注意 n 字段:若某窗口本应有 5 条记录却只有 2 条,说明采集中断,后续建模时应将该窗口标记为低置信度,而不是直接当作正常均值使用。

五、方案落地时的几个判断依据

设计采集方案时,可以用几条可操作的判断标准来检验:其一,DO 的采样间隔是否小于其最快下降时间的一半,否则可能漏掉夜间骤降;其二,是否保留了原始高频数据与聚合数据两套,便于事后回溯;其三,异常标记是否与原始值一同入库,保证可追溯;其四,是否记录了每次校准的时间与结果,使漂移可以被量化而非凭感觉判断。把这四点落实到采集端,后续的趋势预测才有可靠的数据底座。