예제 #1
0
def train(X, y, args, quantiles):
    num_ts, num_periods, num_features = X.shape
    num_quantiles = len(quantiles)
    model = MQRNN(args.seq_len, num_quantiles, num_features,
                  args.embedding_size, args.encoder_hidden_size, args.n_layers,
                  args.decoder_hidden_size)
    optimizer = Adam(model.parameters(), lr=args.lr)
    Xtr, ytr, Xte, yte = util.train_test_split(X, y)
    losses = []
    yscaler = None
    if args.standard_scaler:
        yscaler = util.StandardScaler()
    elif args.log_scaler:
        yscaler = util.LogScaler()
    elif args.mean_scaler:
        yscaler = util.MeanScaler()
    if yscaler is not None:
        ytr = yscaler.fit_transform(ytr)
    num_obs_to_train = args.num_obs_to_train
    seq_len = args.seq_len
    progress = ProgressBar()
    for epoch in progress(range(args.num_epoches)):
        # print("Epoch {} start...".format(epoch))
        for step in range(args.step_per_epoch):
            X_train_batch, y_train_batch, Xf, yf = batch_generator(
                Xtr, ytr, num_obs_to_train, args.seq_len, args.batch_size)
            X_train_tensor = torch.from_numpy(X_train_batch).float()
            y_train_tensor = torch.from_numpy(y_train_batch).float()
            Xf = torch.from_numpy(Xf).float()
            yf = torch.from_numpy(yf).float()
            ypred = model(X_train_tensor, y_train_tensor, Xf)

            # quantile loss
            loss = torch.zeros_like(yf)
            num_ts = Xf.size(0)
            for q, rho in enumerate(quantiles):
                ypred_rho = ypred[:, :, q].view(num_ts, -1)
                e = ypred_rho - yf
                loss += torch.max(rho * e, (rho - 1) * e)
            loss = loss.mean()

            losses.append(loss.item())
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

    mape_list = []
    X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape(
        (num_ts, -1, num_features))
    Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features))
    y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1))
    if yscaler is not None:
        y_test = yscaler.transform(y_test)
    yf_test = yte[:, -seq_len:]
    ypred = model(X_test, y_test,
                  Xf_test)  # (1, num_quantiles, output_horizon)
    ypred = ypred.data.numpy()
    if yscaler is not None:
        ypred = yscaler.inverse_transform(ypred)
    ypred = np.maximum(0, ypred)

    # P50 quantile MAPE
    mape = util.MAPE(yf_test, ypred[:, :, 1])
    print("MAPE: {}".format(mape))
    mape_list.append(mape)

    if args.show_plot:
        show_idx = 0
        plt.figure(1)
        plt.plot([k + seq_len + num_obs_to_train - seq_len \
            for k in range(seq_len)], ypred[show_idx, :, 1], "r-")
        plt.fill_between(x=[k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], \
            y1=ypred[show_idx, :, 0], y2=ypred[show_idx, :, 2], alpha=0.5)
        plt.title('Prediction uncertainty')
        yplot = yte[show_idx, -seq_len - num_obs_to_train:]
        plt.plot(range(len(yplot)), yplot, "k-")
        plt.legend(["P50 forecast", "true", "P10-P90 quantile"],
                   loc="upper left")
        plt.xlabel("Periods")
        plt.ylabel("Y")
        plt.show()
    return losses, mape_list
