library(tidyverse)
library(lubridate)
library(viridis)
library(cowplot)
library(latex2exp)
library(plotly)
library(ggallin)
load("res_premium.RData")

We test what happens to the R^2 if we remove the negative part of predictions. (akin to ReLU activation in neural networks).

prediction_threshold <- 3

g1 <- res %>% 
    filter(pred < prediction_threshold, pred > (-0.99)) %>%
    mutate(pred_const = if_else(pred < 0, 0, pred),
           TT = as.factor(TT)) %>%
    group_by(x, y, TT) %>%              # Grouping variables
    summarize(mse = mean(e2, na.rm = T),
              v_y = var(y_test, na.rm = T),
              mse_const = mean((pred_const-y_test)^2), na.rm = T) %>%
    mutate(r2 = 1-mse/v_y) %>%
    ggplot() + 
    geom_point(aes(x = r2, y = 1-mse_const/v_y, color = TT), size = 0.7) +
    stat_function(fun = function(x)(x)) +
    #xlim(0,0.3) + ylim(0,0.3) +
    theme(legend.position = c(0.8,0.3)) +
    scale_x_continuous(trans = pseudolog10_trans) +
    scale_y_continuous(trans = pseudolog10_trans) +
    scale_color_viridis(begin = 0.18, end = 0.98, discrete = T, option = "B") +
    ylab("OOS R squared with constraint (log-scale)") +
    xlab("OOS R squared (log-scale)")
`summarise()` regrouping output by 'x', 'y' (override with `.groups` argument)
g2 <- res %>% 
    filter(pred < prediction_threshold, pred > (-0.99)) %>%
    mutate(pred_const = if_else(pred < 0, 0, pred)) %>%
    group_by(x, y, TT) %>%              # Grouping variables
    summarize(mse = mean(e2, na.rm = T),
              v_y = var(y_test, na.rm = T),
              r_x = mean(rho_x, na.rm = T),
              mse_const = mean((pred_const-y_test)^2), na.rm = T) %>%
    ggplot() + 
    geom_point(aes(x = 1-mse/v_y, y = 1-mse_const/v_y, color = r_x), size = 0.5) +
    stat_function(fun = function(x)(x)) +
    #xlim(0,0.3) + ylim(0,0.3) +
    theme(legend.position = c(0.8,0.3)) +
    scale_x_continuous(trans = pseudolog10_trans) +
    scale_y_continuous(trans = pseudolog10_trans) +
    scale_color_viridis(begin = 0.18, end = 0.98, direction = -1) +
    ylab("OOS R squared with constraint (log-scale)") +
    xlab("OOS R squared (log-scale)")
`summarise()` regrouping output by 'x', 'y' (override with `.groups` argument)
plot_grid(g1, g2, nrow=1)

# ggsave("constraints.pdf", width = 7, height = 4)
res %>% 
    filter(pred < prediction_threshold, pred > (-0.99)) %>%
    mutate(pred_const = if_else(pred < 0, 0, pred)) %>%
    group_by(x, y, TT) %>%              # Grouping variables
    summarize(mse = mean(e2),
              mse_const = mean((pred_const-y_test)^2)) %>%
    ungroup() %>%
    summarise(m = mean(mse),
              m_const = mean(mse_const))
`summarise()` regrouping output by 'x', 'y' (override with `.groups` argument)

Below, we look at the histogram of the MSE (raw versus constrained predictions).

prediction_threshold <- 3

res %>% 
    filter(pred < prediction_threshold, pred > (-0.99)) %>%
    mutate(pred_const = if_else(pred < 0, 0, pred)) %>%
    group_by(x, y, TT) %>%              # Grouping variables
    summarize(mse = mean(e2),
              mse_const = mean((pred_const-y_test)^2)) %>%
    select(mse, mse_const) %>%
    pivot_longer(cols = c("mse", "mse_const"), names_to = "type", values_to = "mse") %>%
    ggplot(aes(x = mse, fill = type)) + 
    geom_histogram(position = "dodge") 
`summarise()` regrouping output by 'x', 'y' (override with `.groups` argument)
Adding missing grouping variables: `x`, `y`

