Update crps learning introduction slide + finger alignment
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-30%, 0%);
|
||||||
transition: opacity 0.4s ease-in-out;
|
transition: opacity 0.4s ease-in-out;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,3 +185,13 @@
|
|||||||
doi = {10.48550/arXiv.2201.06808},
|
doi = {10.48550/arXiv.2201.06808},
|
||||||
url = {https://arxiv.org/abs/2201.06808}
|
url = {https://arxiv.org/abs/2201.06808}
|
||||||
}
|
}
|
||||||
|
@article{taylor2023angular,
|
||||||
|
title = {Angular Combining of Forecasts of Probability Distributions},
|
||||||
|
author = {Taylor, James W and Meng, Xiaochun},
|
||||||
|
year = {2023},
|
||||||
|
month = {5},
|
||||||
|
journal = {arXiv preprint arXiv:2305.16735},
|
||||||
|
publisher = {Cornell University},
|
||||||
|
doi = {10.48550/arXiv.2305.16735},
|
||||||
|
url = {https://arxiv.org/abs/2305.16735}
|
||||||
|
}
|
||||||
350
index.qmd
350
index.qmd
@@ -776,6 +776,8 @@ Berrisch, J., & Ziel, F. [-@BERRISCH2023105221]. *Journal of Econometrics*, 237(
|
|||||||
- Horizontal aggregation, vincentization
|
- Horizontal aggregation, vincentization
|
||||||
- Combining across probabilities
|
- Combining across probabilities
|
||||||
- Vertical aggregation
|
- Vertical aggregation
|
||||||
|
- Combining at an angle
|
||||||
|
- @taylor2023angular
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -789,7 +791,7 @@ Berrisch, J., & Ziel, F. [-@BERRISCH2023105221]. *Journal of Econometrics*, 237(
|
|||||||
|
|
||||||
## Time
|
## Time
|
||||||
|
|
||||||
```{r, echo = FALSE, fig.height=6, cache = TRUE}
|
```{r, echo = FALSE, fig.height=8, cache = TRUE}
|
||||||
par(mfrow = c(3, 3), mar = c(2, 2, 2, 2))
|
par(mfrow = c(3, 3), mar = c(2, 2, 2, 2))
|
||||||
set.seed(1)
|
set.seed(1)
|
||||||
# Data
|
# Data
|
||||||
@@ -813,113 +815,234 @@ plot(X[, 1],
|
|||||||
xaxt = "n",
|
xaxt = "n",
|
||||||
yaxt = "n",
|
yaxt = "n",
|
||||||
bty = "n",
|
bty = "n",
|
||||||
col = "#2050f0"
|
col = "#80C684FF"
|
||||||
)
|
)
|
||||||
plot(w[, 1],
|
plot(w[, 1],
|
||||||
lwd = 4, type = "l",
|
lwd = 4, type = "l",
|
||||||
ylim = c(0, 1),
|
ylim = c(0, 1),
|
||||||
xlab = "",
|
xlab = "",
|
||||||
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#2050f0"
|
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#80C684FF"
|
||||||
)
|
)
|
||||||
text(6, 0.5, TeX("$w_1(t)$"), cex = 2, col = "#2050f0")
|
text(6, 0.5, TeX("$w_1(t)$"), cex = 2, col = "#80C684FF")
|
||||||
arrows(13, 0.25, 15, 0.0, , lwd = 4, bty = "n")
|
arrows(13, 0.25, 15, 0.0, , lwd = 4, bty = "n", col = "#414141FF")
|
||||||
plot.new()
|
plot.new()
|
||||||
plot(X[, 2],
|
plot.new()
|
||||||
lwd = 4,
|
plot.new()
|
||||||
type = "l", ylim = c(8, 12),
|
|
||||||
xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "purple"
|
text(6, 0.6, TeX("$w_2(t)$"), cex = 2, col = "#FFD44EFF")
|
||||||
)
|
arrows(13, 0.5, 15, 0.5, , lwd = 4, bty = "n", col = "#414141FF")
|
||||||
plot(w[, 2],
|
plot(rowSums(X * w), lwd = 4, type = "l", xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#D81A5FFF")
|
||||||
lwd = 4, type = "l",
|
|
||||||
ylim = c(0, 1),
|
|
||||||
xlab = "",
|
|
||||||
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "purple"
|
|
||||||
)
|
|
||||||
text(6, 0.6, TeX("$w_2(t)$"), cex = 2, col = "purple")
|
|
||||||
arrows(13, 0.5, 15, 0.5, , lwd = 4, bty = "n")
|
|
||||||
plot(rowSums(X * w), lwd = 4, type = "l", xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#298829")
|
|
||||||
plot(X[, 3],
|
plot(X[, 3],
|
||||||
lwd = 4,
|
lwd = 4,
|
||||||
type = "l", ylim = c(8, 12),
|
type = "l", ylim = c(8, 12),
|
||||||
xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#e423b4"
|
xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#FFD44EFF"
|
||||||
)
|
)
|
||||||
plot(w[, 3],
|
plot(w[, 3],
|
||||||
lwd = 4, type = "l",
|
lwd = 4, type = "l",
|
||||||
ylim = c(0, 1),
|
ylim = c(0, 1),
|
||||||
xlab = "",
|
xlab = "",
|
||||||
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#e423b4"
|
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#FFD44EFF"
|
||||||
)
|
)
|
||||||
text(6, 0.25, TeX("$w_3(t)$"), cex = 2, col = "#e423b4")
|
text(6, 0.25, TeX("$w_3(t)$"), cex = 2, col = "#FFD44EFF")
|
||||||
arrows(13, 0.75, 15, 1, , lwd = 4, bty = "n")
|
arrows(13, 0.75, 15, 1, , lwd = 4, bty = "n", col = "#414141FF")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Distribution
|
## Distribution
|
||||||
|
|
||||||
```{r, echo = FALSE, fig.height=6, cache = TRUE}
|
```{ojs}
|
||||||
par(mfrow = c(3, 3), mar = c(2, 2, 2, 2))
|
d3 = require("d3@7")
|
||||||
set.seed(1)
|
```
|
||||||
# Data
|
|
||||||
X <- matrix(ncol = 3, nrow = 31)
|
|
||||||
|
|
||||||
X[, 1] <- dchisq(0:30, df = 10)
|
```{ojs}
|
||||||
X[, 2] <- dnorm(0:30, mean = 15, sd = 5)
|
cdf_data = FileAttachment("assets/crps_learning/weights_plot/cdf_data.csv").csv({ typed: true })
|
||||||
X[, 3] <- dexp(0:30, 0.2)
|
```
|
||||||
# Weights
|
|
||||||
w <- matrix(ncol = 3, nrow = 31)
|
```{ojs}
|
||||||
w[, 1] <- sin(0.05 * 0:30)
|
function updateChartInner(g, x, y, linesGroup, color, line, data) {
|
||||||
w[, 2] <- cos(0.05 * 0:30)
|
// Update axes with transitions
|
||||||
w[, 3] <- seq(from = -2, 0.25, length.out = 31)^2
|
x.domain(d3.extent(data, d => d.x));
|
||||||
w <- (w / rowSums(w))
|
g.select(".x-axis").transition().duration(1500).call(d3.axisBottom(x).ticks(10));
|
||||||
# Vis
|
y.domain([0, d3.max(data, d => d.y)]);
|
||||||
plot(X[, 1],
|
g.select(".y-axis").transition().duration(1500).call(d3.axisLeft(y).ticks(5));
|
||||||
lwd = 4,
|
|
||||||
type = "l",
|
// Group data by basis function
|
||||||
xlab = "",
|
const dataByFunction = Array.from(d3.group(data, d => d.b));
|
||||||
ylab = "",
|
const keyFn = d => d[0];
|
||||||
xaxt = "n",
|
|
||||||
yaxt = "n",
|
// Update basis function lines
|
||||||
bty = "n",
|
const u = linesGroup.selectAll("path").data(dataByFunction, keyFn);
|
||||||
col = "#2050f0"
|
u.join(
|
||||||
)
|
enter => enter.append("path").attr("fill","none").attr("stroke-width",3)
|
||||||
plot(X[, 2],
|
.attr("stroke", (_, i) => color(i)).attr("d", d => line(d[1].map(pt => ({x: pt.x, y: 0}))))
|
||||||
lwd = 4,
|
.style("opacity",0),
|
||||||
type = "l",
|
update => update,
|
||||||
xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "purple"
|
exit => exit.transition().duration(1000).style("opacity",0).remove()
|
||||||
)
|
)
|
||||||
plot(X[, 3],
|
.transition().duration(1000)
|
||||||
lwd = 4,
|
.attr("d", d => line(d[1]))
|
||||||
type = "l",
|
.attr("stroke", (_, i) => color(i))
|
||||||
xlab = "", ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#e423b4"
|
.style("opacity",1);
|
||||||
)
|
}
|
||||||
plot(w[, 1],
|
|
||||||
lwd = 4, type = "l",
|
chart = {
|
||||||
ylim = c(0, 1),
|
// State variable for selected mu parameter
|
||||||
xlab = "",
|
let selectedMu = 1;
|
||||||
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#2050f0"
|
|
||||||
)
|
const filteredData = () => cdf_data.filter(d =>
|
||||||
text(12, 0.5, TeX("$w_1(x)$"), cex = 2, col = "#2050f0")
|
Math.abs(selectedMu - d.mu) < 0.001
|
||||||
arrows(26, 0.25, 31, 0.0, , lwd = 4, bty = "n")
|
);
|
||||||
plot(w[, 2],
|
|
||||||
lwd = 4, type = "l",
|
const container = d3.create("div")
|
||||||
ylim = c(0, 1),
|
.style("max-width", "none")
|
||||||
xlab = "",
|
.style("width", "100%");
|
||||||
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "purple"
|
|
||||||
)
|
const controlsContainer = container.append("div")
|
||||||
text(15, 0.5, TeX("$w_2(x)$"), cex = 2, col = "purple")
|
.style("display", "flex")
|
||||||
arrows(15, 0.25, 15, 0, , lwd = 4, bty = "n")
|
.style("gap", "20px")
|
||||||
plot(w[, 3],
|
.style("align-items", "center");
|
||||||
lwd = 4, type = "l",
|
|
||||||
ylim = c(0, 1),
|
// Single slider control for mu
|
||||||
xlab = "",
|
const sliderContainer = controlsContainer.append('div')
|
||||||
ylab = "", xaxt = "n", yaxt = "n", bty = "n", col = "#e423b4"
|
.style('display','flex')
|
||||||
)
|
.style('align-items','center')
|
||||||
text(20, 0.5, TeX("$w_3(x)$"), cex = 2, col = "#e423b4")
|
.style('gap','10px')
|
||||||
arrows(5, 0.25, 0, 0, , lwd = 4, bty = "n")
|
.style('flex','1');
|
||||||
plot.new()
|
|
||||||
plot(rowSums(X * w),
|
sliderContainer.append('label')
|
||||||
lwd = 4, type = "l", xlab = "", ylab = "", xaxt = "n",
|
.text('Naive:')
|
||||||
yaxt = "n", bty = "n", col = "#298829"
|
.style('font-size','20px');
|
||||||
)
|
|
||||||
|
const muSlider = sliderContainer.append('input')
|
||||||
|
.attr('type','range')
|
||||||
|
.attr('min', 0)
|
||||||
|
.attr('max', 1)
|
||||||
|
.attr('step', 0.1)
|
||||||
|
.property('value', selectedMu)
|
||||||
|
.on('input', function(event) {
|
||||||
|
selectedMu = +this.value;
|
||||||
|
muDisplay.text(selectedMu.toFixed(1));
|
||||||
|
updateChart(filteredData());
|
||||||
|
})
|
||||||
|
.style('width', '100%')
|
||||||
|
//.style('-webkit-appearance', 'none')
|
||||||
|
.style('appearance', 'none')
|
||||||
|
.style('height', '8px')
|
||||||
|
.style('background', '#BDBDBDFF');
|
||||||
|
|
||||||
|
const muDisplay = sliderContainer.append('span')
|
||||||
|
.text(selectedMu.toFixed(1))
|
||||||
|
.style('font-size','20px');
|
||||||
|
|
||||||
|
// Add Reset button
|
||||||
|
controlsContainer.append('button')
|
||||||
|
.text('Reset')
|
||||||
|
.style('font-size', '20px')
|
||||||
|
.style('align-self', 'center')
|
||||||
|
.style('margin-left', 'auto')
|
||||||
|
.on('click', () => {
|
||||||
|
selectedMu = 0.5;
|
||||||
|
muSlider.property('value', selectedMu);
|
||||||
|
muDisplay.text(selectedMu.toFixed(1));
|
||||||
|
updateChart(filteredData());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Build SVG
|
||||||
|
const width = 600;
|
||||||
|
const height = 450;
|
||||||
|
const margin = {top: 40, right: 20, bottom: 40, left: 40};
|
||||||
|
const innerWidth = width - margin.left - margin.right;
|
||||||
|
const innerHeight = height - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
// Set controls container width to match SVG plot width
|
||||||
|
controlsContainer.style("max-width", "none").style("width", "100%");
|
||||||
|
// Distribute each control evenly and make sliders full-width
|
||||||
|
controlsContainer.selectAll("div").style("flex", "1").style("min-width", "0px");
|
||||||
|
controlsContainer.selectAll("input").style("width", "100%").style("box-sizing", "border-box");
|
||||||
|
|
||||||
|
// Create scales
|
||||||
|
const x = d3.scaleLinear()
|
||||||
|
.range([0, innerWidth]);
|
||||||
|
|
||||||
|
const y = d3.scaleLinear()
|
||||||
|
.range([innerHeight, 0]);
|
||||||
|
|
||||||
|
// Create a color scale for the basis functions
|
||||||
|
const color = d3.scaleOrdinal(["#80C684FF", "#FFD44EFF", "#D81A5FFF"]);
|
||||||
|
|
||||||
|
// Create SVG
|
||||||
|
const svg = d3.create("svg")
|
||||||
|
.attr("width", "100%")
|
||||||
|
.attr("height", "auto")
|
||||||
|
.attr("viewBox", [0, 0, width, height])
|
||||||
|
.attr("preserveAspectRatio", "xMidYMid meet")
|
||||||
|
.attr("style", "max-width: 100%; height: auto;");
|
||||||
|
|
||||||
|
// Create the chart group
|
||||||
|
const g = svg.append("g")
|
||||||
|
.attr("transform", `translate(${margin.left},${margin.top})`);
|
||||||
|
|
||||||
|
// Add axes
|
||||||
|
const xAxis = g.append("g")
|
||||||
|
.attr("transform", `translate(0,${innerHeight})`)
|
||||||
|
.attr("class", "x-axis")
|
||||||
|
.call(d3.axisBottom(x).ticks(10))
|
||||||
|
.style("font-size", "20px");
|
||||||
|
|
||||||
|
const yAxis = g.append("g")
|
||||||
|
.attr("class", "y-axis")
|
||||||
|
.call(d3.axisLeft(y).ticks(5))
|
||||||
|
.style("font-size", "20px");
|
||||||
|
|
||||||
|
// Add a horizontal line at y = 0
|
||||||
|
g.append("line")
|
||||||
|
.attr("x1", 0)
|
||||||
|
.attr("x2", innerWidth)
|
||||||
|
.attr("y1", y(0))
|
||||||
|
.attr("y2", y(0))
|
||||||
|
.attr("stroke", "#000")
|
||||||
|
.attr("stroke-opacity", 0.2);
|
||||||
|
|
||||||
|
// Add gridlines
|
||||||
|
g.append("g")
|
||||||
|
.attr("class", "grid-lines")
|
||||||
|
.selectAll("line")
|
||||||
|
.data(y.ticks(5))
|
||||||
|
.join("line")
|
||||||
|
.attr("x1", 0)
|
||||||
|
.attr("x2", innerWidth)
|
||||||
|
.attr("y1", d => y(d))
|
||||||
|
.attr("y2", d => y(d))
|
||||||
|
.attr("stroke", "#ccc")
|
||||||
|
.attr("stroke-opacity", 0.5);
|
||||||
|
|
||||||
|
// Create a line generator
|
||||||
|
const line = d3.line()
|
||||||
|
.x(d => x(d.x))
|
||||||
|
.y(d => y(d.y))
|
||||||
|
.curve(d3.curveBasis);
|
||||||
|
|
||||||
|
// Group to contain the basis function lines
|
||||||
|
const linesGroup = g.append("g")
|
||||||
|
.attr("class", "basis-functions");
|
||||||
|
|
||||||
|
// Store the current basis functions for transition
|
||||||
|
let currentBasisFunctions = new Map();
|
||||||
|
|
||||||
|
// Function to update the chart with new data
|
||||||
|
function updateChart(data) {
|
||||||
|
updateChartInner(g, x, y, linesGroup, color, line, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the update function
|
||||||
|
svg.node().update = updateChart;
|
||||||
|
|
||||||
|
// Initial render
|
||||||
|
updateChart(filteredData());
|
||||||
|
|
||||||
|
container.node().appendChild(svg.node());
|
||||||
|
return container.node();
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
:::
|
:::
|
||||||
@@ -2586,42 +2709,39 @@ weights_q %>%
|
|||||||
|
|
||||||
## Knot Placement Illustration
|
## Knot Placement Illustration
|
||||||
|
|
||||||
```{ojs}
|
|
||||||
d3 = require("d3@7")
|
|
||||||
```
|
|
||||||
|
|
||||||
```{ojs}
|
```{ojs}
|
||||||
bsplineData = FileAttachment("assets/mcrps_learning/basis_functions.csv").csv({ typed: true })
|
bsplineData = FileAttachment("assets/mcrps_learning/basis_functions.csv").csv({ typed: true })
|
||||||
```
|
```
|
||||||
|
|
||||||
```{ojs}
|
```{ojs}
|
||||||
function updateChartInner(g, x, y, linesGroup, color, line, data) {
|
// Defined above
|
||||||
// Update axes with transitions
|
// function updateChartInner(g, x, y, linesGroup, color, line, data) {
|
||||||
x.domain([0, d3.max(data, d => d.x)]);
|
// // Update axes with transitions
|
||||||
g.select(".x-axis").transition().duration(1500).call(d3.axisBottom(x).ticks(10));
|
// x.domain([0, d3.max(data, d => d.x)]);
|
||||||
y.domain([0, d3.max(data, d => d.y)]);
|
// g.select(".x-axis").transition().duration(1500).call(d3.axisBottom(x).ticks(10));
|
||||||
g.select(".y-axis").transition().duration(1500).call(d3.axisLeft(y).ticks(5));
|
// y.domain([0, d3.max(data, d => d.y)]);
|
||||||
|
// g.select(".y-axis").transition().duration(1500).call(d3.axisLeft(y).ticks(5));
|
||||||
|
|
||||||
// Group data by basis function
|
// // Group data by basis function
|
||||||
const dataByFunction = Array.from(d3.group(data, d => d.b));
|
// const dataByFunction = Array.from(d3.group(data, d => d.b));
|
||||||
const keyFn = d => d[0];
|
// const keyFn = d => d[0];
|
||||||
|
|
||||||
// Update basis function lines
|
// // Update basis function lines
|
||||||
const u = linesGroup.selectAll("path").data(dataByFunction, keyFn);
|
// const u = linesGroup.selectAll("path").data(dataByFunction, keyFn);
|
||||||
u.join(
|
// u.join(
|
||||||
enter => enter.append("path").attr("fill","none").attr("stroke-width",3)
|
// enter => enter.append("path").attr("fill","none").attr("stroke-width",3)
|
||||||
.attr("stroke", (_, i) => color(i)).attr("d", d => line(d[1].map(pt => ({x: pt.x, y: 0}))))
|
// .attr("stroke", (_, i) => color(i)).attr("d", d => line(d[1].map(pt => ({x: pt.x, y: 0}))))
|
||||||
.style("opacity",0),
|
// .style("opacity",0),
|
||||||
update => update,
|
// update => update,
|
||||||
exit => exit.transition().duration(1000).style("opacity",0).remove()
|
// exit => exit.transition().duration(1000).style("opacity",0).remove()
|
||||||
)
|
// )
|
||||||
.transition().duration(1000)
|
// .transition().duration(1000)
|
||||||
.attr("d", d => line(d[1]))
|
// .attr("d", d => line(d[1]))
|
||||||
.attr("stroke", (_, i) => color(i))
|
// .attr("stroke", (_, i) => color(i))
|
||||||
.style("opacity",1);
|
// .style("opacity",1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
chart = {
|
chart0 = {
|
||||||
// State variables for selected parameters
|
// State variables for selected parameters
|
||||||
let selectedMu = 0.5;
|
let selectedMu = 0.5;
|
||||||
let selectedSig = 1;
|
let selectedSig = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user