如何解读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"))
对应时间块的季节性成分可视化

《FPP3》中相关特征定义
seasonal_peak_year:季节性成分峰值出现的时间(对应月份或季度),用于体现季节性特征。例如澳大利亚旅游数据中,若峰值在第3季度,说明冬季是旅游旺季;若在第1季度,则夏季更受欢迎。seasonal_trough_year:季节性成分谷值出现的时间(对应月份或季度)。
取值为0的原因分析
当seasonal_trough_year返回0时,核心原因是该时间块内的季节性成分不存在唯一的谷值:
- 可能存在多个月份的季节性成分数值相等且同为最小值,算法无法确定唯一的谷值月份,因此返回0;
- 以
.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
相关产品推荐
相关产品推荐