LS0tCm91dHB1dDogaHRtbF9ub3RlYm9vawp0aXRsZTogIlZhbHVlIG9mIGVjb25vbWljIGNvbnN0cmFpbnRzIgotLS0KCgpgYGB7ciwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KGxhdGV4MmV4cCkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ2dhbGxpbikKbG9hZCgicmVzX3ByZW1pdW0uUkRhdGEiKQpgYGAKCldlIHRlc3Qgd2hhdCBoYXBwZW5zIHRvIHRoZSBSXjIgaWYgd2UgcmVtb3ZlIHRoZSBuZWdhdGl2ZSBwYXJ0IG9mIHByZWRpY3Rpb25zLiAoYWtpbiB0byBSZUxVIGFjdGl2YXRpb24gaW4gbmV1cmFsIG5ldHdvcmtzKS4KCmBgYHtyfQpwcmVkaWN0aW9uX3RocmVzaG9sZCA8LSAzCgpnMSA8LSByZXMgJT4lIAogICAgZmlsdGVyKHByZWQgPCBwcmVkaWN0aW9uX3RocmVzaG9sZCwgcHJlZCA+ICgtMC45OSkpICU+JQogICAgbXV0YXRlKHByZWRfY29uc3QgPSBpZl9lbHNlKHByZWQgPCAwLCAwLCBwcmVkKSwKICAgICAgICAgICBUVCA9IGFzLmZhY3RvcihUVCkpICU+JQogICAgZ3JvdXBfYnkoeCwgeSwgVFQpICU+JSAgICAgICAgICAgICAgIyBHcm91cGluZyB2YXJpYWJsZXMKICAgIHN1bW1hcml6ZShtc2UgPSBtZWFuKGUyLCBuYS5ybSA9IFQpLAogICAgICAgICAgICAgIHZfeSA9IHZhcih5X3Rlc3QsIG5hLnJtID0gVCksCiAgICAgICAgICAgICAgbXNlX2NvbnN0ID0gbWVhbigocHJlZF9jb25zdC15X3Rlc3QpXjIpLCBuYS5ybSA9IFQpICU+JQogICAgbXV0YXRlKHIyID0gMS1tc2Uvdl95KSAlPiUKICAgIGdncGxvdCgpICsgCiAgICBnZW9tX3BvaW50KGFlcyh4ID0gcjIsIHkgPSAxLW1zZV9jb25zdC92X3ksIGNvbG9yID0gVFQpLCBzaXplID0gMC43KSArCiAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpKHgpKSArCiAgICAjeGxpbSgwLDAuMykgKyB5bGltKDAsMC4zKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuOCwwLjMpKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSBwc2V1ZG9sb2cxMF90cmFucykgKwogICAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gcHNldWRvbG9nMTBfdHJhbnMpICsKICAgIHNjYWxlX2NvbG9yX3ZpcmlkaXMoYmVnaW4gPSAwLjE4LCBlbmQgPSAwLjk4LCBkaXNjcmV0ZSA9IFQsIG9wdGlvbiA9ICJCIikgKwogICAgeWxhYigiT09TIFIgc3F1YXJlZCB3aXRoIGNvbnN0cmFpbnQgKGxvZy1zY2FsZSkiKSArCiAgICB4bGFiKCJPT1MgUiBzcXVhcmVkIChsb2ctc2NhbGUpIikKZzIgPC0gcmVzICU+JSAKICAgIGZpbHRlcihwcmVkIDwgcHJlZGljdGlvbl90aHJlc2hvbGQsIHByZWQgPiAoLTAuOTkpKSAlPiUKICAgIG11dGF0ZShwcmVkX2NvbnN0ID0gaWZfZWxzZShwcmVkIDwgMCwgMCwgcHJlZCkpICU+JQogICAgZ3JvdXBfYnkoeCwgeSwgVFQpICU+JSAgICAgICAgICAgICAgIyBHcm91cGluZyB2YXJpYWJsZXMKICAgIHN1bW1hcml6ZShtc2UgPSBtZWFuKGUyLCBuYS5ybSA9IFQpLAogICAgICAgICAgICAgIHZfeSA9IHZhcih5X3Rlc3QsIG5hLnJtID0gVCksCiAgICAgICAgICAgICAgcl94ID0gbWVhbihyaG9feCwgbmEucm0gPSBUKSwKICAgICAgICAgICAgICBtc2VfY29uc3QgPSBtZWFuKChwcmVkX2NvbnN0LXlfdGVzdCleMiksIG5hLnJtID0gVCkgJT4lCiAgICBnZ3Bsb3QoKSArIAogICAgZ2VvbV9wb2ludChhZXMoeCA9IDEtbXNlL3ZfeSwgeSA9IDEtbXNlX2NvbnN0L3ZfeSwgY29sb3IgPSByX3gpLCBzaXplID0gMC41KSArCiAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpKHgpKSArCiAgICAjeGxpbSgwLDAuMykgKyB5bGltKDAsMC4zKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuOCwwLjMpKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSBwc2V1ZG9sb2cxMF90cmFucykgKwogICAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gcHNldWRvbG9nMTBfdHJhbnMpICsKICAgIHNjYWxlX2NvbG9yX3ZpcmlkaXMoYmVnaW4gPSAwLjE4LCBlbmQgPSAwLjk4LCBkaXJlY3Rpb24gPSAtMSkgKwogICAgeWxhYigiT09TIFIgc3F1YXJlZCB3aXRoIGNvbnN0cmFpbnQgKGxvZy1zY2FsZSkiKSArCiAgICB4bGFiKCJPT1MgUiBzcXVhcmVkIChsb2ctc2NhbGUpIikKcGxvdF9ncmlkKGcxLCBnMiwgbnJvdz0xKQojIGdnc2F2ZSgiY29uc3RyYWludHMucGRmIiwgd2lkdGggPSA3LCBoZWlnaHQgPSA0KQpgYGAKCgoKCmBgYHtyfQpyZXMgJT4lIAogICAgZmlsdGVyKHByZWQgPCBwcmVkaWN0aW9uX3RocmVzaG9sZCwgcHJlZCA+ICgtMC45OSkpICU+JQogICAgbXV0YXRlKHByZWRfY29uc3QgPSBpZl9lbHNlKHByZWQgPCAwLCAwLCBwcmVkKSkgJT4lCiAgICBncm91cF9ieSh4LCB5LCBUVCkgJT4lICAgICAgICAgICAgICAjIEdyb3VwaW5nIHZhcmlhYmxlcwogICAgc3VtbWFyaXplKG1zZSA9IG1lYW4oZTIpLAogICAgICAgICAgICAgIG1zZV9jb25zdCA9IG1lYW4oKHByZWRfY29uc3QteV90ZXN0KV4yKSkgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBzdW1tYXJpc2UobSA9IG1lYW4obXNlKSwKICAgICAgICAgICAgICBtX2NvbnN0ID0gbWVhbihtc2VfY29uc3QpKQpgYGAKCkJlbG93LCB3ZSBsb29rIGF0IHRoZSBoaXN0b2dyYW0gb2YgdGhlIE1TRSAocmF3IHZlcnN1cyBjb25zdHJhaW5lZCBwcmVkaWN0aW9ucykuCgpgYGB7cn0KcHJlZGljdGlvbl90aHJlc2hvbGQgPC0gMwoKcmVzICU+JSAKICAgIGZpbHRlcihwcmVkIDwgcHJlZGljdGlvbl90aHJlc2hvbGQsIHByZWQgPiAoLTAuOTkpKSAlPiUKICAgIG11dGF0ZShwcmVkX2NvbnN0ID0gaWZfZWxzZShwcmVkIDwgMCwgMCwgcHJlZCkpICU+JQogICAgZ3JvdXBfYnkoeCwgeSwgVFQpICU+JSAgICAgICAgICAgICAgIyBHcm91cGluZyB2YXJpYWJsZXMKICAgIHN1bW1hcml6ZShtc2UgPSBtZWFuKGUyKSwKICAgICAgICAgICAgICBtc2VfY29uc3QgPSBtZWFuKChwcmVkX2NvbnN0LXlfdGVzdCleMikpICU+JQogICAgc2VsZWN0KG1zZSwgbXNlX2NvbnN0KSAlPiUKICAgIHBpdm90X2xvbmdlcihjb2xzID0gYygibXNlIiwgIm1zZV9jb25zdCIpLCBuYW1lc190byA9ICJ0eXBlIiwgdmFsdWVzX3RvID0gIm1zZSIpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gbXNlLCBmaWxsID0gdHlwZSkpICsgCiAgICBnZW9tX2hpc3RvZ3JhbShwb3NpdGlvbiA9ICJkb2RnZSIpIApgYGA=