# Features for time series classification

I consider the problem of (multiclass) classification based on time series of variable length $T$, that is, to find a function $$f(X_T) = y \in [1..K]\\ \text{for } X_T = (x_1, \dots, x_T)\\ \text{with } x_t \in \mathbb{R}^d ~,$$ via a global representation of the time serie by a set of selected features $v_i$ of fixed size $D$ independent of $T$, $$\phi(X_T) = v_1, \dots, v_D \in \mathbb{R}~,$$ and then use standard classification methods on this feature set. I'm not interested in forecasting, i.e. predicting $x_{T+1}$. For example, we may analyse the way a person walks to predict the gender of the person.

What are the standard features that I may take into account ? In example, we can obviously use the mean and variance of the serie (or higher order moments) and also look into the frequency domain, like the energy contained in some interval of the Discrete Fourier Transform of the serie (or Discrete Wavelet Transform).

## Simple statistical features

• Means in each of the $d$ dimensions
• Standard deviations of the $d$ dimensions
• Skewness, Kurtosis and Higher order moments of the $d$ dimensions
• Maximum and Minimum values

## Time serie analysis related features

• The $d \times d-1$ Cross-Correlations between each dimension and the $d$ Auto-Correlations
• Orders of the autoregressive (AR), integrated (I) and moving average (MA) part of an estimated ARIMA model
• Parameters of the AR part
• Parameters of the MA part

## Frequency domain related features

See Morchen03 for a study of energy preserving features on DFT and DWT

• frequencies of the $k$ peaks in amplitude in the DFTs for the detrended $d$ dimensions
• $k$-quantiles of these DFTs
• Emile, This question is similar to one I just posed (stats.stackexchange.com/questions/51475/…). Would you be able to post any R code for the DFT features? Mar 6, 2013 at 15:43
• Is there any method based on shapelets for variable length time series? Jun 9, 2015 at 4:18

As the other answers suggested, there is a huge number of time series characteristics that can be used as potential features. There are simple features such as the mean, time series related features such as the coefficients of an AR model or highly sophisticated features such as the test statistic of the augmented dickey fuller hypothesis test.

# Comprehensive Overview over possible time series features

The python package tsfresh automates the extraction of those features. Its documentation describes the different calculated features. You can find the page with the calculated features here.

Disclaimer: I am one of the authors of tsfresh.

Emile, I think the features listed in your answer are pretty good starting points, though as always, I think some domain expertise (or at least a good long think) about your problem is equally important.

You may want to consider including features calculated from the derivatives (or integrals) of your signal. For example, I would wager that rapid acceleration/deceleration is a reasonably good predictors of accident-prone driving. That information is obviously still present in the position signal, but it's not nearly as explicit.

You may also want to consider replacing the Fourier coefficients with a wavelet or wavelet packet representation. The major advantage of wavelets is that they allow you to localize a feature in both frequency and time, while the traditional Fourier coefficients are restricted to only time. This might be particularly useful if your data contains components that switch on/off irregularly or has square wave-like pulses that can be problematic for Fourier methods.

I suggest you, instead of using classic approaches for extracting hand-engineered features, utilise autoencoders. Autoencoders plays an important role in the feature extraction of deep learning architecture.

The autoencoder tries to learn a function $f(X_T)≈X_T$. In other words, it is trying to learn an approximation to the identity function, so as to output $\hat X_T$ that is similar to $X_T$.

The identity function seems a particularly trivial function to be trying to learn; but by placing constraints on the network, such as by limiting the number of hidden units, we can discover interesting structure about the data. In this way, your desired $ϕ(X_T)=v_1,…,v_D \in R$ will be equivalent to the output values of the middlemost layer in a deep autoencoder, If you limit the number of hidden units in the middlemost to $D$.

Additionally, you can use many flavors of autoencoder for finding the best solution to your problem.

The linked paper will be somewhat enlightening, since it is interested in the more or less the same issue in another context.

Paper abstract (in the Internet Archive)