예제 #2
0
def train(X, y, args):
    '''
    Args:
    - X (array like): shape (num_samples, num_features, num_periods)
    - y (array like): shape (num_samples, num_periods)
    - epoches (int): number of epoches to run
    - step_per_epoch (int): steps per epoch to run
    - seq_len (int): output horizon
    - likelihood (str): what type of likelihood to use, default is gaussian
    - num_skus_to_show (int): how many skus to show in test phase
    - num_results_to_sample (int): how many samples in test phase as prediction
    '''
    # rho = args.quantile
    num_ts, num_periods, num_features = X.shape
    model = DFRNN(num_features, args.noise_nlayers, args.noise_hidden_size,
                  args.global_nlayers, args.global_hidden_size, args.n_factors)
    optimizer = Adam(model.parameters(), lr=args.lr)
    random.seed(2)
    # select sku with most top n quantities
    Xtr, ytr, Xte, yte = util.train_test_split(X, y)
    losses = []
    cnt = 0

    yscaler = None
    if args.standard_scaler:
        yscaler = util.StandardScaler()
    elif args.log_scaler:
        yscaler = util.LogScaler()
    elif args.mean_scaler:
        yscaler = util.MeanScaler()
    if yscaler is not None:
        ytr = yscaler.fit_transform(ytr)

    # training
    progress = ProgressBar()
    seq_len = args.seq_len
    num_obs_to_train = args.num_obs_to_train
    for epoch in progress(range(args.num_epoches)):
        # print("Epoch {} starts...".format(epoch))
        for step in range(args.step_per_epoch):
            Xtrain, ytrain, Xf, yf = batch_generator(Xtr, ytr,
                                                     num_obs_to_train, seq_len,
                                                     args.batch_size)
            Xtrain_tensor = torch.from_numpy(Xtrain).float()
            ytrain_tensor = torch.from_numpy(ytrain).float()
            Xf = torch.from_numpy(Xf).float()
            yf = torch.from_numpy(yf).float()
            mu, sigma = model(Xtrain_tensor)
            loss = util.gaussian_likelihood_loss(ytrain_tensor, mu, sigma)
            losses.append(loss.item())
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            cnt += 1

    # test
    mape_list = []
    # select skus with most top K
    X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape(
        (num_ts, -1, num_features))
    Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features))
    y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1))
    yf_test = yte[:, -seq_len:].reshape((num_ts, -1))
    if yscaler is not None:
        y_test = yscaler.transform(y_test)

    result = []
    n_samples = args.sample_size
    for _ in tqdm(range(n_samples)):
        y_pred = model.sample(Xf_test)
        y_pred = y_pred.data.numpy()
        if yscaler is not None:
            y_pred = yscaler.inverse_transform(y_pred)
        result.append(y_pred.reshape((-1, 1)))

    result = np.concatenate(result, axis=1)
    p50 = np.quantile(result, 0.5, axis=1)
    p90 = np.quantile(result, 0.9, axis=1)
    p10 = np.quantile(result, 0.1, axis=1)

    mape = util.MAPE(yf_test, p50)
    print("P50 MAPE: {}".format(mape))
    mape_list.append(mape)

    if args.show_plot:
        plt.figure(1, figsize=(20, 5))
        plt.plot([k + seq_len + num_obs_to_train - seq_len \
            for k in range(seq_len)], p50, "r-")
        plt.fill_between(x=[k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], \
            y1=p10, y2=p90, alpha=0.5)
        plt.title('Prediction uncertainty')
        yplot = yte[-1, -seq_len - num_obs_to_train:]
        plt.plot(range(len(yplot)), yplot, "k-")
        plt.legend(["P50 forecast", "true", "P10-P90 quantile"],
                   loc="upper left")
        ymin, ymax = plt.ylim()
        plt.vlines(seq_len + num_obs_to_train - seq_len,
                   ymin,
                   ymax,
                   color="blue",
                   linestyles="dashed",
                   linewidth=2)
        plt.ylim(ymin, ymax)
        plt.xlabel("Periods")
        plt.ylabel("Y")
        plt.show()
    return losses, mape_list
