开发者文档:/v1/forecast 与 /v1/clean 已开放,API 密钥在 SequenxAI 平台自助创建。

清洗策略版本参考

清洗策略写作 预设@版本,例如 default@2026-13。预设决定「哪些改动可以自动执行」,版本决定「用哪一套规则和阈值」。本页按执行顺序列出每个版本的全部步骤和参数,并给出清洗报告中每个决定 id、问题代码的含义。报告的字段结构与采纳 / 拒绝的用法见清洗策略与清洗报告。

1. 策略一览

策略说明如何选择
default@2026-13平台当前默认。保留 2026-12 的全部步骤,把 10% 缺失占比拒绝改为按缺失位置判断(见缺失判断规则),并逐项列出健康分扣分。不传 version 时使用(除非密钥或组织另有设置)。
default@2026-12已弃用,将在公告后移除。保留 2026-11 的全部步骤,并固定预测起点:末尾至多 3 个空值按未知处理,不再删除。options.cleaning.version: "2026-12";响应带 cleaning_version_deprecated 提醒。
default@2026-11已弃用,将在公告后移除。保留 2026-10 的全部步骤,另加逐段补值、补值的物理约束、工作日网格 B 与更多数据检查。options.cleaning.version: "2026-11";响应带 cleaning_version_deprecated 提醒。
default@2026-10已弃用,将在公告后移除。最初的冻结规则集,输出由回归基线逐字节锁定。options.cleaning.version: "2026-10";响应带 cleaning_version_deprecated 提醒。
strict@2026-13(已弃用:strict@2026-10、strict@2026-11、strict@2026-12)与同版本的 default 运行同一套规则,但只自动执行结构性决定,其余降为提议。options.cleaning.preset: "strict",可同时指定 version。
raw@2026-10不清洗,只做严格的结构校验,数据原样交给模型。options.cleaning.preset: "raw"。

raw 不经过清洗服务,结构校验规则与版本无关,见第 7 节。

2. 版本承诺

  • 带日期的版本是冻结的。 已发布版本的规则、阈值和默认参数不再修改。
  • 同样的输入得到同样的输出。 数据、选项、策略 id 相同时,清洗结果和决定 id 都相同。唯一与模型有关的一步是最小长度检查,它取决于所选模型的最小上下文。
  • 规则调整以新版本发布。 平台默认改用新版本时会公告;被替换的旧版本先标记为已弃用,仍可显式选择(响应带 cleaning_version_deprecated 提醒),在公告的日期之后才移除。
  • 默认值按层解析。 预设和版本分别按「请求 > 密钥默认 > 组织默认 > 平台默认」取第一个设置了的值。平台默认目前是 default@2026-13;2026-10、2026-11 与 2026-12 已弃用,将在公告后移除。密钥或组织的默认值由平台配置,目前没有自助设置入口。
  • 实际生效的策略总会回显。 成功响应的 effective_policy 写明 id、preset、version 与 source(request、key、org、platform 之一,取设置了预设或版本的最高层级)。记录 effective_policy.id 即可复现同一次清洗。

3. 选择版本与 2026-11 参数

只有需要默认 2026-13 以外的版本时,才在 options.cleaning 中传 version。下面七个参数从 2026-11 起提供,默认版本下同样可用,也放在 options.cleaning 中:

forecast-cleaning-parameters.json
{
"model": "hora-1.0",
"h": 24,
"freq": "1h",
"series": [
  {"unique_id": "pv-01", "ds": "2026-06-01T00:00:00Z", "y": 0.0},
  {"unique_id": "pv-01", "ds": "2026-06-01T01:00:00Z", "y": null}
],
"options": {
  "cleaning": {
    "preset": "default",
    "impute_method": "auto",
    "nonnegative": "true",
    "bounds": {"lower": 0, "upper": 500},
    "structural_zero": "auto",
    "business_days": "off"
  }
}
}

(series 已截断,实际请求需要满足模型的最小上下文。)

参数取值默认作用
impute_methodauto、linear、pchip、seasonalautoauto 为每个缺口单独选方法(见逐段补值);指定方法无法执行时回退到线性,并在报告中写明原因。
seasonal_period整数 2 至 10000(网格步数)按频率推断指定季节周期。指定时只要求序列覆盖至少 2 个周期,不再检验自相关。
nonnegativeauto、true、falseautoauto:观测值至少 8 个且没有负数时,补值截到 0 以上。true:总是截断,并标记负的观测值。false:关闭。
bounds{"lower": …, "upper": …}无声明的物理范围:补值截到范围内,范围外的观测值被标记(out_of_bounds)。至少给一个边界,且 lower ≤ upper。
structural_zeroauto、offautoauto:几乎总为 0 的季节相位上,补值保持为 0。
business_daysauto、on、offautoauto:没有周末日期的日频数据使用工作日网格 B。on:日频数据强制使用 B。off:保持自然日。
long_gapfill、maskfill模型如何读取超过短缺口上限的内部长缺口(long_gap 问题)。fill:读取补值。mask:补值与报告不变,但支持缺失屏蔽的模型把这些位置当作缺失读取。见长缺口:填补还是屏蔽。

