<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Dave Cote, M.Sc. on Medium]]></title>
        <description><![CDATA[Stories by Dave Cote, M.Sc. on Medium]]></description>
        <link>https://medium.com/@dave.cote.msc?source=rss-a351f759381e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*XBalYEtwICcvhUanUj6BOg.jpeg</url>
            <title>Stories by Dave Cote, M.Sc. on Medium</title>
            <link>https://medium.com/@dave.cote.msc?source=rss-a351f759381e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 23:47:54 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@dave.cote.msc/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Hybrid (multimodal) neural network architecture : Combination of tabular, textual and image inputs…]]></title>
            <link>https://medium.com/@dave.cote.msc/hybrid-multimodal-neural-network-architecture-combination-of-tabular-textual-and-image-inputs-7460a4f82a2e?source=rss-a351f759381e------2</link>
            <guid isPermaLink="false">https://medium.com/p/7460a4f82a2e</guid>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[nlp]]></category>
            <category><![CDATA[computer-vision]]></category>
            <category><![CDATA[multimodal]]></category>
            <category><![CDATA[neural-networks]]></category>
            <dc:creator><![CDATA[Dave Cote, M.Sc.]]></dc:creator>
            <pubDate>Fri, 18 Nov 2022 20:29:45 GMT</pubDate>
            <atom:updated>2022-11-18T20:38:00.530Z</atom:updated>
            <content:encoded><![CDATA[<h3>Hybrid (multimodal) neural network architecture : Combination of tabular, textual and image inputs to predict house prices.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/657/1*Zt7XpOgUkVBx6YcCDQcyzw.png" /></figure><p>Modality refers to a certain type of information and/or the representation format in which information is stored.</p><p>According to wikipedia, « <strong><em>Multimodal learning attempts to model the combination of different modalities of data, often rising in real-world applications. An example of joint data is combining text (typically represented as discrete word count vectors) with imaging data consisting of pixel intensities and annotation tags. As these modalities have fundamentally different statistical properties, combining them is non-trivial, which is why specialized modelling strategies and algorithms are required.</em></strong> »</p><p>Can we simultaneously train structured (tabular) and unstructured (text, image) data in the same neural network model while optimizing the same output target ?</p><p>We’ll perform this experiment using a very simple example by implementing a « concat » combination method that will concatenate text features, tabular features, and image features all at once before our final regressor layer(s).</p><p>Specifically, we will build a multimodal neural network that contains 3 input heads :</p><ul><li><strong>Image</strong> : Inception V3 input layers (Transfer Learning from Imagenet)</li><li><strong>Text<em> </em></strong>: Bidirectionnal LSTM with Attention layers pretrained on GlOve embeddings</li><li><strong>Structured<em> </em></strong>: Multi-layers perceptron</li></ul><p>And 1 output head :</p><ul><li><strong>House Price</strong></li></ul><p>Of course, more advanced methods and strategies exist to solve multimodal problems. For example, the great HuggingFace offers a <a href="https://multimodal-toolkit.readthedocs.io/en/latest/notes/combine_methods.html"><strong>multimodal-toolkit</strong></a><strong> </strong>that you can experiment with.</p><h3>Table of contents</h3><ul><li><strong>Dataset</strong></li><li><strong>Tabular data engineering</strong></li><li><strong>Text cleaning</strong></li><li><strong>Image cleaning — Fine-tune VGG16 to predict good/bad images</strong></li><li><strong>Architecture#1 — Structured Data fine-tuning with MLP (Python code)</strong></li><li><strong>Architecture#2 — Text Data fine-tuning using GlOve BiLSTM with Attention (Python code)</strong></li><li><strong>Architecture#3 — Image Data fine-tuning with Inception V3 (Python code)</strong></li><li><strong>Final Architecture — Load each previously fine-tuned weights and create the final hybrid neural networks training architecture by using the concat method. (Python Code)</strong></li><li><strong>Results and Conclusion</strong></li><li><strong>Final words</strong></li></ul><h3>Dataset</h3><p>First, let’s take a quick look at the dataset we’re going to use. I searched a very long time to find a dataset containing images, text and tabular data and finally found one! The link to download the dataset is here: <a href="https://www.kaggle.com/datasets/ericpierce/austinhousingprices"><strong>https://www.kaggle.com/datasets/ericpierce/austinhousingprices</strong></a> (You must have a Kaggle account to download it).</p><p>As it is written on the Kaggle page:</p><p><em>“Context — Austin Housing</em></p><p><em>This data was originally sourced in support of my capstone project at Northwestern University. The Austin Housing market is one of the hottest markets in 2021, and these listings show how that market has changed over the past couple of years.”</em></p><p>The data contains a csv file with all the tabular features, a text description feature and a column that specify the image filename associated with the dataset row. The csv dataset comes with a huge zipped file containing the house images. Unfortunatly, there is only one image available for each house but we will work with that.</p><p>The goal here is to predict house <strong>price</strong> using all the data we have.</p><h3>Tabular data engineering</h3><p>Although it is said that the data has been cleaned, there are still many data quality issues left. For example, there are impossible feature values like houses with 0 bathrooms or 0 bedrooms or negative square foot of living area.</p><p>Here is a table that resume some of the major data transformations and cleaning steps performed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*reKcuHpArI4N-RaGHoIUKg.png" /></figure><p>An important step is to clean up our target value, <strong>house prices</strong>, using inflation rates (concept drift problem). Past selling prices do not match actual selling prices due to inflation; the definition of 1$ unit is not the same over time. For this purpose, I used a table of inflation rates to correct the price amount.</p><p>Once cleaned, our dataset contains <strong>56 features </strong>and <strong>10537 rows</strong>.</p><p>Here is a geospatial plot (plotly) of all Austin Houses we have:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/899/1*onm6V05XESmwMkTXtipsfw.png" /></figure><p>We can see that there are some zipcode clusters where the price is higher (red) than other regions (blue). I’ve created a new feature that represent the zipcode clusters called <strong>regionCluster </strong>using the kmeans algorithm:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2b3512373f4926a4c4ba56868c6ee8d4/href">https://medium.com/media/2b3512373f4926a4c4ba56868c6ee8d4/href</a></iframe><h3>Text cleaning</h3><p>To clean up house text descriptions, we apply normalization, remove stop words and find the root of each word using lemmatization.</p><p>Here is an example of the result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*7QOaZfBmrWPARhLXXmFeZA.png" /></figure><h3>Image cleaning — Fine-tune VGG16 to predict good/bad images</h3><p>This one is a bit tricky. After randomly exploring some images, there seem to be very different / heterogenous types of house images. Here are a few:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*0sgfy8mCy0Ner5RrKfgR7g.png" /><figcaption><strong>Nice picture!</strong></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*A8D5BptZxBslYNpZGbIW9Q.png" /><figcaption><strong>Nice river but… which house are we talking about?</strong></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/1*x1Ij1PKbK7yuJN3tG_R9jg.png" /><figcaption><strong>Not very useful…</strong></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*q4WBWBjuaZ-1Uqvu6zrUaA.png" /><figcaption><strong>Interior picture…</strong></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*UZ0i8wAHz11n5JAaGq2_Sg.png" /><figcaption><strong>Would have a fresh beer on that patio but not very useful…</strong></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*dkNJNnVw2D0D22q_hJNT4g.png" /><figcaption><strong>What is this!!? A cemetery? …</strong></figcaption></figure><p>As you can see, there are several heterogeneous types of house images. Another challenge is that we only have one image available per house, so the image must be useful.</p><p>Since there are about 10,000 images, we can’t look at all of them to decide which data to keep and which data to delete. To help us, we will fine-tune a <strong>VGG16</strong> to predict good/bad images for us.</p><p>First, we need to determine what is a good image for us. I decided to keep only images where you can see the complete architecture of the house from the outside:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*L7G685LCJx841BrUB62Wrw.png" /></figure><p>Bad images would be any interior image or any image where we cannot see the full architecture of the house from the outside.</p><p>As we are using <strong>transfer learning</strong>, fewer samples from each class should do the job.</p><p>We need to create two directories, one for the good images and one for the bad ones, then manually dispatch some of them in the right place. After an hour, I sorted around <strong>800 images </strong>for the train set (400 good and 400 bad) and around <strong>250 images </strong>for the test set.</p><p>We are now ready to fine-tune our VGG16 model!</p><p>Python Code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f720e2d1a7b0713e205aaefbde4fa3c5/href">https://medium.com/media/f720e2d1a7b0713e205aaefbde4fa3c5/href</a></iframe><p>Here is the final <strong>confusion matrix</strong> from the test data sample:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/797/1*GPJnpaSboR0JKimE6m-VDA.png" /><figcaption><strong>Confusion Matrix from the VGG16 image cleaning test set</strong></figcaption></figure><p>We can now predict every image we have using our <strong>“VGG16 cleaner”</strong> and remove all rows of our dataset where the available image has been classified as <strong>“bad”</strong>.</p><p>For the next steps, the strategy we will use is to individually train each neural network, save the weights and then load the trained weights into our final hybrid model and retrain with all the parts merged together.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*GZ86aJXN_G1zFZFsXHwnrA.png" /><figcaption>Fine-tuning each neural network architecture individually first</figcaption></figure><h3>Architecture#1 — Structured Data fine-tuning with MLP:</h3><p>Python code to create the neural network architecture, fine-tune, and save the weights:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/213a26e3f070b9780f035a804485e30a/href">https://medium.com/media/213a26e3f070b9780f035a804485e30a/href</a></iframe><p>Multi-layer perceptron (MLP) architecture:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/563/1*Ksro6pVtnDwNvprNc0pOxQ.png" /><figcaption>Structured Data Neural Netowrk Architecture (MultiLayers Perceptron)</figcaption></figure><p>Here are the most important shapley values for our tabular features (Using the DeepLift algorithm (DeepExplainer) from the awesome <a href="https://shap.readthedocs.io/en/latest/index.html"><strong>SHAP package</strong></a>) :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/341/1*y3M_F3rhQvLzHmg-bSyrMA.png" /></figure><p>This barplot shows us that the 3 most important features to predict price of our structured data neural network are: <strong>livingAreaSqFt</strong>, <strong>zipcode</strong> and <strong>regionCluster</strong>.</p><p>numPriceChanges, yearBuilt and lotSizeSqFt follow next.</p><p>If we look at some of these features:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/1*4tlXI_OAQ0IYJMECz9vejQ.png" /></figure><p>The biggest <strong>livingAreaSqFt</strong>, the biggest shapley value, the biggest price (seems logical!)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/490/1*x8qfcKBvTVoz4scuyTlm7A.png" /></figure><p>The more recent <strong>yearBuilt</strong>, the biggest shapley value, the biggest price (seems logical!)</p><h3>Architecture#2 — Text Data fine-tuning GlOve BiLSTM with Attention:</h3><p>Python code to create the neural network architecture, fine-tune, and save the weights:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f78c31c085344b1efba1e50d888f56f0/href">https://medium.com/media/f78c31c085344b1efba1e50d888f56f0/href</a></iframe><p>BiLSTM Attention with GloVe embeddings architecture:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/503/1*fhfhiWP8C7DuIwg2qw4ssw.png" /><figcaption>Text Neural Netowrk Architecture (BiLSTM Attention with GlOve Embeddings)</figcaption></figure><p>Again using shapley values, here are some useful <strong>ngrams</strong> of the house text description to predict price:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/455/1*uRUa_RXQd2VewgmMwXZ20g.png" /></figure><p>The “<strong>large private backyard</strong>”, “<strong>open live area</strong>” and “<strong>wood laminate floor</strong>” grams appear to have the most positive influence on price according to the shapley values.</p><p>In contrast, “<strong>bright open floor</strong>”, “<strong>beautiful wood floor</strong>”, “<strong>yes sprinkler sy</strong>” and “<strong>vinyl plank floor”</strong> seem to have the most negative influence on the price.</p><h3>Architecture#3 — Image Data fine-tuning with Inception V3:</h3><p>We use the pre-trained InceptionV3 model on generic image (imagenet weights) and fine-tune only the head layer using our houses prices.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*RwjhzFL8pT09po88QMRWJA.png" /></figure><p>Python code to create the neural network architecture, fine-tune, and save the weights:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f5f3bb8479a41df86c7eec889f4bf169/href">https://medium.com/media/f5f3bb8479a41df86c7eec889f4bf169/href</a></iframe><p>The final architecture (InceptionV3 is presented here as a single layer but represents a more complex underlying architecture):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/627/1*1GMUt8bz_FVyEq-6FibhJA.png" /><figcaption>Image Neural Netowrk Architecture (InceptionV3)</figcaption></figure><p>Using the <strong>gradcam</strong> method, we can try to understand what our CNN is looking at:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*jpvEAY68pOkXWYg00hROFg.png" /></figure><p>The neural network seems to focus mostly on the house part of the images, which is fine, but there is no evidence which parts of the houses are more important than others… maybe our model is not trained enough !</p><p>Grad-CAM, <strong><em>Gradient-weighted Class Activation Mapping</em></strong>, uses the feature maps / class-specific gradient information flowing into the final convolutional layer of a CNN. It produces a visual explanation heat-maps / localization map that will help us understand how the model make decisions / the important regions in the image.</p><p>Python code for the gradcam:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/14db1a22c6dc13f85aa010398183c5b4/href">https://medium.com/media/14db1a22c6dc13f85aa010398183c5b4/href</a></iframe><h3>Final Architecture — Load fine-tuned weights and create final hybrid architecture for training</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*suqH3y6p_1yZtZurBuhFrg.png" /></figure><p>Here is the python code to load all our fine-tuned neural network architecture and then create the final architecture:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2965d73a71710808d7ceebbf9f2ba889/href">https://medium.com/media/2965d73a71710808d7ceebbf9f2ba889/href</a></iframe><p>The final architecture:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IYV9oOXmDVDt84Da-11g7Q.png" /><figcaption>Final Hybrid (Multimodal) Neural Netowrk Architecture</figcaption></figure><p>We can see the concatenate layer in the center that concatenate our 3 previous neural network architectures; image, text and structured data respectively.</p><h3>Results and Conclusions</h3><p>If we take a quick look at our first results:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cb661356e91da8107ede0a41eec0bd6c/href">https://medium.com/media/cb661356e91da8107ede0a41eec0bd6c/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/695/1*55nukJZoDiwOqIpGvczzVw.png" /><figcaption>Model benchmark</figcaption></figure><p>The worst model of all is the dummy mean house price model where the price of each house = average price of the whole training set.</p><p>The second worst model of all is the <strong>Image Data NN Architecture</strong> alone where there seems to be very slight house price predictive power, meaning that house images doesn’t correlate very much with the house prices.</p><p>Does it make sense ?</p><p>The price of a house is not limited to the appearance of the exterior. The local real estate market seems a lot more important. For example, if we take the same house and simply move it to another <strong>regionCluster</strong>, the price could be very different.<strong> </strong>Therefore, it should not be surprising that our Image Data NN Architecture alone trained on image didn’t perform as well as the Structured Data NN Architecture trained on the attributes containing much more context about the local real estate market. Since our result is bad, we could use some strategies to improve our image data neural network and dataset:</p><ul><li>Having a dataset where photos are more consistent and taken from the same angles could be helpful.</li><li>It is difficult to represent a full house using a single image. Having a dataset with multiple photos for each house (interior, exterior, kitchen, bathroom, etc.) could have helped our model a lot. Multiple images can be done by creating a montage that combines all images into a single image and then pass the montage through the CNN input.</li><li>Direct regression task on images maybe not the best choice. Using bounding boxes to detect objects in images like different types of garages, windows, doors, patio, swimming pool, etc. could be an interesting alternative and surely reduced some unwanted pixel noise in images but requires much more work and time to prepare datasets.</li><li>Maybe more epochs could have helped… choosing a different model than InceptionV3… hyper-parameter tuning… etc.</li></ul><p>Our <strong>Text Data NN Architecture</strong> alone performed better than the dummy mean house price model. There seems to be predictive information / correlations on house prices when using the text description.</p><p>However, adding the textual description with our structured data (Hybrid [Structured+Text] NN architecture) seems to have only added noises because the performance is almost the same as structured data alone. One explanation could be that the house textual description contains redundant information from our structured features.</p><p>Third place is our <strong>Final Hybrid neural network architecture</strong> where images and text seem to have added noise to the structured features.</p><p>The 2 winners (almost tied) are the <strong>Structured Data Neural Network </strong>with a MAE of <strong>79 105$</strong> and the <strong>Hybrid (Structured + Text) Neural Network</strong> with a MAE of <strong>77 911$</strong> (Sounds high but our Austin houses present in the dataset are expensives with an average price of <strong>499 635$</strong>)</p><h3>Final words</h3><p>In a context where we have better informative images and better informative texts correlated to our target, it would be very interesting to experiment again with this kind of hybrid architecture and see how it goes !</p><p>Also, keep in mind that in practice, it is difficult to combine different noise levels and conflicts between modalities. Moreover, modalities have different quantitative influence on the prediction output.</p><p>The most common method is to combine high-level embeddings from the different inputs by concatenating them, just like we did. The problem with this approach is that it would give an equal importance to all the sub-networks / modalities which is highly unlikely in real-life situations. For example, using a weighted combination of networks could be an alternative.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7460a4f82a2e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Experimenting Confusion Matrix for Regression — A powerfull model analysis tool]]></title>
            <link>https://medium.com/@dave.cote.msc/experimenting-confusion-matrix-for-regression-a-powerfull-model-analysis-tool-7c288d99d437?source=rss-a351f759381e------2</link>
            <guid isPermaLink="false">https://medium.com/p/7c288d99d437</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[metrics]]></category>
            <category><![CDATA[regression]]></category>
            <category><![CDATA[model-selection]]></category>
            <category><![CDATA[confusion-matrix]]></category>
            <dc:creator><![CDATA[Dave Cote, M.Sc.]]></dc:creator>
            <pubDate>Tue, 24 May 2022 21:09:31 GMT</pubDate>
            <atom:updated>2022-05-27T14:37:44.633Z</atom:updated>
            <content:encoded><![CDATA[<h3>Experimenting Confusion Matrix for Regression — A powerfull model analysis tool</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WPLOTdzutmN8hknKoP5-8A.png" /></figure><h3><strong>Table of contents :</strong></h3><ul><li><strong>1- Confusion Matrix (CM)</strong></li><li><strong>2- Multiclass Confusion Matrix (MCM)</strong></li><li><strong>3- Regression Confusion Matrix</strong></li><li><strong>4- RCM Accuracy AUC Score</strong></li><li><strong>5- RCM F1 AUC Score</strong></li><li><strong>6- Conclusion</strong></li></ul><h3><strong>1-Confusion Matrix (CM)</strong></h3><p>Confusion matrix is a popular tool for summarizing the performance of a classification algorithm (A model which is used to predict a <strong>discrete variable</strong>) by giving a better idea of what is correctly predicted and what types of errors your algorithm is making. The confusion matrix is a N x N matrix, where N is the number of classes or outputs. For 2 classes, we obtain a 2 x 2 confusion matrix.</p><p>The name « confusion » stems from the fact that it makes it easy to see whether the system is confusing / mislabeling two classes. It have two dimensions “actual” vs “predicted” and for 2 X 2 matrix (binary problems), it produce 4 count metrics :</p><ul><li><strong>True Positive (TP)</strong> : predicted(1), actual(1)</li><li><strong>False Positive (FP)</strong> : predicted(1), actual(0)</li><li><strong>True Negative (TN)</strong> : predicted(0), actual(0)</li><li><strong>False Negative (FN)</strong> : predicted(0), actual(1)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/433/1*tkF_YW4BOcJyboupZpfNzg.png" /></figure><p>Those 4 count metrics are also very usefull for calculating a bunch of classification model performance metrics like precision, recall, f1 score on go on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*0QKNOPpCf0sl7Osf7MmZXQ.png" /></figure><h3><strong>2-Multiclass Confusion Matrix (MCM)</strong></h3><p>The binary confusion matrix can be extended for multiclass classification problems. For example, for 3 classes we obtain a 3 X 3 confusion matrix.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/412/1*emepIrFI42uqWk6p4U3Acg.png" /></figure><p>How to calculate TP, FN, FP, TN? Pretty much the same logic here but we have to calculate the sum of values for each class. For example, using the 3 X 3 confusion matrix above we obtain:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/557/1*X49GPkzyB-uFoSbsKB8CFA.png" /></figure><p>Once we have our TP, FN, FP, TN for each class there are two main approaches in defining performance metrics called “micro” and “macro”. The difference between macro and micro averaging is that macro weighs each <strong>class equally</strong> whereas micro weighs <strong>each sample equally</strong>. The macro and micro will have the same score if we have an equal number of samples for each class.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*ed-pPz5SQIXi7uaCHsEnZA.png" /></figure><h3><strong>3-Regression Confusion Matrix</strong></h3><p>Continuous data is measured while discrete data is counted… Is it possible to extend the use of the confusion matrix from a discrete variable problem (classification) to a continuous variable problem (regression)?</p><p>To make it possible we have to convert our continous variable to a discrete form first!</p><p>How can we do that ? Simply by <strong>discretizing</strong> the continuous values into regions (bins). Discretization is the process of transforming continuous variables into a discrete form. We do this by creating a set of continuous intervals:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tNnohqLtfzcbJRhWNLMlWw.jpeg" /></figure><p>Let’s do it!</p><p>Suppose we have this simple regression problem X vs Y :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*hHHPiiqmU3LGfLHsScx57Q.png" /></figure><ol><li>The first step is to fit our regression model :</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*-B1H1HHkpq3tFYxN3xv2gQ.png" /></figure><p>Code example :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/288/1*onSthZEwpHnjprMprxorHA.png" /></figure><p>2.Second, we discretize the target Y in N bins. We will start with <strong>4 bins</strong>. We can use pandas « <strong>qcut</strong> » function to do that:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/398/1*SASVRXjAq7V4_jrF0Wdj1w.png" /></figure><p>Code example :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/355/1*fT39fKlKe_iv6A6TNo06Kw.png" /></figure><p>Result :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/166/1*RK72-1jsaHPKPWdIZCAyUQ.png" /></figure><p>We can see that we have almost the same sample size for each discretized bin label. Here is the new dataframe :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/311/1*murWbEjANhmLusIMgtjdcw.png" /></figure><p>3. Next, we have to merge the Y True continous intervals with the Y Pred results, like this :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/637/1*2GDAQ1zBGuJnYyZkiiWyYw.png" /></figure><p>Result :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*tsm9Tyn2BGvUX5W1dWX9Hg.png" /></figure><p>We are now ready to calculate our multiclass Confusion Matrix for Regression ! (Don’t forget to use the test set or validation set as we don’t want to evaluate the performance on the fitted data used for training)</p><p><strong>LINEAR REGRESSION — CONFUSION MATRIX (4 BINS)</strong></p><p>With this simple 4 X 4 confusion Matrix, we can see that our model is not breathtaking. A perfect model would result in a perfectly centered dark diagonal which is far from the case here !:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/449/1*7oqiGf8LwjiYUgIgK7RJQA.png" /></figure><p><strong>Perfect Model example :</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/338/1*Zmk898Ag9ymjm9FivxWTgA.png" /></figure><p>With the Linear Regression metric, we have more like a reverse « L » shape than a diagonal. We have a <strong>roc auc</strong> of 0.5250 and an <strong>accuracy</strong> of 0.2877. If we look at the regression metrics we have a <strong>R2</strong> of 0.0695 and a <strong>RMSE</strong> of 129.303.</p><p>This is nice because we can now use pretty much all the classification metrics to benchmark the performance of our regression model.</p><p>Now if we do the same with a default <strong>CatBoostRegressor</strong> :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*JNnqB57gdyrHzO2i-2uXiw.png" /></figure><p><strong>CATBOOST REGRESSION — CONFUSION MATRIX (4 BINS)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/451/1*dUwO8hyJQp7qCdtS8XQlIQ.png" /></figure><p>Seems a lot better ! We begin to see a centered diagonal. We now have a <strong>roc auc</strong> of 0.64873 and an <strong>accuracy</strong> of 0.47308. If we now look at the regression metrics we have a <strong>R2</strong> of 0.6323 and a <strong>RMSE</strong> of 81.2865.</p><p>What happen if we split our continuous target into more bins ?</p><p>In this context, more bins means a more accurate confusion matrix of our regression model.</p><p>More bins means also smaller sample by class which result in a less credible evaluation. In general, the more bins we add, the more our model should tend to lose performance when using the confusion matrix, since we are looking at the data much more precisely.</p><p>Let’s now try with 10 bins and the <strong>Linear Regression </strong>model :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/163/1*Lok9z6X6slSAI0XFbzMNsQ.png" /></figure><p><strong>LINEAR REGRESSION — CONFUSION MATRIX (10 BINS)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/452/1*g_F90dLqTELj_QE6sEKzlw.png" /></figure><p>Wow, now we can see more precisely how the model fits the continuous data and where the errors are. Our Linear regression model is not capable of predicting the first bins (&lt; 279) and the last bins (&gt; 447) as there are 0 counts in the predicted columns. As we expected, the <strong>accuracy</strong> have now dropped from <strong>0.2877</strong> to <strong>0.09055</strong>. Note that the <strong>RMSE</strong> and <strong>R2</strong> remains the same as those metrics are calculated with the overall results.</p><p>If we do the same with the CatBoost model :</p><p><strong>CATBOOST REGRESSION — CONFUSION MATRIX (10 BINS)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/452/1*oUdsPgaMDI3FsFSyPHjSFg.png" /></figure><p>Again we see a more centered diagonal compared to the linear regression. Accuracy decreased from 0.47308 to 0.14438, which is a smaller drop (~67%) than with linear regression (~80%) and still has better overall accuracy.</p><p>The nice thing about using the confusion matrix for regression problems is that it gives you a powerful visual tool to interpret the overall fit of the model and help spot problems in specific regions of the continuous data, even for multivariate problems where it is not possible to plot X vs Y (you can also see my previous article <a href="https://medium.com/@dave.cote.msc/visualization-trick-for-multivariate-regression-problems-5b3aa25ff2f8">visualization trick for multivariate regression problems</a> for more tools).</p><p>We can add a last model, a polynomial regression and compare the 3 models for 4, 10 and 24 bins:</p><p><strong>POLYNOMIAL REGRESSION</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*g0-sWui4teg3ctCfhHMqLQ.png" /></figure><p><strong>CONFUSION MATRICES BENCHMARK</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*FPpzJdrJ-4tAs_7cg_6nlg.png" /></figure><h3><strong>4-RCM Accuracy AUC Score</strong></h3><p>Can we calculate a classification metric that takes into account multiple bins to get a better performance evaluation and benchmark models together ?</p><p>We will experiment someting here… Let’s create a new regression-classification metrics that we can call <strong>RCM Accuracy AUC Score </strong>(RegressionConfusionMatrix Accuracy AreaUnderCurve Score)</p><p>First, let’s calculate <strong>accuracy</strong> (can be any classification metrics) using multiple bins, for each model.</p><p>Then we can do a simple interpolation and draw a curve where Y = <strong>Performance Score</strong> and X = <strong>Number of bins</strong>, like this :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*4jaRLc57mdyclBxjvdcrDg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*D-J0gOXST-rmhxtnKGvZjw.png" /></figure><p>Now we can calculate the area under the curve, for each model using the sklearn<strong> “auc”</strong> function that calculates area under curve using the trapezoidal rule :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/257/1*8aqWbLbUmeTTiaATVn19cg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*Su6BjEjTycYGk7RsvSofXg.png" /></figure><p>Based on this new<strong> RCM Accuracy AUC Score</strong>, Catboost seems to have the bigger area!</p><p>Is it the same story with the F1 Score ?</p><h3><strong>5-RCM F1 AUC Score</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*85sLlmIEmahzh4QTLumbKA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/549/1*E1cD0fCFfB5bev4Xmg3ldg.png" /></figure><p>Based on this new<strong> RCM F1 AUC Score</strong>, again, Catboost seems to have the bigger area under the curve!</p><h3><strong>6-Conclusion</strong></h3><p>Final model benchmark:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*2LzcWNVOeQ_uVor5y12OcQ.png" /></figure><p>With the traditional regression model performance metrics, the polynomial regression model seems a little bit better than the CatBoost model in all metrics (RMSE, MAE, R2). However, with the classification metrics applied on discretized continuous range, the Catboost seems better than the polynomial regression… Why ? … This is an interesting experiment that need more digging!</p><p>To conclude, as we experimented, confusion matrix can also be used as a powerfull tool for regression model visualization, analysis and benchmark.</p><p>Even when the regression problem is multivariate, the regression confusion matrix can offer an interesting visualization tool to help understand how the model fits our target and where the error lies.</p><p>For more tools to help multivariate regression visualization you can also try this trick : <a href="https://medium.com/@dave.cote.msc/visualization-trick-for-multivariate-regression-problems-5b3aa25ff2f8">Visualization trick for multivariate regression problems</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7c288d99d437" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hands-On Advanced Deep Learning Time Series Forecasting with Tensors]]></title>
            <link>https://medium.com/@dave.cote.msc/hands-on-advanced-deep-learning-time-series-forecasting-with-tensors-7facae522f18?source=rss-a351f759381e------2</link>
            <guid isPermaLink="false">https://medium.com/p/7facae522f18</guid>
            <category><![CDATA[transformers]]></category>
            <category><![CDATA[forecasting]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[time-series-analysis]]></category>
            <category><![CDATA[tutorial]]></category>
            <dc:creator><![CDATA[Dave Cote, M.Sc.]]></dc:creator>
            <pubDate>Mon, 04 Apr 2022 20:47:23 GMT</pubDate>
            <atom:updated>2022-04-04T20:47:23.920Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5qa1EtqpSnpSKAIgo5oQoQ.png" /></figure><p>There are billions of deep learning forecasting tutorials out there (exagerating a bit). So what’s special about this one?</p><ul><li>So far I have seen very few tutorials explaining in detail how to work with 3D tensors. I will explain it with some simple visuals to understand the steps of transformation from 2d matrix to 3d tensor.</li><li>I’ve seen many deep learning tutorials showing good optimistic results in the learning process, but what about going beyond the test set, being completely blindsided in the future? (Sometimes this step is missing but can demonstrate big overfitting issues from the data preparation, especially when creating the tensor slices).</li><li>How about extrapolating long-term multisteps into the futur ? 1 year into the futur ?</li><li>We will also experiment a colossal collection of advanced neural networks architectures with our 3d tensors : <strong>Bidirectional LSTM, Seq2Seq, Seq2Seq with Attention, Transformers</strong>, etc.</li><li>We will experiment time series vector representation embeddings with the awesome <strong>Time2Vec</strong></li><li>Not all time series are equal; some are deterministic, other more complex with multiple seasonal structures and cycles and some are completely stochastic. We will try different ones!</li><li>We will implement a Multivariate-Multisteps-Multioutput deep learning forecasting model.</li><li>At the end, I’ll give you access to the jupyter notebooks with <strong>all the codes </strong>in a way that it is <strong>easy for you to re-use it with your own time series.</strong></li></ul><p><strong>Warning*</strong>: Like the title suggest, this is a more <strong>hands-on</strong> article, soo don’t expect to deep dive into all the concepts and theory (but I’m a nice guy soo I will give you some links on the way if your interested in learning more).</p><p>Also, in order not to write a long endless novel, I did not include any <strong>time series analysis (TSA)</strong> parts which is not a good practice at all ! We should always start with a good TSA to understand our time series before embarking on our forecasting journey.</p><h3>Table of contents</h3><ul><li>1. Time serie#1 — Monthly easy deterministic</li><li>2. Feature Engineering</li><li>3. Converting 2d matrice to 3d tensor</li><li>4. RdR Score Performance Metric</li><li>5. Bidirectional LSTM (BiLSTM)</li><li>6. Seq2Seq</li><li>7. CNN-BiLSTM</li><li>8. TCN-BiLSTM</li><li>9. MDN-BiLSTM</li><li>10. Attention-BiLSTM</li><li>11. Seq2Seq with Attention</li><li>12. MultiHeadAttention-BiLSTM</li><li>13. Time2Vec-BiLSTM</li><li>14. Time2Vec with Transformer</li><li>15. Average Ensemble Model</li><li>16. Final Benchmark</li><li>17. Time serie#2 — Daily multi-seasonalities</li><li>18. Time serie#3 — Daily stochastic (Amazon Stock)</li><li>19. Multivariate-Multisteps-Multioutput</li><li>20. Link to all the CODE</li><li>21. Conclusion</li></ul><h3>1. Time serie#1 — Monthly easy deterministic</h3><p>Here is the first time series we will use :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*9xj1XoOwYFYyuF2YDVNsvw.png" /></figure><p>This is a monthly time serie. As you can see just by looking at the time serie, there is a strong deterministic trend with a strong deterministic monthly seasonality. If the trend and the seasonality remains the same over time, it should not be a big deal to find a model that performs very well on this.</p><p>Normally, as this is a very predictable and univariate time series, I would approach this problem using a simple SARIMA, HoltWinters, FbProphet or Thymeboost model, but the goal here is to experiment deep learning models with tensors !</p><p>For this first experiment, we will try to forecast <strong>24 months</strong> into the future !</p><h3>2. Feature Engineering</h3><p>This diagram illustrates the feature engineering pipeline we’ll be experimenting with (the <strong>green cells</strong> are the steps used for this particular time series but the full pipeline is implemented in the notebook):</p><p><strong>The parameters:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b0c4541bee7dc991cca65c2743fa4945/href">https://medium.com/media/b0c4541bee7dc991cca65c2743fa4945/href</a></iframe><p><strong>The corresponding pipeline:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/586/1*xcPeZblM9evixXdPXjISgQ.png" /></figure><p>As you can see in this schema, by splitting at the start of the feature engineering process, we ensure that we do not add any overfitting signals from the test sequence in our train sequence.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1e9aa63ddc86051b18fb563c744ac7c5/href">https://medium.com/media/1e9aa63ddc86051b18fb563c744ac7c5/href</a></iframe><p>We want our deep learning model to better understand the historical patterns (autoregressive correlations) soo we will add some lagged values as features (X).</p><p>We also need to compute the leaded values that will represent the future timesteps targets our model will train on (Y).</p><p><strong>Lagged and leaded values:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dd1214155cef75fdea5e02846921fbb4/href">https://medium.com/media/dd1214155cef75fdea5e02846921fbb4/href</a></iframe><p><strong>Seasonal Means:</strong></p><p>Since there seems to be strong monthly seasonality in our time series, we will add monthly and quarterly averages as features (X).</p><p>The following function take the periodicity of the time series as input (ex: monthly = 12, daily = 365, etc.) and compute automaticly the proper seasonal averages.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a0a959497f47daddc2c95e398cfbd76b/href">https://medium.com/media/a0a959497f47daddc2c95e398cfbd76b/href</a></iframe><p>We could have applied differencing to our Y time series and un-differencing after the forecast to treat the trending problem (non-stationarity of mean).</p><p>We could also have applied a log transformation on the Y time series to treat the non-stationarity of variance (seems heteroskedastic) and un-log it after the forecast.</p><p>The code is all here in the jupyter notebook but I did not included thoses processing steps as the results were better without them for this particular time series. You could definitively try this at home if you want!</p><p><strong>Final feature engineering pipeline:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bd1f4ccb9a00b7316a78d288e01ac57c/href">https://medium.com/media/bd1f4ccb9a00b7316a78d288e01ac57c/href</a></iframe><p>The final preprocessing step is to convert the 2d matrice into 3d Tensor. We have to be very careful here to not add any <strong>Y signals</strong> in the same <strong>X row</strong> as it would result in a highly overfitted model, very good test score and very bad / strange results in the forecasting step. A single X tensor slice should contains time series information at time T0, T-1, T-2, etc. and a single y tensor slice should contain information at time T+1, T+2, T+3, etc.</p><h3>3. Converting 2d matrice to 3d tensor</h3><p>How can we transform a 2d matrice into a 3d tensor ? We already have the rows (time series past observation in time), and the features (lags, means, exogenous, etc.), we now need to add the <strong>sequence length dimension</strong>.</p><p>There are other ways we can do this 3d transformation. In fact, you can try multiple 3d configurations that can lead you to very different results ! Here, I’ll show you one 3d configuration that gave me good forecasting results with the studied time series.</p><p>We will define a function that will create time slices (sequence length) from our 2d matrice where the length of the sequence match the steps we want to predict into the future :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/1*6Hn5D7S-oPZC_Uwj83434g.png" /></figure><p>The following function will require <strong>4 inputs</strong>;</p><ul><li>2d matrice</li><li>column name(s) <strong>list</strong> of the <strong>target(s)</strong> we want to forecast (can manage multioutput)</li><li>date column name</li><li>number of steps we want to forecast.</li></ul><p>There will also be <strong>4 outputs</strong>;</p><ul><li>X_train 3dtensor</li><li>y_train 3d tensor</li><li>X_pred 3d tensor</li><li>List of the final train features (metadata).</li></ul><p><strong>The 2d matrice to 3d tensor function:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8635eb7809295f792cafb92f072a2b0c/href">https://medium.com/media/8635eb7809295f792cafb92f072a2b0c/href</a></iframe><p><strong>Calling the function:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8759a5589044c282e419f17d40d519f5/href">https://medium.com/media/8759a5589044c282e419f17d40d519f5/href</a></iframe><p>This call is for the test-validation sets. We just have to input the full time series to obtain the full training set and the forecasting set. Easy as this!</p><p>What exactly happen in this small function ? Simply, at each step, a new tensor slice is append to a list and then the list is converted to a tensor. Let’s analyze how those tensor slices are created, step by step with some simple visuals!</p><p>For example, if we want to forecast a <strong>2 inputs</strong>, <strong>1 output</strong> time series with <strong>2 steps</strong> into the future, here what the function do with our 2d matrice input:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/251/1*oSSiGKzFzrNuA_KcgWNnsw.png" /><figcaption>input dataframe</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/493/1*fqmyOvCQ4DMkPyVeKDDIyQ.png" /><figcaption>output tensors</figcaption></figure><p>The output tensors shapes are X_train (9, 2, 2), y_Train (9, 2, 1) and X_Forecast (1,2,2).</p><p>At each iteration, a new slice was created (orange) :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/565/1*7QWFUgUL-GYVRRqpgmrxqw.png" /></figure><p><strong>The last slice:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/420/1*SHGf_At-ocrYDdznrZjIMg.png" /><figcaption>last tensor slices</figcaption></figure><p>As you can see, X and y are are offset from each other (we want our model to learn to extrapolate into the future).</p><p>Now, what if we want to forecast a <strong>2 inputs</strong>, <strong>1 output</strong> time series, but this time <strong>3 steps</strong> into the future ? Well… not very different;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/240/1*Hxj2J_njreg6Wf_EBeP5SQ.png" /><figcaption>input dataframe</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/698/1*XAa_HpnGRdULFu2iG24sww.png" /><figcaption>ouput tensors</figcaption></figure><p>The shapes of our output tensors are now; X_Train (7, 3, 2), y_Train (7, 3, 1) and X_Forecast (1,3,2).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/585/1*3sANuudgw9sdnwgeMdZSbA.png" /></figure><p><strong>The last slice:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/427/1*pOguFPY8fpx3zZ6nl0BfWg.png" /><figcaption>last tensor slices</figcaption></figure><p>Ok… and maybe a tricky one! What if I have <strong>2 features</strong> and <strong>2 outputs</strong> to forecast <strong>3 steps</strong> into the future ? To make this working, we can use the actual transformation function to get our 3d tensors but we will have to change our neural network model architecture a bit:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/249/1*-thqYyarNeboCd4TpcyxhQ.png" /><figcaption>input dataframe</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/759/1*A-vyWxyX-s8MU5IoFjgeRg.png" /><figcaption>output tensors</figcaption></figure><p>Observe that now our Y tensor is (7, 3, <strong>2</strong>) versus a single output. This require a new neural network architecture to make this work… if you read the article until the end I will give you an example ! 😉</p><p>The shapes of our tensors are now; X_train (7, 3, 2), y_train (7, 3, 2) and X_Forecast (1,3,2).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/744/1*kgqqcaIxEKZmkhDdKb6AsQ.png" /></figure><p><strong>The last slice:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/521/1*bLcsg0RClKLE5m97GBnIwQ.png" /><figcaption>last tensor slices</figcaption></figure><p>Now we are ready to go to the model part!</p><h3><strong>4. RdR Score Performance Metric</strong></h3><p>To benchmark the performance of the model forecasts, we will use my custom <strong>RdR score</strong> which is deeply explained <a href="https://medium.com/@dave.cote.msc/rdr-score-metric-for-evaluating-time-series-forecasting-models-1c23f92f80e7">here</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/695/1*avqCamD3HIL-XM4K9hNhsA.png" /></figure><p>In short, we can interpret the RdR score as the percentage of difference (In error and shape similarity) between your model and a simple random walk model, based on RMSE score and DTW (Dynamic Time Warping) score.</p><p>If the percentage is <strong>negative</strong>, your model is [X]% <strong>worst</strong> than randomness.</p><p>If the percentage is <strong>positive</strong>, your model is [X]% <strong>better</strong> than randomness.</p><p>In another words, the [X]% will change depending on the RMSE errors and the DTW distance around 0, which is the bound of naïve randomness.</p><p>Why RMSE ? I think that penalizing the average error with large errors reflect more the reality and the stability of the model but we could have replaced the RMSE with SMAPE or any regression metric we want.</p><h3>5. Bidirectional LSTM (BiLSTM)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/680/1*23NtBVc-YaBy3d8mOhnNYw.png" /></figure><p>LSTM preserves information from inputs that has already passed through it using the hidden state. Using bidirectional LSTM will run the inputs in two ways, one from past to future and one from future to past. If you want to know more about LSTM, go <a href="https://www.analyticsvidhya.com/blog/2021/03/introduction-to-long-short-term-memory-lstm/#:~:text=Long%20Short%20Term%20Memory%20Network,is%20used%20for%20persistent%20memory">here</a></p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/329ba701bdc5881e1bed1aec20b21dd1/href">https://medium.com/media/329ba701bdc5881e1bed1aec20b21dd1/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.554537</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*q_6XixGgKpUOTnWOTE0_9A.png" /></figure><h3>6. Seq2Seq</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/417/1*J9K8-xLBHBb6mHZxBI8l5A.png" /></figure><p>Seq2Seq models are LSTM with encoder-decoder architecture. If you want to know more about Seq2Seq, go <a href="https://www.analyticsvidhya.com/blog/2020/08/a-simple-introduction-to-sequence-to-sequence-models/">here</a>:</p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/44a1e9c7392ee36e10487495f0c63390/href">https://medium.com/media/44a1e9c7392ee36e10487495f0c63390/href</a></iframe><p>The <strong>TimeDistributed</strong> layer is a keras wrapper that allows you to apply a same Dense (fully-connected) operation to every temporal slice, one time step at a time, of an input 3D Tensor. Example, if TimeDistributed receives data of shape (None, 100, 32, 256) then the wrapped layer (e.g. Dense) will be called for every slice of shape (None, 32, 256). Here none corresponds to samples/batch size.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*5mQGdSg5ru89UOaM3oopRw.png" /></figure><p>The <strong>RepeatVector</strong> is used to repeat the input for set number, n of times. Here, it produce N copies of Encoder’s output. For example, if RepeatVector with argument 3 is applied to layer having input shape (batch_size, 16), then the output shape of the layer will be (batch_size, 16, 3). The RepeatVector layer acts as a <strong>bridge between the encoder and decoder</strong> modules.</p><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.482833</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/581/1*wClg2q3MFV1UB_W3Re1UQw.png" /></figure><p>The encoder-decoder did is job! The time series seems denoised.</p><h3><strong>7. CNN-BiLSTM</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/798/1*DzW4AMK6rPc3ME38P_c_Tw.png" /></figure><p>A CNN-BiLSTM is Convolutional layers followed by BiLSTM layers with a Dense layer on the output. The Convolutional layers are used for <strong>feature extraction</strong> and the BiLSTM layers for learning the extracted features across time steps.</p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/49be78d3e88febc65c17967147173156/href">https://medium.com/media/49be78d3e88febc65c17967147173156/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.585092</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*fkc1gJfPtkczlVUOgrCryw.png" /></figure><h3>8. TCN-BiLSTM</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qwB--q1Ir-pIF08ibear_w.png" /></figure><p>In a TCN model (Temporal Convolutional Network), the convolutions are causal, meaning that there is no information leakage from future to past (Causal here simply means a filter at time step t can only see inputs that are no later than t). The network use dilated convolutions (a.k.a. atrous convolutions), a technique that expands the kernel (input) by inserting holes / spaces / defined gaps between the values. TCN can also be improved by adding residual blocks between each layer to speed up convergence and enable deeper models (At the core of residual blocks, there is a direct connection which skips some layers in between. This connection is called a « skip connection »). For this special neural network architecture we will use this library « <strong><em>pip install keras-tcn </em></strong>». If you want more information about the TCN models, go <a href="https://unit8.com/resources/temporal-convolutional-networks-and-forecasting/">here</a></p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c2cf135a50c6421e5c6c1549eed5a78/href">https://medium.com/media/8c2cf135a50c6421e5c6c1549eed5a78/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.483058</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/579/1*CnuYw7K-v05ZfnfnHRljlQ.png" /></figure><h3>9. MDN-BiLSTM</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/874/1*9o_as_cEe7-mmWf8EMK-wA.png" /></figure><p>A MDN-BLSTM is BLSTM layers followed by a Mixture Density Network layer that learns the parameters (mean, variance and probability) of the distributions mixture in the data. For this special neural network architecture we will use this library « <strong><em>pip install keras-mdn-layer</em></strong> ». If you want to learn more about the MDN neural network, you can read an article I wrote <a href="https://medium.com/@dave.cote.msc/made-easy-mixture-density-network-for-multivariate-regression-49e576721b3">here</a> :</p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/02c5b04adbfd5bf9eea4b3d5cd69b954/href">https://medium.com/media/02c5b04adbfd5bf9eea4b3d5cd69b954/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.441485</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*rB3ju_aRZrHB_5pwib6J8Q.png" /></figure><h3><strong>10. Attention-BiLSTM</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/652/1*iru5MmPml0W8xnodUMWVIg.png" /></figure><p>Adding attention layer can help our BiLSTM in memorizing large sequences of data by enhancing some parts of the input data while diminishing other parts (focus). The final model should devote more focus to a smaller but more important part of the data. For this special neural network architecture we will use this library « <strong><em>pip install keras-self-attention </em></strong>» but keras also offer an Attention layer (Luong-style attention). If you want to learn more about attention, you can go <a href="https://machinelearningmastery.com/the-transformer-attention-mechanism/">here</a> and <a href="https://blog.floydhub.com/attention-mechanism/">here</a></p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0cb7b72ca296e5e3da58d0eb045e077d/href">https://medium.com/media/0cb7b72ca296e5e3da58d0eb045e077d/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.536199</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*UV5MU8pS7gfUxWMRpD3drA.png" /></figure><h3>11. Seq2Seq with Attention</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jMT7wvr505iIgwTk4D15ZA.png" /></figure><p>Encoder-decoder architecture where the attention alignement is applied between the decoder LSTM state of the seq2seq model and the prediction (Luong Attention Model). Is you want to learn more about seq2seq with attention go <a href="https://colab.research.google.com/github/kmkarakaya/ML_tutorials/blob/master/seq2seq_Part_F_Encoder_Decoder_with_Bahdanau_%26_Luong_Attention_Mechanism.ipynb">here</a></p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5f33e2ee59ecc4356f84eb20c0480bab/href">https://medium.com/media/5f33e2ee59ecc4356f84eb20c0480bab/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.604704</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*x-urYydkTfjyQeG_cCjoOQ.png" /></figure><h3>12. MultiHeadAttention-BiLSTM</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/465/1*4iRm1UeyVkoZCyclcpRLdQ.png" /></figure><p>MultiHead attention runs the attention mechanism several times in parallel for consistent performance improvements over conventional attention. The independent attention outputs are then concatenated and linearly transformed into the expected dimension. For this special neural network architecture we will use this library « <strong><em>pip install keras-multi-head </em></strong>» but keras also offer a MultiHeadAttention layer as described in the paper “Attention is all you Need” (Vaswani et al., 2017). If you want to learn more about multihead attention mechanism, go <a href="https://data-science-blog.com/blog/2021/04/07/multi-head-attention-mechanism/">here</a></p><p><strong>keras implementation:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/58988319ebfaf61e9565cf2ec1a30981/href">https://medium.com/media/58988319ebfaf61e9565cf2ec1a30981/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.527637</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/579/1*MkRTL2MH0zMo6ActcCTyug.png" /></figure><h3>13. Time2Vec BiLSTM</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*BR1ONPjxEI_kRQJGQTrgRw.png" /></figure><p>Time series embeddings are a representation of time data in the form of vector embeddings. The official paper is <a href="https://arxiv.org/pdf/1907.05321.pdf">here</a>. According to the paper the Time2Vec representations have 3 main properties:</p><ul><li>1-Capturing both periodic and non-periodic (linear) patterns with the help of periodic activation functions with learnable parameters</li><li>2-Invariant to time rescaling</li><li>3-Being simple enough so it can be combined with many models</li></ul><p><strong>Time2Vec Layer:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/19a33d3575784c9003bc75068c7f78aa/href">https://medium.com/media/19a33d3575784c9003bc75068c7f78aa/href</a></iframe><p><strong>keras implementation (model):</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c880fde98431460987e9ccb51a0b4b4e/href">https://medium.com/media/c880fde98431460987e9ccb51a0b4b4e/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.642626</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*r1Rd45-9P3jYtrMfySjOFw.png" /></figure><p>Impressive results!</p><h3>14. Time2Vec with Transformer</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*GOUXbRknXWM_QkrbIONtdg.png" /></figure><p>And finaly, the last model! Here, we use the awesome Time2Vec to create time data embeddings and we add a transformer block to it. In the Transformer, the Attention module repeats its computations multiple times in parallel. Deeper explanation available <a href="https://towardsdatascience.com/the-time-series-transformer-2a521a0efad3">here</a></p><p><strong>Transformer:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0e2df061c0dcf12570ee96b52aa26ff/href">https://medium.com/media/f0e2df061c0dcf12570ee96b52aa26ff/href</a></iframe><p><strong>keras implementation (Model):</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/08eac9f749932d85735f48912bda0f5d/href">https://medium.com/media/08eac9f749932d85735f48912bda0f5d/href</a></iframe><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.532287</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*y2-6qH9-72pW8FSrhxDFCA.png" /></figure><h3>15. Average Ensemble Model</h3><p>If we take all the results of the preceding models and make an average, we’ve got our average ensemble model!</p><p><strong>Mean RdR Score (On 12 random seeds): </strong>0.611903</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*Oq44vzig1qY95-i94-5SjQ.png" /></figure><h3>15. Final Benchmark</h3><p>Since neural networks are extremely stochastic by nature, I executed all the models with different seeds 12 times to get the final results.</p><p><strong>Mean RdR Scores (after 12 runs):</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/366/1*cmAY5TlaE6pz-fY19yGHYg.png" /><figcaption>Mean RdR Scores from 12 different random seed executions</figcaption></figure><p>We can see that, in this case, all the model are superior than a naïve Random Walk model.</p><p>The <strong>Time2Vec-BiLSTM</strong> is, by far, the great Winner here! What about the stability ?:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ytmnd6lcEa9MFlu8tO9aZg.png" /></figure><p>After runing 12 times the same notebook with different random seed, we can see that, given the actual hyperparameters, some model are much more stable than others (yes, 12 samples is few for establishing a representative distribution but still, it’s better than nothing considering the computing time needed to get more samples!).</p><p><strong>Standard Deviations (all metrics):</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/358/1*uXGDzEjgD5bhccIWQQb07Q.png" /><figcaption>standard deviation from 12 different random seed executions</figcaption></figure><p>The Attention-BiLSTM and the TCN-BiLSTM seems to be the less stable models (wider distributions).</p><p>The <strong>Average Ensemble</strong> and the <strong>Time2Vec-BiLSTM</strong> seems to be both, the more stable models (narrow distribution) and the more performant models (the highest mean RdR Score), using this experiment configuration, of course!</p><p>In forecasting, doing an Average Ensemble model is always a good idea as it can ensure higher performance stability over time than using a single model.</p><p>To improve the stability on other models we could try to tune some hyper-parameters like the batch size, the number of hidden neurons, weights decay (regularization), etc.</p><h3>16-Time serie#2 –Daily multi-seasonalities</h3><p>Here is the second time series we will use :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/626/1*rtniOy65yHhxbnlX7e40BA.png" /></figure><p>This is a daily time serie. Just by looking at the time series no obvious trend can be seen. However, the seasonal structure is much more complex than the previous one as it seems to have multiple seasonal components: Weekly, Monthly, Day of month, Week of year, etc.</p><p>For this second experiment, we will try to forecast <strong>365 days</strong> into the future:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eebdb546700a428130197032da5d7b08/href">https://medium.com/media/eebdb546700a428130197032da5d7b08/href</a></iframe><p>Because <strong>Time2Vec-BiLSTM</strong> was the best model from the last experiment, we will try it on our new time series (code remains the same).</p><p>The new <strong>RdR Score</strong> is<strong>: </strong>0.389154</p><p>We can see that the RdR score is still a lot better than a naïve random walk model but lower than the previous time series score. In fact, this time series is more complex and should be more difficult to predict which is the case here !</p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/631/1*UYHxWkqi8RQLj_bvCPnNZA.png" /></figure><p><strong>If we zoom (Blue = Validation forecast, Orange = Ground truth):</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/627/1*1rAA1G1jYovyYCmz-PQPOw.png" /></figure><p>Not bad at all for a first try on a 365 days forecast into the future !</p><h3>17-Time serie#3 –Daily stochastic (Amazon Stock)</h3><p>Here is the last time series we will use :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*uEnxlhWdwm9Sp2oqbHea6A.png" /></figure><p>This is a daily time series, again. This time, no obvious seasonal structure can be seen. The trend seems to go up, exponentially-alike then stabilize and seems to go down. Very difficult to predict what will happen next just by looking at it ! We will try to forecast <strong>120 days</strong> into the future.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/563/1*Z1FBY5yEeUOEpjRvAQsMaA.png" /></figure><p>If we start with a simple <strong>BiLSTM </strong>model:</p><p>The new <strong>RdR Score</strong> is<strong>: <em>-0.676</em></strong></p><p><strong>Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*3m0w0w_dAJuERI5t_7hPAg.png" /></figure><p><strong>If we zoom:</strong></p><ul><li><strong>Blue</strong>: Ground Truth</li><li><strong>Orange: </strong>Validation forecast (test)</li><li><strong>Red: </strong>Validation Naïve Random Walk</li><li><strong>Green: </strong>Forecast</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*hq96nSRwG3iFphQ3oNYHig.png" /></figure><p>What happened here ? Our model is worst than a simple naïve random walk model !</p><p>Well, stocks are very <strong>stochastic in nature</strong>, so there are rarely good historical recurring patterns that our model can learn from. By definition, a stochastic signal is unpredictable. In this case, we can try to improve the results by adding some exogenous features (ex: other stocks, tweets, etc.) and hope that there is some <strong>temporal cross correlations</strong> between the exogenous and endogenous time series that our model will catch during the training process.</p><p>This little diagram can help to understand the different types of time series:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ccqsDRKPAqtvAmWmHS_DPQ.png" /></figure><p>The same experiment seems to be better with the <strong>Time2Vec BiLSTM (RdR Score: 0.288) </strong>… however great care needs to be taken here due to the unpredictable stochastic nature of the time series itself (A good one-time validation test does not necessarily imply that the model will always going to perform well in the future):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/903/1*8NThUKIhaVINatIiZ_OzZQ.png" /></figure><p><strong>Adding exogenous features:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/613/1*B1bvqbDyG7OOzYkO9Te5PA.png" /></figure><p>We add 3 exogenous features and set “exog = True”:</p><ul><li><strong>MSFT_CLOSE </strong>(Microsoft stocks)</li><li><strong>covid</strong> (Google Trends: covid search term)</li><li><strong>amazon </strong>(Google Trends: amazon search term)</li></ul><p><strong>BiLSTM:</strong></p><p>The new <strong>RdR Score</strong> is<strong>: <em>-0.034. </em></strong>Small performance increase, but still worst than Naïve Random Walk:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/903/1*pVhFTJuwlxPbLYVZPXf_Qw.png" /></figure><p><strong>Time2Vec BiLSTM:</strong></p><p>The new <strong>RdR Score</strong> is <strong>0.603</strong> vs 0.288 before. Considerable performance increase here.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/901/1*LhVEsZ6spKzMBwYqo5pg7w.png" /></figure><p>Again, as the stochastic nature of the time series should trigger us an alert, we should dig deeper into the <strong>temporal cross correlations</strong> analysis between the added exogenous features and the amazon stocks as both model got an increased performance with it. We could also test with different random seeds and different time sequences to measure the stability of the performance over time.</p><h3>18-Multivariate-Multisteps-Multioutput</h3><p>To finish, we will use the same time series from the first experiment but we will extract the Trend, Seasonal and Residuals components and we will simultaneously forecast the 3 resulting time series using a Multivariate Multisteps Multioutput neural network model:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0a63a0e536ff6b496b94d31d8be66754/href">https://medium.com/media/0a63a0e536ff6b496b94d31d8be66754/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aa3fc40b34a1bd4ab76163b37de8025a/href">https://medium.com/media/aa3fc40b34a1bd4ab76163b37de8025a/href</a></iframe><p>We now have 3 time series we want to forecast at the same time using the same model:</p><ul><li>EASY — <strong>Trend</strong> (Output #1)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/356/1*aOyvUQJRlE44Negt0eSeQg.png" /></figure><ul><li>EASY — <strong>Seasonal</strong> (Output #2)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/361/1*EgBrq4fRxBxUiR8THIQy9Q.png" /></figure><ul><li>EASY — <strong>Residuals</strong> (Output #3)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*eM_rhX7JT7Dv9yOZ6jkIzA.png" /></figure><p><strong><em>*WARNING*</em></strong>: There is something very important we need to take into consideration here. If you look at the 3 time series, the <strong>Seasonal </strong>seems stationary but the <strong>Trend</strong> have a mean non-stationary issue and the <strong>Residuals</strong> have a variance non-stationary issue (heteroskedastic variance).</p><p>If we want our model to perform on both 3 time series at the same time, we can’t just apply the same transformations (ex: differencing or log) on all the time series, we need to apply specific transformation for specific time series depending on the specific needs.</p><p>This is why, if you look at the new parameter of the configuration dictionary, <strong>stabilize_mean</strong> and <strong>stabilize_variance</strong> now takes list of columns as input instead of a binary indicator TRUE / FALSE. This means that the transformations will be applied only on the specified times series in the lists.</p><p>According to the parameters:</p><ul><li><strong>Trend</strong> time series will receive a <strong>differencing</strong> treatment</li><li><strong>Residuals</strong> time series a <strong>log transformation</strong></li><li><strong>Seasonal</strong> time series will not receive any treatment</li></ul><p>For the 2d matrice conversion to 3d tensor, we can re-use our precious function as it take a list of y targets colnames as input. The transformation logic is the same!</p><ul><li>The X_Train 3d tensor shape is : (139, 24, 45)</li><li>The y_Train 3d tensor shape is : (139, 24, <strong><em>3</em></strong>)</li></ul><p>If we continue with our favorite <strong>Time2Vec-BiLSTM</strong> model, here is 2 possible ways of constructing our neural network architecture to be able to manage multiple outputs:</p><p>1- Using the <strong>TimeDistributed layer </strong>at the end, like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c493c8ecf84a472bb3a4b8f1c61a54a9/href">https://medium.com/media/c493c8ecf84a472bb3a4b8f1c61a54a9/href</a></iframe><p>2- Using the <strong>Reshape layer </strong>at the end, like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/30e6c5500f90ba386e1b0c77839cca5a/href">https://medium.com/media/30e6c5500f90ba386e1b0c77839cca5a/href</a></iframe><p>If we take the <strong>TimeDistributed</strong> architecture, here is the results:</p><ul><li>RdR Score for Trend: <strong>0.84317</strong></li><li>RdR Score for Seasonal: <strong>0.75001</strong></li><li>RdR Score for Residuals: <strong>0.30810</strong></li></ul><p><strong>Trend Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/944/1*3I2Zd3jxzHMXQTXRb0_d0Q.png" /></figure><p><strong>Seasonal Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*-tzWfo_ay46AU89gAy7-PQ.png" /></figure><p>Here, there seems to have some problems. We should go back to hyper-parameters and feature engineering tuning steps ! This time series should be very easy to understand by our model as it’s the same repeating pattern over time.</p><p><strong>Residual Forecast Result:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/953/1*RQGHDCjGjXVDKPaqYpy3Qw.png" /></figure><p>Here, normally, the residual component should be pure random white noise. We may think that the initial decomposition didn’t do its job because there is some structure left in the remaining residues.</p><p>For fun, if we combine the 3 forecasts together (additive) we obtain:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*49foKSPEGtOuRfuG7BZ_IA.png" /></figure><p>That’s a very interesting experiment !</p><h3>19-Link to all the code</h3><p>In my public github, <a href="https://github.com/CoteDave/blog/tree/master/Hands-on%20Advanced%20Deep%20Learning%20Time%20Series%20Forecasting%20with%20Tensors"><strong><em>here</em></strong></a>, you have all the code needed to calculate easily my custom RdR Score as well as the custom “differencing” and “Log” preprocessing classes I made for time series.</p><p>I also added 4 jupyter notebooks:</p><ul><li><a href="https://github.com/CoteDave/blog/blob/master/Hands-on%20Advanced%20Deep%20Learning%20Time%20Series%20Forecasting%20with%20Tensors/Advanced%20DL%20Forecasting%20-%20EASY.ipynb">Advanced DL Forecasting — EASY.ipynb</a></li><li><a href="https://github.com/CoteDave/blog/blob/master/Hands-on%20Advanced%20Deep%20Learning%20Time%20Series%20Forecasting%20with%20Tensors/Advanced%20DL%20Forecasting%20-%20MEDIUM.ipynb">Advanced DL Forecasting — MEDIUM.ipynb</a></li><li><a href="https://github.com/CoteDave/blog/blob/master/Hands-on%20Advanced%20Deep%20Learning%20Time%20Series%20Forecasting%20with%20Tensors/Advanced%20DL%20Forecasting%20-%20HARD.ipynb">Advanced DL Forecasting — HARD.ipynb</a></li><li><a href="https://github.com/CoteDave/blog/blob/master/Hands-on%20Advanced%20Deep%20Learning%20Time%20Series%20Forecasting%20with%20Tensors/Advanced%20DL%20Forecasting%20-%20EASY-Multivariate-Multisteps-Multioutput.ipynb">Advanced DL Forecasting — EASY Mulivariate-Multisteps-Multioutput.ipynb</a></li></ul><p>These are templates that you can easily adapt with your own time series:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/767/1*ZWrNMB0GapLwQDi34eI3Vg.png" /></figure><p>Each notebook has a table of contents where you can quickly access the parts of interest:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/444/1*qyuDRZdrLpTIvjq61VpURw.png" /></figure><p>Each model is split into 4 parts:</p><ul><li>Model Architecture</li><li>Model Training</li><li>Model Validation</li><li>Model Forecasting</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/303/1*zL6Sx6bqVEHBIcYNTJBLBg.png" /></figure><p>Enjoy!</p><h3>20-Conclusions</h3><p>In this tutorial, we experimented various deep learning architectures with a set of diverse time series using 3d tensors. Here are some on the conclusions we can retain from this experiments:</p><ul><li>Preparing the 3d tensor from the 2 matrice is a crucial step in the deep learning forecasting journey.</li><li>We have to be very careful not to add any future “y signals” in the “X features” when preparing the tensors. You can start by spliting your time series before doing any preprocessing step.</li><li>There is no “one size fit all” model or feature engineering for time series problems.</li><li>Multivariate Multisteps Multioutput models are powerful but tricky and not always a good idea if the mixed time series to be produced are too heterogeneous (better to treat them individually with different parameters or preprocessing).</li><li>Time2Vec is a great vector embeddings tool to try for improving model performance.</li><li>A more complex model does not always mean a better model.</li><li>Using an average ensemble of multiple heterogenous forecasting models can help with the stability of the results over time.</li><li>To perform well on an autoregressive (univariate) time series forecasting problem, the time series itself must have a minimum of historical deterministic structural patterns. Generally speaking, the model will perform poorly on univariate stochastic time series.</li><li>We can try to improve the results of stochastic time series by adding some exogenous features (temporal cross correlations)</li><li>A good one-time validation test does not necessarily imply that the model will always perform well in the future. We can try different random seeds and different historical time sequences to measure the stability of the performance over time. We can also dig into temporal correlations to find results explanations.</li><li>As we extrapolate over time, the results should always be used with extreme caution. As the model learns from past structure and past correlations, it cannot predict future changes it has never seen before such as data drift, context drift or new disruptive events.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7facae522f18" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RdR score metric for evaluating time series forecasting models]]></title>
            <link>https://medium.com/@dave.cote.msc/rdr-score-metric-for-evaluating-time-series-forecasting-models-1c23f92f80e7?source=rss-a351f759381e------2</link>
            <guid isPermaLink="false">https://medium.com/p/1c23f92f80e7</guid>
            <category><![CDATA[time-series-analysis]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[model-validation]]></category>
            <category><![CDATA[forecasting]]></category>
            <dc:creator><![CDATA[Dave Cote, M.Sc.]]></dc:creator>
            <pubDate>Tue, 08 Feb 2022 19:06:53 GMT</pubDate>
            <atom:updated>2022-02-08T19:06:53.640Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/859/0*YyHp5jydlp11owP6" /></figure><p>In this text, I will propose you an experimental technic to evaluate the performance of time series forecasting models but before, we will quickly surf on popular time series scoring technics:</p><ol><li><strong>MAE, RMSE and AIC</strong></li><li><strong>Mean Forecast Accuracy</strong></li><li><strong>Warning: The time series model EVALUATION TRAP!</strong></li><li><strong>RdR Score Benchmark</strong></li></ol><p>This new RdR Score technique will give several benefits such as being able to:</p><ul><li>Compare models together and select the best one</li><li>Facilitate explanation to manager or business team</li><li>Help decide whether the forecasting model should be use or not</li><li>How much a forecasting model is good, alone or compared to other models</li><li>Use the<em> shape similarity</em> of the forecast as an important evaluation criterion</li><li>Use <em>randomness</em> as an important evaluation criterion; is the forecasting model better than a naïve random decision? How much better?</li></ul><p>The proposed <strong>RdR metric </strong>use:</p><ul><li><strong>R: Naïve Random Walk</strong></li><li><strong>d: Dynamic Time Warping</strong></li><li><strong>R: Root Mean Squared Error</strong></li></ul><p><strong><em>*Warning</em></strong>: This is very experimental and not issued from any research paper. I named this technic RdR score only to give this experimentation a name and to facilitate the understanding of what the metric actually do. Use it at your own risk!</p><p>The code of this experimental RdR score technic is available on my <a href="https://github.com/CoteDave/blog"><strong>github</strong></a>.</p><p>To experiment this metric, we will work on three different datasets and four models to resolve multistep forecasting problems:</p><ul><li><strong>SARIMA (Box-Jenkins method)</strong></li><li><strong>Holt-Winters (Triple Exponential Smoothing)</strong></li><li><strong>LightGBM (Gradient Boosting) (as a Multivariate Multi-Target Regressor)</strong></li><li><strong>Seq2Seq (Deep Learning) (as a Multivariate Multi-Target Regressor)</strong></li></ul><p>I will assume that you know those models. If not, those models are a mix of popular old school econometric forecasting, machine learning and deep learning. There is plenty information on them if you search on Google.</p><p><strong>1MAE, RMSE and AIC</strong></p><p>Currently, the most popular metrics for evaluating time series forecasting models are <strong>MAE, RMSE </strong>and <strong>AIC</strong>.</p><p>If you want to read more about those metrics:</p><p><strong>· MAE vs RMSE</strong>: <a href="https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d">https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d</a></p><p><strong>· AIC</strong>: <a href="https://en.wikipedia.org/wiki/Akaike_information_criterion">https://en.wikipedia.org/wiki/Akaike_information_criterion</a>, <a href="https://stats.stackexchange.com/questions/24116/one-sentence-explanation-of-the-aic-for-non-technical-types">https://stats.stackexchange.com/questions/24116/one-sentence-explanation-of-the-aic-for-non-technical-types</a>, <a href="https://towardsdatascience.com/the-akaike-information-criterion-c20c8fd832f2">https://towardsdatascience.com/the-akaike-information-criterion-c20c8fd832f2</a></p><p>To briefly summarize, both <strong>MAE</strong> and <strong>RMSE</strong> measures the magnitude of errors in a set of predictions. The major difference between MAE and RMSE is the impact of the large errors. For example, if some prediction data points are large outliers errors when compared to the ground truth, those large errors will be diluted in the mean of MAE while RMSE score will be higher because of the square operation.</p><p><strong>AIC</strong> measure the loss of information and penalize the complexity of a model. It is the negative log likelihood penalized for a number of parameters. The main idea behind AIC is that model with less number of parameters is better. AIC lets you test how well your model fits the dataset without overfitting it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/983/0*wkaR1DDAXxCZ5Jwe" /></figure><p>With MAE and RMSE, the perfect score is 0 (The goal is to have the lowest score possible). Both values range from 0 to ∞, and depend on the scale of the target we want to forecast.</p><p>MAE is the easiest to interpret. For example if MAE is 450$, we could say that our forecasting model have an average error of 450$ per forecast (+ or -). Very easy to explain to a manager or a business team. Is it good? Should we use it? Well, it depends on the use case context, the distribution of the errors (skewed or not, outliers or not) and many other things.</p><p>RMSE interpretation is less intuitive. If RMSE is 450$, we could say that our forecasting model have an “penalized” average error of 450$ per forecast, which is somewhat not very intuitive.</p><p>For AIC, there is no perfect score, the lower is the better. Soo it is not possible to evaluate the AIC score alone, it is only use to compare models together. For example, if used alone, an AIC of -950 does not give any clue about the model performance and impossible to explain to a manager.</p><p><strong>2Mean Forecast Accuracy</strong></p><p>The <strong>Mean Forecast Accuracy</strong> is also an interesting metric. This metric is very intuitive and easy to explain to a manager (Our model have an average of 66% forecasting accuracy, which also means that our models have an average forecasting error of 34%). It gives a good approximation of how well a forecasting model performs. For example, take these forecasting results:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/829/0*RO2iT_QH_Tg-MMYe" /></figure><p><strong><em>Well… Nothing is perfect!</em></strong></p><p>We can see that this metric have a major flaw. The mean has one main disadvantage; it is particularly susceptible to the influence of outliers. When the forecast results are really bad (when the error alone is higher than the expected ground truth result), the percentage can goes really low (In this example: (1 — (225/25)) gives <em>Minus 800%</em>) which will have a big negative impact on the global Mean Forecast Accuracy.</p><p>· A solution to this problem could be to clip the minimum percentage value to 0%, to reduce the impact of isolated / outlier forecast results.</p><p>· We could also have use the median instead of the mean</p><p>For example, if we used median instead of zero clipping, it gives us a Median Forecast Accuracy of 85% (the outlier have been ignored), compared to 66% with Mean Forecast Accuracy with zero clipping.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/693/0*JMG0J4fCIg5wRG64" /></figure><p>In general, when your error distribution is skewed, you should use Median instead of Mean. In some case, the Mean Forecast Accuracy could also mean totally nothing. If you remember your statistics; the <strong>coefficient of variation (CV)</strong> represents the ratio of the standard deviation to the mean (Coefficient of Variation = (Standard Deviation / Mean) * 100). A big CV value means big variability, which also means greater level of dispersion around the mean. For example, we could consider anything above a CV of 0.7 as highly variable and not really forecastable. In addition, it can show that your forecasting model prediction’s ability is very unstable! (The mean have a poor meaning in this case) <strong><em>(source: </em></strong><a href="https://blog.arkieva.com/do-you-use-coefficient-of-variation-to-determine-forecastability/"><strong><em>https://blog.arkieva.com/do-you-use-coefficient-of-variation-to-determine-forecastability/</em></strong></a><strong><em>)</em></strong></p><p><strong>3Warning: The time series model EVALUATION TRAP!</strong></p><p>Okay, before we deep dive into the experimental RdR technic, I would like to talk about one important mistake I have seen so many times on the internet: <strong><em>Please, do not calculate performance metrics on the fitted data / training data!</em></strong></p><p>In <em>traditional statistics</em>, time series forecasting models were often evaluated on the “fit” (“find the best <em>fit”</em>) predictions results of the model, which I think, makes absolutely no sense at all! In machine learning process, are we evaluating / choosing our models on the fit results? <em>NEVER (I hope so!)</em>. Unless you want to know if your model is overfitting or underfitting (you can compare validation and training set results)</p><p>I think this way of thinking comes from old fashion curve fitting technics where the goal is to fit a curve as best as possible. When you add the time dimension, the problem is that when we try to extrapolate this overfitted curve through time, the results are rarely good:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/234/0*Eo0x6mU6GYno1tpr" /><figcaption>Source: <a href="https://www.explainxkcd.com/wiki/index.php/2048:_Curve-Fitting">https://www.explainxkcd.com/wiki/index.php/2048:_Curve-Fitting</a></figcaption></figure><p>Another big problem with that way of thinking is, when you use advanced technics like gradient boosting ensemble or deep learning, the fit will usually be very good or perfect and hide overfitting problems that you will only discover in the <strong><em>extrapolation process through time</em>.</strong></p><p>I have read several experiments where a deep learning model is perfectly fit on a time series with the conclusion: <em>“Wow, deep learning with time series is so revolutionary and incredible!”</em> (And of course, you don’t see the extrapolation process through time that should come next and that probably didn’t work very well…). Fitting is not a problem anymore (You just have to set a big number of estimators to an ensemble model or a big number of epochs to a neural network model), overfitting is!</p><p><strong>4RdR Score Benchmark</strong></p><p>The proposed RdR score technic will mainly answer three questions:</p><p><em>How can we take into account the </em><strong><em>shape similarity</em></strong><em> of a time series? :</em></p><ul><li>Answer: <strong>Dynamic Time Warping</strong></li></ul><p><em>How can we know if we should use our forecasting model or not? :</em></p><ul><li>Answer: Is it better or worst than a <strong>Naïve Random Walk</strong>?</li></ul><p><em>How can we take into account the errors? :</em></p><ul><li>Answer: <strong>Root Mean Squared Error (RMSE)</strong></li></ul><p>Now, suppose we have those two following models, with exactly the same RMSE:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/737/0*NxvAsMg6rETLwEX1" /></figure><p>Which model would you choose?</p><p>One big flaw about using MAE, RMSE or AIC; those metrics does not take into account an important criterion of the forecast: <strong>THE SHAPE SIMILARITY!</strong></p><p>Why use <strong>Dynamic Time Warping (DTW) </strong>as a similarity metric? :</p><p>• Euclidean distance between time series: Bad choice because there is distortion in the time axis</p><p>• DTW: Find the optimal (minimum distance) warping path between two time series, by « synchronizing » / « align » the different signals on the time axis</p><p>• The DTW distance is the square root cost of optimal warping path</p><p>• The lowest the distance on the warping path, the more similar are the time series.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/456/0*dOes9OHmn1LQ1BcW" /><figcaption>source: <a href="https://www.slideshare.net/DavideNardone/accelerating-dynamic-time-warping-subsequence-search-with-gpu">https://www.slideshare.net/DavideNardone/accelerating-dynamic-time-warping-subsequence-search-with-gpu</a></figcaption></figure><p>If you want to know more about Dynamic Time Warping (DTW): <a href="https://www.slideshare.net/DavideNardone/accelerating-dynamic-time-warping-subsequence-search-with-gpu"><strong><em>https://www.slideshare.net/DavideNardone/accelerating-dynamic-time-warping-subsequence-search-with-gpu</em></strong></a></p><p>If a manager ask you, “should we use our forecasting model to predict the future? Is it good or not?” An interesting answer could be: Well, based on the performance evaluation metrics, our model is 65% better than if we randomly make a decision. This is where random walk shows off.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/974/0*tSXRfJjBy0VRiLQ5" /></figure><p>We can interpret the RdR score as the percentage of difference (In error and shape similarity) between your model and a simple random walk model, based on RMSE score and DTW score. If the percentage is negative, your model is <em>[X]%</em> worst than randomness. If the percentage is positive, your model is <em>[X]%</em> better than randomness. In another words, the <em>[X]%</em> will change depending on the RMSE errors and the DTW distance around 0, which is the bound of naïve randomness. Why RMSE instead of MAE? I think that penalizing the average error with large errors reflect more the reality and the stability of the model.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/0*r-_YlBoXn6ggm6Av" /></figure><p>-∞% means that sometimes, you may have a very big negative percentage score like -98695%; This is bad news and it means that you should definitely not use the model!</p><p>There could also be a strange situation where the perfect score equals the random walk model (A straight line). Well, in his case, you do not really need a model!</p><p>Enough talking, let’s try it and see what happens!</p><p>Experiment Dataset#1: Easy (Good autocorrelation and seasonal structure, deterministic system):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/862/0*TzD4LCiy4usmZnOF" /></figure><p><em>The multistep unseen test data we will use to validate the performance of our models:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/849/0*hpe5iZAdVVHgEnod" /></figure><p><em>The naïve random walk model (RdR Score = 0):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/871/0*M_MowD3eaPyjyhZ-" /></figure><p>The forecasts from a random walk model (without drift) are equal to the last observation; Scenario where future movements are unpredictable and are equally likely to be up or down (Stochastic). It gives a straight line because if we do infinite random simulations from the last data point, as the chances are equally likely to be up or down, the mean will be equal to the last observation. Like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/0*WBnhD8-5SlUV7SxR" /></figure><p>Can we beat this?</p><p><em>Here, the multistep forecasts of 12 periods in the future (unseen test data) of our four models:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*CJQpK1qF0j8RKnPQ" /></figure><p><em>Let’s calculate the RdR score of each model:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-l5bvFm15bk91fJd" /></figure><p>With this graph, we can see that all the performance are very near. The best model is Seq2Seq.</p><p><em>If we want to have more detailed information on the RdR score, we can plot the RMSE vs DTW like this:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gUSlehxhNamqKjKV" /></figure><p>The y axis is for the penalized errors while the x axis is for the shape similarity of the time series (between prediction and unseen test dataset). In this graph, we can see that Seq2Seq was the best model, in both error and shape and that it is halfway between the random walk score and the perfect score (which represent the 50,32% RdR score). We can see that LightGBM have slightly more errors than the econometric models (RMSE) but have a slightly better shape similarity (DTW distance). All models were a lot better than the Random Walk model performance.</p><p><em>Interpretation of the best model (Seq2Seq):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/0*K7bu4-bA50xAS0id" /></figure><p><em>If we zoom the prediction of the best model (Seq2Seq):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/858/0*s1vFMpVWN8K7u0qb" /></figure><p>Experiment Dataset#2: Medium (Autocorrelation and seasonal structure, with a lot of noise):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/869/0*IvULgLCzu80Co-BX" /></figure><p><em>The multistep unseen test data we will use to validate the performance of our models:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/893/0*YF1puLT9z9XATqp0" /></figure><p><em>The naïve random walk model (RdR Score = 0):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/841/0*rOzmbxkUzazcOOBb" /></figure><p>Can we beat this? :</p><p><em>Here, the multistep forecasts of 12 periods in the future (unseen test data) of our four models:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*F4ACfN0IxFFT6pLx" /></figure><p><em>Let’s calculate the RdR score of each model:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*BwDZdahRlfREY34S" /></figure><p>We can see that the SEQ2SEQ model was the best. SARIMA performed the worst but all models are still better than the random walk. As we expected, we can also see that globally, this round was more difficult than the previous one; the RdR scores are lower.</p><p><em>If we want to have more detailed information on the RdR score, we can plot the RMSE vs DTW like this:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PAgH1XXqXvNjWYcG" /></figure><p>The y axis is for the penalized errors while the x axis is for the shape similarity of the time series. In this graph, we can see that Seq2Seq was the best model, in both error and shape. SARIMA was almost equal RMSE than random walk but the shape of SARIMA time series was better (DTW distance).</p><p><em>Interpretation of the best model (Seq2Seq):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/781/0*gq0kWrRmaJ30Dvwv" /></figure><p><em>If we zoom the prediction of the best model (Seq2Seq):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/752/0*dg8mlmqtKjfjW3FK" /></figure><p>Experiment Dataset#3: Hard (Poor autocorrelation, poor seasonal structure, stock price alike):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/842/0*HeTUB1BqBgU6nJpU" /></figure><p><em>The multistep unseen test data we will use to validate the performance of our models:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/884/0*36hMS1qpBEq47FDj" /></figure><p><em>The naïve random walk model (RdR Score = 0):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/892/0*JhMeUq5AXNuelfSS" /></figure><p>Can we beat this?</p><p><em>Here, the multistep forecasts of 12 periods in the future (unseen test data) of our four models:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ak1Qkm7iD8z_ACOb" /></figure><p><em>Let’s calculate the RdR score of each model:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*OdbeIwlGBqT4Cpfv" /></figure><p>Just by looking at this bar chart, we should not use both Holt-Winters and LightGBM as they are worst (in error and shape similarity) than a simple naïve random walk model.</p><p><em>If we want to have more detailed information on the RdR score, we can plot the RMSE vs DTW distance like this:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6SNKgmKN7xJ_KPBb" /></figure><p>The y axis is for the penalized errors while the x axis is for the shape similarity of the time series. In this, we can see that Seq2Seq was the best model while Holt-Winters and SARIMA were very near the random walk performance. LightGBM was out, the worst model in this case.</p><p><em>If we zoom the prediction of the best model (Seq2Seq):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/851/0*FATffh9PHJRVduHw" /></figure><p><em>Interpretation of the best model (Seq2Seq):</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/0*UJAXMqOfK43JQpum" /></figure><p>With RdR score, we can also try to get an overall score on the three datasets together:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/613/0*w4l478eB9z9MF0Q-" /></figure><p>Seq2Seq win this round with mean RdR score of 38,08%, Holt-Winters in second position, SARIMA then LightGBM.</p><p>Of course, we could have tune the hyper-parameters, make more data transformations, tune neural network architecture, add exogenous data, etc. but the goal here was not to put the focus on the models.</p><p>As usual, the python code of this experimental “RdR score” is avalaible on my github as jupyter notebook experiment:<strong> </strong><a href="https://github.com/CoteDave/blog/blob/master/RdR%20score/RdR_score_experiment.ipynb"><strong>github</strong></a>.</p><p>I hope that this experiment have been useful to you!</p><h3>Dave Cote, Data Scientist, M.Sc. BI</h3><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c23f92f80e7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Visualization trick for multivariate regression problems]]></title>
            <link>https://medium.com/@dave.cote.msc/visualization-trick-for-multivariate-regression-problems-5b3aa25ff2f8?source=rss-a351f759381e------2</link>
            <guid isPermaLink="false">https://medium.com/p/5b3aa25ff2f8</guid>
            <category><![CDATA[visualization]]></category>
            <category><![CDATA[regression-analysis]]></category>
            <category><![CDATA[model-validation]]></category>
            <category><![CDATA[regression]]></category>
            <category><![CDATA[multidimensional]]></category>
            <dc:creator><![CDATA[Dave Cote, M.Sc.]]></dc:creator>
            <pubDate>Tue, 08 Feb 2022 19:03:30 GMT</pubDate>
            <atom:updated>2022-02-08T19:03:30.727Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/proxy/0*g2j4Zd1vzXZ43kOh" /></figure><p>In a univariate regression problem, it is easy to see the model decision function / how your model is generalizing the problem by doing a simple X vs Y plot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*a0Qjt6Ed4QTzZbpe" /></figure><p>With this plot, we can easily see if the model found a good generalization solution, if it overfit, underfit, etc. It is also a nice tool to compare different models together:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*7jqT8Id0PPztCllx" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*vQgLCXqopQRsAUxg" /></figure><p>When you add 1 feature to the regression problem, we can still plot the model decision function but it will be in 3D, and the generalization solution is not a line anymore but become a 3D surface:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/0*jAXpACKkSV1S8GWd" /><figcaption>Source: <a href="https://scipy-lectures.org/packages/statistics/auto_examples/plot_regression_3d.html">https://scipy-lectures.org/packages/statistics/auto_examples/plot_regression_3d.html</a></figcaption></figure><p>It is more difficult to evaluate the model decision function in 3D but still, it is possible !</p><p>Now, what happen if we add other features to the regression model, how can we visualize the model regression function in 4D, 5D, 6D… nD ??? Sometimes, it is difficult to evaluate a model performance only by using the RMSE, MAE or R2 scores because it does not give any clues about how the model is reacting when the data changes, so wee need a visualization to help us out!</p><p>Off course, the visualization trick that I will present you is not perfect, nothing is! Still, it helps to understand how the model reacts when the target change and it also help to validate the overall model generalization performance. Something nice about this trick: It is always the same, no matter how many features you have in your model!</p><p>First, when you got your train fit and test predictions ready, create 2 new datasets with 2 columns each:</p><p>Dataset_1: fit_results_df:</p><p>1. Y_TRUE: Y train set original values</p><p>2. Y_FIT: Y train fit values</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/152/0*DvpiI4QoaRtK4YCO" /></figure><p>Dataset_2: test_pred_results_df:</p><p>1. Y_TRUE: Y test set original values</p><p>2. Y_PRED: Y test prediction values</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/164/0*WVnNA62xZhM-hHfP" /></figure><p>Then, for both datasets, simply sort all the rows by Y_TRUE values in an ascending order and finally, reset the indexes.</p><p>If we plot the Y_TRUE values of both datasets, it will show:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/0*lG3cqWEDPNj2BVFh" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/588/0*L0OGBzj4AB7mgHkV" /></figure><p>This is all the ordered y values of the train and test set in ascending order.</p><p>Then, we plot the corresponding Y_FIT and Y_PRED values of both datasets:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/579/0*PlWgM92sfkaolzqd" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/582/0*qIcTrTCG9PiETIbi" /></figure><p>This model is a simple Decision Tree with a max depth limited to three. With this visualization trick, we can see that:</p><p>· The “simplified” 2d model decision function is “step-alike” (Give a clue that this is a Decision Tree!)</p><p>· The model is probably underfitting (Could have more steps!). George St-Pierre would probably say: <em>“I am not impressed by your performance”</em></p><p>· The performance seems very similar between the train fit and the predictions test set</p><p>· The model seems to follow the target variations; when the y values go up, the prediction and fit goes up too most of the time ! (Sometimes, it happens that the model is only good with high or low target values and do not follow the target variations correctly… the visualization help us to see that very easily!)</p><p>· There are patterns, bunches of fit/predictions that are out! (Maybe outliers? Need some investigations…):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/579/0*FW23OqT_C-NVFTdi" /></figure><p>Let us improve the model a bit and see what will happen! :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/581/0*WuPFG9aPniT83P0o" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/585/0*CzqoPh6hBRoYa1EN" /></figure><p>This new model is a Random Forest with a max depth limited to 5 and 750 estimators.</p><p>We can easily say that this model is better than the old one, without checking at the Scores! (Although, you should check the scores!). We can also see that there are still bunches of fit/predictions data points that are out in the right-bottom corner of the plot, those data points need an investigation!</p><p>If we want, we can also compare multiple models at a time (Let say we are only interested in the predictions of the test set):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*SZIs1ANhsZOpYAkE" /></figure><p>If you prefer, you can also use a line instead of data points to represent the “2D simplified” model decision function on Y Target:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/530/0*jp0rmDDlzKaw0vSY" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nIwF8YQ2nTADYA71" /></figure><p>You can plot the train and the test sets at the same time if you want!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*mGPV1WCkAF1Ec-Dy" /></figure><p><em>Example: Random Forest on boston dataset, test and train datasets</em></p><p>You can also add a prediction interval, like the inductive conformal prediction, around Y prediction target if needed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/835/0*D0sy8RypcMlqAhD1" /></figure><p><em>Example: Deep Neural Network with an Inductive Conformal Prediction</em></p><h3><strong>Conclusion:</strong></h3><p>We saw that this tool:</p><ul><li>Is not perfect but can help to validate and visualize a “2D simplified” multivariate regression model decision function when you have more than two features in your problem</li><li>Can be used to compare different models together</li><li>Can help to identify patterns, for example: If the model follows correctly the target variations or if there are data points clusters that did not fit/predict correctly / need investigations (Maybe some feature engineering / cleaning steps to help the model with those data points!)</li><li>Can be use to compare Train vs Test performance</li><li>Can be customized depending on the preferences or needs of the data sicence practitioner (Scatter vs line plot, inductive conformal prediction, train vs test, etc.)</li><li>Off course, this tool is not sufficient; you should continue to use regression scores like RMSE to validate your models!</li></ul><p>I hope that this shared visualization trick could be useful to you!</p><p>The simplified codes of this experimentation is available on my github (Jupyter notebook experimentation on the boston dataset): <a href="https://github.com/CoteDave/blog/blob/master/Visualization%20trick%20for%20multivariate%20regression%20problems/Visualization%20trick%20for%20multivariate%20regression%20problems.ipynb"><strong>github</strong></a></p><p>Dave Cote, Data Scientist, M.Sc. BI</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5b3aa25ff2f8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Made Easy — Mixture Density Network for multivariate Regression]]></title>
            <link>https://medium.com/@dave.cote.msc/made-easy-mixture-density-network-for-multivariate-regression-49e576721b3?source=rss-a351f759381e------2</link>
            <guid isPermaLink="false">https://medium.com/p/49e576721b3</guid>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[regression]]></category>
            <category><![CDATA[mdn]]></category>
            <category><![CDATA[regression-analysis]]></category>
            <dc:creator><![CDATA[Dave Cote, M.Sc.]]></dc:creator>
            <pubDate>Tue, 08 Feb 2022 19:01:14 GMT</pubDate>
            <atom:updated>2022-02-08T19:01:14.210Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/proxy/0*O6uEPm50nv0j44hB" /></figure><p>In this article, I will first explain briefly what a MDN is and then give you the python code to make your own MDN model with only a few lines of code.</p><p>Before we start…</p><p>If you prefer to follow the jupyter notebook: <a href="https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/Made%20easy%20-%20MDN%20regression.ipynb"><strong><em>https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/Made%20easy%20-%20MDN%20regression.ipynb</em></strong></a></p><p>If you want to play around and experiment yourself with my experimental custom MDN python class model : <a href="https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/mdn_model.py"><strong><em>https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/mdn_model.py</em></strong></a></p><p>First… Mixture Density Network regression … huh What !??? Let’s start slow and explain separately and quickly all the main terms here:</p><p><strong>1. Regression</strong></p><p><strong>2. Density</strong></p><p><strong>3. Mixture Density</strong></p><p><strong>4. Network</strong></p><p><strong>5. Regression Network</strong></p><p><strong>6. Density Network</strong></p><p><strong>7. Mixture Density Network regression</strong></p><p><strong>8. Practice fun — Univariate dataset with custom MDN class</strong></p><p><strong>9. Practice fun — Multivariate dataset with custom MDN class</strong></p><p><strong>10. Conclusion</strong></p><p><strong>1REGRESSION</strong></p><p>First, the term “regression”. If you have click on this article, I assume you know what regression is all about, but if not, here a really quick and simple explanation from <strong>Jason Brownlee</strong> of <strong>Machine Learning Mastery (Great guy by the way!)</strong>:</p><p><em>“Regression predictive modeling is the task of approximating a mapping function (f) from input variables (X) to a continuous output variable (y) […] A regression problem requires the prediction of a quantity. A problem with multiple input variables is often called a multivariate regression problem […] For example, a house may be predicted to sell for a specific dollar value, perhaps in the range of $100,000 to $200,000 […] ” </em><strong><em>(Source: </em></strong><a href="https://machinelearningmastery.com/classification-versus-regression-in-machine-learning/#:~:text=A%20regression%20problem%20requires%20the,called%20a%20multivariate%20regression%20problem."><strong><em>https://machinelearningmastery.com/classification-versus-regression-in-machine-learning/#:~:text=A%20regression%20problem%20requires%20the,called%20a%20multivariate%20regression%20problem.</em></strong></a><strong><em>)</em></strong></p><p>Here another visual explanation that differentiate a classification problem from a regression problem<em>:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/775/0*7jjYLr-IommAv0jd" /><figcaption><em>source: </em><a href="https://towardsdatascience.com/regression-or-classification-linear-or-logistic-f093e8757b9c"><em>https://towardsdatascience.com/regression-or-classification-linear-or-logistic-f093e8757b9c</em></a></figcaption></figure><p>A Last example for the luck…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*m2r7FOO-uK3jxKkI" /><figcaption><em>source: </em><a href="https://vinodsblog.com/2018/11/08/classification-and-regression-demystified-in-machine-learning/"><em>https://vinodsblog.com/2018/11/08/classification-and-regression-demystified-in-machine-learning/</em></a><em>)</em></figcaption></figure><p><strong>2DENSITY</strong></p><p>Okay, now what the term “density” is all about? Here a quick <strong><em>“cheesy” </em></strong>example:</p><p>Suppose you are delivering pizza for pizza-hut. You decide to capture the time (in minutes) of each delivery you just made. After 1000 deliveries, you decide to visualize your data to see how well you performed. Here is the result <em>:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/0*YVnh-wFuNU8aa54N" /><figcaption><em>source: </em><a href="https://statisticsbyjim.com/basics/normal-distribution/"><em>https://statisticsbyjim.com/basics/normal-distribution/</em></a></figcaption></figure><p>Here is the “density” of the distribution of your pizza delivery times data. Soo, in average, it took you 30 minutes per delivery (The peak in the graph). It also says that 95% of the time (2 standard deviations (SD)), your delivery took between 20 and 40 minutes to accomplish. Here, the density <em>kind of</em> represents the “frequency” of the time results. The difference between “frequency” and “density” is that:</p><p><strong>· Frequency</strong>: If you draw a histogram under this curve and counts all the bins, it will sum up to any whole number (depending on the total number of observations captured in your dataset).</p><p><strong>· Density</strong>: If you draw a histogram under this curve and counts all the bins it will always sum up to 1. We can also call this curve the probability density function (pdf).</p><p>In statistical terms, this is a beautiful normal / Gaussian distribution. This normal distribution have two parameters:</p><p>· The <strong>mean</strong></p><p>· The <strong>standard deviation</strong> <em>(According to Wikipedia: “Standard deviation is a number used to tell how measurements for a group are spread out from the average (mean), or expected value. A low standard deviation means that most of the numbers are close to the average. A high standard deviation means that the numbers are more spread out.”)</em></p><p>The change of <strong>mean </strong>and <strong>standard deviation</strong> will affect the shape of the distribution. For Example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jbaMG1UyT6XGoDXR" /><figcaption><em>source: </em><a href="https://towardsdatascience.com/probability-concepts-explained-probability-distributions-introduction-part-3-4a5db81858dc"><em>https://towardsdatascience.com/probability-concepts-explained-probability-distributions-introduction-part-3-4a5db81858dc</em></a></figcaption></figure><p>Of course, there exists a variety of different distributions types with different kind of parameters. For example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/989/0*PYmNg8VetpyvDW1I" /></figure><p><strong>3MIXTURE DENSITY</strong></p><p>Okay now let’s have a look at those 3 distributions:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/810/0*y0uxeolJUUJxIXGY" /><figcaption><em>Source: </em><a href="https://medium.com/analytics-vidhya/learning-from-multimodal-target-mixture-density-network-94891d4e357e"><em>https://medium.com/analytics-vidhya/learning-from-multimodal-target-mixture-density-network-94891d4e357e</em></a></figcaption></figure><p>If we take this bimodal distribution (Also called a general distribution):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/0*Mn2YaFQHG42Kd3_L" /></figure><p>Mixture Density Network use the assumption that any general distribution like this bimodal distribution can be broken down into a mixture of normal distributions (The mixture can also be customize with other type of distributions like Laplace for example):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/455/0*fVPtcZ2WnfPVU8B6" /></figure><p>Soo if you add up those 2 normal distributions (red and blue), where each distribution have is own mean and standard deviation, it will gives back the bimodal general distribution (purple).</p><p><strong>4NETWORK</strong></p><p>Network for Artificial neural network. Soo yes, a Mixture Density Network is a type of artificial neural network. Here a classical example of a neural network:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/709/0*zAOnBtfi7N522uoi" /><figcaption>source: www.<a href="https://www.udemy.com/course/artificial-intelligence-masterclass/learn/lecture/13200042#overview">S</a>uperDataScience.com</figcaption></figure><p>You have the input layer (yellow), the hidden layer (green) and the output layer (red). (I assume here that everyone know what an artificial neural network is, if not, go on google to find out!).</p><p><strong>5REGRESSION NETWORK</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/793/0*oDqWED9ucdHpRRqg" /><figcaption>source: www.<a href="https://www.udemy.com/course/artificial-intelligence-masterclass/learn/lecture/13200042#overview">S</a>uperDataScience.com</figcaption></figure><p>A regression network is an artificial neural network where the goal is to learn to output a continuous value given some input features. In the example above, given the age, sex, education and other features, the artificial neural network learns to predict the salary.</p><p><strong>6DENSITY NETWORK</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/995/0*GwIJf51svlMK-XC4" /><figcaption>source: www.<a href="https://www.udemy.com/course/artificial-intelligence-masterclass/learn/lecture/13200042#overview">S</a>uperDataScience.com</figcaption></figure><p>A density network is an artificial neural network where the goal is not to simply learn to output a single continuous value, but to learn to output the distribution parameters (here, mean and standard deviation), given some input features. In the example above, given the age, sex, education and other features, the artificial neural network learns to predict the mean and the standard deviation of the expected salary distribution. Predicting the distribution versus a single value have advantages like being able to gives uncertainty boundaries with the prediction. This is a “Bayesian” approach of resolving a regression problem. Here is a great illustration of predicting the distribution of each expected continuous values:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*eiwsFmU-MV_OYVa9" /><figcaption><em>Source: </em><a href="https://towardsdatascience.com/bayesian-thinking-estimating-posterior-distribution-for-linear-regression-data-ketchup-2f50a597eb06"><em>https://towardsdatascience.com/bayesian-thinking-estimating-posterior-distribution-for-linear-regression-data-ketchup-2f50a597eb06</em></a></figcaption></figure><p>Another great illustration that shows us the distribution of the expected values, for each predicted instance:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/611/0*zhfjxMq-DI6x7_gy" /><figcaption><a href="https://engineering.taboola.com/predicting-probability-distributions/"><em>https://engineering.taboola.com/predicting-probability-distributions/</em></a></figcaption></figure><p><strong>7MIXTURE DENSITY NETWORK</strong></p><p>Finally! A mixture density network is an artificial neural network where the goal is to learn to output all the parameters (here, the mean, standard deviation and Pi) of all the distribitions mixed in the general distribution, given the specific input features. The new parameter “Pi” is the mixture parameter that gives the weights/probability of a given distribution in the final mixture.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*BoBaAlfItNQgEiz_" /><figcaption>source: www.<a href="https://www.udemy.com/course/artificial-intelligence-masterclass/learn/lecture/13200042#overview">S</a>uperDataScience.com</figcaption></figure><p>The final result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*UDrdVd1DQwAkZEgg" /><figcaption>source: www.<a href="https://www.udemy.com/course/artificial-intelligence-masterclass/learn/lecture/13200042#overview">S</a>uperDataScience.com</figcaption></figure><p><strong>8PRACTICE FUN — UNIVARIATE DATASET WITH CUSTOM MDN CLASS</strong></p><p>Okay, enough of this theoretical stuff, let’s do it!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/442/0*VxKxf7Ik6NT46jpi" /></figure><p>Here we have this famous “half-moon” dataset:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/557/0*A9OKytZrKKlzPC5D" /></figure><p>Just by looking at the data, we can see that there is two overlapping clusters.</p><p>If we plot the density distribution of the target value (y):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/321/0*HK0X8Nj7ci6T8WhB" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/539/0*10zpHVvVe4UwrpsU" /></figure><p>We have a nice <strong><em>“ghost-like”</em></strong> multimodal distribution (general distribution). If we try a standard Linear Regression on this dataset to predict y with X:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/0*hkGL3V54tSSgDNAC" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/556/0*qczp_ROtUE-QBpKS" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/0*pT6yNK3SD6z3baFJ" /></figure><p>Did not work very well!</p><p>Let’s now try a nonlinear model (Radial Basis Function Kernel Ridge regression):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/786/0*uBSClWroBXyS6XfW" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/559/0*v6acA6PnJzLAhpeP" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/542/0*hT8VIp6bhG3JFdic" /></figure><p>Better, but not quite yet!</p><p>The main reason why both model did not make it is because, if you look on the X-axis, multiple different y values exists for the same X value… more specifically, there seems to exists more than one possible y distribution for the same X. The regression model just tried to find the optimal function that minimize the error and did not took in consideration a mixture of densities, which is the case! Those X in the middle do not have a unique Y solution, they have two possible solutions, one high and one low!</p><p>Let’s now try a MDN model to see what this beast can do! For that, I implemented for you a quick nice and easy to use “fit-predict”, “sklearn alike” customized python MDN class. Here is the link to my python code if you want to use it yourself (Be aware: this MDN class is experimental and has not been extensively tested): <a href="https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/mdn_model.py"><strong><em>https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/mdn_model.py</em></strong></a></p><p>To be able to use this class, you will need to have sklearn, tensorflow probability, Tensorflow &lt; 2 (If you want to make this MDN model class compatible with TF2, feel free to contribute!), umap and hdbscan (for custom visualization class function).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/528/0*IZLfN4XD4dOQWcI9" /></figure><p>· <strong>n_mixtures</strong>: number of distribution mixtures to use by the MDN. If set to -1, it will “auto” find the optimal number of mixtures using a gaussian mixtures model (GMM) and a HDBSCAN model on X and y.</p><p>· <strong>dist</strong>: Distribution type to use in the mixture. For now, there are two choices available; “normal” or “laplace”. (Based on some experimentations, Laplace distribution gave me better results than normal distribution).</p><p>· <strong>input_neurons</strong>: Number of neurons to use in the input layer of the MDN</p><p>· <strong>hidden_neurons</strong>: Architecture of the hidden layers. Of the MDN. List of neurons per hidden layer. This parameter give you the ability to choose the number of hidden layers and the number of neurons per hidden layer.</p><p>· <strong>gmm_boost</strong>: Boolean. If set to True, will add cluster features to the dataset.</p><p>· <strong>optimizer</strong>: Optimization algorithm to use.</p><p>·<strong> learning_rate</strong>: Learning rate of the optimization algorithm</p><p>· <strong>early_stopping</strong>: To avoid overfitting when training. This trigger will decide when to stop training when no change in metric over a given number of epochs.</p><p>·<strong> tf_mixture_family</strong>: Boolean. If set to True, will use the tf_mixture family (Recommended): The Mixture object implements batched mixture distributions. The mixture model is defined by a Categorical distribution (the mixture) and a python list of Distribution objects.</p><p><strong>· input_activation</strong>: Activation function of the input layer</p><p>· <strong>hidden_activation</strong>: Activation function of the hidden layer</p><p>Now that our MDN model is fitted on the data, let’s samples from the mixture density distribution and plot the probability density function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/444/0*lkwRZ40PuwSKwsrJ" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/0*Mi24ryDEDRQqLMbU" /></figure><p>Wow! Our MDN model fitted pretty well the true general distribution!</p><p>We can broke down the final mixture distribution into each distribution to see how it looks:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/499/0*zmCrlGLzgHpN6evK" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/541/0*h-oS-Nskly8BFqcu" /></figure><p>Let’s sample again some Y data using our learned mixture distribution and this time, plot the generated samples against the true ones:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/424/0*pIZgx6ocPTA2UVx6" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/556/0*yr9fLYCFm2WkTpyX" /></figure><p>Again, pretty close from reality!</p><p>Given X, we can also generate multiple batch of sample to produce statistics like quantile, mean, etc.:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/651/0*GYKIHzC_P59CQzGr" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/531/0*RjaBkLwPpMDotfr0" /></figure><p>Now, we can plot the mean of each of our learned distributions, with their respective mixture weights (pi):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/563/0*9dscv3Qga_PQazqD" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/565/0*O6uEPm50nv0j44hB" /></figure><p>Wow, MDN just nailed it, again!</p><p>As we have the mean and the standard deviation from each distribution, we can also plot the uncertainties with the full tail; let’s say we plot the mean with a confidence interval of 95%:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/543/0*elDjLI9czVKzIwBO" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/773/0*IAmoDhVIa-wdgv2q" /></figure><p>We can also mix the distribution together and, when we have multiple y distributions for the same X, we choose the most probable mixture using the highest Pi parameter value:</p><p>· Y_preds = for each X, choose the Y mean of the distribution with the max probability/weight (Pi parameter)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/286/0*hJKGluJEUQPWZ43z" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/557/0*7G-a0o6P3Y7fztPb" /></figure><p>If we add the 95% confidence interval:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/339/0*FjsxwJ6IMa8X7ikT" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/0*VY1Pl8vREL7NLXBF" /></figure><p>Not ideal here, because there are clearly two distinct clusters overlapping in our data with near equivalent density. The errors would be higher than a standard regression model. This also means that maybe there is an important feature missing in our dataset that could help to avoid the cluster overlapping in a higher dimensionality.</p><p>We can also choose to mix the distribution using the Pi parameters and the means of all the distribution together:</p><p>· Y_preds = (mean_1 * Pi1) + (mean_2 * Pi2)</p><p>Which gives:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/273/0*g7dGTVi67r7AKrZ7" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/554/0*TxoO9WK6SMaEa0Sb" /></figure><p>If we add the 95 confidence interval:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/558/0*v4pWB1xyM4nQJkLV" /></figure><p>This option gives us pretty much the same result as a non-linear regression model, mixing everything to minimize the distance between the dots and the function. This gives a single function that pass through the two clusters.</p><p>In this very particular case, my favorite option would be to assume that in some region of the data, X have more than one Y while in other regions; only one of the mixture is used. That give use something like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*c5srIqIT2hRQOuXG" /></figure><p>For example, when X = 0, there is two possible distinctive Y solutions from each mixture. When X = -1.5, there is a unique Y solution from mixture 1. Depending on the use case or business context, an action or decision can be triggered when more than one solution exists for the same X.</p><p>With this option, the rows are duplicated when there is an overlapping distribution (If both mixture probabilities are &gt;= given probability threshold). This give something like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/326/0*WvQHpz6FlE-5Awh5" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/0*gqai4QyhKNU7ttJD" /></figure><p>With the 95% confidence interval:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/787/0*cDk_3U6UcfXv4LL2" /></figure><p>Dataset rows passed from 2500 to 4063 and the final predictions dataset looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1009/0*nNDcW2lP1CyUcfF4" /></figure><p>In this data table, we see that, for example, when X = -0.276839, Y can be 1.43926 (with 0.351525 of probabilities of mixture_0) but can also be -0.840593 (with 0.648475 of probabilities of mixture_1).</p><p>The instances with multiple distributions gives also an important information that something is going on in the data and that maybe it needs more analysis. Maybe it is some data quality problems or maybe it indicates that an important feature is missing in the dataset!</p><p>Another example: <em>“traffic scene prediction is a good candidate for where Mixture Density Networks can be used. In traffic scene prediction, we need a distribution over behaviors an agent can exhibit — for example, an agent could turn left, turn right, or go straight. Thus, Mixture Density Networks can be used to represent “behaviors” in each of the mixture it learns, where the behavior consists of a probability and trajectory ((x, y) coordinates up to some time horizon in the future).(source: </em><a href="http://blog.adeel.io/tag/mixture-density-networks/"><em>http://blog.adeel.io/tag/mixture-density-networks/</em></a><em>)“</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/0*btI0_ZtGVCTelQB0" /><figcaption><a href="http://blog.adeel.io/tag/mixture-density-networks/">http://blog.adeel.io/tag/mixture-density-networks/</a></figcaption></figure><p><strong>9PRACTICE FUN — MULTIVARIATE DATASET WITH CUSTOM MDN CLASS</strong></p><p>Okay finally, does MDN perform well with multivariate regression problems? Let’s find out !</p><p>First of all, let’s have a look at the dataset we will use:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/427/0*HrhjunxD8CB_l7vx" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/102/0*IBLB9YqzPtYf1OYv" /></figure><p><strong>· age</strong>: age of primary beneficiary</p><p><strong>· sex</strong>: insurance contractor gender, female, male</p><p><strong>· bmi</strong>: Body mass index, providing an understanding of body, weights that are relatively high or low relative to height, objective index of body weight (kg / m ^ 2) using the ratio of height to weight, ideally 18.5 to 24.9</p><p><strong>· children</strong>: Number of children covered by health insurance / Number of dependents</p><p><strong>· smoker</strong>: Smoking</p><p><strong>· region</strong>: the beneficiary’s residential area in the US, northeast, southeast, southwest, northwest.</p><p><strong>· charges</strong>: Individual medical costs billed by health insurance. This is the target that we want to forecast</p><p>I took this data dictionary from <a href="https://www.kaggle.com/mirichoi0218/insurance">https://www.kaggle.com/mirichoi0218/insurance</a>. If you go to this link, you can also have an interactive visualization of the dataset.</p><p>If you want to do some expriments, the dataset is also available here: <a href="https://github.com/stedy/Machine-Learning-with-R-datasets">https://github.com/stedy/Machine-Learning-with-R-datasets</a></p><p>The problem statement is: Can you accurately predict insurance costs (charges)?</p><p>To see a quick exploratory data exploration on this dataset, you can read one of my previous article here: <a href="https://www.linkedin.com/pulse/demonstrating-power-feature-engineering-part-ii-how-i-dave-c%C3%B4t%C3%A9/">https://www.linkedin.com/pulse/demonstrating-power-feature-engineering-part-ii-how-i-dave-c%C3%B4t%C3%A9/</a></p><p>Now, let’s import the dataset:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/923/0*CJ3d2F5Idtmx48BZ" /></figure><p>…and do some basic data preparation!:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/714/0*HdYPUMf73MXbyQ2B" /></figure><p>The data is ready to feed the MDN model!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/649/0*VC2XeS314hl4PyoK" /></figure><p>Let’s now predict the test dataset using the “best mixture probabilities (Pi parameter) strategy” and plot the result (y_pred vs y_test):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/0*6OoJh6F6ISx6epK8" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*0iVxq1SeFqbyRZGz" /></figure><p>For this visualization technic, you can read one of my previous article: <a href="https://www.linkedin.com/pulse/visualization-trick-multivariate-regression-problems-dave-c%C3%B4t%C3%A9/">https://www.linkedin.com/pulse/visualization-trick-multivariate-regression-problems-dave-c%C3%B4t%C3%A9/</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/582/0*05RqW-jI99lw5noW" /></figure><p>Wow! This is completely insane! With a R2 of 89.09 and a MAE of 882.54, The MDN just destroyed it!</p><p>Let’s plot the fitted vs true distribution for fun:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/443/0*9Pi6_xdZONMzC2iP" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/0*mDsM2erq9zR3quXc" /></figure><p>Almost exactly the same!</p><p>If we broke down the mixture model:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/911/0*Ro8K9O7y7Edz3dLk" /></figure><p>There is a total of six different distributions in the general mixture distribution.</p><p>We can generate multivariate samples from the fitted mixture model (a PCA is applied to visualize the result in 2D):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/781/0*5yaVkyy1qriV-opq" /></figure><p>The generated samples are very close to the real ones!</p><p>We can predict from each distribution if we want:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/647/0*J8jydKskPkIycazi" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8MGCI-DnmQk451La" /></figure><p>We can check if there are overlapping cluster in the dataset:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/947/0*wguze0ibJV2ULGba" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/298/0*pwgqIFJVmoRqMoIF" /></figure><p>y_pred_overlaps have the same number of rows than the X_test dataset, so there is no overlapping! (We can adjust the pi parameter threshold for the sensibility)</p><p><strong>10CONCLUSION</strong></p><p>· MDN did a great job in the <strong>univariate regression</strong> dataset where two clusters overlapped on each other and where X could have more than one Y output, compared to linear or nonlinear classical ML models.</p><p>· MDN did also a great job in the <strong>multivariate regression</strong> problem and can compete with popular model like XGBoost</p><p>· MDN is a great and unique tool to have in your ML toolbox and can resolve particular problems that other models can’t do (capable of learning from data obtained from a mixed distribution)</p><p>· As MDN learn the distribution, you can also compute uncertainty with your predictions or generate new samples from the learned distribution</p><p>I hope this article helped you in your Machine Learning journey!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=49e576721b3" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>