suppressPackageStartupMessages({ library(neuroim2) library(rMVPA) library(dplyr) })
While standard Representational Similarity Analysis (RSA) compares neural patterns with model-based similarity structures, there are cases where more specialized approaches are needed. The rMVPA
package provides two advanced RSA methods:
This vignette explains when and why to use these specialized approaches instead of standard RSA.
Feature-Based RSA is designed for cases where:
Unlike standard RSA which compares similarity matrices, Feature-Based RSA attempts to find a mapping between neural patterns and a feature space.
Feature RSA: Maps neural patterns to feature dimensions
Output:
Feature RSA: Predicted feature values for each stimulus
Use Cases:
Let's walk through a complete example:
# Generate a synthetic dataset with dimensions 6x6x6, 50 observations, divided into 4 blocks # This ensures that the number of trials matches the number of stimuli used below data_out <- rMVPA::gen_sample_dataset(D = c(6,6,6), nobs = 50, blocks = 4, nlevels = 2) print(data_out) # Generate synthetic feature space (e.g., visual features of stimuli) set.seed(123) n_stimuli <- 50 n_features <- 5 # Create feature matrix (stimuli × features) feature_matrix <- matrix(rnorm(n_stimuli * n_features), n_stimuli, n_features) colnames(feature_matrix) <- paste0("feature_", 1:n_features) # Create stimulus labels stim_labels <- paste0("stim_", 1:n_stimuli) # Create feature RSA design feature_design <- feature_rsa_design( F = feature_matrix, # Direct feature matrix labels = stim_labels ) # Create MVPA dataset from the generated data dset <- mvpa_dataset(data_out$dataset$train_data, mask = data_out$dataset$mask) # Create cross-validation structure using the block information crossval <- blocked_cross_validation(data_out$design$block_var) # Create feature RSA model feature_model <- feature_rsa_model( dataset = dset, design = feature_design, method = "scca", # Sparse Canonical Correlation Analysis crossval = crossval # Add cross-validation ) # Create proper region mask from the dataset's mask mask_vol <- data_out$dataset$mask nvox <- sum(mask_vol) region_mask <- neuroim2::NeuroVol( sample(1:3, size = nvox, replace = TRUE), # 3 regions space(mask_vol), indices = which(mask_vol > 0) ) # Run regional analysis results <- run_regional(feature_model, region_mask) # Examine results print(results$performance_table)
Feature-Based RSA supports multiple analysis methods:
Useful when features may be correlated
Partial Least Squares (PLS):
Good for high-dimensional feature spaces
PCA Regression:
# Compare different methods methods <- c("scca", "pca") ## pls is not implemented yet results_list <- lapply(methods, function(method) { model <- feature_rsa_model( dataset = dset, design = feature_design, method = method, crossval = crossval # Add cross-validation ) run_regional(model, region_mask) }) # Compare performance for (i in seq_along(methods)) { cat("\nMethod:", methods[i], "\n") print(results_list[[i]]$performance_table) }
Vector-Based RSA is designed for cases where:
Unlike standard RSA which works with full similarity matrices, Vector-Based RSA operates on vectorized distance matrices and can efficiently handle block structure.
Vector RSA: Works with vectorized distances
Block Handling:
Vector RSA: Built-in efficient block handling
Memory Usage:
# Create distance matrix for stimuli stim_distances <- as.matrix(dist(feature_matrix)) rownames(stim_distances) <- stim_labels # Create block structure (e.g., runs) blocks <- rep(1:5, length.out = n_stimuli) # Create vector RSA design vector_design <- vector_rsa_design( D = stim_distances, labels = stim_labels, block_var = blocks ) # Create vector RSA model vector_model <- vector_rsa_model( dataset = dset, design = vector_design, distfun = cordist(), # Correlation distance rsa_simfun = "pearson" ) # Run analysis results_vector <- run_regional(vector_model, region_mask) # Examine results print(results_vector$performance_table)
Vector-Based RSA automatically handles block structure:
# Compare with different block structures block_sizes <- c(5, 10) results_blocks <- lapply(block_sizes, function(size) { blocks <- rep(1:(n_stimuli/size), each = size) design <- vector_rsa_design( D = stim_distances, labels = stim_labels, block_var = blocks ) model <- vector_rsa_model( dataset = dset, design = design, distfun = cordist() ) run_regional(model, region_mask) }) # Compare results for (i in seq_along(block_sizes)) { cat("\nBlock size:", block_sizes[i], "\n") print(results_blocks[[i]]$performance_table) }
Feature-Based RSA is most appropriate when working with a well-defined feature space where the dimensions have meaningful interpretations. This approach excels at reconstructing and predicting specific stimulus features from neural activity patterns. Common applications include predicting visual features from visual cortex responses, reconstructing semantic dimensions from language area activity, and mapping motion parameters from MT/V5 activation patterns.
Vector-Based RSA is ideal for analyzing large datasets with pre-computed distance matrices. It handles memory efficiently and provides sophisticated block handling capabilities. This makes it particularly valuable when comparing across multiple experimental runs, working with high-resolution fMRI data, or analyzing large-scale similarity structures.
Stick with standard RSA when: - You're testing theoretical models - You want to compare similarity structures - Block structure isn't critical - Memory usage isn't a concern
The rMVPA
package provides three complementary RSA approaches:
Your choice of RSA method should align with your research goals, match your data's structure, fit within computational constraints, and reflect whether you're analyzing feature spaces or similarity patterns.
For implementation details, refer to:
- feature_rsa_model.R
- vector_rsa_model.R
- rsa_model.R
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.