长缺口:填补还是屏蔽

清洗总会填补所有缺口,使报告与清洗后的序列完整。对于内部长缺口,long_gap 决定模型读取什么:

  • fill(默认):模型读取补值,与报告中展示的一致。当补值是合理的替代时保留它,例如序列在缺口期间延续稳定的季节模式。
  • mask:模型把这些位置当作缺失,依据缺口前后的观测值预测。当长缺口是停机、检修或其他真实数值未知、不应影响预测的时段时,可考虑使用。mask 主要适用于离最近数据较远的长缺口;如果长缺口紧挨着最后一个观测值结束,除非在自己的数据上回测表明更好,否则建议保留 fill。

短缺口(不超过短缺口上限)在两种方式下都会为所有模型填补。使用 mask 时,每个实体的 model_input[] 条目会给出 long_gap_points(交给模型的上下文中被屏蔽的长缺口位置数)与 long_gap_handling(模型实际如何读取这些位置)。API 提供的 SequenxAI Omni(hora-1.0)支持缺失屏蔽:这些位置以缺失值交给模型,long_gap_handling 为 "mask"。"fill" 只用于不支持缺失屏蔽的模型,此时模型改为读取补值(long_gap_handling: "fill"、long_gap_reason: "model_without_mask",并附一条 long_gap_mask_unavailable 提醒),请求不会失败;当前 API 提供的模型不会出现这种情况。两种取值计费相同:被屏蔽的位置从未被观测,不计入计费输入点。传入时,所选取值会在 cleaning_report.policy.long_gap 中回显。建议先在自己的数据上用回测比较两种方式,再决定使用哪一种。

参数校验:

  • 在 2026-10 下传这七个参数中的任意一个(nonnegative: "auto" 除外),返回 422 CLEANING_OPTION_UNSUPPORTED,不会被静默忽略:
requires-version.json
{
"error": {
  "code": "CLEANING_OPTION_UNSUPPORTED",
  "message": "Cleaning options require policy version 2026-11",
  "details": {
    "options": ["business_days"],
    "policy": "default@2026-10",
    "requires_version": "2026-11"
  }
}
}
  • 2026-10 下 nonnegative 传 "true" 或 "false" 同样返回 CLEANING_OPTION_UNSUPPORTED,details 为 options 与 supported。
  • 取值非法(例如 lower 大于 upper)返回 422 VALIDATION_ERROR。
  • options.cleaning 内未列出的字段返回 422 VALIDATION_ERROR(details.errors[].field 指出字段),不会被忽略。
  • 未知的 version 返回 422 CLEANING_OPTION_UNSUPPORTED,details.allowed 列出可选版本。
  • raw 预设不接受任何参数,也不接受 accept / decline。
  • freq: "B" 只在 2026-11 及之后的版本下有效;2026-10 返回 FREQ_UNSUPPORTED,raw 下返回 RAW_INPUT_INVALID。

从 2026-11 起,cleaning_report.policy 会回显解析后的参数:impute_method、structural_zero、business_days 未传时回显 auto;seasonal_period、bounds 与 long_gap 只在传入时出现。2026-10 的 policy 保持原有结构。可以先用 /v1/clean 免费预演这些参数的效果。

4. default@2026-10 的处理步骤

每个实体(unique_id)独立按下面的顺序处理。报告中的位置列表最多列出 50 条,超出时 truncated 为 true。

4.1 解析时间戳与时区

  • 支持的时间戳格式见时间戳格式。日月顺序无法从数据判断时,以 AMBIGUOUS_DATE_FORMAT 拒绝,请传 options.ds_format。
  • 带偏移的时间戳按偏移读取;不带偏移的按 options.timezone 读取,未传时按 UTC 读取并报告 naive_timestamps_assumed_utc。
  • 遇到无法解析的时间戳时以 VALIDATION_ERROR 拒绝(2026-10 只报告第一条)。
  • 夏令时相关情况只报告、不修改:dst_missing、dst_duplicate、dst_nonexistent_time、mixed_timezone。对全部按 UTC 读取的逐小时或更细的数据,如果在 3、4、9、10、11 月的周日 0 点至 3 点(UTC)出现恰好一小时的缺口或重复,也会给出 dst_missing / dst_duplicate 提示和 dst_suspected 警告。

4.2 排序

行没有按时间排序时稳定排序(决定 time.reorder,问题 out_of_order)。

4.3 识别缺失值

  • 缺失标记文本。 文本单元格为 na、n/a、nan、null、none、?、#n/a、#value! 或空字符串(不区分大小写)时置为空值(决定 value.tokens)。
  • 单独的破折号 -、--:可能是 0 也可能是缺失,默认按缺失处理,并提议按 0 处理(决定 value.dash_token,proposed)。
  • 缺失值代码。 候选值为 9999、-9999、99999、-99999、-999、999999、65535、-32768。当该值落在其他观测值的范围之外、与最近边界的距离超过「其他观测值 1% 至 99% 分位的跨度」与「10 倍 MAD」中的较大者,且占比不超过 5% 时,自动置为空值;否则只提议,数值保持不变(决定 value.sentinel)。

