Usage Example¶
import numpy as np
import pandas as pd
import torch
from anglepy import ANGLE
from anglepy.metrics import mean_absolute_angular_deviation, circular_mean_directional_error, mean_circular_crps, accuracy, med_err
from anglepy.kernels import c2_wendland
from sklearn.model_selection import train_test_split
from tqdm.auto import tqdm
import math
1. Indian Wind Dataset - Prediction¶
df = pd.read_csv('India_Wind_Data.csv')
random_state=18
device= torch.device("cuda" if torch.cuda.is_available() else "cpu")
X, y = df[['Latitude', 'Longitude']], df['Direction_Rad']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, shuffle=True, random_state=random_state)
X_train, X_test, y_train, y_test = torch.from_numpy(X_train.values).float().to(device), torch.from_numpy(X_test.values).float().to(device), torch.from_numpy(y_train.values).float().to(device), torch.from_numpy(y_test.values).float().to(device)
y_train = y_train.unsqueeze(-1)
# ANGLE-Geodesic
accuracies, mederrs, crpss, cmdes, maads, times = [], [], [], [], [], []
for _ in tqdm(range(50)):
model = ANGLE(
X_train, y_train,
num_layer=3, hidden_dim=100, noise_dim=64,
add_bn=True, resblock=False, noise_std=1,
print_every_nepoch=10000, print_times_per_epoch=0,
lr=0.05, num_epochs=500, batch_size=None,
standardize=False, device=device,
dist_method='geodesic', verbose=False, circular_indices=None,
kernel_func=c2_wendland(), circular_projection='atan2'
)
y_pred = model.predict(X_test)
y_pred_ensemble = model.sample(X_test, sample_size=100)
maad_mean = mean_absolute_angular_deviation(y_pred, y_test, return_degrees=True).item()
cmde = circular_mean_directional_error(y_pred, y_test).item()
crps = mean_circular_crps(y_pred_ensemble, y_test, return_degrees=True)[0]
acc = accuracy(y_pred, y_test, theta=torch.pi/6)
median_err = med_err(y_pred, y_test)
accuracies.append(round(acc,3))
mederrs.append(round(median_err,3))
crpss.append(round(crps, 3))
maads.append(round(maad_mean, 3))
cmdes.append(round(cmde,3))
print(f"{np.mean(accuracies):.2f}\pm{np.std(accuracies):.2f}")
print(f"{np.mean(mederrs):.2f}\pm{np.std(mederrs):.2f}")
print(f"{np.mean(crpss):.2f}\pm{np.std(crpss):.2f}")
print(f"{np.mean(maads):.2f}\pm{np.std(maads):.2f}")
print(f"{np.mean(cmdes):.2f}\pm{np.std(cmdes):.2f}")
# ANGLE-Chordal
accuracies, mederrs, crpss, cmdes, maads, times = [], [], [], [], [], []
for _ in tqdm(range(50)):
model = ANGLE(
X_train, y_train,
num_layer=3, hidden_dim=100, noise_dim=64,
add_bn=True, resblock=False, gamma=1, noise_std=1,
print_every_nepoch=10000, print_times_per_epoch=0,
lr=0.05, num_epochs=800, batch_size=None,
standardize=False, device=device,
dist_method='chordal', verbose=False, circular_indices=None
)
y_pred = model.predict(X_test)
y_pred_ensemble = model.sample(X_test, sample_size=100)
maad_mean = mean_absolute_angular_deviation(y_pred, y_test, return_degrees=True).item()
cmde = circular_mean_directional_error(y_pred, y_test).item()
crps = mean_circular_crps(y_pred_ensemble, y_test, return_degrees=True)[0]
acc = accuracy(y_pred, y_test, theta=torch.pi/6)
median_err = med_err(y_pred, y_test)
accuracies.append(round(acc,3))
mederrs.append(round(median_err,3))
crpss.append(round(crps, 3))
maads.append(round(maad_mean, 3))
cmdes.append(round(cmde,3))
print(f"{np.mean(accuracies):.2f}\pm{np.std(accuracies):.2f}")
print(f"{np.mean(mederrs):.2f}\pm{np.std(mederrs):.2f}")
print(f"{np.mean(crpss):.2f}\pm{np.std(crpss):.2f}")
print(f"{np.mean(maads):.2f}\pm{np.std(maads):.2f}")
print(f"{np.mean(cmdes):.2f}\pm{np.std(cmdes):.2f}")
2. Indian Wind Dataset - Sufficient Dimension Reduction¶
df = pd.read_csv('India_Wind_Data.csv')
random_state=18
device= torch.device("cuda" if torch.cuda.is_available() else "cpu")
X, y = df[['Latitude', 'Longitude']], df['Direction_Rad']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, shuffle=True, random_state=random_state)
X_train, X_test, y_train, y_test = torch.from_numpy(X_train.values).float().to(device), torch.from_numpy(X_test.values).float().to(device), torch.from_numpy(y_train.values).float().to(device), torch.from_numpy(y_test.values).float().to(device)
y_train = y_train.unsqueeze(-1)
model = ANGLE(
X_train, y_train,
num_layer=3, hidden_dim=100, noise_dim=64,
add_bn=True, resblock=False, gamma=1, noise_std=1,
print_every_nepoch=10000, print_times_per_epoch=0,
lr=0.05, num_epochs=800, batch_size=None,
standardize=True, device=device,
dist_method='chordal', verbose=False, circular_indices=None, sdr=True, reduced_dim=1
)
beta_matrix = model.beta_proj
print(beta_matrix.shape)
# Output: (1, d)
# Project your data to 1D for fitting stage-2 ANGLE, or plotting
reduced_X = X_train @ beta_matrix.T