gaitsetpy.features.harup_features
HAR-UP Feature Extractor. Maintainer: @aharshit123456
This file contains the HAR-UP feature extractor class that inherits from BaseFeatureExtractor. It implements the feature extraction methods used in the HAR-UP project.
Reference:
1''' 2HAR-UP Feature Extractor. 3Maintainer: @aharshit123456 4 5This file contains the HAR-UP feature extractor class that inherits from BaseFeatureExtractor. 6It implements the feature extraction methods used in the HAR-UP project. 7 8Reference: 9- Website: https://sites.google.com/up.edu.mx/har-up/ 10- GitHub: https://github.com/jpnm561/HAR-UP 11''' 12 13import numpy as np 14from typing import List, Dict, Any 15from scipy.stats import kurtosis, skew 16from scipy.fftpack import rfft 17from ..core.base_classes import BaseFeatureExtractor 18 19 20class HARUPFeatureExtractor(BaseFeatureExtractor): 21 """ 22 HAR-UP feature extractor class. 23 24 This class implements the feature extraction methods used in the HAR-UP project. 25 It extracts both time-domain and frequency-domain features from sensor data. 26 """ 27 28 def __init__(self, verbose: bool = False): 29 """ 30 Initialize the HAR-UP feature extractor. 31 32 Args: 33 verbose: Whether to print progress information 34 """ 35 super().__init__( 36 name="harup", 37 description="HAR-UP Feature Extractor - Extracts features used in the HAR-UP project" 38 ) 39 self.config = { 40 'time_domain': True, 41 'frequency_domain': True, 42 'verbose': verbose 43 } 44 45 # Define the features to extract 46 self.time_domain_features = [ 47 'mean', 'std', 'rms', 'max_amp', 'min_amp', 'median', 48 'zero_crossings', 'skewness', 'kurtosis', 'q1', 'q3', 'autocorr' 49 ] 50 51 self.freq_domain_features = [ 52 'energy' 53 ] 54 55 def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]: 56 """ 57 Extract features from sliding windows. 58 59 Args: 60 windows: List of sliding window dictionaries 61 fs: Sampling frequency 62 **kwargs: Additional arguments for feature extraction 63 64 Returns: 65 List of feature dictionaries 66 """ 67 # Update config with kwargs 68 self.config.update(kwargs) 69 70 all_features = [] 71 72 # Skip label and activity_id windows 73 sensor_windows = [w for w in windows if w["name"] not in ["labels", "activity_id"]] 74 75 if self.config['verbose']: 76 print(f"Extracting features from {len(sensor_windows)} sensor windows") 77 78 # Process each sensor window 79 for window in sensor_windows: 80 sensor_name = window["name"] 81 sensor_data = window["data"] 82 83 if self.config['verbose']: 84 print(f"Processing {sensor_name} with {len(sensor_data)} windows") 85 86 # For each window of this sensor 87 for i, window_data in enumerate(sensor_data): 88 features = {} 89 features["sensor"] = sensor_name 90 91 # Time domain features 92 if self.config['time_domain']: 93 self._extract_time_domain_features(window_data, features) 94 95 # Frequency domain features 96 if self.config['frequency_domain']: 97 self._extract_freq_domain_features(window_data, features) 98 99 all_features.append(features) 100 101 return all_features 102 103 def _extract_time_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]): 104 """ 105 Extract time domain features from a window. 106 107 Args: 108 window_data: Window data 109 features: Dictionary to store the extracted features 110 """ 111 # Basic statistical features 112 features["mean"] = np.mean(window_data) 113 features["std"] = np.std(window_data) 114 features["rms"] = np.sqrt(np.mean(window_data**2)) 115 features["max_amp"] = np.max(np.abs(window_data)) 116 features["min_amp"] = np.min(np.abs(window_data)) 117 features["median"] = np.median(window_data) 118 119 # Zero crossings 120 zero_crossings = np.where(np.diff(np.signbit(window_data)))[0] 121 features["zero_crossings"] = len(zero_crossings) 122 123 # Higher-order statistics 124 features["skewness"] = skew(window_data) 125 features["kurtosis"] = kurtosis(window_data) 126 127 # Quartiles 128 features["q1"] = np.percentile(window_data, 25) 129 features["q3"] = np.percentile(window_data, 75) 130 131 # Autocorrelation 132 autocorr = np.correlate(window_data, window_data, mode='full') 133 features["autocorr"] = np.median(autocorr) 134 135 def _extract_freq_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]): 136 """ 137 Extract frequency domain features from a window. 138 139 Args: 140 window_data: Window data 141 features: Dictionary to store the extracted features 142 """ 143 # FFT 144 fft_values = abs(rfft(np.asarray(window_data))) 145 146 # Energy 147 features["energy"] = np.sum(fft_values**2) 148 149 def get_feature_names(self) -> List[str]: 150 """ 151 Get names of features extracted by this extractor. 152 153 Returns: 154 List of feature names 155 """ 156 feature_names = [] 157 158 if self.config['time_domain']: 159 feature_names.extend(self.time_domain_features) 160 161 if self.config['frequency_domain']: 162 feature_names.extend(self.freq_domain_features) 163 164 return feature_names 165 166 167# Legacy function wrapper for backward compatibility 168def extract_harup_features(windows: List[Dict], fs: int = 100, 169 time_domain: bool = True, freq_domain: bool = True, 170 verbose: bool = False) -> List[Dict]: 171 """ 172 Legacy function for extracting HAR-UP features. 173 174 Args: 175 windows: List of sliding window dictionaries 176 fs: Sampling frequency (default: 100Hz) 177 time_domain: Whether to extract time domain features 178 freq_domain: Whether to extract frequency domain features 179 verbose: Whether to print progress information 180 181 Returns: 182 List of feature dictionaries 183 """ 184 extractor = HARUPFeatureExtractor(verbose=verbose) 185 return extractor.extract_features( 186 windows, 187 fs=fs, 188 time_domain=time_domain, 189 frequency_domain=freq_domain 190 )
21class HARUPFeatureExtractor(BaseFeatureExtractor): 22 """ 23 HAR-UP feature extractor class. 24 25 This class implements the feature extraction methods used in the HAR-UP project. 26 It extracts both time-domain and frequency-domain features from sensor data. 27 """ 28 29 def __init__(self, verbose: bool = False): 30 """ 31 Initialize the HAR-UP feature extractor. 32 33 Args: 34 verbose: Whether to print progress information 35 """ 36 super().__init__( 37 name="harup", 38 description="HAR-UP Feature Extractor - Extracts features used in the HAR-UP project" 39 ) 40 self.config = { 41 'time_domain': True, 42 'frequency_domain': True, 43 'verbose': verbose 44 } 45 46 # Define the features to extract 47 self.time_domain_features = [ 48 'mean', 'std', 'rms', 'max_amp', 'min_amp', 'median', 49 'zero_crossings', 'skewness', 'kurtosis', 'q1', 'q3', 'autocorr' 50 ] 51 52 self.freq_domain_features = [ 53 'energy' 54 ] 55 56 def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]: 57 """ 58 Extract features from sliding windows. 59 60 Args: 61 windows: List of sliding window dictionaries 62 fs: Sampling frequency 63 **kwargs: Additional arguments for feature extraction 64 65 Returns: 66 List of feature dictionaries 67 """ 68 # Update config with kwargs 69 self.config.update(kwargs) 70 71 all_features = [] 72 73 # Skip label and activity_id windows 74 sensor_windows = [w for w in windows if w["name"] not in ["labels", "activity_id"]] 75 76 if self.config['verbose']: 77 print(f"Extracting features from {len(sensor_windows)} sensor windows") 78 79 # Process each sensor window 80 for window in sensor_windows: 81 sensor_name = window["name"] 82 sensor_data = window["data"] 83 84 if self.config['verbose']: 85 print(f"Processing {sensor_name} with {len(sensor_data)} windows") 86 87 # For each window of this sensor 88 for i, window_data in enumerate(sensor_data): 89 features = {} 90 features["sensor"] = sensor_name 91 92 # Time domain features 93 if self.config['time_domain']: 94 self._extract_time_domain_features(window_data, features) 95 96 # Frequency domain features 97 if self.config['frequency_domain']: 98 self._extract_freq_domain_features(window_data, features) 99 100 all_features.append(features) 101 102 return all_features 103 104 def _extract_time_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]): 105 """ 106 Extract time domain features from a window. 107 108 Args: 109 window_data: Window data 110 features: Dictionary to store the extracted features 111 """ 112 # Basic statistical features 113 features["mean"] = np.mean(window_data) 114 features["std"] = np.std(window_data) 115 features["rms"] = np.sqrt(np.mean(window_data**2)) 116 features["max_amp"] = np.max(np.abs(window_data)) 117 features["min_amp"] = np.min(np.abs(window_data)) 118 features["median"] = np.median(window_data) 119 120 # Zero crossings 121 zero_crossings = np.where(np.diff(np.signbit(window_data)))[0] 122 features["zero_crossings"] = len(zero_crossings) 123 124 # Higher-order statistics 125 features["skewness"] = skew(window_data) 126 features["kurtosis"] = kurtosis(window_data) 127 128 # Quartiles 129 features["q1"] = np.percentile(window_data, 25) 130 features["q3"] = np.percentile(window_data, 75) 131 132 # Autocorrelation 133 autocorr = np.correlate(window_data, window_data, mode='full') 134 features["autocorr"] = np.median(autocorr) 135 136 def _extract_freq_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]): 137 """ 138 Extract frequency domain features from a window. 139 140 Args: 141 window_data: Window data 142 features: Dictionary to store the extracted features 143 """ 144 # FFT 145 fft_values = abs(rfft(np.asarray(window_data))) 146 147 # Energy 148 features["energy"] = np.sum(fft_values**2) 149 150 def get_feature_names(self) -> List[str]: 151 """ 152 Get names of features extracted by this extractor. 153 154 Returns: 155 List of feature names 156 """ 157 feature_names = [] 158 159 if self.config['time_domain']: 160 feature_names.extend(self.time_domain_features) 161 162 if self.config['frequency_domain']: 163 feature_names.extend(self.freq_domain_features) 164 165 return feature_names
HAR-UP feature extractor class.
This class implements the feature extraction methods used in the HAR-UP project. It extracts both time-domain and frequency-domain features from sensor data.
29 def __init__(self, verbose: bool = False): 30 """ 31 Initialize the HAR-UP feature extractor. 32 33 Args: 34 verbose: Whether to print progress information 35 """ 36 super().__init__( 37 name="harup", 38 description="HAR-UP Feature Extractor - Extracts features used in the HAR-UP project" 39 ) 40 self.config = { 41 'time_domain': True, 42 'frequency_domain': True, 43 'verbose': verbose 44 } 45 46 # Define the features to extract 47 self.time_domain_features = [ 48 'mean', 'std', 'rms', 'max_amp', 'min_amp', 'median', 49 'zero_crossings', 'skewness', 'kurtosis', 'q1', 'q3', 'autocorr' 50 ] 51 52 self.freq_domain_features = [ 53 'energy' 54 ]
Initialize the HAR-UP feature extractor.
Args: verbose: Whether to print progress information
56 def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]: 57 """ 58 Extract features from sliding windows. 59 60 Args: 61 windows: List of sliding window dictionaries 62 fs: Sampling frequency 63 **kwargs: Additional arguments for feature extraction 64 65 Returns: 66 List of feature dictionaries 67 """ 68 # Update config with kwargs 69 self.config.update(kwargs) 70 71 all_features = [] 72 73 # Skip label and activity_id windows 74 sensor_windows = [w for w in windows if w["name"] not in ["labels", "activity_id"]] 75 76 if self.config['verbose']: 77 print(f"Extracting features from {len(sensor_windows)} sensor windows") 78 79 # Process each sensor window 80 for window in sensor_windows: 81 sensor_name = window["name"] 82 sensor_data = window["data"] 83 84 if self.config['verbose']: 85 print(f"Processing {sensor_name} with {len(sensor_data)} windows") 86 87 # For each window of this sensor 88 for i, window_data in enumerate(sensor_data): 89 features = {} 90 features["sensor"] = sensor_name 91 92 # Time domain features 93 if self.config['time_domain']: 94 self._extract_time_domain_features(window_data, features) 95 96 # Frequency domain features 97 if self.config['frequency_domain']: 98 self._extract_freq_domain_features(window_data, features) 99 100 all_features.append(features) 101 102 return all_features
Extract features from sliding windows.
Args: windows: List of sliding window dictionaries fs: Sampling frequency **kwargs: Additional arguments for feature extraction
Returns: List of feature dictionaries
150 def get_feature_names(self) -> List[str]: 151 """ 152 Get names of features extracted by this extractor. 153 154 Returns: 155 List of feature names 156 """ 157 feature_names = [] 158 159 if self.config['time_domain']: 160 feature_names.extend(self.time_domain_features) 161 162 if self.config['frequency_domain']: 163 feature_names.extend(self.freq_domain_features) 164 165 return feature_names
Get names of features extracted by this extractor.
Returns: List of feature names
Inherited Members
169def extract_harup_features(windows: List[Dict], fs: int = 100, 170 time_domain: bool = True, freq_domain: bool = True, 171 verbose: bool = False) -> List[Dict]: 172 """ 173 Legacy function for extracting HAR-UP features. 174 175 Args: 176 windows: List of sliding window dictionaries 177 fs: Sampling frequency (default: 100Hz) 178 time_domain: Whether to extract time domain features 179 freq_domain: Whether to extract frequency domain features 180 verbose: Whether to print progress information 181 182 Returns: 183 List of feature dictionaries 184 """ 185 extractor = HARUPFeatureExtractor(verbose=verbose) 186 return extractor.extract_features( 187 windows, 188 fs=fs, 189 time_domain=time_domain, 190 frequency_domain=freq_domain 191 )
Legacy function for extracting HAR-UP features.
Args: windows: List of sliding window dictionaries fs: Sampling frequency (default: 100Hz) time_domain: Whether to extract time domain features freq_domain: Whether to extract frequency domain features verbose: Whether to print progress information
Returns: List of feature dictionaries