这两类文本规则只针对文本形式的单元格(例如上传的 CSV);JSON 请求中 y 为数字或 null,通常不会触发。

4.4 确定频率

  • 传了 freq 时直接使用。
  • 省略时推断:先判断是否为按月 / 季 / 年对齐的日历频率(相邻间隔的中位数至少约 28 天,且至少 90% 的时间戳落在同一个月内日期上,如 1 号、月末或固定某一天);否则取相邻间隔的众数,间隔相差在 2% 或 1 秒以内视为同一间隔。
  • 众数占比至少 90% 为高置信度;70% 至 90% 为低置信度,给出 freq_low_confidence 警告但不拒绝;低于 70% 以 FREQ_INFERENCE_FAILED 拒绝。
  • 第二常见的间隔占全部间隔至少 25%,且不少于最常见间隔的三分之二时,视为有歧义,以 FREQ_AMBIGUOUS 拒绝。省略 freq 时各实体推断出不同频率,同样返回 FREQ_AMBIGUOUS。

4.5 对齐网格

  • 时间戳略偏离格点时对齐到最近的格点(决定 grid.snap,问题 timestamp_jitter)。容差:固定步长为步长的 2%(且不超过半个步长),例如逐小时数据为 72 秒;日历频率为 ±12 小时。
  • 超出容差的行删除(决定 grid.off_grid,问题 off_grid,警告 off_grid_dropped)。偏离网格的行超过该实体行数的 10% 时,以 FREQ_INFERENCE_FAILED 拒绝。

4.6 去重

对齐后同一格点有多行时保留最后一行(决定 time.duplicates,操作 keep_last)。各行值相同时类别为 structural;值不同时类别为 drop,并给出 duplicate_conflict 警告。值冲突的重复至少 3 处且超过该实体行数的 5% 时,额外报告 entity_column_suspected:可能多条序列混在了同一个 unique_id 下。

4.7 裁剪首尾空值

序列开头和结尾的空值直接删除(决定 gap.edge_trim,问题 edge_null)。全部为空的实体以 SERIES_EMPTY 拒绝。从 2026-12 起,末尾空值的处理不同,见固定预测起点。

4.8 模型上下文窗口

历史不会为适配模型而被截断。某个实体长于所选模型的最大上下文时,在清洗前(按不重复的时间戳)或清洗后(按规则网格,含补齐的点)返回 422 SERIES_TOO_LONG;请只发送最近的点。因此引擎的 window.context 决定与 context_window 问题不会出现在 API 响应里。模型的上限见模型与能力上限。

4.9 长缺口拆分

  • 观测值之间的缺口达到阈值时,只保留最后一个长缺口之后的最新一段(决定 gap.split)。
  • 阈值:传了 options.gap_split_min_steps 时取该值(0 关闭拆分);否则取「补值上限加一(即 4 步)」「3 个季节周期」「序列跨度的 5%」三者中最大的。
  • 季节周期步数:亚日频为一天的步数,日频到周频之间为一周的步数,日历频率为一年的步数,周频及更长的固定步长为 1。
  • 最新一段必须至少覆盖模型的最小上下文,且自动阈值下至少覆盖 3 个季节周期,否则不拆分。
  • 被丢弃的观测值不超过一半时自动执行;超过一半时只提议(问题 segment_split_skipped),改为补齐缺口。
  • clean_series: false 时不做拆分。

4.10 缺失占比检查

缺失占比 =(网格上缺少的时间戳 + 空值)÷ 网格总点数,在补值之前计算。低于 1% 为 Healthy,1% 至 10% 为 Warning,达到 10% 为 Critical,以 SERIES_DISCONTINUOUS 拒绝(阻断 health_critical)。2026-13 替换了这一检查,见缺失判断规则。

健康分 health.score(0 至 100)= 100 − min(40, 400 × 缺口占比) − min(20, 200 × 缺失占比) − min(15, 5 × 值冲突的重复数) − min(15, 100 × 异常值占比),四舍五入。Critical 实体的分数不超过 49。

4.11 插入空格点

网格上缺少的时间戳作为空格点插入(决定 grid.regrid,问题 gap)。

4.12 检测异常值(只标记,从不修改)

  • 滚动中位数 / MAD:窗口长度为点数的 1/50,限制在 21 至 101 之间并取奇数;窗口内至少 5 个观测值且 MAD 大于 0 时,评分 0.6745 × |x − 中位数| ÷ MAD 超过 3.5 的点被标记(问题 outlier,警告 outlier_flagged_not_modified)。
  • 日历频率的数据在至少 3 个完整年度周期时,先减去同一季节其他年份的中位数再检测,规律性的年度峰值不会被当作异常。
  • 异常值保持原值交给模型;metrics.outlier_points_suppressed 始终为 0。

4.13 检测平台段与量级跳变(只标记)

  • 平台段 flat_run。 连续相同的非零观测值达到最小长度时标记。最小长度为半个季节周期,固定步长限制在 8 至 288 步之间,日历频率下限为 4 步。所有观测值都是非负整数且 90% 分位不超过 20 时(小计数序列),不做该检测。
  • 量级跳变 level_shift。 相邻两个窗口的中位数相差约 1000 倍(对数差在 3 ± 0.25 以内)时标记,常见于单位换算错误。窗口长度为点数的 1/4,限制在 5 至 48 之间。

