### Install sigkernel via pip Source: https://github.com/crispitagorico/sigkernel/blob/master/README.md Install the library directly from the GitHub repository. ```bash pip install git+https://github.com/crispitagorico/sigkernel.git ``` -------------------------------- ### Manage GPU Acceleration and Memory Source: https://context7.com/crispitagorico/sigkernel/llms.txt Example demonstrating automatic device selection, memory-efficient computation using max_batch, and GPU memory cleanup. ```python import torch import sigkernel # Automatic device selection if torch.cuda.is_available(): device = torch.device('cuda') print("Using NVIDIA CUDA") elif torch.backends.mps.is_available(): device = torch.device('mps') print("Using Apple Silicon MPS") else: device = torch.device('cpu') print("Using CPU (Cython backend)") # Create data on selected device batch, length, dim = 50, 100, 4 X = torch.rand(batch, length, dim, dtype=torch.float64, device=device) Y = torch.rand(batch, length, dim, dtype=torch.float64, device=device) # Setup kernel static_kernel = sigkernel.RBFKernel(sigma=1.0) sig_kernel = sigkernel.SigKernel(static_kernel, dyadic_order=1) # For large datasets, use max_batch to control memory # Smaller max_batch = less memory but more iterations G = sig_kernel.compute_Gram(X, Y, sym=False, max_batch=25) # Move results back to CPU if needed G_cpu = G.cpu().numpy() # Clear GPU memory after computation if device.type == 'cuda': torch.cuda.empty_cache() print(f"Computed on {device}, result shape: {G_cpu.shape}") ``` -------------------------------- ### Run UEA time series classification examples Source: https://github.com/crispitagorico/sigkernel/blob/master/README.md Commands to train, test, and print results for the UEA time series classification models. ```bash python3 time_series_classification.py --train ``` ```bash python3 time_series_classification.py --test ``` ```bash python3 time_series_classification.py --print ``` -------------------------------- ### Compute Signature Kernel Gram Matrix Source: https://context7.com/crispitagorico/sigkernel/llms.txt Basic example of converting data to torch tensors and computing the Gram matrix using an RBF static kernel. ```python X = torch.tensor(batch_paths, dtype=torch.float64) Y = torch.tensor(batch_paths, dtype=torch.float64) static_kernel = sigkernel.RBFKernel(sigma=0.5) sig_kernel = sigkernel.SigKernel(static_kernel, dyadic_order=0) G = sig_kernel.compute_Gram(X, Y, sym=True) print(f"Gram matrix of Brownian paths: {G.shape}") ``` -------------------------------- ### Prepare Features and Target for Sigkernel Model Source: https://github.com/crispitagorico/sigkernel/blob/master/examples/bitcoin_predictions.ipynb Extracts the 'Close' price, defines window sizes for feature engineering, generates the target variable 'y' (next mean price), and creates the feature matrix 'X_window' using `GetWindow` and `sigkernel.transform`. Splits data into training and testing sets. ```python # use only close price close_price = BTC_price.loc[:,'Close'] # close_price = TimeSeriesScalerMeanVariance().fit_transform(close_price.values[None,:]) close_price = pd.DataFrame(np.squeeze(close_price)) # use last h_window observations to predict mean over next f_window observations h_window = 36 f_window = 2 # next mean price y = GetNextMean(close_price, h_window=h_window , f_window=f_window) # normal window features X_window = GetWindow(close_price, h_window, f_window).values X_window = torch.tensor(X_window, dtype=torch.float64) X_window = sigkernel.transform(X_window, at=True, ll=True, scale=1e-5) # train test split x_train, x_test, y_train, y_test = train_test_split(X_window, y, test_size=0.2, shuffle=False) x_train = torch.tensor(x_train, dtype=torch.float64, device='cpu') x_test = torch.tensor(x_test, dtype=torch.float64, device='cpu') ``` -------------------------------- ### Compute Signature Kernels and Gram Matrices Source: https://context7.com/crispitagorico/sigkernel/llms.txt Demonstrates initializing a SigKernel instance and computing batch-wise kernels or full Gram matrices for time series data. ```python import torch import sigkernel # Detect available hardware acceleration device = 'cuda' if torch.cuda.is_available() else ('mps' if torch.backends.mps.is_available() else 'cpu') # Create synthetic time series data batch_size, len_x, len_y, dim = 10, 50, 60, 3 X = torch.rand((batch_size, len_x, dim), dtype=torch.float64, device=device) Y = torch.rand((batch_size, len_y, dim), dtype=torch.float64, device=device) # Initialize static kernel (RBF or Linear) static_kernel = sigkernel.RBFKernel(sigma=0.5) # Create signature kernel with dyadic refinement order # Higher dyadic_order = more accurate but slower (default=0) signature_kernel = sigkernel.SigKernel(static_kernel, dyadic_order=1) # Compute batch-wise kernel: k(x_1,y_1), ..., k(x_batch, y_batch) K = signature_kernel.compute_kernel(X, Y, max_batch=100) print(f"Batch kernel shape: {K.shape}") # Output: torch.Size([10]) # Compute full Gram matrix: k(x_i, y_j) for all i,j pairs G = signature_kernel.compute_Gram(X, Y, sym=False, max_batch=100) print(f"Gram matrix shape: {G.shape}") # Output: torch.Size([10, 10]) # Symmetric Gram matrix (more efficient when X == Y) G_sym = signature_kernel.compute_Gram(X, X, sym=True, max_batch=100) ``` -------------------------------- ### Compute signature kernels and metrics Source: https://github.com/crispitagorico/sigkernel/blob/master/README.md Initialize the signature kernel and perform computations including Gram matrices, MMD distances, and scoring rules. ```python import torch import sigkernel # Specify the static kernel (for linear kernel use sigkernel.LinearKernel()) static_kernel = sigkernel.RBFKernel(sigma=0.5) # Specify dyadic order for PDE solver (int > 0, default 0, the higher the more accurate but slower) dyadic_order = 1 # Specify maximum batch size of computation; if memory is a concern try reducing max_batch, default=100 max_batch = 100 # Initialize the corresponding signature kernel signature_kernel = sigkernel.SigKernel(static_kernel, dyadic_order) # Synthetic data batch, len_x, len_y, dim = 5, 10, 20, 2 # Use 'cuda', 'mps', or 'cpu' depending on available hardware device = 'cuda' if torch.cuda.is_available() else ('mps' if torch.backends.mps.is_available() else 'cpu') X = torch.rand((batch,len_x,dim), dtype=torch.float64, device=device) # shape (batch,len_x,dim) Y = torch.rand((batch,len_y,dim), dtype=torch.float64, device=device) # shape (batch,len_y,dim) Z = torch.rand((batch,len_x,dim), dtype=torch.float64, device=device) # shape (batch,len_y,dim) # Compute signature kernel "batch-wise" (i.e. k(x_1,y_1),...,k(x_batch, y_batch)) K = signature_kernel.compute_kernel(X,Y,max_batch) # Compute signature kernel Gram matrix (i.e. k(x_i,y_j) for i,j=1,...,batch), also works for different batch_x != batch_y) G = signature_kernel.compute_Gram(X,Y,sym=False,max_batch) # Compute MMD distance between samples x ~ X and samples y ~ Y, where X,Y are two distributions on path space... mmd = signature_kernel.compute_mmd(X,Y,max_batch) # ... and to backpropagate through the MMD distance simply call .backward(), like any other PyTorch loss function mmd.backward() # Compute scoring rule between X and a sample path y, i.e. S_sig(X,y) = E[k(X,X)] - 2E[k(X,y] ... y = Y[0] sr = signature_kernel.compute_scoring_rule(X,y,max_batch) # ... and expected scoring rule between X and Y, i.e. S(X,Y) = E_Y[S_sig(X,y)] esr = signature_kernel.compute_expected_scoring_rule(X,Y,max_batch) # Sig CHSIC: XY|Z sigchsic = signature_kernel.SigCHSIC(X, Y, Z, static_kernel, dyadic_order=1, eps=0.1) ``` -------------------------------- ### Apply Path Transformations with Sigkernel Source: https://context7.com/crispitagorico/sigkernel/llms.txt Utilize the sigkernel.transform function to preprocess time series paths by adding time coordinates and applying lead-lag transformations. Demonstrates individual and combined transformations with scaling. ```python import numpy as np import sigkernel # Sample multivariate time series data n_samples, length, dim = 50, 100, 3 paths = np.random.randn(n_samples, length, dim) # Apply transformations using the convenience function # at=True: Add time coordinate (dim -> dim+1) # ll=True: Lead-lag transform (dim -> 2*dim) # scale: Rescale paths # Add time only paths_with_time = sigkernel.transform(paths, at=True, ll=False, scale=1.0) print(f"With time: {paths.shape} -> {paths_with_time.shape}") ``` ```python # Lead-lag only (doubles length and dimension) paths_leadlag = sigkernel.transform(paths, at=False, ll=True, scale=1.0) print(f"Lead-lag: {paths.shape} -> {paths_leadlag.shape}") ``` ```python # Both transformations with scaling paths_full = sigkernel.transform(paths, at=True, ll=True, scale=0.1) print(f"Full transform: {paths.shape} -> {paths_full.shape}") ``` ```python # Individual transformer classes for custom pipelines add_time = sigkernel.AddTime(init_time=0., total_time=1.) lead_lag = sigkernel.LeadLag() # Apply sequentially paths_t = add_time.fit_transform(list(paths)) paths_tll = lead_lag.fit_transform(paths_t) ``` -------------------------------- ### Generate Brownian Motion Paths with Sigkernel Utilities Source: https://context7.com/crispitagorico/sigkernel/llms.txt Utilize helper functions from sigkernel to generate white noise increments and Brownian motion paths. Useful for creating synthetic data for testing and benchmarking signature kernel computations. ```python import numpy as np import torch import sigkernel # Generate white noise increments steps, width, time = 100, 3, 1.0 increments = sigkernel.white(steps, width, time) print(f"White noise shape: {increments.shape}") ``` ```python # Generate Brownian motion paths paths = sigkernel.brownian(steps, width, time) print(f"Brownian path shape: {paths.shape}") print(f"Path starts at: {paths[0]}") ``` ```python # Generate batch of Brownian motions for kernel computation n_paths = 20 batch_paths = np.array([sigkernel.brownian(steps, width) for _ in range(n_paths)]) print(f"Batch shape: {batch_paths.shape}") ``` -------------------------------- ### Load and print results Source: https://github.com/crispitagorico/sigkernel/blob/master/examples/bitcoin_predictions.ipynb Loads the serialized results from a pickle file and prints the final dictionary. ```python # print results with open('../results/bitcoin_results.pkl', 'rb') as file: final = pickle.load(file) print(final) ``` -------------------------------- ### Load and Preprocess Bitcoin Price Data Source: https://github.com/crispitagorico/sigkernel/blob/master/examples/bitcoin_predictions.ipynb Loads Bitcoin price data from a CSV file, performs initial cleaning by dropping a column and reversing the order, sets the 'Date' column as the index, and filters data for a specific date range. ```python # load data (source is https://www.cryptodatadownload.com) BTC_price = pd.read_csv('../data/gemini_BTCUSD_day.csv',header=1) # drop the first column and reverse order BTC_price = BTC_price.iloc[1:,:] BTC_price = BTC_price.iloc[::-1] BTC_price['Date'] = pd.to_datetime(BTC_price['Date']) BTC_price.set_index('Date', inplace=True) # select duration initial_date = '2017-06-01' finish_date = '2018-08-01' BTC_price = BTC_price.loc[BTC_price.index >= initial_date] BTC_price = BTC_price.loc[BTC_price.index <= finish_date] ``` -------------------------------- ### Tqdm Progress Output Source: https://github.com/crispitagorico/sigkernel/blob/master/examples/bitcoin_predictions.ipynb Console output indicating progress of the loops. ```text 0%| | 0/5 [00:00