fix: 异常值裁剪 P1/P99 → P2/P98,避免边界垃圾值污染

- P1-P99 对 pH/DO 等参数不够保守:边界像素模型预测 pH=-22
  导致 P1=-2.38,裁剪后仍保留物理上不可能的值
- 改为 P2-P98(4% 裁剪),IQR 8.3-8.5 的主体数据完全不受影响
- 两处同步:预测端 _clip_outliers + 插值端 _perform_interpolation
This commit is contained in:
duxin
2026-07-28 17:09:42 +08:00
parent 3f2eef4536
commit 241b138bb5
2 changed files with 17 additions and 4 deletions

View File

@ -750,8 +750,8 @@ class WaterQualityInference:
raise
@staticmethod
def _clip_outliers(predictions: np.ndarray, lower_pct: float = 1.0,
upper_pct: float = 99.0) -> np.ndarray:
def _clip_outliers(predictions: np.ndarray, lower_pct: float = 2.0,
upper_pct: float = 98.0) -> np.ndarray:
"""百分位裁剪:将极端异常值裁剪到合理范围。
水体边界/零值区域的光谱异常会导致模型外推到极端值
@ -763,9 +763,9 @@ class WaterQualityInference:
predictions : np.ndarray
原始预测值
lower_pct : float
下百分位(默认 1%,低于此分位数的值被裁剪)
下百分位(默认 2%,低于此分位数的值被裁剪)
upper_pct : float
上百分位(默认 99%,高于此分位数的值被裁剪)
上百分位(默认 98%,高于此分位数的值被裁剪)
Returns
-------

View File

@ -695,6 +695,19 @@ class ContentMapper:
- IDW 作为首选回退:无需拟合变异函数,不会产生纯色图
- scipy linear/nearest 作为最后兜底
"""
# ★ 百分位裁剪:去掉极端异常值,避免色阶被拉爆
# P2-P98比 P1-P99 更保守,避免 pH/DO 等参数在边界区域
# 的模型预测垃圾值pH=-22、DO=-20污染裁剪下限
_lo = np.percentile(values, 2.0)
_hi = np.percentile(values, 98.0)
_n_lo = int(np.sum(values < _lo))
_n_hi = int(np.sum(values > _hi))
if _n_lo > 0 or _n_hi > 0:
print(f"[异常值裁剪] P1={_lo:.4f}, P99={_hi:.4f}, "
f"裁剪低端 {_n_lo} 个, 高端 {_n_hi}"
f"({(_n_lo+_n_hi)/len(values)*100:.1f}%)")
values = np.clip(values, _lo, _hi)
print(f"插值输入检查:")
print(f" - 数据点数量: {len(points)}")
print(f" - 数据值范围: {values.min():.4f} - {values.max():.4f}")