4.14 补值

  • 所有缺失(插入的空格点与空值)按两侧观测值线性插值(决定 gap.impute,操作 linear)。
  • 连续缺失超过补值上限 3 步时仍会补齐,但给出问题 long_gap 与警告 long_gap_filled。
  • imputed 动作的 gaps[] 为每个缺口写明范围、method、tier 与 reason。2026-10 的层级只用于说明缺口长短,不改变方法(P 为第 4.9 节的季节周期步数,n 为序列点数):
层级缺口长度reason
T0≤ 3 步within_gap_fill_max_steps
T1≤ Pno_seasonal_method
T2≤ max(3P, n 的 5%)no_seasonal_method
T3更长exceeds_long_gap_max
  • clean_series: false 时不补值;只要需要任何修复,就以 TIMESTAMP_IRREGULAR 或 SERIES_DISCONTINUOUS 拒绝(阻断 cleaning_required)。

4.15 最小长度

清洗后点数少于模型的最小上下文时,以 SERIES_TOO_SHORT 拒绝(阻断 too_short_for_model)。

5. default@2026-11 的新增步骤

2026-11 按同样顺序执行第 4 节的全部步骤,阈值不变,并在以下位置增加规则。

解析时间戳(第 4.1 步)

所有无法解析的时间戳在一次 VALIDATION_ERROR 中全部列出:details.cleaning_report.blocking[0] 为 unparseable_timestamp,带请求中的行号 rows(最多 50 条)与最多 5 个示例。

数字格式检查(第 4.3 步)

文本单元格不是普通数字时,按类型报告,数值保持缺失,不做猜测(read_as: "missing"):

问题代码示例
thousands_separator1,234.5
decimal_comma12,5
ambiguous_separator1,234(千位分隔还是小数逗号无法判断)
non_numeric_value12kW
number_format_mixed同一序列中同时出现千位分隔与小数逗号

工作日网格 B(第 4.4 步)

  • business_days: "auto" 且省略 freq 时,满足以下全部条件的日频数据使用工作日网格:平均每个日期不超过 1.05 个时间戳;没有周六、周日的日期;工作日日期至少 15 个;跨度至少 21 天;工作日覆盖率(有数据的工作日 ÷ 跨度内的工作日)至少 90%。日期按实体的本地时间判断(options.timezone,否则取数据中最常见的偏移)。
  • 使用 B 时周末不算缺口,预测时间戳跳过周末(决定 grid.business_days,类别 structural;问题 business_days_pattern,count 为跳过的周末天数)。不含节假日日历:工作日的节假日缺失仍按缺口处理。
  • business_days: "on" 对日频数据强制使用 B(未传 freq 或 freq 为日频时),周末的行按偏离网格删除;未传 freq 且数据不是日频时报告 business_days_not_applicable。"off" 始终保持自然日。
  • 也可以直接传 freq: "B"。auto 下显式传入 freq 时不做工作日检测。
  • 拒绝 grid.business_days:<unique_id> 即按自然日处理,周末成为缺口。

真实输出示例:从 2026-09-07(周一)起连续 20 个工作日,未传 freq:

grid.business_days.json
"freq": {"inferred": "B", "used": "B", "source": "inferred",
       "status": "HIGH_CONFIDENCE", "confidence": 1.0, "candidates": []}
{"id": "grid.business_days:fx", "rule": "grid.business_days", "class": "structural",
"status": "applied", "action": "business_day_grid",
"before": {"freq": "D"}, "after": {"freq": "B"}, "reversible": true,
"evidence": {"weekday_dates": 20, "weekend_dates": 0, "span_days": 26,
            "coverage": 1.0, "skipped_weekend_days": 6, "source": "detected"}}
// h=3 的预测时间戳:2026-10-05、2026-10-06、2026-10-07(周一至周三)

2026-10 处理同一份数据时推断为自然日(低置信度),6 个周末日成为缺口,缺失占比超过 10%,以 SERIES_DISCONTINUOUS 拒绝。

常数序列检查(第 4.12 步之后)

观测值从不变化时给出 constant_series 警告;全为 0 时给出 all_zero_series。

季节性检验

每个实体的报告带 series[].seasonality:{period, source, acf, cycles, accepted, reason}。

  • 候选周期 period 由频率决定:亚日频为一天的步数(逐小时为 24),日频到周频之间为一周的步数(日频为 7),工作日为 5,周频及更长的固定步长为一年的步数(周频为 52),日历频率为一年的步数(月频为 12)。候选周期小于 2 时没有周期。
  • 按频率得到的周期需要序列覆盖至少 3 个周期,且滞后一个周期的自相关(只用两端都有观测的点对)至少 0.3,才被采用。
  • 通过 seasonal_period 指定的周期只要求覆盖至少 2 个周期。

逐段补值

每个缺口单独选方法(impute_method: "auto"):

