Skip to content
Snippets Groups Projects
quantile_fit.R 4.53 KiB
Newer Older
  • Learn to ignore specific revisions
  • #' @title quantile_fit
    #'
    #' @description This function plots the quantiles
    #' @param Lfor List of the data needed to plot
    #' @export
    #' @examples
    #' plotprob()
    
    quantile_fit <- function(prm, model, q, data, printout = TRUE, returnanalysis = TRUE, multistep = NA){
    
        if(printout){
            message("----------------")
            if(is.na(prm[1])){
                message("prm=NA, so current parameters are used.")
            }else{
                print_to_message(prm)
            }
        }
        
        # First insert the prm into the model input expressions
        model$insert_prm(prm)
    
    
    
    hgb's avatar
    hgb committed
        ## Compute the effective memory of lambda, the window size
        model$n_in_bin <- round(2*(1/(1-model$regprm$lambda)))
        ## If the effective memory is less then the cold start window, then set it to the cold start window.
        ## HGB 11/02/2025: Unsure if this is correct
    
        if(model$n_in_bin < model$N1){
            model$n_in_bin = model$N1 + 1
        }
    
        ## Transform the data
        
        # Since rls_fit is run from scratch, the init the stored inputs data (only needed when running iteratively)
        #model$datatr <- NA
        #model$yAR <- NA
    
    hgb's avatar
    hgb committed
    
    
        # Reset the model state (e.g. inputs state, stored iterative data, ...)
        model$reset_state()
    
        if(q %in% as.numeric(sub(".*q", "", names(model$info)))){
            model$info <- list()
            model$beta <- list()
        }
    
    
        # Generate the 2nd stage inputs (i.e. the transformed data)
        model$datatr <- model$transform_data(data)
        ## Fit the cold start
        #X <- data.frame(matrix(unlist(model$datatr), ncol = length(model$datatr), byrow = F))
        #colnames(X) <- names(model$datatr)
        Ypred <- NULL
    
        for(k in model$kseq){
    
    hgb's avatar
    hgb committed
            # cat("horizon :", k, "\n")
            # cat("n_in_bin :", model$n_in_bin, "\n")
    
            ## Setup the design matrix for k step
            X <- as.data.frame(subset(model$datatr, kseq=k))
    
    hgb's avatar
    hgb committed
            ## Lag them to match to the output, so the input forecast matches the output.
    
            X <- onlineforecast:::lagdf.matrix(X, k)
            X$y <- data[[model$output]]
            
    
    hgb's avatar
    hgb committed
            if (k > 0) {
                X <- X[-(1:k), ]
            }
    
            fit <- rq(paste("y ~ -1 + ", paste(names(X[, -which(names(X) %in% c("y"))]),  collapse =  " + "), sep = ""), tau = q, data = X[1:(model$N1-k),])
    
    hgb's avatar
    hgb committed
                ## Fill it from start (index 1) to the end of the cold start
                beta <- fit$coefficients
                model$beta[[paste0("q", q)]][[paste0("k", k)]] <- matrix(beta, nrow = model$N1, ncol = model$K, byrow = T)
    
                
                r <- as.matrix(fit$residuals, ncol = length(q))
                for(i in 1:dim(r)[2]){
                    ## So these guys are the zeros, or lie on the constraints?
                    IdxNull <- which(abs(r[,i]) < 10^-2)
                    r[IdxNull, i] <- 0
                }
                ### Initialization of algorithm
                model$info[[paste0("q", q)]][[paste0("k", k)]] <- rq_init_cpp(X = as.matrix(X[1:(model$N1-k),]),
                                                                                R = r,
                                                                                beta = beta,
                                                                                n = model$N1-k,
                                                                                weights = model$regprm$lambda^rev(seq(1,length(r),1)))
    
                ## The quantile estimation
                Ypredres <- update_rq(as.matrix(X[(model$N1+1 - k):nrow(X),]), q, k, model = model)
                ### Get the results, Ypred, loss
                Ypred <- cbind(Ypred, Ypredres)
        }
        
        ## Compute the loss function, maybe the residuals are compute in different place
        loss <- sapply(model$kseq, function(i)  pinball_loss(r = model$info[[paste0("q", q)]][[paste0("k", i)]]$R[data$scoreperiod[(i+1):length(data$scoreperiod)]], q))
        model$Ypred <- Ypred
    
    hgb's avatar
    hgb committed
        
    
        if(!returnanalysis){
            #Yhat <- quantile_prediction(model = model, multistep = model$kseq)
            cat("Quantile, tau:", q, "\n")
            cat("the loss: ", loss, "\n")
            val <- sum(loss)
            if(printout){
                print_to_message(c(loss,sum=val))
            }        
            return(val)
        } else{
            val <- sum(loss)
            if(printout){
                print_to_message(c(loss,sum=val))
            }     
            ## Get predictions
            #Yhat <- model$getPred(multistep = multistep)
            #Yhat <- quantile_prediction(model = model, multistep = multistep)
    
            #invisible(structure(list(Yhat = Yhat, model = model, data = data, scoreval = loss), class = c("quantile_fit")))
        }
    }
    
    
    print_to_message <- function(...) {
        message(paste(utils::capture.output(print(...)), collapse="\n"))
    }