============== Vectorization ============== Vectorization converts variable-length persistence barcodes into fixed-length feature vectors suitable for machine learning. This guide covers all 8 vectorization methods available in MedTDA. Overview ======== Persistence barcodes are sets of (birth, death) pairs with varying sizes across images. Machine learning requires fixed-length feature vectors. **Vectorization methods** solve this problem by summarizing barcodes into consistent-length representations. .. code-block:: python from medtda import FeatureExtractor extractor = FeatureExtractor( normalize=True, vectorization_method='PersStats' ) features = extractor.execute('image.nii.gz', 'mask.nii.gz') # features is a dictionary with fixed-length vectors for each homology dimension Available Methods ================= MedTDA provides 8 vectorization methods: 1. **Persistence Statistics** (``PersStats``) - Statistical summaries 2. **Betti Curves** (``BettiCurve``) - Betti numbers over filtration 3. **Persistence Images** (``PersImage``) - 2D histogram representation 4. **Persistence Landscapes** (``PersLandscape``) - Functional representation 5. **Persistence Silhouettes** (``PersSilhouette``) - Average landscape 6. **Entropy Summary** (``EntropySummary``) - Information-theoretic features 7. **Lifespan Curves** (``PersLifespan``) - Distribution of lifespans 8. **Tropical Coordinates** (``PersTropicalCoordinates``) - Tropical algebra Method Comparison ----------------- .. list-table:: :header-rows: 1 :widths: 30 20 50 * - Method - Speed - Features * - Persistence Stats - Fast - 38/dim (named dict) * - Betti Curves - Medium - resolution/dim (default: 100) * - Persistence Images - Medium - resolution²/dim (default: 400) * - Persistence Landscapes - Medium - num_landscapes × resolution/dim (default: 500) * - Persistence Silhouettes - Medium - resolution/dim (default: 100) * - Entropy Summary - Fast - resolution/dim (default: 100) * - Lifespan Curves - Medium - resolution/dim (default: 100) * - Tropical Coordinates - Slow - 7/dim Persistence Statistics ====================== Statistical summaries of persistence values, birth/death times, and midpoints. Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='PersStats' ) features = extractor.execute(image, mask) Features Extracted ------------------ For each homology dimension (H₀, H₁, H₂), computes **38 features**: **Birth time statistics (8):** * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR **Death time statistics (8):** * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR **Lifespan statistics (8):** * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR **Midpoint statistics (8):** * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR * Midpoint = (birth + death) / 2 **Count (1):** Number of persistence pairs **Entropy (1):** Persistent entropy **Additional statistics (4):** Mean/std of 2nd birth and 2nd death **Example output:** .. code-block:: python { 'PersStats_H0_mean': 0.523, 'PersStats_H0_std': 0.142, 'PersStats_H0_min': 0.001, 'PersStats_H0_max': 0.987, # ... 24 more features for H0 'PersStats_H1_mean': 0.234, # ... 28 features for H1 # ... 28 features for H2 (if max_dimension=2) } Betti Curves ============ Betti number (count of features) as a function of filtration value. Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='BettiCurve' ) # Configure resolution extractor.set_vectorization_params( 'BettiCurve', resolution=100 # Number of points (default=100) ) features = extractor.execute(image, mask) Features Extracted ------------------ For each homology dimension, creates a curve with ``resolution`` points. * 3 dimensions × 100 points = **300 features** (default) * Captures how the number of topological features evolves **Example:** With resolution=100: .. code-block:: python { 'BettiCurve_H0_f0': 0.0, 'BettiCurve_H0_f1': 1.2, 'BettiCurve_H0_f2': 2.5, # ... 97 more points for H0 'BettiCurve_H1_f0': 0.0, # ... 100 points for H1 # ... 100 points for H2 } Parameters ---------- .. code-block:: python extractor.set_vectorization_params( 'BettiCurve', resolution=200 # More points for smoother curve ) Persistence Images ================== 2D histogram representation of persistence diagrams. Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='PersImage' ) # Configure parameters extractor.set_vectorization_params( 'PersImage', resolution=20, # Grid size (default) bandwidth=0.1 # Gaussian smoothing (default) ) features = extractor.execute(image, mask) Features Extracted ------------------ Each persistence diagram → 2D image → flattened vector. * Grid size 20×20 = **400 features per dimension** (default) * 3 dimensions × 400 = **1200 total features** Parameters ---------- .. code-block:: python # Higher resolution (more features) extractor.set_vectorization_params( 'PersImage', resolution=50, # 2500 features/dim bandwidth=0.05 # Less smoothing ) # Lower resolution (fewer features) extractor.set_vectorization_params( 'PersImage', resolution=10, # 100 features/dim bandwidth=0.2 # More smoothing ) Persistence Landscapes ====================== Functional representation based on landscape functions. Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='PersLandscape' ) # Configure parameters extractor.set_vectorization_params( 'PersLandscape', num_landscapes=5, # Number of landscape functions (default) resolution=100 # Points per landscape (default) ) features = extractor.execute(image, mask) Features Extracted ------------------ Multiple landscape functions sampled at regular intervals. * 5 landscapes × 100 points = **500 features per dimension** * 3 dimensions × 500 = **1500 total features** Parameters ---------- .. code-block:: python # More landscapes (capture more detail) extractor.set_vectorization_params( 'PersLandscape', num_landscapes=10, resolution=100 ) # Fewer features extractor.set_vectorization_params( 'PersLandscape', num_landscapes=3, resolution=50 ) Persistence Silhouettes ======================= Weighted average of persistence landscapes (simpler than full landscapes). Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='PersSilhouette' ) # Configure resolution extractor.set_vectorization_params( 'PersSilhouette', resolution=100 ) features = extractor.execute(image, mask) Features Extracted ------------------ Single silhouette function per dimension. * **100 features per dimension** (default resolution) * 3 dimensions × 100 = **300 total features** Entropy Summary =============== Information-theoretic measures of barcode complexity. Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='EntropySummary' ) features = extractor.execute(image, mask) Features Extracted ------------------ For each homology dimension, computes ``resolution`` features (default: 100). **Small feature vector** per dimension. Lifespan Curves =============== Distribution of persistence values (lifespans). Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='PersLifespan' ) extractor.set_vectorization_params( 'PersLifespan', resolution=100 ) features = extractor.execute(image, mask) Features Extracted ------------------ Histogram of persistence values. * **100 features per dimension** (default resolution) Tropical Coordinates ==================== Tropical algebra representation (advanced). Usage ----- .. code-block:: python extractor = FeatureExtractor( vectorization_method='PersTropicalCoordinates' ) features = extractor.execute(image, mask) **Note:** Slower computation, specialized use. Using Multiple Methods ======================= Combine methods for comprehensive feature sets: .. code-block:: python extractor = FeatureExtractor( normalize=True, vectorization_method=[ 'PersStats', 'BettiCurve', 'EntropySummary' ] ) features = extractor.execute(image, mask) print(f"Total features: {len(features)}") Features are combined with prefixes indicating method and dimension. Example Workflow ================ .. code-block:: python from medtda import FeatureExtractor from sklearn.preprocessing import StandardScaler from sklearn.ensemble import RandomForestClassifier import pandas as pd # 1. Extract features with multiple methods extractor = FeatureExtractor( normalize=True, spacing=(1.0, 1.0, 1.0), vectorization_method=[ 'PersStats', 'BettiCurve', 'EntropySummary' ] ) # 2. Process dataset results = [] for case in dataset: features = extractor.execute(case['image'], case['mask']) features['label'] = case['label'] results.append(features) # 3. Prepare for ML df = pd.DataFrame(results) X = df.drop('label', axis=1) y = df['label'] # 4. Standardize scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 5. Train classifier clf = RandomForestClassifier() clf.fit(X_scaled, y) Next Steps ========== * :doc:`batch_processing` - Process multiple images * :doc:`../theory/vectorization_methods` - Mathematical background * :doc:`../api/vectorizers` - Vectorizer API reference