vincenzocoia / distplyr

Draw powerful insights using distributions with this R package.
https://distplyr.netlify.app/
Other
2 stars 2 forks source link

v0.1.3 remaining #11

Closed vincenzocoia closed 2 years ago

vincenzocoia commented 3 years ago

@toast682 I refined the to-do list we were looking at today. Here's what's relevant:

Poisson distribution:

Baseline functions:

Graft distributions:

More insight about graft_left() and graft_right():

Perhaps class should be: c("graft", "dst"). The object should store (1) the two distributions, (2) the cutoff point at which the distribution will be grafted, and (3) some indication as to whether a distribution has been grafted to the left or the right (or perhaps allow for both possibilities to be stored). As with mix(), grafting two finite distributions should result in a finite distribution. But, unlike mix(), if a graft distribution is further grafted, there is no simplification that can happen around the grafting of the original distributions.

What is a graft distribution?

Imagine taking a cdf, and cutting off its right tail (after some specified point). Replace the cut-out section with another cdf (cdf2), just rescaling cdf2 vertically so that it connects with the original cdf. (We only use cdf2 beyond the cutoff point). This is a right-graft; similar concept applies to a left-graft. Useful for extreme value models.

vincenzocoia commented 3 years ago

Demonstrations of distplyr

Here are a few use cases that should be demonstrated in the paper.

1. Predictive Distributions

Machine learning models tend to produce a single value, typically a mean, to use as a prediction. With distplyr, we can easily produce a predictive distribution. By way of demonstration, consider a kernel smoothing method with one predictor -- although the concept extends to multiple predictors and other machine learning methods.

Here is a predictive distribution of a penguin's flipper length if we know its bill length is 30mm. A Gaussian kernel with standard deviation of 2.5mm is used. Here's the cdf and a 90% prediction interval:

library(palmerpenguins)
library(distplyr)
yhat <- dst_empirical(flipper_length_mm, data = penguins, weights = dnorm(bill_length_mm - 30, sd = 2.5))
plot(yhat, "cdf")

eval_quantile(yhat, at = c(0.05, 0.95))
#> [1] 178 198

Created on 2021-07-02 by the reprex package (v0.3.0)

TO DO:

2. Predictive Distributions as a secondary model

I've encountered a situation where a company's first priority was to predict median house price as best as they could, so they fit a machine learning model that predicted the median. By way of demonstration, we can do the same thing, but just with a simple machine learning model, like kNN (which works by taking the k nearest neighbours to some x value of interest, and then taking the median y value). We don't have to worry about optimizing k, because it's just a demo.

TO DO (this part does not require distplyr):

As a secondary goal, the company wanted a prediction interval, and it was determined that fitting a lognormal distribution for Y (given X) was desirable. Although distplyr currently isn't fully up to this task, it can handle a simple version of this task, in the case where the second parameter of the lognormal distribution ("log variance") is constant -- we can calculate the variance of the residuals on the log scale. Here's how:

TO DO:

3. Predictive distribution from a GLM (like Poisson Regression)

There's a technique called Poisson regression, useful whenever the Y variable is a count variable. It fits the mean of Y as an exponential function of X, while also assuming that the distribution of Y (given X) is a Poisson distribution. To demonstrate a predictive distribution here, we'd just have to use a Poisson regression model to make predictions of the mean, and plug those mean predictions into dst_pois().

TO DO:

Others

Some other ideas:

vincenzocoia commented 3 years ago

enframing multiple distributions

I've come across wanting to enframe many distributions at once, but the suite of enframe_ functions only allow one distribution.

Here's an idea: enframe(d1, d2, d3, at = 1:10), making the first argument of the enframe_ functions ....

NOTE: allow for !!! input by first quoting: ellipsis <- rlang::quos(...); then evaluating: rlang::eval_tidy(ellipsis).

vincenzocoia commented 2 years ago

This thread has become a dumping ground, but also, a lot of the things on here have been taken care of.