Skip to content

Commit b18d4a0

Browse files
wagnerlmichaelTimCookCountyDSwrridgeway
authored
Add subset option for faster iteration (#154)
* Upload first draft * Revert upload toggle * Toggle subset for testing * Toggle subset * Guard against low sale volume * Lint * Make names simpler * Adjust lock file * Update dvc * enable subset for bartch * Fix breaks * Update lock and params * Add bold and italics * Revert lock file * Update params.yaml set subset enable to true to test * Update params.yaml Changed the default for subset enable back to false --------- Co-authored-by: TimCookCountyDS <Timothy.Sparer@cookcountyil.gov> Co-authored-by: William Ridgeway <10358980+wrridgeway@users.noreply.github.com>
1 parent 32d6195 commit b18d4a0

5 files changed

Lines changed: 76 additions & 20 deletions

File tree

params.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ input:
7474
weight_min: 0.1
7575
weight_max: 1.0
7676

77+
# Parameters for running the pipeline with a stratified subset of training
78+
# data. Useful for faster development iterations. The subset is stratified
79+
# by year, township, and class to maintain representation across categories
80+
subset:
81+
# Whether to use a subset of the training data instead of the full dataset
82+
enable: false
83+
84+
# Fraction of the training data to keep (between 0 and 1)
85+
fraction: 0.25
86+
7787

7888
# Cross-validation -------------------------------------------------------------
7989

pipeline/00-ingest.R

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,25 @@ training_data_clean <- training_data_clean %>%
615615
as_tibble() %>%
616616
write_parquet(paths$input$training$local)
617617

618+
# Reproducible via the model seed and the subset fraction params tracked by DVC
619+
if (params$input$subset$enable) {
620+
set.seed(params$model$seed)
621+
622+
message(
623+
"Creating stratified training data subset ",
624+
"(fraction: ", params$input$subset$fraction, ")"
625+
)
626+
627+
training_data_clean %>%
628+
group_by(time_sale_year, meta_township_code, meta_class) %>%
629+
group_modify(~ {
630+
n_sample <- max(1L, ceiling(nrow(.x) * params$input$subset$fraction))
631+
slice_sample(.x, n = n_sample)
632+
}) %>%
633+
ungroup() %>%
634+
write_parquet(paths$input$training$local)
635+
}
636+
618637
assessment_data_clean <- assessment_data_clean %>%
619638
left_join(
620639
bldg_rolling_means_dt %>%

pipeline/05-finalize.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ metadata <- tibble::tibble(
6969
input_min_sale_year = params$input$min_sale_year,
7070
input_max_sale_year = params$input$max_sale_year,
7171
input_n_years_prior = params$input$n_years_prior,
72+
input_subset_enable = params$input$subset$enable,
73+
input_subset_fraction = params$input$subset$fraction,
7274
input_building_weight_min = params$input$building$weight_min,
7375
input_building_weight_max = params$input$building$weight_max,
7476
ratio_study_far_year = params$ratio_study$far_year,

reports/performance/_model.qmd

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22
source("../_setup.R")
33
```
44

5+
```{r _subset_warning, results='asis'}
6+
if (isTRUE(metadata$input_subset_enable)) {
7+
cat(paste0(
8+
"\n\n::: {.callout-warning}\n",
9+
"## Subset Mode Active\n\n",
10+
"This model was trained on a **",
11+
scales::percent(metadata$input_subset_fraction, accuracy = 1),
12+
" stratified subset** of the training data. ",
13+
"Test set performance metrics are based on the subset and may not ",
14+
"reflect full model performance. Assessment set performance uses the ",
15+
"full assessment data.\n",
16+
":::\n\n"
17+
))
18+
}
19+
```
20+
521
# Model
622

723
The following document describes performance for ```r metadata$run_id```, a ```r model_parameter_final$engine``` model built to re-assess the ```r metadata$assessment_triad``` triad in ```r metadata$assessment_year```. The document uses four sets of data to measure performance:
@@ -188,7 +204,7 @@ model_township_stats_assessment_df %>%
188204

189205
:::
190206

191-
Prior year values (latest stage available for each year) compared to target year sales and estimates.
207+
Prior year values (latest stage available for each year) compared to ***target year*** sales and estimates.
192208
The median percent change is comparing the nearest assessed value to the estimated value.
193209
PIN and sale counts include residential, regression-class properties only.
194210

@@ -281,9 +297,11 @@ model_ratio_distribution_df <- model_performance_test_quantile_merged %>%
281297
)
282298
)
283299
284-
model_ratio_distribution_labels <- model_ratio_distribution_df %>%
300+
model_ratio_distribution <- model_ratio_distribution_df %>%
285301
filter(stage == "Main Model") %>%
286-
pull(custom_label)
302+
arrange(quantile)
303+
model_ratio_distribution_breaks <- model_ratio_distribution$quantile
304+
model_ratio_distribution_labels <- model_ratio_distribution$custom_label
287305
288306
# Manually set axes to highest and lowest contained in the data
289307
model_ratio_distribution_lims <- model_performance_test_quantile_merged %>%
@@ -318,7 +336,10 @@ model_ratio_distribution_triad_plot <- ggplot(
318336
) +
319337
geom_hline(yintercept = 1, linetype = "dashed", color = "darkgray") +
320338
labs(x = "Decile", y = "Median Ratio", color = "Model Type") +
321-
scale_x_continuous(breaks = 1:10, labels = model_ratio_distribution_labels) +
339+
scale_x_continuous(
340+
breaks = model_ratio_distribution_breaks,
341+
labels = model_ratio_distribution_labels
342+
) +
322343
scale_color_manual(
323344
values = c(
324345
"Main Model" = plot_colors$main,
@@ -366,9 +387,11 @@ generate_model_ratio_township_graph <- function(data, township, lims) {
366387
)
367388
)
368389
369-
data_to_plot_labels <- data_to_plot %>%
390+
data_to_plot_main <- data_to_plot %>%
370391
filter(stage == "Main Model") %>%
371-
pull(custom_label)
392+
arrange(quantile)
393+
data_to_plot_breaks <- data_to_plot_main$quantile
394+
data_to_plot_labels <- data_to_plot_main$custom_label
372395
373396
ggplot(
374397
data = data_to_plot,
@@ -400,7 +423,10 @@ generate_model_ratio_township_graph <- function(data, township, lims) {
400423
lims$min_value,
401424
lims$max_value + 0.08
402425
)) +
403-
scale_x_continuous(breaks = 1:10, labels = data_to_plot_labels) +
426+
scale_x_continuous(
427+
breaks = data_to_plot_breaks,
428+
labels = data_to_plot_labels
429+
) +
404430
scale_color_manual(
405431
values = c(
406432
"Main Model" = plot_colors$main,
@@ -937,11 +963,10 @@ model_big_misses_test <- test_card %>%
937963
) %>%
938964
mutate(
939965
Difference = abs(`Sale Price` - `Est. FMV`),
940-
`Qnt.` = cut(
941-
`Sale Price`,
942-
breaks = quantile(`Sale Price`, probs = c(0, 0.25, 0.5, 0.75, 1)),
943-
labels = c("Q1", "Q2", "Q3", "Q4"),
944-
include.lowest = TRUE
966+
`Qnt.` = factor(
967+
ntile(`Sale Price`, n = 4),
968+
levels = 1:4,
969+
labels = c("Q1", "Q2", "Q3", "Q4")
945970
),
946971
.by = Town
947972
) %>%
@@ -995,11 +1020,10 @@ model_big_misses_assessment <- assessment_pin %>%
9951020
) %>%
9961021
mutate(
9971022
Difference = abs(`Sale 1 Price` - `Est. FMV`),
998-
`Qnt.` = cut(
999-
`Sale 1 Price`,
1000-
breaks = quantile(`Sale 1 Price`, probs = c(0, 0.25, 0.5, 0.75, 1)),
1001-
labels = c("Q1", "Q2", "Q3", "Q4"),
1002-
include.lowest = TRUE
1023+
`Qnt.` = factor(
1024+
ntile(`Sale 1 Price`, n = 4),
1025+
levels = 1:4,
1026+
labels = c("Q1", "Q2", "Q3", "Q4")
10031027
),
10041028
.by = Town
10051029
) %>%

reports/performance/_outliers.qmd

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,10 @@ outliers_ratio_comparison <- training_data_outlier_analysis %>%
300300
ungroup() %>%
301301
distinct(meta_township_name, percent, above_below, triad)
302302
303-
axis_limit_outlier_ratio_comparison <- outliers_ratio_comparison %>%
304-
slice_max(percent, n = 1) %>%
305-
pull(percent)
303+
axis_limit_outlier_ratio_comparison <- max(
304+
outliers_ratio_comparison$percent,
305+
na.rm = TRUE
306+
)
306307
307308
outliers_ratio_comparison %>%
308309
ggplot(aes(x = reorder(meta_township_name, percent), y = percent)) +

0 commit comments

Comments
 (0)