条件方法reason
缺口 ≤ 3 步,且缺口前后各至少 2 个观测值pchipshort_gap
缺口 ≤ 3 步,但一侧观测值不足 2 个linearshort_gap_few_neighbours
缺口更长,季节周期被采用,且每个缺失相位在前后各 7 个周期内至少有 2 个同相位观测值seasonalseasonal_period_accepted
缺口更长,季节周期被采用,但同相位历史不足linearinsufficient_history
缺口更长,季节周期未被采用linearno_seasonality:<原因>,原因同 seasonality.reason
  • pchip:Fritsch–Carlson 单调三次插值,经过所有观测点;每一段都落在两端观测值之间,不会过冲。
  • seasonal:取同一相位在前后各 7 个周期内观测值的中位数,再把缺口两端观测值与各自中位数的偏差线性过渡叠加上去,使补值与两端衔接。
  • 指定 linear 或 pchip 时每个缺口都用该方法(reason: method_option)。指定 seasonal 时需要覆盖至少 2 个周期的周期(不要求自相关)和足够的同相位历史;否则回退为线性,reason 为 seasonal_unavailable(没有可用周期)或 insufficient_history。
  • 层级 tier 的阈值与第 4.14 节相同,但 P 取 seasonality.period;没有周期时,超过 3 步的缺口都记为 T1。
  • 多个缺口用了不同方法时,gap.impute 的操作为 mixed,evidence.methods 给出每种方法补了多少点。

补值的物理约束

约束只作用于补出来的值,观测值从不修改。按以下顺序执行:

  1. 结构性零值(constraint.structural_zero,操作 zero)。某个季节相位至少有 7 个周期的观测,且其中至少 90% 为 0(例如光伏夜间出力)时,该相位的补值设为 0。需要序列至少覆盖 7 个周期;所有相位都满足时视为常数序列,不执行。structural_zero: "off" 关闭。
  2. 非负(constraint.nonnegative,操作 clip_at_zero)。见第 3 节 nonnegative 参数。
  3. 范围(constraint.bounds,操作 clip_to_bounds)。截到声明的 bounds 内。

每条实际改变了补值的约束都生成一条决定(类别 fabricate,reversible: true),可按 id 拒绝。受影响的缺口在 gaps[].constraints 中列出规则,actions[imputed].constraints 给出每条规则改变的点数。违反约束的观测值只被标记:negative_in_nonnegative(nonnegative: "true" 时的负观测值;或 auto 下观测值至少 99% 非负、仅有少数负值时,此时不做截断)与 out_of_bounds。

真实输出示例:逐小时光伏数据,共 8 天,第 6 天出力减半,2026-06-06T16:00Z 至 2026-06-07T05:00Z 缺失 14 个点(跨夜):

default-2026-11-pv.json
"seasonality": {"period": 24, "source": "frequency", "acf": 0.9307, "cycles": 8.0,
              "accepted": true, "reason": "accepted"}
"gaps": [{"range": {"start": "2026-06-06T16:00:00Z", "end": "2026-06-07T05:00:00Z", "points": 14},
        "method": "seasonal", "tier": "T1", "reason": "seasonal_period_accepted",
        "constraints": ["constraint.structural_zero", "constraint.nonnegative"]}]
{"id": "constraint.structural_zero:pv-01", "rule": "constraint.structural_zero",
"class": "fabricate", "status": "applied", "action": "zero",
"before": {"imputed_points": 14}, "after": {"changed": 12}, "reversible": true,
"evidence": {"period": 24, "phases": [0, 1, 2, 3, 4, 5, 6, 18, 19, 20, 21, 22, 23],
            "zero_share": 0.9, "min_cycles": 7}}
{"id": "constraint.nonnegative:pv-01", "rule": "constraint.nonnegative",
"class": "fabricate", "status": "applied", "action": "clip_at_zero",
"before": {"imputed_points": 14}, "after": {"changed": 1}, "reversible": true,
"evidence": {"source": "auto"}}
// 补值:17.1,随后 13 个点为 0(夜间保持为 0)

default@2026-10 处理同一份数据时,这 14 个点按线性插值补齐(tier: T1,reason: no_seasonal_method),夜间的补值大于 0。

固定预测起点(2026-12)

2026-12 保留上述 2026-11 的全部规则,只改变第 4.7 步:即使最后几个 y 为空(例如某个时段的数据还没到),预测也总是从你发送的最后一个 ds 的下一步开始。

  • 最后一个观测值之后至多 3 个网格步(补值上限)的末尾空值保留在网格上,不再删除(决定 gap.masked_tail,类别 fabricate,操作 mask_for_model;同名问题与警告 masked_tail;动作 masked,reason: trailing_null)。这些位置不作为数据使用:不计入 fed_points,不计费;该实体的 model_input[] 条目以 masked_tail 报告,响应的 warnings[] 中有一条 trailing_values_missing。
  • 末尾空值更长,或撤回 gap.masked_tail:<unique_id> 时,以 SERIES_DISCONTINUOUS 拒绝(阻断 trailing_gap_too_long,带 count 与 max_steps),而不是返回一个比你要求更早开始的预测。请发送最新的观测值,或去掉末尾的空行。
  • strict 下,gap.masked_tail 与其他非结构性决定一样降为提议,可按 id 采纳。
  • 开头的空值仍按第 4.7 步删除。2026-10 与 2026-11 下末尾空值同样删除(edge_null),预测从最后一个非空 y 之后开始。

