From 241b138bb56c3f7cdcaa7e4b9ae75a869024982f Mon Sep 17 00:00:00 2001 From: duxin Date: Tue, 28 Jul 2026 17:09:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BC=82=E5=B8=B8=E5=80=BC=E8=A3=81?= =?UTF-8?q?=E5=89=AA=20P1/P99=20=E2=86=92=20P2/P98=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E8=BE=B9=E7=95=8C=E5=9E=83=E5=9C=BE=E5=80=BC=E6=B1=A1?= =?UTF-8?q?=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - P1-P99 对 pH/DO 等参数不够保守:边界像素模型预测 pH=-22 导致 P1=-2.38,裁剪后仍保留物理上不可能的值 - 改为 P2-P98(4% 裁剪),IQR 8.3-8.5 的主体数据完全不受影响 - 两处同步:预测端 _clip_outliers + 插值端 _perform_interpolation --- src/core/prediction/inference_batch.py | 8 ++++---- src/postprocessing/map.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/core/prediction/inference_batch.py b/src/core/prediction/inference_batch.py index d4001cd..3072d25 100644 --- a/src/core/prediction/inference_batch.py +++ b/src/core/prediction/inference_batch.py @@ -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 ------- diff --git a/src/postprocessing/map.py b/src/postprocessing/map.py index b72ed90..0e4f379 100644 --- a/src/postprocessing/map.py +++ b/src/postprocessing/map.py @@ -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}")