예제 #3
0
def train(X, y, args):
    '''
    Args:
    - X (array like): shape (num_samples, num_features, num_periods)
    - y (array like): shape (num_samples, num_periods)
    - epoches (int): number of epoches to run
    - step_per_epoch (int): steps per epoch to run
    - seq_len (int): output horizon
    - likelihood (str): what type of likelihood to use, default is gaussian
    - num_skus_to_show (int): how many skus to show in test phase
    - num_results_to_sample (int): how many samples in test phase as prediction
    '''
    rho = args.quantile
    num_ts, num_periods, num_features = X.shape
    model = DeepAR(num_features, args.embedding_size, args.hidden_size,
                   args.n_layers, args.lr, args.likelihood)
    optimizer = Adam(model.parameters(), lr=args.lr)
    random.seed(2)
    # select sku with most top n quantities
    Xtr, ytr, Xte, yte = util.train_test_split(X, y)
    losses = []
    cnt = 0

    yscaler = None
    if args.standard_scaler:
        yscaler = util.StandardScaler()
    elif args.log_scaler:
        yscaler = util.LogScaler()
    elif args.mean_scaler:
        yscaler = util.MeanScaler()
    if yscaler is not None:
        ytr = yscaler.fit_transform(ytr)

    # training
    seq_len = args.seq_len
    num_obs_to_train = args.num_obs_to_train
    progress = ProgressBar()
    for epoch in progress(range(args.num_epoches)):
        # print("Epoch {} starts...".format(epoch))
        for step in range(args.step_per_epoch):
            Xtrain, ytrain, Xf, yf = batch_generator(Xtr, ytr,
                                                     num_obs_to_train, seq_len,
                                                     args.batch_size)
            Xtrain_tensor = torch.from_numpy(Xtrain).float()
            ytrain_tensor = torch.from_numpy(ytrain).float()
            Xf = torch.from_numpy(Xf).float()
            yf = torch.from_numpy(yf).float()
            ypred, mu, sigma = model(Xtrain_tensor, ytrain_tensor, Xf)
            # ypred_rho = ypred
            # e = ypred_rho - yf
            # loss = torch.max(rho * e, (rho - 1) * e).mean()
            ## gaussian loss
            ytrain_tensor = torch.cat([ytrain_tensor, yf], dim=1)
            loss = util.gaussian_likelihood_loss(ytrain_tensor, mu, sigma)
            losses.append(loss.item())
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            cnt += 1

    # test
    mape_list = []
    # select skus with most top K
    X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape(
        (num_ts, -1, num_features))
    Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features))
    y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1))
    yf_test = yte[:, -seq_len:].reshape((num_ts, -1))
    if yscaler is not None:
        y_test = yscaler.transform(y_test)
    y_pred, _, _ = model(X_test, y_test, Xf_test)
    y_pred = y_pred.data.numpy()
    if yscaler is not None:
        y_pred = yscaler.inverse_transform(y_pred)

    mape = util.MAPE(yf_test, y_pred)
    print("MAPE: {}".format(mape))
    mape_list.append(mape)

    if args.show_plot:
        plt.figure(1)
        plt.plot([k + seq_len + num_obs_to_train - seq_len \
            for k in range(seq_len)], y_pred[-1], "r-")
        plt.title('Prediction uncertainty')
        yplot = yte[-1, -seq_len - num_obs_to_train:]
        plt.plot(range(len(yplot)), yplot, "k-")
        plt.legend(["P50 forecast", "true", "P10-P90 quantile"],
                   loc="upper left")
        plt.xlabel("Periods")
        plt.ylabel("Y")
        plt.show()
    return losses, mape_list