缺失判断规则(2026-13)

2026-13 保留 2026-12 的全部规则,替换第 4.10 步的缺失占比检查。更早的版本拒绝缺失占比达到 10% 的任何序列;2026-13 改看缺失的位置,因为紧挨预测起点的长缺口对预测的影响,远大于同样数量的零散缺失。缺口长度以序列的季节周期计:传了 seasonal_period 时用它,否则小时数据 24 步、30 分钟 48 步、15 分钟 96 步、日数据 7 步、周数据 52 步、月数据 12 步。为模型保留的末尾空值(masked_tail)不计入。

检查拒绝(SERIES_DISCONTINUOUS)接受并给出警告 missing_pattern
之后不足 0.5 个周期观测值的缺口(近期缺口)0.75 个周期及以上(reason: gap_near_origin_too_long)0.25 个周期及以上(gap_near_origin)
其他缺口不单独拒绝2 个周期及以上(long_gap)
缺失占比(缺口加空值)35% 及以上(reason: missing_share_too_high)20% 及以上(missing_share_high)

没有季节周期时(例如频率不规则)只检查缺失占比。被拒绝的实体仍以 health_critical 阻断,并带 reason、reasons、period、near_gap_steps 与 far_gap_steps;caused_by 与之前一致。请补发缺失的近期数据,或只发送缺口之前的历史。

health.factors 列出健康分的各项扣分,格式为 {code, points, count?, ratio?},分数之和等于 100 − score:gap_near_origin、far_gap、missing_share(被接受的实体上合计至多 49 分)、conflicting_duplicates、outliers(有异常值时至少 1 分)、flat_runs、level_shifts,以及 blocked(使被拒绝的实体不高于 49 分)。等级与上表一致:拒绝为 Critical,警告为 Warning。

与 2026-12 的区别。 一部分因缺失达到 10% 而被 2026-12 拒绝的序列,现在会被接受(缺失达到 20% 时带 missing_pattern 提醒);一部分在预测起点前有长缺口、缺失不足 10% 而被 2026-12 接受的序列,现在会以 reason: gap_near_origin_too_long 拒绝。如需暂时保留原有行为,可固定 options.cleaning.version: "2026-12"(已弃用)。

6. strict 预设

strict 运行同版本 default 的全部规则,然后只保留结构性决定,其余 applied 的决定改为 proposed,请求以 422 拒绝并附带报告:

仍然自动执行降为提议
time.reorder、值相同的 time.duplicates、grid.snap、grid.regrid、grid.business_days(2026-11 及之后)。API 不执行 window.context:超长实体返回 SERIES_TOO_LONG(见 §4.8)gap.impute、gap.edge_trim、gap.split、grid.off_grid、值冲突的 time.duplicates、value.sentinel、value.tokens、value.dash_token、constraint.*(2026-11 及之后)、gap.masked_tail(2026-12)
  • 被降级的决定中有 time.* 或 grid.* 时以 TIMESTAMP_IRREGULAR 拒绝,否则以 SERIES_DISCONTINUOUS 拒绝(阻断 cleaning_required)。
  • 把决定 id 放进 accept 后该决定照常执行;所有被降级的决定都采纳后请求通过。
  • strict 下报告的 actions 仍描述 default 会做的操作,以 decisions 的状态为准。

7. raw 预设

raw@2026-10 不清洗:不排序、不去重、不补点、不推断时区,只做结构校验,数据原样交给模型。要求 freq 必填且为固定步长,ds 严格为 YYYY-MM-DDTHH:MM[:SS[.ffffff]] 加 Z 或 ±HH:MM,每个实体严格递增且步长恰好等于 freq,每个 y 都是有限数值。不满足时返回 RAW_INPUT_INVALID。响应没有 cleaning_report,也不能使用 accept / decline 或任何清洗参数。完整说明见 raw 预设。

8. 读取结果:effective_policy、决定与采纳 / 拒绝

  • effective_policy.id 是本次实际使用的策略;cleaning_report.policy 是清洗服务解析后的完整参数(补值上限 gap_fill_max_steps: 3、异常值阈值 outlier_threshold: 3.5、重复处理 duplicate_policy: "last" 等),以及你传入的 accept / decline。
  • cleaning_report.decisions[] 列出每一处改动数据的决定和未执行的提议。id 格式为 规则:unique_id,value.sentinel 额外带数值选择器,例如 value.sentinel:meter-001:-9999。
  • status:applied 已执行;proposed 只提议、数据未改动;declined 被你拒绝。
  • accept 让提议执行:value.sentinel、value.dash_token(按 0 处理)、gap.split,以及 strict 下被降级的任何决定。
  • decline 撤销 reversible: true 的决定:value.sentinel、gap.split、grid.business_days、constraint.structural_zero、constraint.nonnegative、constraint.bounds。撤回 gap.masked_tail 不会删除末尾空值,而是以 trailing_gap_too_long 拒绝请求。
  • 同一个 id 不要同时放进两个列表。列出的 id 在本次数据中不存在时,报告附带 decision_not_applicable 警告,请求照常处理。
  • issues[] 是发现的问题(带位置),warnings[] 是不阻断请求的提醒,blocking[] 是拒绝原因。请求被拒时,错误码由第一条阻断原因决定。

