You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解读feasts中feat_stl生成的seasonal_trough_year?

关于seasonal_trough_year特征取值为0的解读

问题背景

原本认为月度时间序列中seasonal_trough_year的取值应为1-12(对应1月到12月),但在处理FRED的20岁及以上男女劳动力参与率数据时,部分结果出现了0值,而对应时间块的谷值预期应为12月(取值12)。

复现代码

library(fpp3)
library(purrr)
library(fredr)

# 从https://fred.stlouisfed.org/docs/api/api_key.html获取API密钥

fred_df_raw <- c("men >= age 20" = "LNU01300025",
                 "women >= age 20" = "LNU01300026") |> 
  map_dfr(fredr, .id = "series")

fred_df <- fred_df_raw |> 
  select(series, date, value) |> 
  rename(participation_rate = value) |> 
  mutate(date = yearmonth(date)) |> 
  as_tsibble(key = series, index = date)

fred_df |> 
  model(stl = STL(participation_rate ~ trend() + season())) |> 
  components() |>
  autoplot()

fred_tile <- tile_tsibble(fred_df, .size = 4*12) |> 
  arrange(series, .id) |> 
  group_by(series, .id) |> 
  filter(n() == 4*12) |> # 仅保留完整的4年时间块
  ungroup()

fred_tile_features <- fred_tile |>
  features(participation_rate, feature_set(pkgs = "feasts")) 

fred_tile_features |> 
  distinct(seasonal_trough_year)

fred_tile_features |> 
  distinct(seasonal_peak_year)

fred_tile_features |> 
  select(series, .id, seasonal_peak_year, seasonal_trough_year) |> 
  filter(seasonal_trough_year == 0)

fred_tile |>
  filter(.id == 18,
         series == "men >= age 20") |> 
  autoplot()

# 预期谷值应为12月
fred_tile |>
  filter(.id == 18,
         series == "men >= age 20") |> 
  model(stl = STL(participation_rate ~ trend() + season())) |> 
  components() |> 
  ggplot(aes(date, season_year)) +
  geom_line() +
  geom_point() +
  geom_point(aes(color = month(date, abbr = TRUE, label = TRUE) == "Dec"))

对应时间块的季节性成分可视化

标注12月数据点的季节性成分折线图

《FPP3》中相关特征定义

  • seasonal_peak_year:季节性成分峰值出现的时间(对应月份或季度),用于体现季节性特征。例如澳大利亚旅游数据中,若峰值在第3季度,说明冬季是旅游旺季;若在第1季度,则夏季更受欢迎。
  • seasonal_trough_year:季节性成分谷值出现的时间(对应月份或季度)。

取值为0的原因分析

当seasonal_trough_year返回0时,核心原因是该时间块内的季节性成分不存在唯一的谷值:

  1. 可能存在多个月份的季节性成分数值相等且同为最小值,算法无法确定唯一的谷值月份,因此返回0;
  2. 以.id=18的男性劳动力参与率数据为例,可通过以下代码验证每个月份的平均季节性值是否存在多个最小值:
fred_tile |>
  filter(.id == 18, series == "men >= age 20") |>
  model(stl = STL(participation_rate ~ trend() + season())) |>
  components() |>
  mutate(month = month(date)) |>
  group_by(month) |>
  summarise(avg_season = mean(season_year)) |>
  arrange(avg_season)

若输出中有多个月份的avg_season数值完全相同且为最小,就会触发seasonal_trough_year返回0。

内容的提问来源于stack exchange,提问作者Conor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:55:08