Kats 残差翻译检测器(KDEResidualTranslator)深度解析:基于核密度估计的误报概率转换

发布时间:2026/10/8 7:54:43
Kats 残差翻译检测器(KDEResidualTranslator)深度解析:基于核密度估计的误报概率转换 数据分析机器学习数据科学【免费下载链接】KatsKats, a kit to analyze time series data, a lightweight, easy-to-use, generalizable, and extendable framework to perform time series analysis, from understanding the key statistics and characteristics, detecting change points and anomalies, to forecasting future trends.项目地址https://gitcode.com/gh_mirrors/ka/Kats点击查看免费下载导读在时序预测与异常检测任务中一个经典思路是先用某个预测器生成预测值再计算预测值与真实值之间的残差residual最后根据残差的大小将其翻译成误报概率false-alarm probability。Kats 提供的KDEResidualTranslator正是完成这一翻译环节的专用组件它不再假设残差服从正态分布而是用核密度估计Kernel Density Estimation, KDE从数据中学习残差的真实分布从而输出每个时间点属于异常的概率。读完本文你将掌握 KDEResidualTranslator 的完整 API、两种残差输入方式、参数校验规则以及它如何与预测器组合成一套可复现的异常检测流水线。本文主体基于仓库文档 sphinx/source/kats.detectors.residual_translation.rst 所对应的模块 kats/detectors/residual_translation.py并结合其单元测试 kats/tests/utils/test_decomposition.py 中的验证逻辑进行源码级扩充。一、设计动机为什么不能只依赖正态假设模块开头的 docstring 直接说明了设计动机见 kats/detectors/residual_translation.py基于预测器的检测器大致工作流程是计算残差预测值与当前值的差然后根据残差的大小将其翻译成误报概率。这通常依赖于残差服从正态分布的假设。而在实践中残差往往不服从正态分布有时甚至是不对称的。本模块使用核密度估计学习残差的分布并据此输出误报概率。这意味着KDEResidualTranslator承担的是概率校准层的角色它并不关心预测值是怎么来的可以是滚动均值、ARIMA、Prophet 等任意预测器只负责把预测偏差有多大这个原始数值映射到该点属于异常的置信度有多高这个概率上。由于分布是从训练残差中直接估计出来的即使残差分布偏斜、重尾或双峰映射结果也比按标准差缩放的方式更贴合实际数据。二、核心类与完整 APIKDEResidualTranslator位于 kats/detectors/residual_translation.py从源码结构看它是一个典型的 sklearn 风格三件套fit/predict/ 拟合后属性核心成员如下成员类型说明KDEResidualTranslator(ignore_below_frac, ignore_above_frac)构造函数传入训练时忽略的上下分位用于对异常值更鲁棒fit(y, yhat, yhat_lower, yhat_upper, residual)方法拟合残差分布返回self以支持链式调用kde_只读属性拟合完成的sklearn.neighbors.KernelDensity对象predict_proba(y, yhat, yhat_lower, yhat_upper, residual)方法输出与输入逐行对应的异常概率0~1predict_log_proba(...)方法输出自然对数形式的概率2.1 构造函数参数ignore_below_frac训练时忽略的下分位默认0ignore_above_frac训练时忽略的上分位默认1。这两个参数的作用在 fit 实现 中体现得最直观拟合前先用value.quantile(ignore_below_frac)与value.quantile(ignore_above_frac)对残差做区间截断只保留位于两分位之间的样本参与 KDE 拟合从而避免极端残差把概率密度估计带偏。源码对非法取值做了显式校验residual_translation.py#L69-L74ignore_below_frac 0或ignore_above_frac 1抛出ValueError(Illegal ignore fractions)ignore_below_frac ignore_above_frac下分位大于上分位同样抛出ValueError。测试 test_illegal_truncated_fracs 用(-0.1, 0.9)、(1.1, 2.0)、(0.1, -0.9)、(0.1, 1.9)、(0.9, 0.8)五组非法组合逐一验证了这两类异常会被触发。2.2 数据形态约定所有输入输出都使用 Kats 的基础数据结构TimeSeriesData定义于 kats/consts.py它可由pandas.DataFrame、pandas.Series或pandas.DatetimeIndex初始化内部至少包含time与value两个成员。翻译器对输入的要求归纳如下输入数据二选一直接给出residual或给出y与yhat可附带yhat_lower与yhat_upper两者必须成对出现时间列ds/ts至多提供其一。2.3 参数校验规则_get_residualresidual_translation.py#L193-L227是内部的数据归一化与校验入口规则非常严格提供了yhat但未提供y抛ValueError(Must include y if supplying yhat)同时提供了yhat与residual抛ValueError(Must not include residuals if supplying yhat)只提供了yhat_lower/yhat_upper其中之一抛ValueError(Must supply either both yhat_lower and yhat_upper or neither)只提供了residual却又同时提供了y/yhat/yhat_lower/yhat_upper中的任意一个抛ValueError(Must not include y, yhat, yhat_lower, yhat_upper if supplying residuals)什么都没提供抛ValueError(Must supply y and yhat or residual)。值得注意的是TimeSeriesData重载了算术运算符kats/consts.py#L517-L527因此源码中直接写residual y - yhat、residual / yhat_upper - yhat_lower即可完成逐元素减法与除法这也是残差翻译器必须接收 TimeSeriesData这一约定的底层原因。另外在计算残差后_get_residual会剔除值为NaN的行residual_translation.py#L224-L226例如由滚动窗口前window_size个点产生的空值会被自动清理。三、完整代码示例可直接运行模块 docstring 给出了最小可运行的完整示例residual_translation.py#L46-L67下面按两种输入方式分别展开并补充注释与训练集构造细节。方式一基于y与yhat拟合from kats.consts import TimeSeriesData from kats.detectors.residual_translation import KDEResidualTranslator import pandas as pd # ts_data 为某个 TimeSeriesData 时间序列含 time / value 两列 y ts_data # 用长度为 7 的滚动均值构造预测shift(1) 保证预测只使用历史信息 yhat pd.DataFrame({ value: y.value.rolling(7).mean().shift(1), time: y.time, }) yhat TimeSeriesData(yhat) trn KDEResidualTranslator() # 使用默认分位不做截断 trn trn.fit(yy, yhatyhat) # 内部自动计算 residual y - yhat proba trn.predict(y) # 输出与 y 逐行对应的异常概率方式二直接传入残差# 也可以预先算好残差直接交给翻译器 residual y - yhat # TimeSeriesData 支持 - 运算符 trn trn.fit(residualresidual) proba trn.predict(residualresidual)两种方式等价predict实质是对predict_proba的别名调用返回的TimeSeriesData.value中每个元素取值均在[0, 1]区间内数值越接近 1 表示该残差越罕见、越可能对应异常。3.1 真实测试用例参考仓库自带的单元测试 KDEResidualTranslatorTest 直接复用了上述示例的构造逻辑它读取 kats/data/air_passengers.csv以 7 步滚动均值加shift(1)生成yhat并验证了两个关键性质概率一致性np.exp(predict_log_proba(residual).value)与predict_proba(residual).value逐元素相等test_decomposition.py#L590-L593即predict_proba是predict_log_proba的指数变换输出有界所有概率落在[0, 1]内test_decomposition.py#L594-L595分布还原质量用拟合好的kde_重新采样并与原始残差做双样本 KS 检验验证学到的分布与真实残差分布足够接近test_decomposition.py#L596-L602。四、底层原理fit 与 predict 的完整调用链4.1 fit两步式 KDE 拟合fit的实现residual_translation.py#L76-L116可以拆成三步残差归一化经_get_residual得到残差按构造参数分位截断剔除NaN带宽搜索以value.quantile(0.95) - value.quantile(0.05)为区间长度extent将候选带宽设为np.linspace(extent / 1000, extent / 10, 1000)即从区间的千分之一到十分之一均匀取 1000 个候选值内核固定为gaussian随机搜索选参并最终拟合使用sklearn.model_selection.RandomizedSearchCV评分函数为lambda k, x: k.score_samples(x).sum()即对数似然之和random_state0保证可复现选出最优带宽后重新构建KernelDensity(**best_params)并fit(value.to_frame())结果保存在self._kde。fit返回self因此可以链式调用trn trn.fit(...)。4.2 predict从对数概率到概率predict_log_probaresidual_translation.py#L156-L191先经_get_residual归一化再调用self._kde.score_samples(residual.value.to_frame())得到每个残差点的对数概率密度与residual.time一起封装成TimeSeriesData返回predict_probaresidual_translation.py#L126-L154对predict_log_proba的结果逐元素取np.exp即把对数概率密度还原为概率密度。需要说明的是KDE 输出的概率密度值本身不做归一化到[0,1]的强制约束实际应用中通常将其作为相对异常分数使用越大越异常而测试中之所以概率落在[0,1]是因为残差分布在该数据上恰好有界且测试做了验证。因此更稳妥的理解是该分数反映残差在已学习分布中的相对罕见程度可用阈值或下游检测器如 kats/detectors/threshold_detector.py进一步判定是否告警。五、与其他检测器组合的实战建议从 kats/detectors/init.py 可以看到residual_translation与bocpd、cusum_detection、robust_stat_detection、seasonality、trend_mk等一同被导出为kats.detectors的子模块使用前无需额外安装依赖为scikit-learn与numpy/pandas见 requirements.txt。但注意在 kats/detectors/init.py 中prophet_detector被包在try/except ImportError里——若未安装 Prophet 会被跳过并打印 warning而residual_translation则无此限制。推荐的组合范式是预测器 翻译器 告警器三段式from kats.models.arima import ARIMAModel from kats.detectors.residual_translation import KDEResidualTranslator from kats.detectors.threshold_detector import ThresholdDetection # 1) 用任意预测器滚动预测 params ARIMAModel.get_params(ts_data) # 或自选预测模型 model ARIMAModel(ts_data, params) model.fit() fcst model.predict(steps..., ...) # 得到 yhat 区间 # 2) 用 KDE 翻译器把偏差翻译成概率 trn KDEResidualTranslator().fit(yts_data, yhatfcst) proba trn.predict_proba(yts_data, yhatfcst) # 3) 用阈值等检测器在概率序列上触发告警六、快速自检清单输入必须是TimeSeriesData含time与valuevalue建议为数值型 Series要么给residual要么给yyhatyhat_lower/yhat_upper必须成对出现训练前先调用fit否则predict_proba会因为_kde未拟合而无法工作想让翻译器对历史极端值更鲁棒可设置ignore_below_frac0.01, ignore_above_frac0.99之类的小幅截断概率输出的绝对数值依赖具体数据分布建议结合业务阈值或下游检测器使用而非死记固定阈值。七、小结KDEResidualTranslator是 Kats 检测体系中从预测偏差到异常概率的标准化桥梁。它通过核密度估计自动学习残差分布摆脱了正态假设的限制并提供了严格的输入校验、分位截断的鲁棒训练以及predict_proba/predict_log_proba/kde_三个便捷出口。结合 kats/detectors/residual_translation.py 的源码与 kats/tests/utils/test_decomposition.py 的测试用例你可以直接将其嵌入自己的预测—检测流水线在变点、异常和离群点检测任务中获得更贴合实际分布的误报概率。赞分享数据分析机器学习数据科学【免费下载链接】KatsKats, a kit to analyze time series data, a lightweight, easy-to-use, generalizable, and extendable framework to perform time series analysis, from understanding the key statistics and characteristics, detecting change points and anomalies, to forecasting future trends.项目地址https://gitcode.com/gh_mirrors/ka/Kats点击查看免费下载相关推荐零基础搭建Bililive-go多平台直播录制全攻略零基础搭建Bililive go多平台直播录制全攻略 你是否曾经错过心爱主播的精彩直播或者想要保存喜欢的游戏赛事回放Bililive go正是为你量身打造后端音视频视频Vega 概率密度估计实战用 density 变换对比正态分布与核密度估计Probability Density ExampleVega 概率密度估计实战用 density 变换对比正态分布与核密度估计Probability Density Example 导读 本文以 Vega数据可视化概率密度估计方法对比统计至简核密度与参数估计指南概率密度估计方法对比统计至简核密度与参数估计指南 想要从数据中挖掘隐藏的分布规律概率密度估计是数据科学中的关键技术它能够从有限的样本数据中重建出完整的概率示例工程教育教程上一篇osu!移动端开发终极指南iOS和Android版本的技术挑战与创新解决方案下一篇Node-Redis 测试策略单元测试和集成测试的最佳方法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考