├── APLF ├── APLF.py └── Matlab │ ├── APLF.m │ ├── initialize.m │ ├── prediction.m │ ├── test.m │ ├── update_model.m │ └── update_parameters.m ├── Example ├── 400buildings.mat └── README.md ├── LICENSE ├── README.md ├── docs └── images │ ├── CDF.png │ ├── predictions.gif │ └── predictions.png └── requirements.txt /APLF/APLF.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning 4 | @author: Verónica Álvarez 5 | """ 6 | import numpy as np 7 | from scipy.io import loadmat # this is the SciPy module that loads mat-files 8 | import matplotlib.pyplot as plt 9 | from datetime import datetime, date, time 10 | import csv 11 | #import pandas as pd 12 | # data in .mat file 13 | path = '../' 14 | # os.chdir(path) 15 | filename = '400buildings.mat' 16 | mat = loadmat(path + filename) # load mat-file 17 | mdata = mat['data'] # variable in mat file 18 | mdtype = mdata.dtype 19 | data = {n: mdata[n][0, 0] for n in mdtype.names} 20 | 21 | # [MAPE, RMSE, predictions, load_demand, estimated_errors] = APLF(data, 300, 0.2, 0.7, 24, 48, 3) 22 | 23 | def initialize(C, R): 24 | # initialize parameters 25 | import numpy as np 26 | class Theta: 27 | pass 28 | class Gamma: 29 | pass 30 | a = Theta() 31 | a.etad = np.zeros((2, C)) 32 | a.sigmad = np.zeros((1, C)) 33 | a.etar = np.zeros((R, C)) 34 | a.sigmar = np.zeros((1, C)) 35 | a.wt = np.zeros((1, C)) 36 | a.sigmat = np.zeros((1, C)) 37 | b = Gamma() 38 | b.gammat = np.zeros((1, C)) 39 | b.Pt = np.zeros((1, C)) 40 | b.gammad = np.zeros((1, C)) 41 | b.gammar = np.zeros((1, C)) 42 | b.Pd = np.zeros((C, 2, 2)) 43 | b.Pr = np.zeros((C, R, R)) 44 | for i in range(C): 45 | b.Pd[i] = np.eye(2) 46 | b.Pr[i] = np.eye(R) 47 | return a, b 48 | 49 | def update_parameters(eta, sigma, P, gamma, l, s, u): 50 | if np.size(P) > 1: 51 | if P.trace() > 10: 52 | P = np.eye(len(P)) 53 | P = (1/l)*(P - (np.dot(np.dot(np.dot(P, u), u.T), P)/(l + np.dot(np.dot(u.T, P),u)))) 54 | gamma = 1 + l*gamma 55 | sigma = np.sqrt(sigma**2 - (1/gamma)*(sigma**2 - ( l**2*(s - np.dot(u.T,eta)[0])**2)/(l + np.dot(np.dot(u.T, P)[0],u)[0])**2)) 56 | sigma = float(sigma) 57 | eta = eta + (np.dot(P, u)/(l + np.dot(np.dot(u.T, P)[0],u)[0]))*(s - np.dot(u.T, eta)[0]) 58 | else: 59 | if P > 10: 60 | P = 1 61 | P = (1/l)*(P - (P*u*np.transpose(u)*P)/(l + np.transpose(u)*P*u)) 62 | gamma = 1 + l*gamma 63 | sigma = np.sqrt(sigma**2 - (1/gamma)*(sigma**2 - ( l**2*(s - np.transpose(u)*eta)**2)/(l + np.transpose(u)*P*u)**2)) 64 | eta = eta + (P*u/(l + np.transpose(u)*P*u))*(s - np.transpose(u)*eta) 65 | return eta, sigma, P, gamma 66 | 67 | def test(predictions, load_demand): 68 | n = len(predictions) 69 | m = np.zeros(n) 70 | r = np.zeros(n) 71 | for i in range(n): 72 | m[i] = np.abs(predictions[i] - load_demand[i])/load_demand[i] 73 | r[i] = (predictions[i] - load_demand[i])**2 74 | MAPE = 100*np.nanmean(m) 75 | RMSE = np.sqrt(np.nanmean(r)) 76 | return MAPE, RMSE 77 | 78 | def update_model(Theta, Gamma, y, x, c, lambdad, lambdar): 79 | s0 = x[0] 80 | w = x[1:] 81 | L = len(y) 82 | y = [[s0], y[0:]] 83 | flat_list = [] 84 | for sublist in y: 85 | for item in sublist: 86 | flat_list.append(item[0]) 87 | y = flat_list 88 | for i in range(L): 89 | [Theta.wt[0][c[i]], Theta.sigmat[0,c[i]], Gamma.Pt[0,c[i]], Gamma.gammat[0,c[i]]] = update_parameters(Theta.wt[0,c[i][0]], Theta.sigmat[0,c[i][0]], Gamma.Pt[0,c[i][0]], Gamma.gammat[0, c[i][0]], 1, w[0][i][0], 1) 90 | if Theta.wt[0][c[i]] - w[0][i][0] > 20 and (w[0][i][0] > 80 or w[0][i][0] < 20): 91 | alpha1 = 1 92 | alpha2 = 0 93 | elif Theta.wt[0][c[i]] - w[0][i][0] < -20 and (w[0][i][0] > 80 or w[0][i][0] < 20): 94 | alpha1 = 0 95 | alpha2 = 1 96 | else: 97 | alpha1 = 0 98 | alpha2 = 0 99 | ud = np.ones((2, 1)) 100 | ud[1, 0] = y[i] 101 | [Theta.etad[0:, c[i]], Theta.sigmad[0, c[i][0]], Gamma.Pd[c[i][0]], Gamma.gammad[0, c[i][0]]] = update_parameters(Theta.etad[0:, c[i]], Theta.sigmad[0, c[i][0]], Gamma.Pd[c[i][0]], Gamma.gammad[0, c[i][0]], lambdad, y[i+1], ud) 102 | ur = np.ones((3, 1)) 103 | ur[1, 0] = alpha1 104 | ur[2, 0] = alpha2 105 | [Theta.etar[0:, c[i]], Theta.sigmar[0][c[i]], Gamma.Pr[c[i][0]], Gamma.gammar[0][c[i]]] = update_parameters(Theta.etar[0:, c[i]], Theta.sigmar[0][c[i][0]], Gamma.Pr[c[i][0]], Gamma.gammar[0][c[i][0]], lambdar, y[i+1], ur) 106 | return Theta, Gamma 107 | 108 | def prediction(theta, x, C): 109 | # prediction function 110 | L = len(x[1]) 111 | pred_s = np.zeros((L+1, 1)) 112 | e = np.zeros((L+1, 1)) 113 | pred_s[0, 0] = x[0] 114 | w = x[1:] 115 | for i in range(L): 116 | c = C[i] 117 | ud = [1, pred_s[i, 0]] 118 | ud = np.transpose(ud) 119 | if theta.wt[0][c] - w[0][i][0] > 20 and (w[0][i][0] > 80 or w[0][i][0] < 20): 120 | alpha1 = 1 121 | alpha2 = 0 122 | elif theta.wt[0][c] - w[0][i][0] < -20 and (w[0][i][0] > 80 or w[0][i][0] < 20): 123 | alpha1 = 0 124 | alpha2 = 1 125 | else: 126 | alpha1 = 0 127 | alpha2 = 0 128 | ur = np.transpose([1, alpha1, alpha2]) 129 | pred_s[i+1, 0] = (np.dot(np.transpose(ud), theta.etad[0:, c])*theta.sigmar[0][c]**2 + np.dot(np.transpose(ur), theta.etar[0:, c])*(theta.sigmad[0][c]**2 + np.dot(np.dot([0, 1], theta.etad[0:, c])**2, e[i]**2)))/(theta.sigmar[0][c]*theta.sigmar[0][c] + theta.sigmad[0][c]**2 + np.dot((np.dot([0, 1], theta.etad[0:, c])**2),e[i]**2)) 130 | e[i+1, 0] = np.sqrt((theta.sigmar[0][c]**2 * (theta.sigmad[0][c]**2 + np.dot(np.dot([0, 1], theta.etad[0:, c])**2, e[i]**2)))/(theta.sigmar[0][c]**2 + theta.sigmad[0][c]**2 + np.dot(np.dot([0, 1], theta.etad[0:, c])**2, e[i]**2))) 131 | return pred_s[1:], e[1:] 132 | 133 | # def APLF(data, days_train, lambdad, lambdar, L, C, R): 134 | # [MAPE, RMSE, predictions, load_demand, estimated_errors] = APLF(data, 300, 0.2, 0.7, 24, 48, 3) 135 | # days_train > 1 number of training days 136 | days_train = 300 137 | lambdad = 0.2 # forgetting factor 138 | lambdar = 0.7 # forgetting factor 139 | L = 24 # prediction horizon (hours) 140 | C = 48 # length of the calendar information 141 | R = 3 # length of feature vector of observations 142 | n = len(data.get('consumption')) 143 | # consumption = data.get('consumption') 144 | consumption = data.get('consumption') 145 | ct = data.get('c') 146 | ct = ct - 1 147 | temperature = data.get('temperature') 148 | n_train = 24*days_train 149 | [Theta, Gamma] = initialize(C, R) 150 | predictions = [] 151 | estimated_errors = [] 152 | load_demand = [] 153 | for i in range(0, n_train - L, L): 154 | s0 = consumption[i] 155 | w = temperature[i+1:i+L+1] 156 | x = [s0, w] 157 | y = consumption[i+1:i+L+1] 158 | cal = ct[i+1:i+L+1] 159 | [Theta, Gamma] = update_model(Theta, Gamma, y, x, cal, lambdad, lambdar) 160 | for j in range(i+L+1, n-L, L): 161 | s0 = consumption[j] 162 | w = temperature[j+1:j+L+1] 163 | x = [s0, w] 164 | [pred_s, e] = prediction(Theta, x, ct[j+1:j+L+1]) 165 | predictions = np.append(predictions, np.transpose(pred_s)) 166 | estimated_errors = np.append(estimated_errors, np.transpose(e)) 167 | y = consumption[j+1:j+L+1] 168 | load_demand = np.append(load_demand, np.transpose(y)) 169 | [Theta, Gamma] = update_model(Theta, Gamma, y, x, ct[j+1:j+L+1], lambdad, lambdar) 170 | [MAPE, RMSE] = test(predictions, load_demand) 171 | print('MAPE = ', MAPE) 172 | print('RMSE = ', RMSE) 173 | with open('results.csv', 'w+') as file: 174 | writer = csv.writer(file) 175 | writer.writerow(("predictions", "load demand", "estimated errors")) 176 | rcount = 0 177 | for i in range(len(predictions)): 178 | writer.writerow((predictions[i], load_demand[i], estimated_errors[i])) 179 | rcount = rcount + 1 180 | file.close() 181 | 182 | # return MAPE, RMSE, predictions, load_demand, estimated_errors 183 | -------------------------------------------------------------------------------- /APLF/Matlab/APLF.m: -------------------------------------------------------------------------------- 1 | % 2 | % This file includes code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning. 3 | % @author: Verónica Álvarez 4 | % 5 | function [RMSE, MAPE, predictions, load_demand, estimated_errors] = APLF(data, days_train, lambdad, lambdar, L, C, R) 6 | % [RMSE, MAPE, predictions, load_demand, estimated_errors] = APLF(data, 1, 0.2, 0.7, 24, 48, 3); 7 | % 8 | % Inputs 9 | % data is a Matlab struct such that: 10 | % data.consumption is load demand 11 | % data.temperature is the temperature 12 | % data.c is the calendar information 13 | % days_train > 1 is the number of days that we will use for training 14 | % lambdad = 0.2 forgetting factor 15 | % lambdar = 0.7 forgetting factor 16 | % L = 24 is the prediction horizon 17 | % C = 48 is the length of the calendar information 18 | % R = 3 is the length of the feature representation of observations 19 | % 20 | % Outputs 21 | % RMSE is the root mean square error 22 | % MAPE is the mean average percentage error 23 | % predictions are load forecasts 24 | % load_demand are real loads corresponding with load forecasts 25 | % estimated_errors are the estimatation of the accuracy of load forecasts 26 | % 27 | % The mean of the temperatures that is included in the instance vector is 28 | % updated together with model parameters 29 | % Number of samples 30 | n = length(data.consumption); 31 | % Number of hours that we will use for training 32 | n_train = 24*days_train; 33 | % Initialize the model (model parameters and state variables) 34 | [Theta, Gamma] = initialize(C, R); 35 | predictions = []; 36 | estimated_errors = []; 37 | load_demand = []; 38 | n0 = 12; 39 | for i = 1:L:n_train-L 40 | s0 = data.consumption(i); 41 | w = data.temperature(i+1:i+L); 42 | x = [s0, w']; % instance vector, wt is included in Theta 43 | y = data.consumption(i+1:i+L); 44 | [Theta, Gamma] = update_model(Theta, Gamma, y, x, data.c(i+1:i+L), lambdad, lambdar); 45 | end 46 | for j = i+L+1:L:n - L 47 | s0 = data.consumption(j); 48 | w = data.temperature(j+1:j+L); 49 | x = [s0, w']; % instance vector, wt is included in Theta 50 | % Prediction 51 | [pred_s, e] = prediction(Theta, x, data.c(j+1:j+L)); % L Load forecasts and probabilistic load forecasts 52 | predictions = [predictions, pred_s']; % List of load forecasts 53 | estimated_errors = [estimated_errors, e']; % List of estimated errors 54 | % Learning (update model parameters and state variables) 55 | y = data.consumption(j+1:j+L); 56 | load_demand = [load_demand, y']; % List of load demand 57 | [Theta, Gamma] = update_model(Theta, Gamma, y, x, data.c(j+1:j+L), lambdad, lambdar); 58 | end 59 | % Prediction errors 60 | [MAPE, RMSE] = test(predictions, load_demand); 61 | end 62 | -------------------------------------------------------------------------------- /APLF/Matlab/initialize.m: -------------------------------------------------------------------------------- 1 | function [Theta, Gamma] = initialize(C, R) 2 | % 3 | % This file includes code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning. 4 | % @author: Verónica Álvarez 5 | % 6 | % This function initializes model parameters and state variables for each calendar type c = 1, 2, ..., C 7 | % 8 | % Inputs 9 | % C is the length of calendar information 10 | % R is the length of feature vector representation of observations 11 | % 12 | % Outputs 13 | % Theta is the updated list of model parameters 14 | % Gamma is the updated list of state variables require to update model parameters 15 | % 16 | % For each c, etad is a vector with length 2 17 | Theta.etad = zeros(2, C); 18 | Theta.sigmad = zeros(1, C); 19 | Gamma.gammad = zeros(1, C); 20 | % For each c, etad is a vector with length R 21 | Theta.etar = zeros(R, C); 22 | Theta.sigmar = zeros(1, C); 23 | Gamma.gammar = zeros(1, C); 24 | for i = 1:C 25 | Gamma.Pd(:, :, i) = eye(2); 26 | Gamma.Pr(:, :, i) = eye(R); 27 | end 28 | % Mean of the temperature 29 | Theta.wt = zeros(1, C); 30 | Theta.sigmat = zeros(1, C); 31 | Gamma.gammat = zeros(1, C); 32 | Gamma.Pt = ones(1, C); 33 | end 34 | -------------------------------------------------------------------------------- /APLF/Matlab/prediction.m: -------------------------------------------------------------------------------- 1 | function [pred_s, e] = prediction(Theta, x, C) 2 | % 3 | % This file includes code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning. 4 | % @author: Verónica Álvarez 5 | % 6 | % This function obtains load forecasts and estimates of their accuracy. 7 | % 8 | % Inputs 9 | % Theta is the list of model parameters 10 | % x = [s0, w] is the instance vector (wt is included in Theta) 11 | % C is the calendar information 12 | % Outputs 13 | % pred_s is the vector of L load forecasts 14 | % e is the vector of L estimations of the accuracy of load forecasts 15 | % 16 | L = length(x)-1; % Prediction horizon 17 | pred_s = zeros(L+1, 1); % Predictions 18 | e = zeros(L+1, 1); % Estimated errors 19 | pred_s(1, 1) = x(1); 20 | w = x(2:end); % temperature 21 | for i=2:L+1 22 | c = C(i-1); 23 | % Feature vector that represents load 24 | ud = [1, pred_s(i-1)]'; 25 | % Feature vector that represents observations 26 | if Theta.wt(c) - w(i-1) > 20 && (w(i-1) > 80 || w(i-1) < 20) 27 | alpha1 = 1; 28 | alpha2 = 0; 29 | elseif Theta.wt(c) - w(i-1) < - 20 && (w(i-1) > 80 || w(i-1) < 20) 30 | alpha1 = 0; 31 | alpha2 = 1; 32 | else 33 | alpha1 = 0; 34 | alpha2 = 0; 35 | end 36 | ur = [1, alpha1, alpha2]'; 37 | % Predictions 38 | pred_s(i, 1) = (ud'*Theta.etad(:, c)*Theta.sigmar(c)^2 + ur'*Theta.etar(:, c)*(Theta.sigmad(c)^2 + ([0, 1]*Theta.etad(:, c))^2*e(i-1, 1)))/(Theta.sigmar(c)^2 + Theta.sigmad(c)^2 + ([0, 1]*Theta.etad(:, c))^2*e(i-1, 1)); 39 | e(i,1) = sqrt(((Theta.sigmad(c)^2 + ([0, 1]*Theta.etad(:, c))^2*e(i-1, 1))*Theta.sigmar(c)^2)/(Theta.sigmar(c)^2 + Theta.sigmad(c)^2 + ([0, 1]*Theta.etad(:, c))^2*e(i-1, 1))); 40 | end 41 | pred_s(1) = []; 42 | e(1) = []; 43 | end 44 | -------------------------------------------------------------------------------- /APLF/Matlab/test.m: -------------------------------------------------------------------------------- 1 | function [MAPE, RMSE] = test(forecast, load_demand) 2 | % 3 | % This file includes code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning. 4 | % @author: Verónica Álvarez 5 | % 6 | % This function quantifies the prediction errors root mean square error (RMSE) and mean average percentage error (MAPE) 7 | % 8 | % Inputs 9 | % Forecast is a vector of load forecasts 10 | % load_demand is a vector of load corresponding with load forecasts 11 | % 12 | % Outputs 13 | % MAPE 14 | % RMSE 15 | % 16 | m = []; 17 | r = []; 18 | n = length(forecast); 19 | for i = 1:n 20 | if load_demand(i) > 0 21 | % MAPE 22 | m(i) = abs((load_demand(i) - forecast(i))/load_demand(i)); 23 | % RMSE 24 | r(i) = (load_demand(i) - forecast(i))^2; 25 | end 26 | end 27 | MAPE = 100*nanmean(m); 28 | RMSE = sqrt(nanmean(r)); 29 | end 30 | -------------------------------------------------------------------------------- /APLF/Matlab/update_model.m: -------------------------------------------------------------------------------- 1 | function [Theta, Gamma] = update_model(Theta, Gamma, y, x, c, lambdad, lambdar) 2 | % 3 | % This file includes code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning. 4 | % @author: Verónica Álvarez 5 | % 6 | % This function updates model parameters and state variables 7 | % 8 | % Inputs 9 | % Theta is the list of model parameters 10 | % Gamma is the list of state variables 11 | % y is the vector of new loads 12 | % x = [s0, w] is the instance vector (wt is included in Theta is updated in this step) 13 | % c is the calendar information 14 | % lambdad, lambdar forgetting factors 15 | % 16 | % Outputs 17 | % Theta is the updated list of model parameters 18 | % Gamma is the updated list of state variables 19 | % 20 | % Prediction horizon 21 | s0 = x(1); 22 | w = x(2:end); 23 | L = length(y); 24 | y = [s0, y']; 25 | for i = 1:L 26 | % Update the mean of temperatures with the forgetting factor lambda = 1 and the 27 | % feature vector u = 1 28 | [Theta.wt(c(i)), Theta.sigmat(c(i)), Gamma.Pt(c(i)), Gamma.gammat(c(i))] = update_parameters(Theta.wt(c(i)), Theta.sigmat(c(i)), Gamma.Pt(c(i)), Gamma.gammat(c(i)), 1, w(i), 1); 29 | % Dummy varibles 30 | if Theta.wt(c(i)) - w(i) > 20 && (w(i) > 80 || w(i) < 20) 31 | alpha1 = 1; 32 | alpha2 = 0; 33 | elseif Theta.wt(c(i)) - w(i) < - 20 && (w(i) > 80 || w(i) < 20) 34 | alpha1 = 0; 35 | alpha2 = 1; 36 | else 37 | alpha1 = 0; 38 | alpha2 = 0; 39 | end 40 | % Feature vector that represents load 41 | ud = [1, y(i)]'; 42 | % Update parameters denoted by d 43 | [Theta.etad(:, c(i)), Theta.sigmad(c(i)), Gamma.Pd(:, :, c(i)), Gamma.gammad(c(i))] = update_parameters(Theta.etad(:, c(i)), Theta.sigmad(c(i)), Gamma.Pd(:, :, c(i)), Gamma.gammad(c(i)), lambdad, y(i+1), ud); 44 | % Feature vector that represents observations 45 | ur = [1, alpha1, alpha2]'; 46 | % Update parameters denoted by r 47 | [Theta.etar(:, c(i)), Theta.sigmar(c(i)), Gamma.Pr(:, :, c(i)), Gamma.gammar(c(i))] = update_parameters(Theta.etar(:, c(i)), Theta.sigmar(c(i)), Gamma.Pr(:, :, c(i)), Gamma.gammar(c(i)), lambdar, y(i+1), ur); 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /APLF/Matlab/update_parameters.m: -------------------------------------------------------------------------------- 1 | function [eta, sigma, P, gamma] = update_parameters(eta, sigma, P, gamma, lambda, s, u) 2 | % 3 | % This file includes code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning. 4 | % @author: Verónica Álvarez 5 | % 6 | % This function updates recursively each parameter and each state variable 7 | % 8 | % Inputs 9 | % eta 10 | % sigma 11 | % P 12 | % gamma 13 | % lambda is the forgetting factor 14 | % u is the feature vector 15 | % s is the load 16 | % 17 | % Outputs 18 | % eta is the updated eta parameter 19 | % sigma is the updated sigma parameter 20 | % P is the updated state variable P 21 | % gamma is the updated state variable gamma 22 | % 23 | % Avoid possible inestabilities of matrix P 24 | if trace(P) > 10 25 | P = eye(length(P)); 26 | end 27 | % Update matrix P 28 | P = (1/lambda)*(P - (P*u*u'*P)/(lambda + u'*P*u)); 29 | % Update gamma 30 | gamma = 1 + lambda*gamma; 31 | % Update sigma 32 | sigma = sqrt(sigma^2 - (1/gamma)*(sigma^2 - lambda^2*(s - u'*eta)^2)/(lambda + u'*P*u)^2); 33 | % Update eta 34 | eta = eta + (P*u/(lambda + u'*P*u))*(s - u'*eta); 35 | end 36 | -------------------------------------------------------------------------------- /Example/400buildings.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MachineLearningBCAM/Load-forecasting-IEEE-TPWRS-2020/f4e1ea75e8c06f3f795d8b5ebda85e5a2d77bb2b/Example/400buildings.mat -------------------------------------------------------------------------------- /Example/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | We forecast load for [400 buildings](https://data.mendeley.com/datasets/zm4f727vvr/1#file-a01cdaa0-340d-4ebf-8fe5-c59a53d8f6b0). The dataset contains electricity load data for 6031 residential customers in NEW South Wales for the calendar year 2013. We forecast the mean of load for 400 buildings. 4 | 5 | We execute the following code in Matlab language 6 | 7 | ``` 8 | # Input 9 | load('400buildings.mat') 10 | days_training = 300; 11 | lambdas = 0.2; # Forgetting factor 12 | lambdar = 0.7; # Forgetting factor 13 | L = 24; # Prediction horizon 14 | C = 48; # Calendar types 15 | R = 3; # Length of feature vector that represents observations 16 | [RMSE, MAPE, load_forecasts, load_demand, estimated_errors] = APLF(data, days_training, lambdas, lambdar, L, C, R); 17 | ``` 18 | 19 | We obtain that 20 | 21 | ``` 22 | RMSE = 0.03; 23 | MAPE = 6.27; 24 | ``` 25 | 26 | We plot one week of load demand, load forecasts, and estimated errors 27 | 28 | ![alt text](../docs/images/predictions.png) 29 | 30 | We show the CDF of error 31 | 32 | ![alt text](../docs/images/CDF.png) 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Veronica Alvarez 4 | veronicaalvcas@gmail.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Probabilistic Load Forecasting based on Adaptive Online Learning (APLF) 2 | 3 | [![GitHub license](https://img.shields.io/badge/License-MIT-blue)](https://github.com/VeronicaAlvarez/online-probabilistic-load-forecasting/blob/master/LICENSE) [![Made with!](https://img.shields.io/badge/Made%20with-MATLAB-red)](APLF/Matlab) [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](APLF/APLF.py) [![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](#support-and-author) 4 | 5 | This repository contains code for the paper Probabilistic Load Forecasting based on Adaptive Online Learning [[1]](#1). We use the implementation details described in the paper. 6 | 7 | ![grab-landing-page](docs/images/predictions.gif) 8 | 9 | ## Implementation of the method 10 | 11 | APLF folder contains the [Python file](APLF/APLF.py), a [Jupyter notebook](APLF/APLF.ipynb) and a [Matlab folder](APLF/Matlab) that contains all the Matlab scripts required to execute the method: 12 | 13 | * APLF.m is the main file. 14 | * initialize.m function inizializes model parameters. 15 | * prediction.m function obtain load forecasts and probabilistic load forecasts in form of mean and standard deviation of a Gaussian density function. 16 | * test.m function quantifies the prediction errors RMSE and MAPE. 17 | * update_model.m function updates the model for each new training sample. 18 | * update_parameters.m function updates model parameters. 19 | 20 | ## Data 21 | 22 | We use 7 publicly available datasets corresponding with regions that have different sizes. The datasets are: 23 | 24 | > [Load demand in Belgium from 2017-2019 made available by Elia group.](https://www.elia.be/en/grid-data/data-download-page) 25 | [Load demand in New England from 2003-2014 made available by ISO-NE organization.](https://www.iso-ne.com/isoexpress/web/reports/load-and-demand/-/tree/historical-hourly-flows-and-limits) 26 | [Global Energy forecasting Competition 2012 dataset from 2004-2007.](http://blog.drhongtao.com/2016/07/gefcom2012-load-forecasting-data.html) 27 | [Global Energy Forecasting Competition 2014 dataset from 2005-2011.](http://blog.drhongtao.com/2017/03/gefcom2014-load-forecasting-data.html) 28 | [Load demand in Dayton from 2004-2016 made available by PJM interconnection.](https://www.pjm.com/markets-and-operations/data-dictionary.aspx) 29 | [Load demand for 400 buildings in New South Wales from 2013 made available by the Australian Government.](http://dx.doi.org/10.17632/zm4f727vvr.1#file-a01cdaa0-340d-4ebf-8fe5-c59a53d8f6b0) 30 | [Load demand for 100 buildings in New South Wales from 2013 made available by the Australian Government.](http://dx.doi.org/10.17632/zm4f727vvr.1#file-a01cdaa0-340d-4ebf-8fe5-c59a53d8f6b0) 31 | 32 | We save the data in .mat files that contain a struct with following fields: 33 | 34 | * Hourly load time series 35 | * Temperature time series 36 | * Date and hour or timestamp when the load is measure 37 | 38 | ## Installation 39 | 40 | ```console 41 | git clone https://github.com/VeronicaAlvarez/online-probabilistic-load-forecasting 42 | ``` 43 | 44 | Running python code: 45 | ```console 46 | cd online-probabilistic-load-forecasting\APLF 47 | python APLF.py 48 | ``` 49 | 50 | 51 | ## Test case 52 | 53 | We display in this reposity an example for a dataset that contains load data of [400 buildings](https://data.mendeley.com/datasets/zm4f727vvr/1#file-a01cdaa0-340d-4ebf-8fe5-c59a53d8f6b0). [Example folder](/Example) includes more details of the dataset, commands to execute the code, and results. 54 | 55 | ## Support and Author 56 | 57 | Verónica Álvarez Castro 58 | 59 | valvarez@bcamath.org 60 | 61 | [![ForTheBadge built-with-science](http://ForTheBadge.com/images/badges/built-with-science.svg)](https://github.com/VeronicaAlvarez) 62 | 63 | ## License 64 | 65 | Load-forecasting-IEEE-TPWRS-2020 carries a MIT license. 66 | 67 | ## Citation 68 | 69 | If you find useful the code in your research, please include explicit mention of our work in your publication with the following corresponding entry in your bibliography: 70 | 71 | [1] 72 | V. Alvarez, S. Mazuelas, J.A. Lozano. 73 | "Probabilistic Load Forecasting based on Adaptive Online Learning," 74 | *IEEE-Transactions on Power Systems.* 2021. 75 | 76 | The corresponding BiBTeX citation is given below: 77 | 78 | ``` 79 | @article{AlvMazLoz:21, 80 | title={Probabilistic Load Forecasting based on Adaptive Online Learning}, 81 | author={Ver\'{o}nica Alvarez and Santiago Mazuelas and Jos\'{e} A. Lozano}, 82 | journal={IEEE Transactions on Power Systems}, 83 | year={2021}, 84 | volume={36}, 85 | number={4}, 86 | month= {Jul.}, 87 | pages={3668 -- 3680} 88 | } 89 | ``` 90 | -------------------------------------------------------------------------------- /docs/images/CDF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MachineLearningBCAM/Load-forecasting-IEEE-TPWRS-2020/f4e1ea75e8c06f3f795d8b5ebda85e5a2d77bb2b/docs/images/CDF.png -------------------------------------------------------------------------------- /docs/images/predictions.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MachineLearningBCAM/Load-forecasting-IEEE-TPWRS-2020/f4e1ea75e8c06f3f795d8b5ebda85e5a2d77bb2b/docs/images/predictions.gif -------------------------------------------------------------------------------- /docs/images/predictions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MachineLearningBCAM/Load-forecasting-IEEE-TPWRS-2020/f4e1ea75e8c06f3f795d8b5ebda85e5a2d77bb2b/docs/images/predictions.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | matplotlib==3.3.0 2 | numpy==1.22.0 3 | scipy==1.10.0 4 | --------------------------------------------------------------------------------