请求示例与各规则的前后对比见清洗策略与清洗报告。

9. 术语表

决定规则

规则类别操作含义可采纳 / 可拒绝
time.reorderstructuralstable_sort行没有按时间排序,已按时间稳定排序。—
time.duplicatesstructural / dropkeep_last同一时间戳有多行,只保留最后一行。值不同时为 drop。—
grid.snapstructuralnearest_slot时间戳略偏离格点,已对齐到最近的格点。—
grid.off_griddropdrop时间戳落在两个格点之间,该行已删除。—
grid.business_daysstructuralbusiness_day_grid2026-11。只有工作日的日频数据,改用工作日网格 B,周末不算缺口。可拒绝
gap.edge_trimdropdrop序列首尾的空值已删除。—
gap.masked_tailfabricatemask_for_model2026-12。至多 3 个末尾空值保留在网格上、不作为数据使用,预测仍从最后一个 ds 之后开始。可撤回(撤回后请求以 trailing_gap_too_long 拒绝)
window.contextdropkeep_latest历史长于模型最大上下文,只保留最近的部分。API 不会产生,此类序列返回 SERIES_TOO_LONG。—
gap.splitdropkeep_latest_segment序列中有很长的缺口,只保留缺口之后的最新一段。可采纳、可拒绝
grid.regridstructuralinsert_empty_slots网格上缺少的时间戳已作为空格点插入。—
gap.imputefabricatelinear / pchip / seasonal / mixed缺失值已补齐,操作为所用方法(2026-10 始终为 linear)。—
constraint.structural_zerofabricatezero2026-11。几乎总为 0 的相位上,补值设为 0。可拒绝
constraint.nonnegativefabricateclip_at_zero2026-11。非负序列的补值截到 0 以上。可拒绝
constraint.boundsfabricateclip_to_bounds2026-11。补值截到声明的范围内。可拒绝
value.sentinelfabricatenull数值是常见的缺失值代码,已置为空值后补齐;证据不足时只提议。可采纳、可拒绝
value.tokenssemanticnull文本单元格中的缺失标记(如 N/A)已置为空值。—
value.dash_tokensemanticzero单独的破折号,提议按 0 处理;未采纳时按缺失处理。可采纳

strict 预设下被降级的决定都可以采纳。

问题代码 issues[].code

代码含义
timestamp_format时间戳不是 ISO 8601,或日月顺序是从数据推断的;报告写明读取所用的格式。
naive_timestamps_assumed_utc时间戳不带偏移且未传 options.timezone,已按 UTC 读取。
dst_missing夏令时开始时缺少的一小时(来自偏移变化,或对 UTC 数据的推测)。
dst_duplicate夏令时结束时重复的一小时。
dst_nonexistent_time该本地时间在所用时区中不存在(夏令时跳过的时段)。
mixed_timezone同一实体内 UTC 偏移发生了夏令时以外的变化,可能混用了时区。
non_numeric_token文本单元格是缺失标记(如 N/A),已置为空值。
dash_token文本单元格是单独的破折号,可能是 0 也可能是缺失。
sentinel_value缺失值代码已置为空值。
suspected_sentinel疑似缺失值代码,证据不足,保留原值;可按 id 采纳。
thousands_separator2026-11。带千位分隔的数字文本,保持缺失。
decimal_comma2026-11。使用小数逗号的数字文本,保持缺失。
ambiguous_separator2026-11。无法判断逗号是千位分隔还是小数点,保持缺失。
number_format_mixed2026-11。同一序列中混用了千位分隔与小数逗号。
non_numeric_value2026-11。不是数字的文本(如带单位),保持缺失。
missing_valuey 为空值。
business_days_pattern2026-11。数据只有工作日,已使用工作日网格;count 为跳过的周末天数。
business_days_not_applicable2026-11。要求使用工作日网格,但数据不是日频,未使用。
out_of_order有行没有按时间排序。
duplicate_timestamp同一时间戳出现多行;conflicting 为值不同的重复数。
entity_column_suspected大量值冲突的重复时间戳,可能多条序列混在同一个 unique_id 下。
timestamp_jitter时间戳略偏离格点,已对齐。
off_grid时间戳落在两个格点之间,已删除;ratio 为占比。
edge_null序列首尾的空值,已删除。
masked_tail2026-12。保留在网格上、不作为数据使用的末尾空值;count 为步数。
trailing_gap_too_long2026-12。末尾空值超过可保留的步数(max_steps),或撤回了 gap.masked_tail(declined: true)。
missing_pattern2026-13。缺失的位置会影响预测;reasons 列出触发的检查(见缺失判断规则)。被接受时严重度为 warning,被拒绝时为 error。
context_window保留;API 不会产生,此类序列直接返回 SERIES_TOO_LONG。
segment_split_skipped有很长的缺口,但拆分会丢弃过半观测值,未执行,改为补齐;可按 id 采纳拆分。
gap网格上缺少的时间戳。
long_gap连续缺失超过补值上限(3 步),仍已补齐。
outlier异常值,只标记,数值未修改。
constant_series2026-11。观测值从不变化,没有可供预测的信号。
all_zero_series2026-11。观测值全为 0,常意味着没有数据。
flat_run一段连续相同的非零值,可能是传感器卡住;只标记。
level_shift前后两段相差约 1000 倍,可能是单位换算错误;只标记。
negative_in_nonnegative2026-11。非负序列中出现负的观测值;只标记。
out_of_bounds2026-11。观测值超出声明的 bounds;只标记。
too_short清洗后点数不足模型的最小上下文,或没有任何数值。