예제 #4
0
def train(X, y, args):

    num_ts, num_periods, num_features = X.shape
    Xtr, ytr, Xte, yte = util.train_test_split(X, y)
    yscaler = None
    if args.standard_scaler:
        yscaler = util.StandardScaler()
    elif args.log_scaler:
        yscaler = util.LogScaler()
    elif args.mean_scaler:
        yscaler = util.MeanScaler()
    if yscaler is not None:
        ytr = yscaler.fit_transform(ytr)

    progress = ProgressBar()
    seq_len = args.seq_len
    num_obs_to_train = args.num_obs_to_train

    model = ExtremeModel(num_features)
    optimizer = Adam(model.parameters(), lr=args.lr)
    losses = []
    cnt = 0
    for epoch in progress(range(args.num_epoches)):
        # print("Epoch {} starts...".format(epoch))
        for step in range(args.step_per_epoch):
            Xtrain, ytrain, Xf, yf = batch_generator(Xtr, ytr,
                                                     num_obs_to_train, seq_len,
                                                     args.batch_size)
            Xtrain_tensor = torch.from_numpy(Xtrain).float()
            ytrain_tensor = torch.from_numpy(ytrain).float()
            Xf = torch.from_numpy(Xf).float()
            yf = torch.from_numpy(yf).float()
            ypred = model(Xtrain_tensor, Xf)
            loss = F.mse_loss(ypred, yf)
            losses.append(loss.item())
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            cnt += 1

    mape_list = []
    mse_list = []
    rmse_list = []
    mae_list = []

    # select skus with most top K
    X_test = Xte[:, -seq_len - num_obs_to_train:-seq_len, :].reshape(
        (num_ts, -1, num_features))
    Xf_test = Xte[:, -seq_len:, :].reshape((num_ts, -1, num_features))
    y_test = yte[:, -seq_len - num_obs_to_train:-seq_len].reshape((num_ts, -1))
    yf_test = yte[:, -seq_len:].reshape((num_ts, -1))
    if yscaler is not None:
        y_test = yscaler.transform(y_test)
    ypred = model(X_test, Xf_test)
    ypred = ypred.data.numpy()
    if yscaler is not None:
        ypred = yscaler.inverse_transform(ypred)

    mape = util.MAPE(yf_test, ypred)
    mae = util.MAE(yf_test, ypred)
    mse = util.MSE(yf_test, ypred)
    rmse = util.RMSE(yf_test, ypred)
    print("MAE: {}".format(mae))
    print("RMSE: {}".format(rmse))
    print("MSE: {}".format(mse))
    print("MAPE: {}".format(mape))
    mape_list.append(mape)
    mse_list.append(mse)
    mae_list.append(mae)
    rmse_list.append(rmse)

    if args.show_plot:
        plt.figure(1)
        plt.plot(
            [k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)],
            ypred[-1], "r-")
        plt.title('Prediction uncertainty')
        yplot = yte[-1, -seq_len - num_obs_to_train:]
        plt.plot(range(len(yplot)), yplot, "k-")
        plt.legend(["forecast", "true"], loc="upper left")
        plt.xlabel("Periods")
        plt.ylabel("Y")
        plt.show()

    return losses, mape_list, mse_list, mae_list, rmse_list
        result = []
        n_samples = sample_size
        for _ in tqdm(range(n_samples)):
            y_pred, _, _ = model(X_test, y_test, Xf_test)
            y_pred = y_pred.data.numpy()
            if yscaler is not None:
                y_pred = yscaler.inverse_transform(y_pred)
            result.append(y_pred.reshape((-1, 1)))

        #     result (100,12,1)
        result = np.concatenate(result, axis=1)  # (12,100)
        p50 = np.quantile(result, 0.5, axis=1)  # (12,)
        p90 = np.quantile(result, 0.9, axis=1)
        p10 = np.quantile(result, 0.1, axis=1)
        # yf_test(1,12)
        mape = util.MAPE(yf_test, p50)
        print("P50 MAPE: {}".format(mape))
        mape_list.append(mape)

        if show_plot:
            plt.figure(1, figsize=(20, 5))
            plt.plot([k + seq_len + num_obs_to_train - seq_len \
                      for k in range(seq_len)], p50, "r-")
            plt.fill_between(x=[k + seq_len + num_obs_to_train - seq_len for k in range(seq_len)], \
                             y1=p10, y2=p90, alpha=0.5)
            plt.title('Prediction uncertainty')
            yplot = yte[-1, -seq_len - num_obs_to_train:]
            plt.plot(range(len(yplot)), yplot, "k-")
            plt.legend(["P50 forecast", "true", "P10-P90 quantile"],
                       loc="upper left")
            ymin, ymax = plt.ylim()