<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/tsrepr-time-series-representations-in-r/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://petolau.github.io/TSrepr-time-series-representations/"> Peter Laurinec</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I’m happy to announce a new package that has recently appeared on CRAN, called “<strong>TSrepr</strong>” (version 1.0.0: <a rel="nofollow" href="https://cran.r-project.org/package=TSrepr" target="_blank">https://CRAN.R-project.org/package=TSrepr</a>).</p>
<p>The <strong>TSrepr</strong> package contains methods of time series representations (dimensionality reduction, feature extraction or preprocessing) and several other useful helper methods and functions.</p>
<p>Time series representation can be defined as follows:</p>
<p>Let \( x \) be a time series of length \( n \), then representation of \( x \) is a model \( \hat{x} \) with reduced dimensionality \( p \) \( (p &lt; n) \) such that \( \hat{x} \) approximates closely \( x \) (Esling and Agon (2012)).</p>
<p>Time series representations are used for:</p>
<ul>
<li>significant reduction of the time series dimensionality</li>
<li>emphasis on fundamental (essential) shape characteristics</li>
<li>implicit noise handling</li>
<li>reducing the dimension will reduce memory requirements and computational complexity of consequent machine learning methods.</li>
</ul>
<p>Therefore, they are awesome!</p>
<p>Time series representation methods can be divided into four groups (types) (Aghabozorgi, Seyed Shirkhorshidi, and Ying Wah (2015)):</p>
<ul>
<li>nondata adaptive</li>
<li>data adaptive</li>
<li>model-based</li>
<li>data dictated (clipped data).</li>
</ul>
<p>In <strong>nondata adaptive</strong> representations, the parameters of transformation remain the same for all time series, irrespective of their nature.<br>
In <strong>data adaptive</strong> representations, the parameters of transformation vary depending on the available data.<br>
An approach to the <strong>model-based</strong> representation relies on the assumption that the observed time series was created based on basic model. The aim is to find the parameters of such a model as a representation. Two time series are then considered as similar if they were created by the same set of parameters of a basic model.<br>
In <strong>data dictated</strong> approaches, the compression ratio is defined automatically based on raw time series such as clipped (Aghabozorgi, Seyed Shirkhorshidi, and Ying Wah (2015)).</p>
<p>Most famous (well known) methods for <strong>nondata adaptive</strong> type of representations are PAA (Piecewise Aggregate Approximation), DWT (Discrete Wavelet Transform), DFT (Discrete Fourier Transform), DCT (Discrete Cosine Transform) or PIP (Perceptually Important Points). For <strong>data adaptive</strong> type of representations, it is SAX (Symbolic Aggregate approXimation), PLA (Piecewise Linear Approximation) and SVD (Singular Value Decomposition).<br>
For <strong>model-based</strong> representations it is ARMA, mean profiles or estimated regression coefficients from a statistical model (e.g. linear model).<br>
The <strong>data dictated</strong> is the less known type of representation and the most famous method of this type is clipping (bit-level) representation (Bagnall et al. (2006)).</p>
<h2>Implemented methods and functions</h2>
<p>In the <strong>TSrepr</strong> package, these time series representation methods are implemented (the function names are in brackets):</p>
<ul>
<li>Nondata adaptive:
<ul>
<li>PAA – Piecewise Aggregate Approximation (<code>repr_paa</code>)</li>
<li>DWT – Discrete Wavelet Transform (<code>repr_dwt</code>)</li>
<li>DFT – Discrete Fourier Transform (<code>repr_dft</code>)</li>
<li>DCT – Discrete Cosine Transform (<code>repr_dct</code>)</li>
<li>SMA – Simple Moving Average (<code>repr_sma</code>)</li>
<li>PIP – Perceptually Important Points (<code>repr_pip</code>)</li>
</ul>
</li>
<li>Data adaptive:
<ul>
<li>SAX – Symbolic Aggregate Approximation (<code>repr_sax</code>)</li>
<li>PLA – Piecewise Linear Approximation (<code>repr_pla</code>)</li>
</ul>
</li>
<li>Model-based:
<ul>
<li>Mean seasonal profile – Average seasonal profile, Median seasonal profile, etc. (<code>repr_seas_profile</code>)</li>
<li>Model-based seasonal representations based on linear (additive) model (LM, RLM, L1, GAM) (<code>repr_lm</code>, <code>repr_gam</code>)</li>
<li>Exponential smoothing seasonal coefficients (<code>repr_exp</code>)</li>
</ul>
</li>
<li>Data dictated:
<ul>
<li>FeaClip – Feature extraction from clipping representation (<code>repr_feaclip</code>, <code>clipping</code>)</li>
<li>FeaTrend – Feature extraction from trending representation (<code>repr_featrend</code>, <code>trending</code>)</li>
<li>FeaClipTrend – Feature extraction from clipping and trending representation (<code>repr_feacliptrend</code>)</li>
</ul>
</li>
</ul>
<p>Some additional useful functions are also implemented in the <strong>TSrepr</strong> package, such as:</p>
<ul>
<li>Windowing (<code>repr_windowing</code>) – applies to the above mentioned representations to every window of a time series</li>
<li>Matrix of representations (<code>repr_matrix</code>) – applies to the above mentioned representations to every row of a matrix of time series</li>
<li>Normalisation functions – z-score (<code>norm_z</code>), min-max (<code>norm_min_max</code>)</li>
<li>Normalisation functions with output also of scaling parameters – z-score (<code>norm_z_list</code>), min-max (<code>norm_min_max_list</code>)</li>
<li>Denormalisation functions – z-score (<code>denorm_z</code>), min-max (<code>denorm_min_max</code>)</li>
<li>Forecasting accuracy measures – MAE, RMSE, MdAE, MAPE, sMAPE, MASE.</li>
</ul>
<h2>Usage of the TSrepr package</h2>
<p>The <strong>TSrepr</strong> functions can be used very easily. The input is always a numeric vector (univariate time series) and additional arguments can occur in some methods.</p>
<p>Let’s load the package and ggplot2 for visualizations:</p>
<figure>
<pre><code data-lang="r"><span># install.packages(&quot;TSrepr&quot;)</span><span><br data-jekyll-commonmark-ghpages=""></span><span>library</span><span>(</span><span>TSrepr</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span>library</span><span>(</span><span>ggplot2</span><span>)</span></code></pre>
</figure>
<p>Let’s load electricity consumption data (<code>elec_load</code>) and use first time series from the dataset. There is 672 values, so 14 days of measurements.</p>
<figure>
<pre><code data-lang="r"><span>data</span><span>(</span><span>&quot;elec_load&quot;</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""> <br data-jekyll-commonmark-ghpages=""></span><span>data_ts</span><span> </span><span>&lt;-</span><span> </span><span>as.numeric</span><span>(</span><span>elec_load</span><span>[</span><span>1</span><span>,])</span><span><br data-jekyll-commonmark-ghpages=""> <br data-jekyll-commonmark-ghpages=""></span><span>ggplot</span><span>(</span><span>data.frame</span><span>(</span><span>Time</span><span> </span><span>=</span><span> </span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_ts</span><span>),</span><span> </span><span>Value</span><span> </span><span>=</span><span> </span><span>data_ts</span><span>),</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>()</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-2" src="https://i2.wp.com/petolau.github.io/images/post_7/unnamed-chunk-2-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Now, we want to for example reduce dimensionality and reduce the noise of our time series. We can of course, use the time series representations from the <strong>TSrepr</strong> package. We can compare multiple methods here that are suitable for this task (smoothing of highly noised time series), for example, <strong>PAA</strong>, <strong>DWT</strong>, <strong>DFT</strong> or <strong>DCT</strong>.<br>
We will reduce dimensionality 8 times, so from 672 to 84.</p>
<figure>
<pre><code data-lang="r"><span># DWT with level of 2^3</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_dwt</span><span> </span><span>&lt;-</span><span> </span><span>repr_dwt</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>level</span><span> </span><span>=</span><span> </span><span>3</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># first 84 DFT coefficients are extracted and then inverted</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_dft</span><span> </span><span>&lt;-</span><span> </span><span>repr_dft</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>coef</span><span> </span><span>=</span><span> </span><span>84</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># first 84 DCT coefficients are extracted and then inverted</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_dct</span><span> </span><span>&lt;-</span><span> </span><span>repr_dct</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>coef</span><span> </span><span>=</span><span> </span><span>84</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># Classical PAA</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_paa</span><span> </span><span>&lt;-</span><span> </span><span>repr_paa</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>q</span><span> </span><span>=</span><span> </span><span>8</span><span>,</span><span> </span><span>func</span><span> </span><span>=</span><span> </span><span>mean</span><span>)</span></code></pre>
</figure>
<p>Let’s plot the results:</p>
<figure>
<pre><code data-lang="r"><span>data_plot</span><span> </span><span>&lt;-</span><span> </span><span>data.frame</span><span>(</span><span>Value</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>data_dwt</span><span>,</span><span> </span><span>data_dft</span><span>,</span><span> </span><span>data_dct</span><span>,</span><span> </span><span>data_paa</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>Time</span><span> </span><span>=</span><span> </span><span>rep</span><span>(</span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_dwt</span><span>),</span><span> </span><span>4</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>Method</span><span> </span><span>=</span><span> </span><span>factor</span><span>(</span><span>rep</span><span>(</span><span>c</span><span>(</span><span>&quot;DWT&quot;</span><span>,</span><span> </span><span>&quot;DFT&quot;</span><span>,</span><span> </span><span>&quot;DCT&quot;</span><span>,</span><span> </span><span>&quot;PAA&quot;</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>each</span><span> </span><span>=</span><span> </span><span>length</span><span>(</span><span>data_dwt</span><span>))))</span><span><br data-jekyll-commonmark-ghpages=""> <br data-jekyll-commonmark-ghpages=""></span><span>ggplot</span><span>(</span><span>data_plot</span><span>,</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>,</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>Method</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>(</span><span>alpha</span><span> </span><span>=</span><span> </span><span>0.80</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>0.8</span><span>)</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-4" src="https://i2.wp.com/petolau.github.io/images/post_7/unnamed-chunk-4-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>We can see that the electricity consumption pattern remains also after significant reduction of dimensionality. The difference between these four representation methods is not really significant, every one of them “did the job” well.</p>
<p>For seasonal time series as electricity load data, the model-based representations are highly recommended (Laurinec et al. (2016), Laurinec and Lucká (2016)). By model-based representation, we can extract a daily profile of some consumer. We can do it by simple average (or median) daily profile or by extraction of <strong>seasonal regression coefficients</strong>.</p>
<p>For this task, several methods are implemented in the <strong>TSrepr</strong> package. The mean <strong>seasonal profile</strong> (<code>repr_seas_profile</code>), seasonal linear models (<code>repr_lm</code>), seasonal additive model (<code>repr_gam</code>) or seasonal exponential smoothing coefficients (<code>repr_exp</code>). Let’s compare them on our data.</p>
<figure>
<pre><code data-lang="r"><span>data_lm</span><span> </span><span>&lt;-</span><span> </span><span>repr_lm</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>freq</span><span> </span><span>=</span><span> </span><span>48</span><span>,</span><span> </span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;lm&quot;</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># robust linear model and l1 regression are also implemented</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_l1</span><span> </span><span>&lt;-</span><span> </span><span>repr_lm</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>freq</span><span> </span><span>=</span><span> </span><span>48</span><span>,</span><span> </span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;l1&quot;</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># GAM</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_gam</span><span> </span><span>&lt;-</span><span> </span><span>repr_gam</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>freq</span><span> </span><span>=</span><span> </span><span>48</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># median seasonal profile</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_seas_prof</span><span> </span><span>&lt;-</span><span> </span><span>repr_seas_profile</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>freq</span><span> </span><span>=</span><span> </span><span>48</span><span>,</span><span> </span><span>func</span><span> </span><span>=</span><span> </span><span>median</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span># exponential smoothing</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_exp</span><span> </span><span>&lt;-</span><span> </span><span>repr_exp</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>freq</span><span> </span><span>=</span><span> </span><span>48</span><span>)</span></code></pre>
</figure>
<p>And let’s plot the results:</p>
<figure>
<pre><code data-lang="r"><span>data_plot</span><span> </span><span>&lt;-</span><span> </span><span>data.frame</span><span>(</span><span>Value</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>data_lm</span><span>,</span><span> </span><span>data_l1</span><span>,</span><span> </span><span>data_seas_prof</span><span>,</span><span> </span><span>data_exp</span><span>,</span><span> </span><span>data_gam</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>Time</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>rep</span><span>(</span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_lm</span><span>),</span><span> </span><span>4</span><span>),</span><span> </span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_gam</span><span>)),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>Method</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>rep</span><span>(</span><span>c</span><span>(</span><span>&quot;LM&quot;</span><span>,</span><span> </span><span>&quot;L1&quot;</span><span>,</span><span> </span><span>&quot;Median seas. prof.&quot;</span><span>,</span><span> </span><span>&quot;Exp. smooth.&quot;</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>each</span><span> </span><span>=</span><span> </span><span>48</span><span>),</span><span> </span><span>rep</span><span>(</span><span>&quot;GAM&quot;</span><span>,</span><span> </span><span>47</span><span>)))</span><span><br data-jekyll-commonmark-ghpages=""> <br data-jekyll-commonmark-ghpages=""></span><span>ggplot</span><span>(</span><span>data_plot</span><span>,</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>,</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>Method</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>(</span><span>alpha</span><span> </span><span>=</span><span> </span><span>0.80</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>0.8</span><span>)</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-6" src="https://i2.wp.com/petolau.github.io/images/post_7/unnamed-chunk-6-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>We can see that the most fluctuate result has exponential smoothing representation and the most smooth (denoised) result has seasonal <strong>GAM</strong> representation. Median daily profile and seasonal L1 regression coefficients are almost identical, the seasonal linear model regression coefficients representation is similar to them, but not that smooth.</p>
<p>There are also two similar time series representation methods in <strong>TSrepr</strong> package that extract important points from time series – <strong>PIP</strong> and <strong>PLA</strong>. Let’s try it on our data, and we will extract 60 points from the original time series (there will be 61 points in the end because of the nature of these methods). If we set <code>return = &quot;both&quot;</code>, then data.frame with both places and points will be returned.</p>
<figure>
<pre><code data-lang="r"><span>data_pip</span><span> </span><span>&lt;-</span><span> </span><span>repr_pip</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>times</span><span> </span><span>=</span><span> </span><span>60</span><span>,</span><span> </span><span>return</span><span> </span><span>=</span><span> </span><span>&quot;both&quot;</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_pla</span><span> </span><span>&lt;-</span><span> </span><span>repr_pla</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>times</span><span> </span><span>=</span><span> </span><span>60</span><span>,</span><span> </span><span>return</span><span> </span><span>=</span><span> </span><span>&quot;both&quot;</span><span>)</span></code></pre>
</figure>
<p>And, of course, let’s plot the results.</p>
<figure>
<pre><code data-lang="r"><span>data_plot</span><span> </span><span>&lt;-</span><span> </span><span>data.frame</span><span>(</span><span>Value</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>data_pip</span><span>$</span><span>points</span><span>,</span><span> </span><span>data_pla</span><span>$</span><span>points</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>Time</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_ts</span><span>),</span><span> </span><span>data_pip</span><span>$</span><span>places</span><span>,</span><span> </span><span>data_pla</span><span>$</span><span>places</span><span>),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>Method</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>rep</span><span>(</span><span>&quot;Original&quot;</span><span>,</span><span> </span><span>length</span><span>(</span><span>data_ts</span><span>)),</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>rep</span><span>(</span><span>c</span><span>(</span><span>&quot;PIP&quot;</span><span>,</span><span> </span><span>&quot;PLA&quot;</span><span>),</span><span> </span><span>each</span><span> </span><span>=</span><span> </span><span>length</span><span>(</span><span>data_pla</span><span>$</span><span>places</span><span>))))</span><span><br data-jekyll-commonmark-ghpages=""> <br data-jekyll-commonmark-ghpages=""></span><span>ggplot</span><span>(</span><span>data_plot</span><span>,</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>,</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>Method</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>(</span><span>alpha</span><span> </span><span>=</span><span> </span><span>0.65</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>0.8</span><span>)</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-8" src="https://i1.wp.com/petolau.github.io/images/post_7/unnamed-chunk-8-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>We can see some significant differences among these two methods, but both approaches identified important points well.</p>
<p>The next data adaptive representation method is <strong>SAX</strong>. The SAX is a famous time series representation method – for its adaptability and originality. It extracts symbols as representation, in other words, it transforms aggregates of a time series to alphabetical symbols. Let’s use it on our data:</p>
<figure>
<pre><code data-lang="r"><span># aggregates of size 12 and alphabet of size 10</span><span><br data-jekyll-commonmark-ghpages=""></span><span>repr_sax</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>q</span><span> </span><span>=</span><span> </span><span>12</span><span>,</span><span> </span><span>a</span><span> </span><span>=</span><span> </span><span>10</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">##  [1] &quot;g&quot; &quot;i&quot; &quot;g&quot; &quot;j&quot; &quot;g&quot; &quot;j&quot; &quot;j&quot; &quot;j&quot; &quot;f&quot; &quot;i&quot; &quot;j&quot; &quot;j&quot; &quot;f&quot; &quot;h&quot; &quot;j&quot; &quot;j&quot; &quot;f&quot;<br data-jekyll-commonmark-ghpages="">## [18] &quot;i&quot; &quot;h&quot; &quot;h&quot; &quot;f&quot; &quot;i&quot; &quot;i&quot; &quot;i&quot; &quot;f&quot; &quot;i&quot; &quot;f&quot; &quot;i&quot; &quot;f&quot; &quot;g&quot; &quot;g&quot; &quot;i&quot; &quot;f&quot; &quot;i&quot;<br data-jekyll-commonmark-ghpages="">## [35] &quot;g&quot; &quot;h&quot; &quot;f&quot; &quot;f&quot; &quot;f&quot; &quot;i&quot; &quot;h&quot; &quot;h&quot; &quot;f&quot; &quot;i&quot; &quot;f&quot; &quot;g&quot; &quot;f&quot; &quot;i&quot; &quot;f&quot; &quot;h&quot; &quot;g&quot;<br data-jekyll-commonmark-ghpages="">## [52] &quot;i&quot; &quot;f&quot; &quot;h&quot; &quot;g&quot; &quot;i&quot;</code></pre>
</figure>
<p>The last type of implemented representation methods is the <strong>data dictated</strong> – clipped. I developed two methods in this category – <strong>FeaClip</strong> and <strong>FeaTrend</strong>.<br>
Both creates bit-level (binary) representation from original time series and computes run lengths of values by RLE (Run Length Encoding). Then interpretable features are extracted from run lengths.</p>
<p>I will now describe the first of the mentioned methods – **FeaClip **. Clipping representation is created very easily – if a value of a time series is greater then its average value, then the value is transformed to 1 and otherwise to 0. It can be defined formally as follows:</p>
<p></p>
<p>where $\mu$ is the average value of a time series. On <strong>clipping</strong> (bit-level) representation $\hat{x}$, compression method for binary series named Run Length Encoding (<strong>RLE</strong>) is applied. A run is continuous sequence of ones, respectively zeros. The number of ones respectively zeros in a run we call the run lengths. From run lengths counted by RLE, eight simple interpretable features are extracted to form the final representation and are defined as</p>
<p></p>
<p>Now, I will use methods implemented in <strong>TSrepr</strong> package to show you how it works. The clipped series is created by function <code>clipping</code>, I will only extract the first day from the electricity consumption time series.</p>
<figure>
<pre><code data-lang="r"><span>data_oneday</span><span> </span><span>&lt;-</span><span> </span><span>data_ts</span><span>[</span><span>1</span><span>:</span><span>48</span><span>]</span><span><br data-jekyll-commonmark-ghpages=""></span><span>clipping</span><span>(</span><span>data_oneday</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">##  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1<br data-jekyll-commonmark-ghpages="">## [36] 1 1 0 0 0 0 1 1 1 1 1 0 0</code></pre>
</figure>
<p>If we visualize the data with its average value, then we can see that it works as the definition above:</p>
<figure>
<pre><code data-lang="r"><span>ggplot</span><span>(</span><span>data.frame</span><span>(</span><span>Time</span><span> </span><span>=</span><span> </span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_oneday</span><span>),</span><span> </span><span>Value</span><span> </span><span>=</span><span> </span><span>data_oneday</span><span>),</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>()</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data.frame</span><span>(</span><span>Time</span><span> </span><span>=</span><span> </span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_oneday</span><span>),</span><span> </span><span>Value</span><span> </span><span>=</span><span> </span><span>mean</span><span>(</span><span>data_oneday</span><span>)),</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>),</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>&quot;red&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>1</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>0.8</span><span>)</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-11" src="https://i1.wp.com/petolau.github.io/images/post_7/unnamed-chunk-11-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Then RLE is used for the extraction of run lengths:</p>
<figure>
<pre><code data-lang="r"><span>rleC</span><span>(</span><span>clipping</span><span>(</span><span>data_oneday</span><span>))</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## $lengths<br data-jekyll-commonmark-ghpages="">## [1] 16  3 15  3  4  5  2<br data-jekyll-commonmark-ghpages="">## <br data-jekyll-commonmark-ghpages="">## $values<br data-jekyll-commonmark-ghpages="">## [1] 0 1 0 1 0 1 0</code></pre>
</figure>
<p>And finally, the extraction of interpretable features and all previous procedures is implemented in the <code>repr_feaclip</code> function:</p>
<figure>
<pre><code data-lang="r"><span>repr_feaclip</span><span>(</span><span>data_oneday</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## max_1 sum_1 max_0 jumps  0_1.  0_n.  1_1.  1_n. <br data-jekyll-commonmark-ghpages="">##     5    11    16     6    16     2     0     0</code></pre>
</figure>
<p>The <strong>FeaClip</strong> method is recommended to use with <strong>windowing</strong> approach, so for every specified window the FeaClip computation is separately applied. For the electricity consumption data, I am using the length of the window equal to 1 day so 48 measurements. The windowing method is implemented by function <code>repr_windowing</code> and its arguments are representation function (<code>func</code>), window size (<code>win_size</code>) and list of additional arguments to representation function (<code>args</code>). Let’s use it in our case:</p>
<figure>
<pre><code data-lang="r"><span>data_feaclip</span><span> </span><span>&lt;-</span><span> </span><span>repr_windowing</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>func</span><span> </span><span>=</span><span> </span><span>repr_feaclip</span><span>,</span><span> </span><span>win_size</span><span> </span><span>=</span><span> </span><span>48</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""> <br data-jekyll-commonmark-ghpages=""></span><span>ggplot</span><span>(</span><span>data.frame</span><span>(</span><span>Time</span><span> </span><span>=</span><span> </span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_feaclip</span><span>),</span><span> </span><span>Value</span><span> </span><span>=</span><span> </span><span>data_feaclip</span><span>),</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>()</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-14" src="https://i1.wp.com/petolau.github.io/images/post_7/unnamed-chunk-14-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>The second data dictated method is <strong>FeaTrend</strong>. It extracts features from “trending” (again binary) representation. The trending representation is defined as follows:</p>
<p></p>
<p>So, when time series value increased then it is 1, otherwise it is 0.</p>
<p>Before the computation of trending representation, a time series is smoothed (denoised) by simple moving average method (<code>repr_sma</code>) in order to have more compact run lengths. Let’s demonstrate this factor in our example case, so we will use <code>trending</code> and RLE function on original and also on the smoothed time series:</p>
<figure>
<pre><code data-lang="r"><span># original time series</span><span><br data-jekyll-commonmark-ghpages=""></span><span>rleC</span><span>(</span><span>trending</span><span>(</span><span>data_oneday</span><span>))</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## $lengths<br data-jekyll-commonmark-ghpages="">##  [1] 2 2 2 2 1 2 2 4 2 2 1 1 1 2 2 2 1 4 4 4 4<br data-jekyll-commonmark-ghpages="">## <br data-jekyll-commonmark-ghpages="">## $values<br data-jekyll-commonmark-ghpages="">##  [1] 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0</code></pre>
</figure>
<figure>
<pre><code data-lang="r"><span># smoothed time series by SMA</span><span><br data-jekyll-commonmark-ghpages=""></span><span>rleC</span><span>(</span><span>trending</span><span>(</span><span>repr_sma</span><span>(</span><span>data_oneday</span><span>,</span><span> </span><span>order</span><span> </span><span>=</span><span> </span><span>4</span><span>)))</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## $lengths<br data-jekyll-commonmark-ghpages="">##  [1] 6 2 2 4 5 4 2 1 2 5 3 5 2<br data-jekyll-commonmark-ghpages="">## <br data-jekyll-commonmark-ghpages="">## $values<br data-jekyll-commonmark-ghpages="">##  [1] 0 1 0 1 0 1 0 1 0 1 0 1 0</code></pre>
</figure>
<p>As expected, the run lengths of smoothed time series are more compact.<br>
The <strong>FeaTrend</strong> is designed to extract an arbitrary feature from run lengths of a trending representation. The recommended feature is the maximum value of zeros and ones, but it can vary from an application. In the <code>repr_featrend</code> function, the windowing is directly implemented, so the original time series is divided into pieces (subseries) and features are extracted from them separately. Let’s try it in our case, but at first we will smooth original time series <code>data_ts</code> dramatically by SMA (order of moving average will be 48*7, so weekly seasonality) and do it only on whole time series (<code>pieces = 1</code>).</p>
<figure>
<pre><code data-lang="r"><span># visualize smoothed time series</span><span><br data-jekyll-commonmark-ghpages=""></span><span>data_sma</span><span> </span><span>&lt;-</span><span> </span><span>repr_sma</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>order</span><span> </span><span>=</span><span> </span><span>48</span><span>*</span><span>7</span><span>)</span><span><br data-jekyll-commonmark-ghpages=""></span><span>ggplot</span><span>(</span><span>data.frame</span><span>(</span><span>Time</span><span> </span><span>=</span><span> </span><span>1</span><span>:</span><span>length</span><span>(</span><span>data_sma</span><span>),</span><span> </span><span>Value</span><span> </span><span>=</span><span> </span><span>data_sma</span><span>),</span><span> </span><span>aes</span><span>(</span><span>Time</span><span>,</span><span> </span><span>Value</span><span>))</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>geom_line</span><span>()</span><span> </span><span>+</span><span><br data-jekyll-commonmark-ghpages=""> </span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-16" src="https://i2.wp.com/petolau.github.io/images/post_7/unnamed-chunk-16-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<figure>
<pre><code data-lang="r"><span># compute FeaTrend representation</span><span><br data-jekyll-commonmark-ghpages=""></span><span>repr_featrend</span><span>(</span><span>data_ts</span><span>,</span><span> </span><span>func</span><span> </span><span>=</span><span> </span><span>max</span><span>,</span><span> </span><span>pieces</span><span> </span><span>=</span><span> </span><span>1</span><span>,</span><span> </span><span>order</span><span> </span><span>=</span><span> </span><span>48</span><span>*</span><span>7</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## [1] 15 30</code></pre>
</figure>
<p>So, the maximal run length of ones is 15 and maximal run length of zeros is 30, as expected, the number of zeros is much more than the number of ones because of decreasing character of the used time series.</p>
<p>And we have described and used every time series representation method implemented in the <strong>TSrepr</strong> package. In the next post (tutorial), I will show you one typical use case for using time series representation – clustering of time series.</p>
<h2>References</h2>
<p>Aghabozorgi, Saeed, Ali Seyed Shirkhorshidi, and Teh Ying Wah. 2015. “Time-series clustering – A decade review.” Information Systems 53. Elsevier: 16–38.</p>
<p>Bagnall, Anthony, Chotirat Ratanamahatana, Eamonn Keogh, Stefano Lonardi, and Gareth Janacek. 2006. “A bit level representation for time series data mining with shape based similarity.” Data Mining and Knowledge Discovery 13 (1): 11–40.</p>
<p>Esling, Philippe, and Carlos Agon. 2012. “Time-series data mining.” ACM Computing Surveys 45 (1). ACM: 1–34.</p>
<p>Laurinec, Peter, and Mária Lucká. 2016. “Comparison of Representations of Time Series for Clustering Smart Meter Data.” In Lecture Notes in Engineering and Computer Science: Proceedings of the World Congress on Engineering and Computer Science 2016, 458–63.</p>
<p>Laurinec, Peter, Marek Lóderer, Petra Vrablecová, Mária Lucká, Viera Rozinajová, and Anna Bou Ezzeddine. 2016. “Adaptive Time Series Forecasting of Energy Consumption Using Optimized Cluster Analysis.” In Data Mining Workshops (Icdmw), 2016 Ieee 16th International Conference on, 398–405. IEEE.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://petolau.github.io/TSrepr-time-series-representations/"> Peter Laurinec</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/vYL29OBFc_E" height="1"></a></div>