Paper PDF

Depending on the length of your time series, the usual approach is to epoch the data into segments, e.g. 10 secs.

However, often prior to breaking the time-series into segments it is necessary to perform some preprocessing such as filtering and artifact rejection. You can then compute a variety of features such as those based on frequency (i.e. take an FFT for each epoch), time (e.g. mean, variance etc of the time-series in that epoch) or morphology, (i.e. the shape of the signal/time-series in each epoch).

Usually the features used to classify segments (epochs) of a time-series/signal are domain-specific but Wavelet/Fourier analysis are simply tools to allow you examine your signal in the frequency/time-frequency domains rather than being features in themselves.

In a classification problem each epoch will have a class label e.g. 'happy' or 'sad', you would then train a classifier to distinguish between 'happy' and 'sad' epochs using the 6 features calculated for each epoch.

In the event that each time series represents a single case for classification, you need to calculate each feature across all samples of the time series. The FFT is only relevant here if the signal is linear time invariant (LTI), i.e. if the signal can be considered to be stationary over the whole time series, if the signal is not stationary over the period of interest, a wavelet analysis may be more appropriate. This approach will mean that each time series will produce one feature vector and will constitute one case for classification.

• I've always felt that breaking time series, a naturally continuous process, into discrete periods (or epochs), results in a loss of information. Unless there is natural epochs in the series, how does one choose epochs? Likely epochs can be found that fits any desired outcome. Feb 25, 2013 at 16:02
• Not sure that an epoch can be found to suit every outcome but for any practical problem With a non-stationary signal you need to find someway to take into account temporal variations (if a signal/time-series adequately described analytically or is linear time invariant this not necessary). The epoch length is again domain specific but usually chosen to be short enough that the signal is stationary under the time period (epoch) of interest. Feb 25, 2013 at 16:10
• BGreene, could you explain what is the benefit of partitioning the serie into epochs for selecting features used in classification ? I see this partitioning as a helper for later computations (i.e. FFT), but not as something related to the selection of features themselves. Maybe it is related to the "morphology" you mentioned. Feb 25, 2013 at 16:20
• The partitioning into epochs has nothing to do with feature selection. If you have a long signal (e.g. 10 hours of recording sampled @100Hz) then in order to examine how the signal changes over time you need to break it into epochs. In a classification problem each epoch will have a class label e.g. 'happy' or 'sad', you would then train a classifier to distinguish between 'happy' and 'sad' epochs using the 6 features calculated for each epoch. Feb 25, 2013 at 16:39
• Ok:) It is definitely unrelated to my original question. I consider the case where the class labels the whole serie. I'm going to edit my question to add a clarifying example. Feb 25, 2013 at 16:52

The TSFEL package provides this very comprehensive list of possible time series features. The source code shows how every feature is calculated in detail.

You can find a comprehensive list below:

