library(dplyr)
library(tibble)
library(stringr)
library(readr)
library(glue)
library(knitr)
validation_results <- read_csv(
"data/inaugural/next-token-validation.csv",
na = c("", "NA"),
col_types = cols(
split = col_character(),
model = col_character(),
context_tokens = col_integer(),
interpolation_strength = col_double(),
next_token_rows = col_integer(),
oov_target_share = col_double(),
seen_context_share = col_double(),
mean_log_loss = col_double(),
perplexity = col_double(),
selected = col_logical(),
selection_reason = col_character()
)
)
test_results <- read_csv(
"data/inaugural/next-token-test.csv",
na = c("", "NA"),
col_types = cols(
split = col_character(),
model = col_character(),
context_tokens = col_integer(),
interpolation_strength = col_double(),
next_token_rows = col_integer(),
oov_target_share = col_double(),
seen_context_share = col_double(),
mean_log_loss = col_double(),
perplexity = col_double(),
top_1_accuracy = col_double(),
role = col_character()
)
)
test_by_speech <- read_csv(
"data/inaugural/next-token-test-by-speech.csv",
na = character(),
col_types = cols(
speech_id = col_character(),
next_token_rows = col_integer(),
model = col_character(),
perplexity = col_double()
)
)
validation_trigram <- validation_results |>
filter(selected)
test_uniform <- test_results |>
filter(model == "uniform")
test_unigram <- test_results |>
filter(model == "unigram")
test_trigram <- test_results |>
filter(model == "trigram")
perplexity_reduction <- 1 -
test_trigram$perplexity / test_unigram$perplexity
paired_test <- test_by_speech |>
select(speech_id, model, perplexity) |>
tidyr::pivot_wider(
names_from = model,
values_from = perplexity
) |>
summarise(
test_speeches = n(),
trigram_wins = sum(trigram < unigram),
ties = sum(trigram == unigram),
trigram_losses = sum(trigram > unigram)
)
evidence_ledger <- tribble(
~evidence_id, ~source_artifact, ~split, ~measure, ~value, ~unit, ~limit,
"E1", "next-token-validation.csv", "validation", "trigram perplexity",
validation_trigram$perplexity, "perplexity",
"trigram with interpolation strength 100; minimum across 13 candidates",
"E2", "next-token-test.csv", "test", "uniform perplexity",
test_uniform$perplexity, "perplexity",
"2,500 equally likely vocabulary items",
"E3", "next-token-test.csv", "test", "unigram perplexity",
test_unigram$perplexity, "perplexity",
"predeclared baseline under the same tokens",
"E4", "next-token-test.csv", "test", "trigram perplexity",
test_trigram$perplexity, "perplexity",
"selected on validation speeches",
"E5", "next-token-test.csv", "test", "trigram top-1 accuracy",
test_trigram$top_1_accuracy, "share",
"one highest-probability guess per row",
"E6", "next-token-test-by-speech.csv", "test", "speech-level wins",
paired_test$trigram_wins, "speeches",
"paired against the unigram on the same test speeches",
"E7", "next-token-test.csv", "test", "targets mapped to <unk>",
test_trigram$oov_target_share, "share",
"the original unseen token is not identified",
"E8", "data-raw/build-next-token-study.R", "study", "token rule",
NA_real_, "setup",
"lowercase ASCII alphabetic tokens; training-only vocabulary",
"E9", "R/inaugural-corpus.R", "study", "corpus grain",
NA_real_, "setup",
"reconstructed inaugural paragraphs; paragraph-bounded contexts"
)
kable(
evidence_ledger |>
mutate(
value = case_when(
unit == "share" ~ sprintf("%.1f%%", 100 * value),
unit == "speeches" ~ as.character(as.integer(value)),
unit == "setup" ~ "documented",
TRUE ~ sprintf("%.1f", value)
)
),
col.names = c(
"Evidence ID",
"Source artifact",
"Split",
"Measure",
"Value",
"Unit",
"Limit"
),
caption = "Evidence records available to the report",
row.names = FALSE
)