警告 warnings[].code

代码含义
freq_low_confidence推断频率的置信度在 70% 至 90% 之间,照常使用,建议显式传 freq。
duplicate_conflict重复时间戳的值不同,保留了最后一行。
entity_column_suspected同名问题的汇总。
off_grid_dropped删除了偏离网格的行。
segment_split已按长缺口拆分,丢弃了较早的数据。
segment_split_skipped同名问题的汇总。
dst_suspectedUTC 数据中疑似夏令时造成的缺失或重复,考虑传 options.timezone。
long_gap_filled补齐了超过补值上限的长缺口。
masked_tail2026-12。同名问题的汇总。
missing_pattern2026-13。同名问题的汇总,带 reasons。
outlier_flagged_not_modified标记了异常值,数值未修改。
decision_not_applicableaccept / decline 中的 id 在本次数据中不存在;ids 列出这些 id。

阻断原因 blocking[].code

代码错误码含义
unparseable_timestampVALIDATION_ERROR2026-11。有无法解析的时间戳,rows 列出所在行。
ambiguous_date_formatAMBIGUOUS_DATE_FORMAT无法从数据判断日月顺序。
freq_irregularFREQ_INFERENCE_FAILED无法推断稳定的频率,或偏离网格的行超过 10%(reason: off_grid)。
freq_ambiguousFREQ_AMBIGUOUS频率有多个候选,或各实体推断出不同频率。
freq_unsupportedFREQ_UNSUPPORTED频率无法识别。
all_nullSERIES_EMPTY实体没有任何数值型 y。
health_criticalSERIES_DISCONTINUOUS近期缺口或缺失占比未通过缺失判断规则,见 reason(已弃用的版本:缺失占比达到 10%)。带 caused_by 时,缺失主要由缺失值判定造成,按其中的 decline / accept 调整即可。
too_short_for_modelSERIES_TOO_SHORT清洗后点数少于模型的最小上下文。
trailing_gap_too_longSERIES_DISCONTINUOUS2026-12。末尾空值超过可保留的步数,或撤回了 gap.masked_tail;count 与 max_steps 给出具体数值。
cleaning_requiredTIMESTAMP_IRREGULAR / SERIES_DISCONTINUOUS需要修复,但 clean_series 为 false 或 strict 未采纳;reason 为 timestamp_irregular 或 series_discontinuous。

动作 actions[].code

代码method含义
reorderedstable_sort按时间重新排序。
deduplicatedlast删除重复时间戳,保留最后一行。
snappednearest_slot时间戳对齐到格点。
droppedgrid_align / edge_trim / latest_segment删除数据;reason 为 off_grid、edge_null 或 long_gap_split。
regriddedinsert_missing_stamps插入缺少的时间戳。
sentinel_to_nulltoken_table / sentinel_list缺失标记或缺失值代码置为空值。
imputedlinear / pchip / seasonal / mixed补齐缺失值;gaps[] 为每个缺口写明范围、方法、层级与原因。
maskedmodel_mask2026-12。为模型保留、不作为数据使用的末尾空值;reason 为 trailing_null。

补值原因 gaps[].reason

原因版本含义
within_gap_fill_max_steps2026-10缺口不超过补值上限(3 步)。
no_seasonal_method2026-10缺口超过补值上限;该版本没有季节补值,使用线性。
exceeds_long_gap_max2026-10缺口长于 T2 上限。
short_gap2026-11短缺口,两侧观测值充足,使用 PCHIP。
short_gap_few_neighbours2026-11短缺口,一侧观测值不足 2 个,使用线性。
seasonal_period_accepted2026-11季节周期被采用,使用季节补值。
no_seasonality:<原因>2026-11季节周期未被采用,使用线性;原因见下表。
insufficient_history2026-11同相位历史不足,回退为线性。
method_option2026-11使用 impute_method 指定的方法。
seasonal_unavailable2026-11指定了 seasonal,但没有可用周期,回退为线性。

季节性结论 seasonality.reason

原因含义
accepted按频率得到的周期通过检验(至少 3 个周期,自相关至少 0.3)。
option使用 seasonal_period 指定的周期(至少 2 个周期)。
insufficient_cycles序列覆盖的周期数不足。
weak_autocorrelation滞后一个周期的自相关低于 0.3,或无法计算。
no_seasonal_period该频率没有候选周期。

缺口层级 gaps[].tier

层级含义
T0短缺口:不超过补值上限(3 步)。
T1不超过一个季节周期。
T2不超过 3 个季节周期或序列长度的 5%(取较大者)。
T3更长。