* abs_energy(signal)    Computes the absolute energy of the signal.
* auc(signal, fs)   Computes the area under the curve of the signal computed with trapezoid rule.
* autocorr(signal)  Computes autocorrelation of the signal.
* calc_centroid(signal, fs)     Computes the centroid along the time axis.
* calc_max(signal)  Computes the maximum value of the signal.
* calc_mean(signal)     Computes mean value of the signal.
* calc_median(signal)   Computes median of the signal.
* calc_min(signal)  Computes the minimum value of the signal.
* calc_std(signal)  Computes standard deviation (std) of the signal.
* calc_var(signal)  Computes variance of the signal.
* distance(signal)  Computes signal traveled distance.
* ecdf(signal[, d])     Computes the values of ECDF (empirical cumulative distribution function) along the time axis.
* ecdf_percentile(signal[, percentile])     Computes the percentile value of the ECDF.
* ecdf_percentile_count(signal[, percentile])   Computes the cumulative sum of samples that are less than the percentile.
* ecdf_slope(signal[, p_init, p_end])   Computes the slope of the ECDF between two percentiles.
* entropy(signal[, prob])   Computes the entropy of the signal using the Shannon Entropy.
* fft_mean_coeff(signal, fs[, nfreq])   Computes the mean value of each spectrogram frequency.
* fundamental_frequency(signal, fs)     Computes fundamental frequency of the signal.
* hist(signal[, nbins, r])  Computes histogram of the signal.
* human_range_energy(signal, fs)    Computes the human range energy ratio.
* interq_range(signal)  Computes interquartile range of the signal.
* kurtosis(signal)  Computes kurtosis of the signal.
* lpcc(signal[, n_coeff])   Computes the linear prediction cepstral coefficients.
* max_frequency(signal, fs)     Computes maximum frequency of the signal.
* max_power_spectrum(signal, fs)    Computes maximum power spectrum density of the signal.
* mean_abs_deviation(signal)    Computes mean absolute deviation of the signal.
* mean_abs_diff(signal)     Computes mean absolute differences of the signal.
* mean_diff(signal)     Computes mean of differences of the signal.
* median_abs_deviation(signal)  Computes median absolute deviation of the signal.
* median_abs_diff(signal)   Computes median absolute differences of the signal.
* median_diff(signal)   Computes median of differences of the signal.
* median_frequency(signal, fs)  Computes median frequency of the signal.
* mfcc(signal, fs[, pre_emphasis, nfft, …])     Computes the MEL cepstral coefficients.
* negative_turning(signal)  Computes number of negative turning points of the signal.
* neighbourhood_peaks(signal[, n])  Computes the number of peaks from a defined neighbourhood of the signal.
* pk_pk_distance(signal)    Computes the peak to peak distance.
* positive_turning(signal)  Computes number of positive turning points of the signal.
* power_bandwidth(signal, fs)   Computes power spectrum density bandwidth of the signal.
* rms(signal)   Computes root mean square of the signal.
* skewness(signal)  Computes skewness of the signal.
* slope(signal)     Computes the slope of the signal.
* spectral_centroid(signal, fs)     Barycenter of the spectrum.
* spectral_decrease(signal, fs)     Represents the amount of decreasing of the spectra amplitude.
* spectral_distance(signal, fs)     Computes the signal spectral distance.
* spectral_entropy(signal, fs)  Computes the spectral entropy of the signal based on Fourier transform.
* spectral_kurtosis(signal, fs)     Measures the flatness of a distribution around its mean value.
* spectral_positive_turning(signal, fs)     Computes number of positive turning points of the fft magnitude signal.
* spectral_roll_off(signal, fs)     Computes the spectral roll-off of the signal.
* spectral_roll_on(signal, fs)  Computes the spectral roll-on of the signal.
* spectral_skewness(signal, fs)     Measures the asymmetry of a distribution around its mean value.
* spectral_slope(signal, fs)    Computes the spectral slope.
* spectral_spread(signal, fs)   Measures the spread of the spectrum around its mean value.
* spectral_variation(signal, fs)    Computes the amount of variation of the spectrum along time.
* sum_abs_diff(signal)  Computes sum of absolute differences of the signal.
* total_energy(signal, fs)  Computes the total energy of the signal.
* wavelet_abs_mean(signal[, function, widths])  Computes CWT absolute mean value of each wavelet scale.
* wavelet_energy(signal[, function, widths])    Computes CWT energy of each wavelet scale.
* wavelet_entropy(signal[, function, widths])   Computes CWT entropy of the signal.
* wavelet_std(signal[, function, widths])   Computes CWT std value of each wavelet scale.
* wavelet_var(signal[, function, widths])   Computes CWT variance value of each wavelet scale.
* zero_cross(signal)    Computes Zero-crossing rate of the signal.

• At present this is more of a comment than an answer. You could expand it, perhaps by giving a summary of the information at the link, or you can convert it into a comment. Jan 4, 2021 at 19:19
• Thank you for your comment. I edited my answer. It now provides a comprehensive list of the mentionef features. Jan 5, 2021 at 9:45