<?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 Carolina Bento on Medium]]></title>
        <description><![CDATA[Stories by Carolina Bento on Medium]]></description>
        <link>https://medium.com/@carolinabento?source=rss-e960c0367546------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*E3Fc5VDEf5yYT82A8iI5Hw.png</url>
            <title>Stories by Carolina Bento on Medium</title>
            <link>https://medium.com/@carolinabento?source=rss-e960c0367546------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 05 Nov 2026 14:41:10 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@carolinabento/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[Large Language Models: A Short Introduction]]></title>
            <link>https://medium.com/data-science/large-language-models-a-short-introduction-bb8366118ad0?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/bb8366118ad0</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[large-language-models]]></category>
            <category><![CDATA[getting-started]]></category>
            <category><![CDATA[neural-networks]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Tue, 21 Jan 2025 19:48:18 GMT</pubDate>
            <atom:updated>2025-01-21T20:23:00.627Z</atom:updated>
            <content:encoded><![CDATA[<h4>And why you should care about LLMs</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WuN_rWpzNO0L1ZSmSI3ZBQ.png" /><figcaption>Image by author.</figcaption></figure><p>There’s an acronym you’ve probably heard non-stop for the past few years: LLM, which stands for Large Language Model.</p><p>In this article we’re going to take a brief look at what LLMs are, why they’re an extremely exciting piece of technology, why they matter to you and me, and why you should care about LLMs.</p><p><em>Note: in this article, we’ll use Large Language Model, LLM and model interchangeably.</em></p><h3>What is an LLM</h3><p>A <a href="https://en.wikipedia.org/wiki/Large_language_model">Large Language Model</a>, typically referred to as LLM since it is a bit of a tongue twister, is a mathematical model that generates text, like filling in the gap for the next word in a sentence [1].</p><p>For instance, when you feed it the sentence <em>The quick brown fox jumps over the lazy ____</em>, it doesn’t know exactly that the next word is <em>dog</em>. What the model produces instead is a list of possible next words with their corresponding probability of <em>coming next</em> in a sentence that starts with those exact words.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*r84a3t4cOdO8-7MK3JKjPw.png" /><figcaption>Example of prediction of the next word in a sentence. Image by author.</figcaption></figure><p>The reason why LLMs are so good at predicting the next word in a sentence is because they are trained with an incredibly large amount of text, which typically is scraped from the Internet. So if a model is ingesting the text in this article by any chance, Hi 👋</p><p>On the other hand, if you’re building an LLM that is specific to a particular domain, for example, you’re building a chatbot that could converse with you as if they were a character in <a href="https://en.wikipedia.org/wiki/William_Shakespeare">Shakespeare’s</a> plays, the internet will for sure have a lot of snippets or even his complete works, but it will have a ton of other text that’s not relevant to the task at hand. In this case, you would feed the LLM on the chatbot only Shakespeare context, i.e., all of his plays and sonnets.</p><p>Although LLMs are trained with a gigantic amount of data, that’s not what the <em>Large</em> in Large Language Models stands for. Besides the size of the training data, the other large quantity in these models is the number of parameters they have, each one with the possibility of being adjusted, i.e., tuned.</p><p>The simplest statistical models is <a href="https://en.wikipedia.org/wiki/Simple_linear_regression">Simple Linear Regression</a>, with only two parameters, the slope and the intercept. And even with just two parameters, there are a few different shapes the model output can take.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4mxDtmSa8Nx4n5Hd2mKekQ.png" /><figcaption>Different shapes of a linear regression. Image by author.</figcaption></figure><p>As a comparison, when GPT-3 was released in 2020 it had 175B parameters, yes Billion![3] While LLaMa, Meta’s open source LLM, had a number of different models ranging from 7B to 65B parameters when it was <a href="https://ai.meta.com/blog/large-language-model-llama-meta-ai/">released in 2023</a>.</p><p>These billions of parameters all start with random values, at the beginning of the training process, and it’s during the <a href="https://en.wikipedia.org/wiki/Backpropagation">Backpropagation</a> part of the training phase that they continually get tweaked and adjusted.</p><p>Similar to any other Machine Learning model, during the training phase, the output of the model is compared with the actual expected value for the output, in order to calculate the error. When there’s still room for improvement, Backpropagation ensures the model parameters are adjusted such that the model can predict values with a little bit less error the next time.</p><p>But this is just what’s called <em>pre-training</em>, where the model becomes proficient at predicting the next word in a sentence.</p><p>In order for the model to have really good interactions with a human, to the point that you — the human — can ask the chatbot a question and its response seems structurally accurate, the underlying LLM has to go through a step of <em>Reinforcement Learning with Human Feedback</em>. This is literally the <a href="https://en.wikipedia.org/wiki/Human-in-the-loop"><em>human in the loop</em></a> that is often talked about in the context of Machine Learning models.</p><p>In this phase, humans tag predictions that are not as good and by taking in that feedback, model parameters are updated and the model is trained again, as many times needed, to reach the level of prediction quality desired.</p><p>It’s clear by now that these models are extremely complex, and need to be able to perform millions, if not billions of computations. This high-intensity compute required novel architectures, at the model level with <a href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">Transformers</a> and for compute, with <a href="https://en.wikipedia.org/wiki/Graphics_processing_unit">GPUs</a>.</p><p>GPU is this class of graphic processors used in scenarios when you need to perform an incredibly big number of computations in a short period of time, for instance while smoothly rendering characters in a videogame. Compared to the traditional <a href="https://en.wikipedia.org/wiki/Central_processing_unit">CPUs</a> found in your laptop or tower PC, GPUs have the ability to effortlessly run many parallel computations.</p><p>The breakthrough for LLMs was when researchers realized GPUs can also be applied to non graphical problems. Both Machine Learning and Computer Graphics rely on linear algebra, running operations on matrices, so both benefit from the ability to execute many parallel computations.</p><p>Transformers is a new type of architecture developed by Google, which makes it such that each operation done during model training can be parallelized. For instance, while predicting the next word in a sentence, a model that uses a Transformer architecture doesn’t need to <em>read </em>the sentence from start to end, it process the entire text all at the same time, in parallel. It associates each word processed with a long array of numbers that give meaning to that word. Thinking about Linear Algebra again for a second, instead of processing and transforming one data point at a time, the combo of Transformers and GPUs can process tons of points at the same time by leveraging matrices.</p><p>In addition to parallelized computation, what distinguishes Transformers is an unique operation called Attention. In a very simplistic way, Attention makes it possible to look at all the context around a word, even if it occurs multiple times in different sentences like</p><p><em>At the end of the show, the singer took a bow multiple times.</em></p><p><em>Jack wanted to go to the store to buy a new bow for target practice.</em></p><p>If we focus on the word <em>bow</em>, you can see how the context in which this word shows up in each sentence and its actual meaning are very different.</p><p>Attention allows the model to refine the meaning each word encodes based on the context around them.</p><p>This, plus some additional steps like training a <em>Feedforward Neural Network</em>, all done multiple times, make it such that the model gradually refines its capacity to encode the right information. All these steps are intended to make the model more accurate and not mix up the meaning of <em>bow</em>, the motion, and <em>bow</em> (object related to archery) when it runs a prediction task.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*99B5QGFrhXdhRrd3pRHUzg.png" /><figcaption>A basic flow diagram depicting various stages of LLMs from pre-training to prompting/utilization. Prompting LLMs to generate responses is possible at different training stages like pre-training, instruction-tuning, or alignment tuning. “RL” stands for reinforcement learning, “RM” represents reward-modeling, and “RLHF” represents reinforcement learning with human feedback. Image and caption taken from paper referenced in [2]</figcaption></figure><p>The development of Transformers and GPUs allowed LLMs to explode in usage and application compared to prior to language models that needed to read one word at a time. Knowing that a model gets better the more quality data it learns from, you can see how processing one word at a time was a huge bottleneck.</p><h3>Why LLMs Matter</h3><p>With the capacity described, that LLMs can process enormous amounts of text examples and then predict with a high accuracy, the next word in a sentence, combined with other powerful Artificial Intelligence frameworks, many natural language and information retrieval tasks that became much easier to <em>implement </em>and <em>productize</em>.</p><blockquote><em>In essence, </em>Large Language Models (LLMs) have emerged as cutting edge artificial intelligence systems that can process and generate text with coherent communication and generalize multiple tasks<em>[2].</em></blockquote><p>Think about tasks like translating from English to Spanish, summarizing a set of documents, identifying certain passages in documents, or having a chatbot answer your questions about a particular topic.</p><p>These tasks that were possible before, but the effort required to build a model was incredibly higher and the rate of improvement of these models was much slower due to technology bottlenecks. LLMs came in and supercharged all of these tasks and applications.</p><p>You’ve probably interacted or seen someone interacting directly with products that use LLMs at their core.</p><p>These products are much more than a simple LLM that accurately predicts the next word in a sentence. They leverage LLMs and other Machine Learning techniques and frameworks, to understand what you’re asking, search through all the contextual information they’ve seen so far, and present you with a human-like and, most times coherent, answer. Or at least some provide guidance about what to look into next.</p><p>There are tons of Artificial Intelligence (AI) products that leverage LLMs, from Facebook’s <a href="https://about.fb.com/news/2024/04/meta-ai-assistant-built-with-llama-3/">Meta AI</a>, Google’s <a href="https://blog.google/technology/ai/google-gemini-ai/#sundar-note">Gemini</a>, Open AI’s <a href="https://openai.com/index/chatgpt/">ChatGPT</a>, which borrows its name from the Generative Pre-trained Transformer technology under the hood, Microsoft’s <a href="https://blogs.microsoft.com/blog/2023/03/16/introducing-microsoft-365-copilot-your-copilot-for-work/">CoPilot</a>, among many, many others, covering a wide range of tasks to assist you on.</p><p>For instance, a few weeks ago, I was wondering how many studio albums <a href="https://en.wikipedia.org/wiki/Incubus_(band)">Incubus</a> had released. Six months ago, I’d probably Google it or go straight to Wikipedia. Nowadays, I tend to ask <a href="https://gemini.google.com/app">Gemini</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/450/1*DefMG9se8uUO1UEmtS_cJQ.png" /><figcaption>Example of a question I asked Gemini 🤣 Image by author.</figcaption></figure><p>This is only a simplistic example. There are many other types of questions or prompts you can provide to these Artificial Intelligence products, like asking to summarize a particular text or document, or if you’re like me and you’re traveling to Melbourne, asking for recommendations about what to do there.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/775/1*6QEzPHa_vJoumYsXG4-rTA.png" /><figcaption>Example of a question I asked Gemini 🤣 Image by author.</figcaption></figure><p>It cut straight to the point, provided me with a variety of pointers on what to do, and then I was off to the races, able to dig a bit further on specific places that seemed more interesting to me.</p><p>You can see how this saved me a bunch of time that I would probably have to spend between Yelp an TripAdvisor reviews, Youtube videos or blogposts about iconic and recommended places in Melbourne.</p><h3>Conclusion</h3><p>LMMs are, without a doubt, a nascent area of research that has been evolving at a lightning fast pace, as you can see by the timeline below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UuaRdqcgAHGxPu9ZjHyZvw.png" /><figcaption>Chronological display of LLM releases: blue cards represent ‘pre-trained’ models, while orange cards correspond to ‘instruction-tuned’ models. Models on the upper half signify open-source availability, whereas those on the bottom are closed-source. The chart illustrates the increasing trend towards instruction-tuned and open-source models, highlighting the evolving landscape and trends in natural language processing research. Image and caption taken from paper referenced in [2]</figcaption></figure><p>We’re just in the very early days of productization, or product application. More and more companies are applying LLMs to their domain areas, in order to streamline tasks that would take them several years, and an incredible amount of funds to research, develop and bring to market.</p><p>When applied in ethical and consumer-conscious ways, LLMs and products that have LLMs at their core provide a massive opportunity to everyone. For researchers, it’s a cutting edge field with a wealth of both theoretical and practical problems to untangle.</p><p>For example, in Genomics, gLMs or Genomic Language Models, i.e., Large Language Models trained on DNA sequences, are used to accelerate our general understanding of genomes and how DNA works and interacts with other functions[4]. These are big questions for which scientists don’t have definitive answers for, but LLMs are proving to be a tool that can help them make progress at a much bigger scale and iterate on their findings much faster. To make steady progress in science, fast feedback loops are crucial.</p><p>For companies, there’s a monumental shift and opportunity to do more for customers, address more of their problems and pain-points, making it easier for customers to see the value in products. Be it for effectiveness, ease of use, cost, or all of the above.</p><p>For consumers, we get to experience products and tools to assist us on day-to-day tasks, that help perform our our jobs a little better, to gain faster access to knowledge or get pointers to where we can search and dig deeper for that information.</p><p>To me, the most exciting part, is the speed at which these products evolve and outdate themselves. I’m personally curious to see how these products will look like in the next 5 years and how they can become more accurate and reliable.</p><p>Technological leaps and scientific breakthroughs used to take decades or even centuries to occur. So it’s nothing shy of rational to be apprehensive when we experience big technological step-changes multiple times during our lifetime.</p><p>Among all the hype and some of the fads that come and go, the core technology underlying Large Language Models is fascinating and has proven to have interesting and plausible applications.</p><p>Hope you enjoyed this brief overview of LLMs, why they matter, and why it’s worth continuing to keep an eye on this research area and new AI products.</p><p><em>Thanks for reading!</em></p><h3>References</h3><p>[1] Large Language Models explained briefly (<a href="https://www.youtube.com/watch?v=LPZh9BOjkQs&amp;list=WL&amp;index=10">video</a>)</p><p>[2] <a href="https://arxiv.org/abs/2307.06435">A Comprehensive Overview of Large Language Models</a>. 2024.Humza Naveed and Asad Ullah Khan and Shi Qiu and Muhammad Saqib and Saeed Anwar and Muhammad Usman and Naveed Akhtar and Nick Barnes and Ajmal Mian.</p><p>[3] <a href="https://arxiv.org/pdf/2005.14165">Language Models are Few-Shot Learners</a>. 2020. Tom B. Brown and Benjamin Mann and Nick Ryder and Melanie Subbiah and Jared Kaplan and Prafulla Dhariwal and Arvind Neelakantan and Pranav Shyam and Girish Sastry and Amanda Askell and Sandhini Agarwal and Ariel Herbert-Voss and Gretchen Krueger and Tom Henighan and Rewon Child and Aditya Ramesh and Daniel M. Ziegler and Jeffrey Wu and Clemens Winter and Christopher Hesse and Mark Chen and Eric Sigler and Mateusz Litwin and Scott Gray and Benjamin Chess and Jack Clark and Christopher Berner and Sam McCandlish and Alec Radford and Ilya Sutskever and Dario Amodei</p><p>[4]<a href="https://arxiv.org/pdf/2407.11435">Genomic Language Models: Opportunities and Challenges</a>. 2024. Gonzalo Benegas and Chengzhong Ye and Carlos Albors and Jianan Canal Li and Yun S. Song.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bb8366118ad0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/large-language-models-a-short-introduction-bb8366118ad0">Large Language Models: A Short Introduction</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running — The Ultimate Reset]]></title>
            <link>https://medium.com/map-books/running-the-ultimate-reset-d9dcb191bee8?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/d9dcb191bee8</guid>
            <category><![CDATA[meditation]]></category>
            <category><![CDATA[focus]]></category>
            <category><![CDATA[mental-health]]></category>
            <category><![CDATA[workout]]></category>
            <category><![CDATA[running]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Mon, 09 Sep 2024 14:42:15 GMT</pubDate>
            <atom:updated>2024-09-09T14:42:15.413Z</atom:updated>
            <content:encoded><![CDATA[<h3>Running — The Ultimate Reset</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ulszDZ573zHBT1MU" /><figcaption>Photo by <a href="https://unsplash.com/@mattkgross?utm_source=medium&amp;utm_medium=referral">Matt Gross</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>The pavement is uneven, the sun is high. The body moves rhythmically, but the mind is still, it’s all quiet up there. You’re in a familiar place, but it feels different, peaceful. Time stops for a split second, and you’re beaming, a brief out-of-body experience before your foot touches the ground. These are the good days.</p><p>On bad days the mind is racing while the body is trying to keep up. Thoughts come and go, you think about work, house chores you’ve been procrastinating on, and why you forgot to call your mom again. Disjointed thoughts, anxieties, musings, all thrown into a blender at high-speed.</p><p>While running has had a sort of renaissance lately, for me, it’s been part of my life since I was about ten years old. It was a family activity back then, that went dormant during most of my young adult years.</p><p>For a decade or two, my dad was into running, he had his running buddies and raced recreationally, I guess in equals part for the physical and the social aspect. I’m glad I got dragged into that world at such a young age, because it became kind of imprinted in me. I was never the fittest or the fastest, and it doesn’t really matter. Through his experience, I got to appreciate the practice and develop a profound connection with running, develop my own ritual. The thing I like to do regardless of any social pressure, the one thing that constitutes my alone time, even when someone is around.</p><p>The process was long, and for most of my adolescence, running was never a thing, it never really clicked. I’d go for a run every now and then, on my own, defying the small town weird looks.</p><p>A few years ago I moved to a place that is fairly close to a regional park, with different trails, so picked it up again, as way to clear my head and force myself to workout. Although not on the first try, it shook me to the core. In one of those lightbulb moments, it finally clicked. I could feel it in my body, it became something I need, enjoy and look forward to. The kind of thing you make time for in your life.</p><p>Today running is a pillar for my health, physical and mental.</p><p>On the days my mind is especially loud and busy, those are the best days to go out for a run. The biggest hurdle is always getting ready, I can find a million reasons why I’m tired or need to do something later and running would delay everything.</p><p>Once the running gear is on, there’s no turning back. There’s a habit forming component to it too, and I use every trick I get to keep it going.</p><p>On the first few strides, my body gets acclimated and then goes into autopilot, the body knows it’s time to reset and quiet the mind.</p><p>Despite never being completely easy, the mental practice is worth the physical discomfort. Many days start off easy, thinking it’s going to be just a stroll, only to realize I’m more tired than I realized. From that moment on, the mind takes over and it’s all about listening to my body, so I don’t get injured, and pushing through, enforcing the discipline, practicing resilience. Just another half mile, just one more.</p><p>Some days it’s easier to embrace the challenge and push through, but it&#39;s never a sure thing. On those days you throw in the towel and stop, walk back home, and it&#39;s fine too.</p><p>Even on the days that laziness almost wins, or maybe especially on those days, that’s when running is more rewarding, more restorative. It forces the natural purge of stress and anxiety, you come out on the other side tired and maybe sore, but there’s a glow, a feeling of stillness and accomplishment.</p><p>It only takes me a good day, when my body feels good and responsive, mind and body in sync, to forget about the days when each mile felt like a marathon.</p><p>Running is a very personal experience, a moment of deep focus introspection. A natural cleanser, a time to organize the mind by being completely silent with myself while still surround by people or nature.</p><p>Nature runs are specially peaceful and relaxing. Running on a trail it&#39;s almost like asking Nature for permission to be there. It’s a place where nature comes first and if there are animals, it’s their environment, you’re just a passerby, so you have to respect them.</p><p>A mix of habit and necessity, it’s something that took me years to appreciate and develop. Looking back, there were times when I completely forgot that it was there for me as a tool and as a practice, a way of keeping me fit and serene.</p><p>Today, it’s my ultimate reset.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d9dcb191bee8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/map-books/running-the-ultimate-reset-d9dcb191bee8">Running — The Ultimate Reset</a> was originally published in <a href="https://medium.com/map-books">Side Notes by Carolina Bento</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Porque é que corres aqui? || Why are you running here?]]></title>
            <link>https://medium.com/map-books/porque-%C3%A9-que-corres-aqui-why-are-you-running-here-d06a5e5f5185?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/d06a5e5f5185</guid>
            <category><![CDATA[poesía]]></category>
            <category><![CDATA[running]]></category>
            <category><![CDATA[poetry]]></category>
            <category><![CDATA[poesia]]></category>
            <category><![CDATA[versos]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Sun, 28 Jul 2024 18:06:28 GMT</pubDate>
            <atom:updated>2024-07-28T18:06:28.129Z</atom:updated>
            <content:encoded><![CDATA[<h3>Porque é que corres aqui? ||Why are you running here?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ZDaN4mEnd-luR9hp" /><figcaption>Photo by <a href="https://unsplash.com/@mario?utm_source=medium&amp;utm_medium=referral">Mario Verduzco</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>São como torres de carbono<br>Uma a cada dez metros <br>Ou mais próxima de uma outra</p><p>O ritmo interno soa a multidão<br>E lá fora não há mais nada<br>Só céu e chão</p><p>Abre-se um fogo que vem do meio do estômago<br>Incendeia e não pára, mesmo em chuva forte<br>Presente, o tempo todo, como escudo</p><p>O peito aperta, a dor é ajuda<br>E por uns segundos há leveza<br>A visão é esbatida, mas fica tudo mais claro</p><p>O tempo pára, o corpo acelera<br>E por uns segundos comprimes-te num átomo<br>Passa tudo tão depressa, queres sentir outra vez</p><p>Só a exaustão pára o impulso<br>Ou o próximo compromisso<br>Passa tudo tão depressa, queres sentir outra vez</p><p>Like towers made of carbon<br>Ten meters away from one another<br>Or maybe closer</p><p>The rhythm sounds like a massive crowd<br>And outside there&#39;s nothing else<br>Just the sky and the pavement</p><p>There&#39;s a fire in the pit of my stomach<br>Burns bright and doesn&#39;t die, even in intense rain<br>Just there, all the time, like a shield</p><p>My chest hurts, the pain is acute<br>And for a split second you&#39;re weightless<br>My vision in blurry, but everything looks clear now</p><p>Time stops, the body races<br>And for a split second, you&#39;re the size of an atom<br>Everything goes by so fast, you want to feel it again</p><p>Only exhaustion stops the impulse<br>Or the next commitment<br>Everything goes by so fast, you want to feel it again</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d06a5e5f5185" width="1" height="1" alt=""><hr><p><a href="https://medium.com/map-books/porque-%C3%A9-que-corres-aqui-why-are-you-running-here-d06a5e5f5185">Porque é que corres aqui? || Why are you running here?</a> was originally published in <a href="https://medium.com/map-books">Side Notes by Carolina Bento</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hidden Markov Models Explained with a Real Life Example and Python code]]></title>
            <link>https://medium.com/data-science/hidden-markov-models-explained-with-a-real-life-example-and-python-code-2df2a7956d65?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/2df2a7956d65</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[hidden-markov-models]]></category>
            <category><![CDATA[editors-pick]]></category>
            <category><![CDATA[statistics]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Sun, 05 Nov 2023 23:35:29 GMT</pubDate>
            <atom:updated>2023-11-05T23:35:29.243Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jHeJ2Ge0jT7QZrIcBrLiaA.png" /><figcaption>Image by Author</figcaption></figure><p><em>Hidden Markov Models are probabilistic models used to solve real life problems ranging from something everyone thinks about at least once a week — how is the weather going to be like tomorrow?</em>[1] — <em>to hard molecular biology problems, such as predicting peptide binders to the human MHC class II molecule</em>[2].</p><p><em>Hidden Markov Models are close relatives of Markov Chains, but their hidden states make them a unique tool to use when you’re interested in determining the probability of a sequence of random variables.</em></p><p><em>In this article we’ll breakdown Hidden Markov Models into all its different components and see, step by step with both the Math and Python code, which emotional states led to your dog’s results in a training exam. We’ll be using the Viterbi Algorithm to determine the probability of observing a specific sequence of observations, and how you can use the Forward Algorithm to determine the likelihood of an observed sequence, when you’re given a sequence of hidden states.</em></p><p>The real world is full of phenomena for which we can see the final outcome, but can’t actually observe the underlying factors that generated those outcomes. One example is predicting the weather, determining if it’s going to be rainy or sunny tomorrow, based on past weather observations and the observed probabilities of the different weather outcomes.</p><p>Although driven by factors we can’t observe, with an <strong>Hidden Markov Model </strong>it’s possible to model these phenomena as probabilistic systems.</p><h3>Markov Models with Hidden States</h3><p><a href="https://en.wikipedia.org/wiki/Hidden_Markov_model">Hidden Markov Models</a>, known as HMM for short, are statistical models that work as a sequence of labeling problems. These are the types of problems that describe the evolution of observable events, which themselves, are dependent on internal factors that can’t be directly observed — they are <strong>hidden</strong>[3].</p><p>An Hidden Markov Model is made of two distinct <a href="https://en.wikipedia.org/wiki/Stochastic_process">stochastic processes</a>, meaning those are processes that can be defined as sequences of <a href="https://en.wikipedia.org/wiki/Random_variable">random variables</a> — variables that depend on random events.</p><p>There’s an <strong>invisible process </strong>and an <strong>observable process</strong>.</p><p>The <strong>invisible process</strong> is a <a href="https://towardsdatascience.com/markov-models-and-markov-chains-explained-in-real-life-probabilistic-workout-routine-65e47b5c9a73">Markov Chain</a>, like chaining together multiple <strong>hidden states</strong> that are traversed over time in order to reach an outcome. This is a probabilistic process because all the parameters of the Markov Chain, as well as the score of each sequence, are in fact probabilities[4].</p><p>Hidden Markov Models describe the evolution of observable events, which themselves, are dependent on internal factors that can’t be directly observed — they are <strong>hidden</strong>[3]</p><p>Just like any other <a href="https://towardsdatascience.com/markov-models-and-markov-chains-explained-in-real-life-probabilistic-workout-routine-65e47b5c9a73">Markov Chain</a>, in order to know which state you’re going next, the only thing that matters is where you are now — in which state of the Markov Chain you’re currently in. None of the previous <em>history </em>of states you’ve been in the past matters to understand where you’re going next.</p><p>This kind of <em>short-term </em>memory is one of the key characteristics of HMMs and it’s called the <strong>Markov Assumption</strong>, indicating that the probability of reaching the next state is only dependent on the probability of the current state.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/879/1*TM-yP_mQKiNs78VEfbXpOQ.jpeg" /><figcaption>Markov Assumption. (Image by Author)</figcaption></figure><p>The other key characteristic of an HMM, is that it also assumes that each observation is only dependent on the state that produced it therefore, being completely independent from any other state in the chain[5].</p><blockquote>The <strong>Markov Assumption</strong> states that the probability of reaching the next state is only dependent on the probability of the current state.</blockquote><p>This is all great background information on HMM but, what classes of problems are they actually used in?</p><p>HMMs help model the behavior of phenomena. Besides modeling and allowing to run simulations, you can also ask different types of questions those phenomena:</p><ul><li><strong>Likelihood </strong>or<strong> Scoring</strong>, as in, determining the probability of observing a sequence</li><li><strong>Decoding</strong> the best sequence of states that generated a specific observation</li><li><strong>Learning</strong> the parameters of the HMM that led to observing a given sequence, that traversed a specific set of states.</li></ul><p>Let&#39;s see this in practice!</p><h3>Dog Training Performance as an HMM</h3><p>Today you’re not as worried about the weather forecast, what’s on your mind is that your dog is possibly graduating from their training lessons. After all the time, effort and dog treats involved, all you want is for them to succeed.</p><p>During dog training sessions, your four-legged friend is expected to do a few actions or tricks, so the trainer can <em>observe</em> and grade their performance. After combining the scores of three trials, they’ll determine if your dog graduates or needs additional training.<br>The trainer only sees the outcome, but there are several factors involved that can’t be directly observed such as, if your dog is tired, happy, if they don’t like the trainer at all or the other dogs around them.</p><p>None of these are directly observed, unless there’s undoubtably a specific action your dog does only when they feel a certain way. Would be great if they could express how they feel in words, maybe in the future!</p><p>With Hidden Markov Models fresh in your mind, this looks like the perfect opportunity to try to predict how your dog was feeling during the exam. They might get a certain score because they were feeling tired, maybe they were hungry, or they were annoyed at the trainer.</p><p>Your dog has been taking lessons for a while and, based on data collected during that training, you have all the building blocks needed to build a Hidden Markov Model.</p><p>In order to build a HMM that models the performance of your dog in the training evaluation you need:</p><ul><li>Hidden States</li><li>Transition Matrix</li><li>Sequence of Observations</li><li>Observation Likelihood Matrix</li><li>Initial Probability Distribution</li></ul><p><strong>Hidden States</strong> are<strong> </strong>those non-observable factors that influence the observation sequence. You’ll only consider if your dog is Tired or Happy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/182/1*DsQy1PvJTraRafSPLiYlkQ.png" /><figcaption><em>Different hidden states in the HMM. (Image by Author)</em></figcaption></figure><p>Knowing your dog very well, the non-observable factors that can impact their exam performance are simply being tired or happy.</p><p>Next you need to know what’s the probability of going from one state to another, which is captured in a <strong>Transition Matrix</strong>. This matrix must also be <a href="https://en.wikipedia.org/wiki/Stochastic_matrix"><strong>row stochastic</strong></a> meaning that the probabilities from one state to any other state in the chain, each row in the matrix, must sum to one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a_0HoKFKzoKQuyjH5csWEw.jpeg" /><figcaption><em>Transition Matrix: represents the probability of moving from one state to another. </em>(Image by Author)</figcaption></figure><p>Regardless of what type of problem you’re solving for, you always need a <strong>Sequence of Observations. </strong>Each observation representing the result of traversing the Markov Chain. Each observation is drawn from a specific vocabulary.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/879/1*66orHoTFrvIIRJk9HL3hqA.jpeg" /><figcaption><em>Vocabulary (Image by Author)</em></figcaption></figure><p>In the case of your dog’s exam you observe the score they get after each trial, which can be <em>Fail</em>, <em>OK</em> or <em>Perfect</em>. These are all the possible <em>terms</em> in the observation vocabulary.</p><p>You also need the <strong>Observation Likelihood Matrix</strong>, which is the probability of an observation being generated from a specific state.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Xf0r-zcGcQDWtmQFMuq6_g.png" /><figcaption>Observation Likelihood Matrix. (Image by Author)</figcaption></figure><p>Finally, there’s the<strong> Initial Probability Distribution</strong>. This is the probability that the Markov Chain will start in each specific hidden state.</p><p>There can also be some states will never be the starting state in the Markov Chain. In these situations, their initial probability is zero. And just like the probabilities in the Transition Matrix, these sum of all initial probabilities must add up to one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/816/1*QTP9H9-ACp1yLqJzMbBfDw.jpeg" /><figcaption>Initial Probabilities (Image by Author)</figcaption></figure><p>The Initial Probability Distribution, along with the Transition Matrix and the Observation Likelihood, make up the <strong>parameters of an HMM</strong>. These are the probabilities you’re figuring out if you have a sequence of observations and hidden states, and attempt to <em>learn</em> which specific HMM could have generated them.</p><p>Putting all of these pieces together, this is what the Hidden Markov model that represents your dog’s performance on the training exam looks like</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/858/1*DfUCrMNxTHU-Rnr2ZGdjZA.jpeg" /><figcaption>Hidden states and the transition probabilities between them. (Image by Autor)</figcaption></figure><p>During the exam, your dog will perform three trials, and graduate only if they don’t <em>Fail </em>in two of those trials.</p><p>At the end of the day, if your dog needs more training, you’ll care for them all the same. The big question circling your mind is <em>How are they feeling during the exam.</em></p><p>Imagining a scenario where they graduate with a score of <em>OK — Fail — Perfect </em>exactly in this order, what sequence of emotional states will they be in? Will they be mostly tired, or hungry throughout, or maybe a mix of both?</p><p>This type of problem falls right under the category of <em>Decoding</em> problems that HMMs can be applied to. In this case, you’re interested figuring out what’s the best sequence of states that generated a specific sequence of observations, <em>OK — Fail — Perfect.</em></p><p>The problem of decoding the sequence of states that generated a given sequence of observations leverages the <strong>Viterbi Algorithm</strong>. However, is worth doing a short detour and take a peek into how you could calculate the probability of a given observation sequence — a Likelihood task — using the <strong>Forward Algorithm</strong>. This will set the stage to better understanding how the Viterbi Algorithm works.</p><h3>The Forward Algorithm</h3><p>If you were modeling this problem like a regular <a href="https://medium.com/p/65e47b5c9a73">Markov Chain</a>, and wanted to calculate the likelihood of observing the sequence of outcomes <em>OK, Fail, Perfect </em>you’d traverse the chain by landing in each specific state that generates the desired outcome. At each step you would take the conditional probability of observing the current outcome given that you’ve observed the previous outcome and multiply that probability by the transition probability of going from one state to the other.</p><p>The big difference is that, in a regular Markov Chain, all states are well known and observable. Not in an Hidden Markov Model! In an Hidden Markov Model you observe a sequence of outcomes, not knowing which specific sequence of hidden states had to be traversed in order to observe that.</p><blockquote>The big difference is that, in a regular Markov Chain, all states are well known and observable. Not in an Hidden Markov Model!</blockquote><p>At this point you might be thinking, <em>Well I can simply traverse all possible paths and eventually have a rule to pick between equivalent paths.</em> The mathematical definition for this approach looks something like this</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tjKvlqJx7hzcl6_einEbyw.jpeg" /><figcaption><em>Calculating the probability of observing a sequence of outcomes, traversing every hidden state sequence possible. (Image by Author)</em></figcaption></figure><p>That’s one strategy for sure! You’d have to calculate the probability of observing the sequence <em>OK, Fail, Perfect </em>for every single combination of hidden states that could ever generate that sequence.</p><p>When you have a small enough number of hidden states and sequence of observed outcomes, it&#39;s possible to do that calculation within a reasonable time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*viK7VDSSEWyfvr97BRL9VA.png" /><figcaption><em>Outline of the possible paths in your HMM (Image by Author)</em></figcaption></figure><p>Thankfully, the Hidden Markov model you just defined is relatively simple, with 3 observed outcomes and 2 hidden states.</p><p>For an observed sequence of length L outcomes, on a HMM with M hidden states, you have “M to the power L” possible states which in your case, means <em>2 to the power of 3</em>, i.e., 8 possible paths for the sequence<em> OK — Fail — Perfect, </em>involving an exponential computational complexity of O(M^L L), described in <a href="https://en.wikipedia.org/wiki/Big_O_notation">Big O-Notation</a>. As the complexity of the model increases, the number of paths you need to take into account grows exponentially.</p><blockquote>As the complexity of the model increases, the number of paths you need to take into account grows exponentially.</blockquote><p>This is where the <strong>Forward Algorithm </strong>shines.</p><p>The Forward Algorithm calculates the probability of a new symbol in the observed sequence, without the need to calculate the probabilities of all possible paths that form that sequence [3].</p><p>Instead of computing the probabilities of all possible paths that form that sequence the algorithm defines the <strong>forward variable</strong> and calculates its value <a href="https://en.wikipedia.org/wiki/Recursion">recursively</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uExL5L6BHuFJU07OZOhHKA.jpeg" /><figcaption>How the forward variable is calculated recursively. (Image by Author)</figcaption></figure><p>The fact that it uses recursion, is the key reason why this algorithm is faster than calculating all the probabilities of possible paths. In fact, it can calculate the probability of observing the sequence <em>x </em>in only “L times M squared” computations, instead of “M to the power of L times L”.</p><p>In your case, with 2 hidden states and a sequence of 3 observed outcomes, it’s the difference between calculating the probabilities O(MˆL L) = 2³x3<em> = </em>8x3<em> = </em>24 times, as opposed to O(L Mˆ2)<em>=</em>3*2²=3x4 = 12 times.</p><blockquote>This reduction in the number of calculations is achieved by <a href="https://en.wikipedia.org/wiki/Dynamic_programming">Dynamic Programming</a>, a programming technique that uses an auxiliary data structures to store intermediate information, therefore making sure the same calculations are not done multiple times.</blockquote><p>Every time the algorithm is about to calculate a new probability it checks if it has already computed it, and if so, it can easily access that value in the intermediate data structure. Otherwise, the probability is calculated and the value is stored.</p><p>Let’s get back to your decoding problem, using the Viterbi Algorithm.</p><h3>The Viterbi Algorithm</h3><p>Thinking in <em>pseudo code</em>, If you were to brute force your way into decoding the sequence of hidden states that generate a specific observation sequence, all you needed to do was:</p><ul><li>generate all possible permutations of paths that lead to the desired observation sequence</li><li>use the Forward Algorithm to calculate the likelihood of each observation sequence, for each possible sequence of hidden states</li><li>pick the sequence of hidden states with highest probability</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/840/1*KJoQzpEuhmXTyPaUDI7gBw.jpeg" /><figcaption>All possible hidden state sequences that generate the observation sequence <em>OK — Fail — Perfect </em>(Image by Author)</figcaption></figure><p>For your specific HMM, there are 8 possible paths that lead to an outcome of <em>OK — Fail — Perfect</em>. Add just one more observation, and you’ll have double the amount of possible sequences of hidden states! Similarly to what was described for the Forward Algorithm, you easily end up with an exponentially complex algorithm and hit performance ceiling.</p><p>The Viterbi Algorithm, gives you a hand with that.</p><p>When the sequence of hidden states in the HMM is traversed, at each step, the probability <em>vt(j)</em> is the probability that the HMM is in the hidden state <em>j </em>after seeing the observation and is being traversed through the most probable state that lead to <em>j</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R1mzFRbmuxRakmk3IL3iKA.png" /><figcaption>Viterbi path to hidden state <em>j </em>on time step <em>t. </em>(Image by Author)</figcaption></figure><p>The key to decoding the sequence of hidden states that generate a specific observation sequence, is this concept of the <strong>most probable path</strong>. Also called the <strong>Viterbi path, </strong>the most probable path, is the path that has highest likelihood, from all the paths that can lead to any given hidden state.</p><blockquote>The key to decoding the sequence of hidden states that generate a specific observation sequence, is to use the Viterbi path. The most probable path that leads to any given hidden state.</blockquote><p>You can draw a parallel between the Forward Algorithm and the Viterbi Algorithm. Where the Forward Algorithm sums all probabilities to obtain the likelihood of reaching a certain state taking into account all the paths that lead there, the Viterbi algorithm doesn’t want to explore all possibilities. It focuses on the most probable path that leads to any given state.</p><p>Going back to the task of decoding the sequence of hidden states that lead to the scores of OK — Fail — Perfect in their exam, <em>running</em> the <strong>Viterbi Algorithm</strong> by hand would look like this</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*65eFIRhd_RND4O9-FPaYow.png" /><figcaption>Viterbi paths and decoded sequence. (Image by Author)</figcaption></figure><p>Another unique characteristic of the Viterbi algorithm is that it must have a way to keep track of all the paths that led to any given hidden state, in order to compare their probabilities. To do that it keeps track of <strong>backpointers </strong>to each hidden state, using an auxiliary data structure typical of dynamic programming algorithms. That way it can easily access the probability of any viterbi path traversed in the past.</p><p><strong>Backpointers are the key to figure out the most probable path that leads to an observation sequence.</strong></p><p>In the example of your dogs’ exam, when you calculate the Viterbi paths <em>v3(Happy) </em>and <em>v3(Tired)</em>, you pick the path with highest probability and start going backwards, i.e., backtracking, through all the paths that led to where you are.</p><h3>The Viterbi Algorithm in Python</h3><p>Doing all of this by hand is time consuming and error prone. Miss one significant digit and you might have to start from scratch and re-check all your probabilities!</p><p>The good news is that you can leverage software libraries like <a href="https://hmmlearn.readthedocs.io/en/stable/tutorial.html">hmmlearn</a>, and with a few lines of code you can decode the sequence of hidden states that lead to your dog graduating with <em>OK — Fail — Perfect </em>in the trials, exactly in this order.</p><pre>from hmmlearn import hmm<br>import numpy as np<br><br>## Part 1. Generating a HMM with specific parameters and simulating the exam<br>print(&quot;Setup HMM model with parameters&quot;)<br># init_params are the parameters used to initialize the model for training<br># s -&gt; start probability<br># t -&gt; transition probabilities<br># e -&gt; emission probabilities<br>model = hmm.CategoricalHMM(n_components=2, random_state=425, init_params=&#39;ste&#39;)<br><br># initial probabilities<br># probability of starting in the Tired state = 0<br># probability of starting in the Happy state = 1<br>initial_distribution = np.array([0.1, 0.9])<br>model.startprob_ = initial_distribution<br><br>print(&quot;Step 1. Complete - Defined Initial Distribution&quot;)<br><br># transition probabilities<br>#        tired    happy<br># tired   0.4      0.6<br># happy   0.2      0.8<br><br>transition_distribution = np.array([[0.4, 0.6], [0.2, 0.8]])<br>model.transmat_ = transition_distribution<br>print(&quot;Step 2. Complete - Defined Transition Matrix&quot;)<br><br># observation probabilities<br>#        Fail    OK      Perfect<br># tired   0.3    0.5       0.2<br># happy   0.1    0.5       0.4<br><br>observation_probability_matrix = np.array([[0.3, 0.5, 0.2], [0.1, 0.5, 0.4]])<br>model.emissionprob_ = observation_probability_matrix<br>print(&quot;Step 3. Complete - Defined Observation Probability Matrix&quot;)<br><br># simulate performing 100,000 trials, i.e., aptitude tests<br>trials, simulated_states = model.sample(100000)<br><br># Output a sample of the simulated trials<br># 0 -&gt; Fail<br># 1 -&gt; OK<br># 2 -&gt; Perfect<br>print(&quot;\nSample of Simulated Trials - Based on Model Parameters&quot;)<br>print(trials[:10])<br><br>## Part 2 - Decoding the hidden state sequence that leads<br>## to an observation sequence of OK - Fail - Perfect<br><br># split our data into training and test sets (50/50 split)<br>X_train = trials[:trials.shape[0] // 2]<br>X_test = trials[trials.shape[0] // 2:]<br><br>model.fit(X_train)<br><br># the exam had 3 trials and your dog had the following score: OK, Fail, Perfect (1, 0 , 2)<br>exam_observations = [[1, 0, 2]]<br>predicted_states = model.predict(X=[[1, 0, 2]])<br>print(&quot;Predict the Hidden State Transitions that were being the exam scores OK, Fail, Perfect: \n 0 -&gt; Tired , &quot;<br>      &quot;1 -&gt; Happy&quot;)<br>print(predicted_states)</pre><p>In a few seconds you get an output that matches results the calculations you did by hand, much fast and with much less room for error.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RSDSzEcwvMqO1xzz98iFQQ.png" /><figcaption>Output of running the code above. (Image by Author)</figcaption></figure><h3>Conclusion</h3><p>What’s fascinating about Hidden Markov Models is how this statistical tool created in the mid 1960’s [6] is so powerful and applicable to real world problems in such distinct areas, from weather forecasting to finding the next word in a sentence.</p><p>In this article, you had the chance to learn about the different components of an HMM, how they can be applied to different types of tasks, and spotting the similarities between the Forward Algorithm and Viterbi Algorithm. Two very similar algorithms that use dynamic programming to deal with the exponential number of calculations involved.</p><p>Either doing the calculations by hand or plugging in the parameters into TensorFlow code, hope you enjoyed diving deep into the world of HMMs.</p><p><em>Thank you for reading!</em></p><h3>References</h3><ol><li>D. Khiatani and U. Ghose, “Weather forecasting using Hidden Markov Model,” 2017 International Conference on Computing and Communication Technologies for Smart Nation (IC3TSN), Gurgaon, India, 2017, pp. 220–225, doi: 10.1109/IC3TSN.2017.8284480.</li><li>Noguchi H, Kato R, Hanai T, Matsubara Y, Honda H, Brusic V, Kobayashi T. Hidden Markov model-based prediction of antigenic peptides that interact with MHC class II molecules. J Biosci Bioeng. 2002;94(3):264–70. doi: 10.1263/jbb.94.264. PMID: 16233301.</li><li>Yoon BJ. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2766791/">Hidden Markov Models and their Applications in Biological Sequence Analysis</a>. Curr Genomics. 2009 Sep;10(6):402–15. doi: 10.2174/138920209789177575. PMID: 20190955; PMCID: PMC2766791.</li><li>Eddy, S. <a href="https://www.nature.com/articles/nbt1004-1315">What is a hidden Markov model?</a>. <em>Nat Biotechnol</em> <strong>22</strong>, 1315–1316 (2004). <a href="https://doi.org/10.1038/nbt1004-1315">https://doi.org/10.1038/nbt1004-1315</a></li><li>Jurafsky, Dan and Martin, James H.. <em>Speech and language processing : an introduction to natural language processing, computational linguistics, and speech recognition</em>. Upper Saddle River, N.J.: Pearson Prentice Hall, 2009.</li><li>Baum, Leonard E., and Ted Petrie. “<a href="https://projecteuclid.org/journals/annals-of-mathematical-statistics/volume-37/issue-6/Statistical-Inference-for-Probabilistic-Functions-of-Finite-State-Markov-Chains/10.1214/aoms/1177699147.full">Statistical Inference for Probabilistic Functions of Finite State Markov Chains.</a>” <em>The Annals of Mathematical Statistics</em> 37, no. 6 (1966): 1554–63.</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2df2a7956d65" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/hidden-markov-models-explained-with-a-real-life-example-and-python-code-2df2a7956d65">Hidden Markov Models Explained with a Real Life Example and Python code</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ROC Analysis and the AUC — Area Under the Curve]]></title>
            <link>https://medium.com/data-science/roc-analysis-and-the-auc-area-under-the-curve-404803b694b9?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/404803b694b9</guid>
            <category><![CDATA[model-performance]]></category>
            <category><![CDATA[getting-started]]></category>
            <category><![CDATA[area-under-the-curve]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[editors-pick]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Wed, 28 Dec 2022 01:48:46 GMT</pubDate>
            <atom:updated>2023-01-05T03:00:07.154Z</atom:updated>
            <content:encoded><![CDATA[<h3>ROC Analysis and the AUC — Area Under the Curve</h3><h4>Explained with a Real Life Example in Python</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QviLXpMLCXaKvw6eTaRd7Q.png" /><figcaption>(Image by Author)</figcaption></figure><p><em>Receiver Operating Characteristic Curve (ROC) analysis and the Area Under the Curve (AUC) are tools widely used in Data Science, borrowed from signal processing, to assess the quality of a model under different parameterizations, or compare performance of two or more models.</em></p><p><em>Traditional performance metrics, like precision and recall, rely heavily on positive observations. So instead, ROC and AUC use True Positive and False Positive Rates to assess quality, which take into account both positive and negative observations.</em></p><p>The road from breaking down a problem and solving it with Machine Learning has multiple steps. At a high-level it involves data collection, cleaning and feature engineering, building the model and, last but not least, <strong>evaluating model performance</strong>.</p><p>When you’re evaluating the quality of a model, typically you use metrics like <a href="https://en.wikipedia.org/wiki/Precision_and_recall">precision and recall</a>, also referred to as confidence in the data mining field and sensitivity, respectively.</p><p>These metrics compare the predicted values to the real observation values, usually from a hold-out set, and are best visualized using a <a href="https://en.wikipedia.org/wiki/Confusion_matrix">confusion matrix</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vf4PXEybOl_AzervGOlgqw.png" /><figcaption><em>Confusion Matrix (Image by Author)</em></figcaption></figure><p>Let’s focus on <strong>Precision </strong>first, also referred to as Positive Predictive Value. Using the <strong>confusion matrix</strong>, you can construction Precision as the ratio of all the true positives over all predicted positives.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/344/1*KG9Z7pL0gx0eDxvazaqxGg.png" /></figure><p><strong>Recall</strong>, which is also referred to as True Positive Rate, represents the ratio fo True Positives over all the Positives, observed and predicted.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/327/1*1Y9klrS07lwKnYhj00124Q.png" /></figure><p>Describing Precision and Recall using the different sets of observations in the confusion matrix, you can start to see how these metrics might provide a narrow view of model performance.</p><p>Something that stands out is the fact that Precision and Recall only focus on the positive examples and predictions[1], and don’t take into account any negative examples. Additionally, they don’t compare the performance of the model against a median-scenario, one that simply random-guesses.</p><blockquote>After digging deeper into how Precision and Recall are calculated, you can start to see how these metrics might provide a narrow view of model performance.</blockquote><p>To complement your model evaluation and rule out biases from Precision and Recall you can reach for a few robust tools in the Data Scientist’s toolkit: the <strong>Receiver Operation Characteristic Curve (ROC)</strong> analysis and its <strong>Area Under the Curve (AUC)</strong>.</p><h3>ROC Curve: from Signal Theory to Machine Learning</h3><p>ROC is as summary tool, used to visualize the trade-off between Precision and Recall[2].</p><p>This technique emerged in the field of signal detection theory, as part of the development of radar technology during World War II [3]. The name may be a bit confusing for those unfamiliar with signal theory, but it refers to reading<em> </em>radar signals by military radar operators, hence the <em>Receiver Operating </em>part of <a href="https://en.wikipedia.org/wiki/Receiver_operating_characteristic#History">Receiver Operating Characteristic Curve</a>.</p><p>Part of a radar operator’s job is to identify approaching enemy units on a radar, the key part, being able to literally distinguish signal, i.e., actual incoming units, from noise, e.g., static noise or other random interference. They are experts at determining what’s signal and what’s noise, to avoid charging at a supposed enemy unit when it’s either one of your own units or simply there’s nothing there.</p><p>Right now you may be thinking <em>Hold on, this sounds like a familiar task!</em></p><p>And indeed it is, this task is conceptually very similar to classifying an image as a cat or not, or detecting a patient developed a disease or not, while keeping a low false positive rate.</p><p><strong>ROC analysis</strong> uses the ROC curve to determine how much of the value of a binary signal is polluted by noise, i.e., randomness[4]. It provides a summary of sensitivity and specificity across a range of operating points, for a continuous predictor[5].</p><p>The ROC curve is obtained by plotting the <em>False Positive Rate</em>, on the x-axis, against the <em>True Positive Rate</em>, on the y-axis.</p><p>Because the <em>True Positive Rate </em>is the probability of detecting a signal and <em>False Positive Rate </em>is the probability of a false alarm, ROC analysis is also widely used in medical studies, to determine the thresholds that confidently detect diseases or other behaviors[5].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/704/1*Ltf1bAZDm6SnjJlSc2wmIQ.png" /><figcaption>Examples of different ROC curves (Image by author)</figcaption></figure><p>A perfect model will have a <em>False Positive </em>of zero and <em>True Positive Rate </em>equal to one, so it will be a single operating point to the top left of the ROC plot. Whereas the worst possible model will have a single operating point on the bottom-right of the ROC plot, where the <em>False Positive Rate</em> is equal to one and <em>True Positive Rate </em>is equal to zero.</p><blockquote>It [ROC Curve] provides a summary of sensitivity and specificity across a range of operating points, for a continuous predictor.</blockquote><p>A random-guessing model, has a 50% chance of correctly predicting the result so, <em>False Positive Rate</em> will always be equal to the <em>True Positive Rate</em>. That’s why there’s a diagonal on the plot, representing that 50/50 chance of <em>detecting signal vs noise</em>.</p><h3>Using Area Under the Curve (AUC) to evaluate Machine Learning models</h3><p>Your parents have a cozy bed and breakfast and you, as a Data Scientist, set yourself up to the task of building a model that classifies their reviews as positive or negative.</p><p>To tackle this <a href="https://en.wikipedia.org/wiki/Sentiment_analysis">Sentiment Analysis</a> task, you started off by using the <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">Multilayer Perceptron</a> and used accuracy and loss as a way to understand if was really good enough to solve your classification problem.</p><p>Knowing how <strong>ROC analysis</strong> is resistant to bias, and the fact that it’s used in Machine Learning to compare models or to compare different parameterizations of the same model, you want to see if the Multilayer Perceptron is actually a good model when it comes to classifying reviews from your parents’ bed and breakfast.</p><p>To rebuild the model, you take the corpus of reviews, then split it into training and testing and tokenize it.</p><pre>from sklearn.model_selection import train_test_split<br>from sklearn.feature_extraction.text import TfidfVectorizer<br><br>corpus = [<br>    &#39;We enjoyed our stay so much. The weather was not great, but everything else was perfect.&#39;,<br>    &#39;Going to think twice before staying here again. The wifi was spotty and the rooms smaller than advertised&#39;,<br>    &#39;The perfect place to relax and recharge.&#39;,<br>    &#39;Never had such a relaxing vacation.&#39;,<br>    &#39;The pictures were misleading, so I was expecting the common areas to be bigger. But the service was good.&#39;,<br>    &#39;There were no clean linens when I got to my room and the breakfast options were not that many.&#39;,<br>    &#39;Was expecting it to be a bit far from historical downtown, but it was almost impossible to drive through those narrow roads&#39;,<br>    &#39;I thought that waking up with the chickens was fun, but I was wrong.&#39;,<br>    &#39;Great place for a quick getaway from the city. Everyone is friendly and polite.&#39;,<br>    &#39;Unfortunately it was raining during our stay, and there weren\&#39;t many options for indoors activities. Everything was great, but there was literally no other oprionts besides being in the rain.&#39;,<br>    &#39;The town festival was postponed, so the area was a complete ghost town. We were the only guests. Not the experience I was looking for.&#39;,<br>    &#39;We had a lovely time. It\&#39;s a fantastic place to go with the children, they loved all the animals.&#39;,<br>    &#39;A little bit off the beaten track, but completely worth it. You can hear the birds sing in the morning and then you are greeted with the biggest, sincerest smiles from the owners. Loved it!&#39;,<br>    &#39;It was good to be outside in the country, visiting old town. Everything was prepared to the upmost detail&#39;<br>    &#39;staff was friendly. Going to come back for sure.&#39;,<br>    &#39;They didn\&#39;t have enough staff for the amount of guests. It took some time to get our breakfast and we had to wait 20 minutes to get more information about the old town.&#39;,<br>    &#39;The pictures looked way different.&#39;,<br>    &#39;Best weekend in the countryside I\&#39;ve ever had.&#39;,<br>    &#39;Terrible. Slow staff, slow town. Only good thing was being surrounded by nature.&#39;,<br>    &#39;Not as clean as advertised. Found some cobwebs in the corner of the room.&#39;,<br>    &#39;It was a peaceful getaway in the countryside.&#39;,<br>    &#39;Everyone was nice. Had a good time.&#39;,<br>    &#39;The kids loved running around in nature, we loved the old town. Definitely going back.&#39;,<br>    &#39;Had worse experiences.&#39;,<br>    &#39;Surprised this was much different than what was on the website.&#39;,<br>    &#39;Not that mindblowing.&#39;<br>]<br><br># 0: negative sentiment.  1: positive sentiment<br>targets = [1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0]<br><br># Splitting the dataset<br>train_features, test_features, train_targets, test_targets = train_test_split(corpus, targets, test_size=0.25,random_state=123)<br><br>#Turning the corpus into a tf-idf array<br>vectorizer = TfidfVectorizer(stop_words=&#39;english&#39;, lowercase=True, norm=&#39;l1&#39;)</pre><p>The <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">Multilayer Perceptron</a> model is ready to be trained.</p><pre>from sklearn.neural_network import MLPClassifier<br><br>def buildMLPerceptron(train_features, train_targets, num_neurons=2):<br>    &quot;&quot;&quot; Build a Multi-layer Perceptron and fit the data<br>        Activation Function: ReLU<br>        Optimization Function: SGD, Stochastic Gradient Descent<br>        Learning Rate: Inverse Scaling<br>    &quot;&quot;&quot;<br><br>    classifier = MLPClassifier(hidden_layer_sizes=num_neurons, max_iter=35, activation=&#39;relu&#39;, solver=&#39;sgd&#39;, verbose=10, random_state=762, learning_rate=&#39;invscaling&#39;)<br>    classifier.fit(train_features, train_targets)<br><br>    return classifier<br><br>train_features = vectorizer.fit_transform(train_features)<br>test_features = vectorizer.transform(test_features)<br><br># Build Multi-Layer Perceptron with 3 hidden layers, each with 5 neurons<br>ml_percetron_model = buildMLPerceptron(train_features, train_targets, num_neurons=5)</pre><p>All set to train the model! When you run the code above you’ll see something like the following.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/698/1*UmLuDDF38-ayr7E7MqVYhA.png" /><figcaption><em>Output of training the Multilayer Perceptron model. (Image by Author)</em></figcaption></figure><p>To fully analyze the ROC Curve and compare the performance of the Multilayer Perceptron model you just built against a few other models, you actually want to calculate the <a href="https://en.wikipedia.org/wiki/Receiver_operating_characteristic#Area_under_the_curve">Area Under the Curve (AUC)</a>, also referred to in literature as <em>c-statistic</em>.</p><p>The <strong>Area Under the Curve (AUC)</strong> has values between zero and one, since the curve is plotted on a 1x1 grid and, drawing a parallel with signal theory, it’s a measure of a signal’s detectability[6].</p><p>This is a very useful statistic, because it gives an idea of how well models can rank true observations as well as false observations. It’s actually a normalized version of the <a href="https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test#Area-under-curve_(AUC)_statistic_for_ROC_curves">Wilcoxon-Mann-Whitney sum of ranks test</a>, which tests the null hypothesis where two samples of ordinal measurements are drawn from a single distribution [4].</p><p>The c-statistic normalizes the number of pairs of one positive and one negative draws.</p><blockquote>[…] drawing a parallel with signal theory, [the area under the curve] it’s a measure of a signal’s detectability.</blockquote><p>To plot the ROC Curve and calculate the Area Under the Curve (AUC) you decided to use <a href="https://scikit-learn.org/stable/modules/generated/sklearn.metrics.RocCurveDisplay.html#sklearn.metrics.RocCurveDisplay.from_estimator">SckitLearn’s RocCurveDisplay method</a> and compare your <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">Multilayer Perceptron</a> to a Random Forests model, attempting to solve the same classification task.</p><pre>import matplotlib.pyplot as plt<br>from sklearn.ensemble import RandomForestClassifier<br>from sklearn.metrics import roc_auc_score, RocCurveDisplay<br><br>def plot_roc(model, test_features, test_targets):<br>    &quot;&quot;&quot;<br>    Plotting the ROC curve for a given Model and the ROC curve for a Random Forests Models<br>    &quot;&quot;&quot;<br><br>    # comparing the given model with a Random Forests model<br>    random_forests_model = RandomForestClassifier(random_state=42)<br>    random_forests_model.fit(train_features, train_targets)<br><br>    rfc_disp = RocCurveDisplay.from_estimator(random_forests_model, test_features, test_targets)<br>    model_disp = RocCurveDisplay.from_estimator(model, test_features, test_targets, ax=rfc_disp.ax_)<br>    model_disp.figure_.suptitle(&quot;ROC curve: Multilayer Perceptron vs Random Forests&quot;)<br><br>    plt.show()<br><br># using perceptron model as input<br>plot_roc(ml_percetron_model, test_features, test_targets)</pre><p>The code above plots the ROC curves for your <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">Multilayer Perceptron</a> and the Random Forests model. It also calculates the Area Under the Curve (AUC) for both models.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*CyvaircoBPNiX_iGT5GGDw.png" /><figcaption>ROC Plot for the Multilayer Perceptron vs a Random Forests model. (Image by Author)</figcaption></figure><h3>Conclusion</h3><p>From the ROC analysis plot and the value of the Area Under the Curve (AUC) for each model, you can see the overall AUC for your Multilayer Perceptron model, denoted in the plot as MLPClassifier, is slightly higher.</p><p>When compared to a Random Forests model attempting to solve the same task of classifying the sentiment of reviews for your parents’ bed and breakfast, the Multilayer Perceptron did a better job.</p><p>In this particular case, that’s also visible by how <em>close </em>the orange line starts getting to the top-left corner of the plot, where the True Positive Rate of the predictions is increasingly higher and, by opposition, the False Positive Rate is increasingly lower.</p><p>You can also see the Random Forests model is only slightly better than a Random Model, which would have an AUC equal to 0.5.</p><p>Hope you enjoyed learning about ROC analysis and the Area Under the Curve, two powerful techniques to compare Machine Learning models, using metrics that are more resistant to bias.</p><p><em>Thanks for reading!</em></p><h3>References</h3><ol><li>Powers, David. (2008). <a href="https://arxiv.org/abs/2010.16061">Evaluation: From Precision, Recall and F-Factor to ROC</a>, International Journal of Machine Learning Technology 2:1 (2011), pp.37–63</li><li><em>Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani. (2021). An introduction to statistical learning : with applications in R. (2nd Edition) Springer</em></li><li>Streiner DL, Cairney J. What’s under the ROC? <a href="https://journals.sagepub.com/doi/10.1177/070674370705200210">An Introduction to Receiver Operating Characteristics Curves</a>. The Canadian Journal of Psychiatry. 2007;52(2):121–128</li><li>Flach, P.A. (2011). ROC Analysis. In: Sammut, C., Webb, G.I. (eds) Encyclopedia of Machine Learning. Springer, Boston, MA.</li><li>Cook NR. <a href="https://www.ahajournals.org/doi/10.1161/CIRCULATIONAHA.106.672402">Use and misuse of the receiver operating characteristic curve in risk prediction</a>. Circulation. 2007 Feb 20;115(7):928–35.</li><li>Green DM. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7363450/">A homily on signal detection theory</a>. J Acoust Soc Am. 2020 Jul;148(1):222.</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=404803b694b9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/roc-analysis-and-the-auc-area-under-the-curve-404803b694b9">ROC Analysis and the AUC — Area Under the Curve</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recurrent Neural Networks Explained with a Real Life Example and Python Code]]></title>
            <link>https://medium.com/data-science/recurrent-neural-networks-explained-with-a-real-life-example-and-python-code-e8403a45f5de?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/e8403a45f5de</guid>
            <category><![CDATA[hands-on-tutorials]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[sentiment-analysis]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[editors-pick]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Tue, 31 May 2022 06:28:29 GMT</pubDate>
            <atom:updated>2022-05-31T15:59:01.595Z</atom:updated>
            <content:encoded><![CDATA[<h4>Using Recurrent Neural Networks in a Sentiment Analysis task</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j948jQDc9vIDip3Yei149Q.png" /><figcaption>Image by Author</figcaption></figure><p>This is the second article in a series dedicated to Deep Learning, a group of Machine Learning methods that has its roots dating back to the 1940’s. Deep Learning gained attention in the last decades for its groundbreaking applications in areas like image classification, speech recognition, and machine translation.</p><p>The first article focused on the MultiLayer Perceptron. Stay tuned if you’d like to see different Deep Learning algorithms explained with real-life examples and some Python code.</p><p>The development of the <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">MultiLayer Perceptron</a> was an important landmark for Artificial Neural Networks. For the first time we could <em>stack together</em> many perceptrons and organize them in layers, to create models that best represent complex problems.</p><p>MultiLayer Perceptron works in an atemporal, discrete way. It takes one input vector, performs a feedforward computational step, back-propagates the errors, and stops once the loss function can’t be minimized any further, generating the output.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*MF1q2Q3fbpYlXX8fZUiwpA.png" /><figcaption><em>Example of a MultiLayer Perceptron with one hidden layer. (Image by author)</em></figcaption></figure><p>But lots of real-world problems involve a time dimension. What about when the problem at hand comes in the form of a sequence?</p><h3>Neural Networks for Sentiment Analysis</h3><p>In the previous article you used the <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">MultiLayer Perceptron for the task of Sentiment Analysis</a>. You took the reviews for your parents’ cozy bed and breakfast in the countryside, trained a MultiLayer Perceptron and predicted the overall sentiment of the review.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JqZwnV5kg9TZzD0_NI-vcw.png" /><figcaption><em>MultiLayer Perceptron used to learn the sentiment of reviews from your parent’s bed and breakfast. (Image by author)</em></figcaption></figure><p>The MultiLayer perceptron used the tokenized word vector of each review as input, but it <em>looked at</em> each review a single, an atomic unit.</p><p>A more precise way of analyzing these reviews would take into account the position of each word the review, because the structure of a sentence plays a role in giving it meaning.</p><p>A much powerful model than the MultiLayer Perceptron would analyze reviews according to how each sentence is constructed. For instance, with sentences like <em>This time around the service was great </em>and <em>The service was great this time around</em>, it would be clever enough to determine these sentences have same sentiment[1]. Even though the words were shuffled around.</p><p>To go one step further in that sentiment analysis task, you need a different model.</p><p>You need a model that <em>looks </em>at each review as an ordered sequence of words, not an atomic unit. Each sequence of words can also have and an arbitrary length, since each sentence can be made up of a different number of words.</p><p>You need to build a <a href="https://en.wikipedia.org/wiki/Recurrent_neural_network">Recurrent Neural Network</a>.</p><h3>Recurrent Neural Networks</h3><p><strong>Recurrent Neural Networks </strong>are used in several domains. For instance, in <a href="https://en.wikipedia.org/wiki/Natural_language_processing">Natural Language Processing</a> (NLP), they’ve been used to <a href="https://arxiv.org/abs/1308.0850">generate handwritten text</a>, perform <a href="https://arxiv.org/pdf/1409.3215.pdf">machine translation</a> and <a href="http://proceedings.mlr.press/v32/graves14.pdf">speech recognition</a>. But their applications are not restricted to processing language. In <a href="https://en.wikipedia.org/wiki/Computer_vision">Computer Vision</a>, Recurrent Neural Networks have been used in tasks like <a href="https://arxiv.org/abs/1411.4389">image captioning</a> and <a href="https://arxiv.org/abs/1505.02074">image question-answer</a>.</p><p>What distinguishes a <strong>Recurrent Neural Network</strong> from the <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">MultiLayer Perceptron</a> is that a Recurrent Neural Network is built to handle inputs that represent a sequence, like the sequence of words in a review from your parents’ bed and breakfast. But it also handles an output sequence, like when you’re translating a sentence from one language to another.</p><p><strong>Recurrent Neural Networks</strong> act like a chain. The computation performed at each <em>time step,</em> depends on the previous computation.</p><p>The magic of Deep Learning training is in the hidden layers.</p><p>At the beginning of training the architecture of the network is defined, in this case, a Recurrent Neural Network. But we only know which inputs match with which outputs. The algorithm will learn how to use the hidden layers to make the best approximation of each input to output data point[1].</p><h3>Visualizing a Recurrent Neural Network</h3><p>One of the best ways to visualize a Recurrent Neural Network is as a cyclic computational graph[1]. In this representation the Recurrent Neural Network has three major states:</p><ul><li><strong>Input state</strong>, which captures the input data for the model.</li><li><strong>Output state</strong>, which captures the results of the model.</li><li><strong>Recurrent state</strong>, which is in fact a chain of hidden states, and captures all the computations between the input and output states.</li></ul><p>Similarly to other <a href="https://en.wikipedia.org/wiki/Supervised_learning">Supervised Machine Learning Models</a>, Recurrent Neural Networks use a <a href="https://en.wikipedia.org/wiki/Loss_function">loss function</a> to compare the output of the model to the ground truth. That loss is later back-propagated and model weights are update, like in the <a href="https://towardsdatascience.com/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">MultiLayer Perceptron</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/836/1*ZnsO8KWB2LqHplqy3fC6hg.png" /><figcaption>Recurrent Neural Network represented as a computation graph. <em>(Image by author)</em></figcaption></figure><p>This is a <em>compressed view</em>, more like a summary of the mechanics of Recurrent Neural Networks. In practice, it’s easier to visualize the recurrence when you <em>unfold</em> this graph. Especially when working with text sequences.</p><p>In this <em>unfolded view</em> of a Recurrent Neural Network each computation corresponds to one <em>step</em>, also referred to as internal state. And each step depends on the computation from the previous step.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7jJHmKDUx91twz9N_Qi4zA.png" /><figcaption><em>Recurrent Neural Network represented as an unfolded computational graph. (Image by author)</em></figcaption></figure><p>As each internal state relies on the previous one, you have information that is propagated onto each layer of neurons in the network since the beginning of the sequence. Like an old memory that is passed on to future generations.</p><p>If MultiLayer Perceptron meant stacking multiple neurons in layers, Recurrent Neural Networks means chaining MultiLayer Perceptrons, to create a sequence of dependent computations.</p><p>In the case of a Recurrent Neural Network, <em>memories</em> are information about the computations applied to the sequence so far.</p><h3>Recurrent Neural Network Superpower: Parameter Sharing</h3><p><em>A single weight vector is shared across all time steps in the network.</em></p><p>A key characteristic of Recurrent Neural Networks is <strong>parameter sharing</strong>. There’s only one set of parameters that is used, and optimized, across all parts of the network. If those parameters were not shared, the model would have to <em>learn</em> the parameters for each part of the input sequence and would have a much harder time generalizing examples it had not seen yet[1].</p><p>Sharing parameters gives Recurrent Neural Networks the ability to handle inputs with different lengths, and still perform predictions in a an acceptable time frame.</p><p>Shared parameters are particularly important to generalize sequences that share inputs, although in different positions. In the case of your parent’s bed and breakfast reviews, without shared parameters, the network would have a much hard time, and would do repeated work learning the same language rules multiple times, to figure out sentences like <em>This time around the service was great </em>and <em>The service was great this time around, </em>have the same output sentiment.</p><p>This is a major advantage of RNNs because, without parameter sharing, you’d have to learn a different model for each time step in your sequence, and you’d need a large training set to accommodate the different model training steps.</p><p>In practice, parameter sharing means the output function is a result of the output from previous time steps, each step updated with the same rule. The latter being another important aspect of Recurrent Neural Networks, the update rule is the same, which means, at each time step, the network applies the same activation function.</p><h3>Many Hidden States, the same Activation Function</h3><p>The network can have as many hidden states as you’d like to, but there’s one important constant. In each hidden state you’re always computing the same <strong>activation function</strong>. The output of each layer is calculated using the same function[3].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*12dIpEwFcwqCDevDvzJoSg.png" /><figcaption>Activation function applied to a Recurring Neural Network to compute the hidden state <em>h</em>. (Image by author)</figcaption></figure><p>The activation function can be as simple as a linear function or the <a href="https://en.wikipedia.org/wiki/Sigmoid_function">sigmoid function</a>. But the <a href="https://en.wikipedia.org/wiki/Hyperbolic_functions#Hyperbolic_tangent">hyperbolic tangent</a> is also commonly used in Deep Learning, because it tends to have fewer occurrences of <a href="https://en.wikipedia.org/wiki/Vanishing_gradient_problem">vanishing gradients</a> when compared to the sigmoid.</p><p>Training a deep neural network with hyperbolic tangent is as simple as training a linear model, as long as computations are small [1].</p><p>The hyperbolic tangent, represented as <em>tanh(x)</em>, is a solid choice for activation function. It behaves like the identity function near zero, such that tanh(0) = 0.</p><p>So, as long as the computations for this activation function are small, training a deep neural network with hyperbolic tangent is as simple as training a linear model[1].</p><h3>The output layer is special: it may need Softmax</h3><p>Right now you might be thinking <em>Didn’t you say that every layer uses the same activation function?</em></p><p>Yes but, in classification tasks, the output layer is special.</p><p>Specifically for Neural Networks that tackle classification problems, there’s also another activation function, applied only to output layer, almost like a post-processing step. Meet the <a href="https://en.wikipedia.org/wiki/Softmax_function">Softmax</a> function.</p><p>The output of a binary classification problem is either a 0 or a 1. But sometimes you’re tackling a multi-class problem, for instance, if the reviews for your parents’ bed and breakfast were categorized as <em>Positive, Neutral or Negative.</em></p><p>In this case, with 3 possible output classes, it’s more useful to know how likely the observation is to belong to the positive class. This is why, along with the activation function you choose for the network, the <strong>Softmax</strong> <strong>function</strong> is applied in the output layer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/155/1*U_M3PNVq_CI_P70tx194YA.png" /><figcaption>Softmax equation. (Image by author)</figcaption></figure><p>Vector z is the result of all the computations since the first layer, it’s the vector that reaches the output layer.</p><p>For instance, if your neural network only has one linear layer, vector <em>z </em>can be look like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*ePFUSH5KTV2YmOmkvivgGg.png" /><figcaption>Vector <em>z </em>for a linear layer. (Image by author)</figcaption></figure><p>With Softmax, this vector is exponentiated and, since this is a classification task, normalized across all possible <em>K</em> classes, turning the vector into a probability distribution. That’s why Softmax is also called the Normalized exponential function.</p><p>After applying Softmax, the sum of all values of vector <em>z</em> always adds up to one. Its values represent the probability that the observation given to network in the input layer belongs to each class.</p><p>If you don’t apply Softmax to the output layer, the output of your Recurrent Neural Network is a number for</p><p>each of the possible classes. The output with the highest value is the winning class for that observation[3].</p><h3>Backpropagation Through Time</h3><p>So far you’ve looked into the broader architecture and components of a Recurrent Neural, i.e., the activation and loss functions. Let’s focus on the learning.</p><p>As the computations flow from each hidden in a layer to the next, it moves forward, towards the output layer. Reaching the output layer you compute the loss function, meaning you compare the output generated to the expected <em>true</em> value for that training observation.</p><p>If the process stopped here, the network would not be able to learn. It would be a <em>feedfoward </em>network, since information moves forward in the network structure. But learning needs some sort of loop. Just like when you learn something in school or on your own: information gets to your brain, this is the feedfoward part, then you process it and as you do this, you sanity-check and, sometimes re-learn certain things, this is the part I call the loop.</p><p>Neural networks are inspired by the brain, mostly inspired by how neurons work. But these neural network architectures, also have this <em>a</em> <em>loop part.</em> The part where they <em>learn</em> how to map the input data to one of the possible outcomes.</p><p>Back to Recurrent Neural Networks!</p><p>Inputs go through all the layers and, when it reaches the output layer it computes the loss function. Now, knowing how different, or distant, from the expected result that chain of computations was, it takes the value of the loss function and computes its gradient with respect to the parameters.</p><p>Then, with the help of another algorithm, like <a href="https://medium.com/p/b7639d5e6a32">Stochastic Gradient Descent</a>, that gradient is sent back in the opposite direction. All the way back to the input layer.</p><p>This way you’re <em>back-propagating </em>the loss function.</p><p>The actual computation of the gradient is what is called <em>back-propagation </em>[1]. But is usually confused with the actual learning part, accomplished by algorithms like Stochastic Gradient Descent.</p><p>Reaching the input layer Stochastic Gradient Descent, or other gradient-based optimizer algorithm, adjusts the network weights and the activation function is computed again through every hidden layer.</p><p>Each weight in the network is updated by subtracting the value of the gradient with respect to the loss function (J), from the current weight vector (theta). This is also called the <em>weight change amount </em>(vt)<em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YrSHKwC_5rbbRR9K6hL5pg.png" /><figcaption><em>Backpropagation weight update rule (Image by author).</em></figcaption></figure><p>The process goes on until the loss function can’t be minimized anymore, so there’s no point in adjusting weights once again, and the performance of the neural network is improved to the maximum given the current training set and architecture.</p><p>More complex algorithms and Neural Network Architectures may increase performance, but it also adds complexity to all computations, leading to longer training time.</p><p>In Machine Learning, you’re always dealing with trade-offs. With more complex models some of the trade-offs are (a) increasing performance, but reducing model interpretability or (b) increasing performance, but increasing training time.</p><h3>RNNs in Action: Sentiment Analysis 👍 👎</h3><p>Instead of building a Recurrent Neural Network from scratch, you’ve decided to use <a href="https://www.tensorflow.org/">TensorFlow</a>’s robust library to help with classify the sentiment from reviews of your parents bed and breakfast.</p><p>First thing you need is to <a href="https://www.tensorflow.org/install">install TensorFlow</a> on your machine via <em>pip</em>, since you’re going to use the local Python environment.</p><p>Following the TensorFlow docs:</p><pre># Requires the latest pip<br>&gt; pip install --upgrade pip</pre><pre># Current stable release for CPU and GPU<br>&gt; pip install tensorflow</pre><p>Then you noticed there’s a robust example of <a href="https://www.tensorflow.org/text/tutorials/text_classification_rnn">Text Classification using RNNs on the TensorFlow resources</a>[6]. That’s a good basis for what you want to do, you just need to adapt it to your own task.</p><p>At a glance, setting up a Recurrent Neural Network to classify the sentiment of all reviews from your parents’ bed and breakfast involves:</p><ol><li>Organizing Training and Testing Files</li><li>Loading Training and Testing Datasets</li><li>Dimensionality Problem: Compressing your Dataset (Vectorization)</li><li>Building the Recurrent Neural Network</li><li>Model Fitting and Evaluation</li><li>Accuracy and Loss Visualized</li></ol><h3>Organizing Training and Testing Files</h3><p>The first step is taking the reviews your cousins have helped classify and organizing them into the corresponding directories. There will be <em>train</em> and <em>test </em>directories, each one with sub-directories that contain <em>positive </em>and <em>negative </em>reviews.</p><p>After this organization, if you run the command <em>tree</em> on your project directory, you’ll have something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RzdLdU2iLq5-MqDT4RvLbg.png" /><figcaption><em>Train and testing dataset directories </em>(Image by author)</figcaption></figure><p>What’s important in this step is there is only one review per file, so it can be properly loaded and processed in the following steps.</p><h3>Loading Training and Testing Datasets</h3><p>To load the train and test datasets you can leverage Keras utility method <a href="https://www.tensorflow.org/api_docs/python/tf/keras/utils/text_dataset_from_directory">text_dataset_from_directory</a>, which specifically requires the directory dataset structure you put together on the previous step.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l1HhYEGNZMiOl7gq9HZsQQ.png" /><figcaption><em>Loading train and testing datasets </em>(Image by author)</figcaption></figure><h3>Dimensionality Problem: Compressing your Dataset (Vectorization)</h3><p>Your parents’ bed and breakfast reviews are not that lengthy. There will be more enthusiastic customers, who write a short essay about their experience but, from a data perspective, the result is a vector of relatively low dimensionality.</p><p>But what if your parents business was so popular that Travel and Leisure magazines start writing articles, essentially reviews, about them? In this case we’re talking about much larger dataset, and each review is a magazine article of at least 800 words.</p><p>In this scenario, you’re dealing with a <strong>dimensionality problem</strong>. You have very large and sparce vectors, which makes all matrix calculations computationally challenging.</p><p>To handle this situation you want to do something similar to what you do with <a href="https://medium.com/p/18134c57ffe7">Principal Component Analysis</a>. You want to compress your dataset, while keeping all of its <em>expressiveness</em>, all its core characteristics.</p><blockquote>“These are built from a very large corpus of documents by a variant of principal components analysis. The idea is that the positions of words in the embedding space preserve semantic meaning; e.g. synonyms should appear near each other.” [5]</blockquote><p>A typical preprocessing step is to reduce the dimensionality with <a href="https://en.wikipedia.org/wiki/Word2vec">wor2vec</a>[4]. In TensorFlow the <a href="https://www.tensorflow.org/api_docs/python/tf/keras/layers/TextVectorization">Keras TextVectorization</a> layer does something similar. It takes a string and either maps it to a 1-dimensional <a href="https://en.wikipedia.org/wiki/Tensor">tensor</a> of indices or a 1-dimensional tensor of floats that represent the data in the string.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9qn_dovQ-v6l-eaZIZVPzg.png" /><figcaption><em>Loading data and Vectorizing training dataset. </em>(Image by author)</figcaption></figure><p>At the end of this step, the training dataset is vectorized and the data preparation phase is complete.</p><p>Now you’re ready to build the Recurrent Neural Network.</p><h3>Building the Recurrent Neural Network</h3><p>Your Recurrent Neural Network model is, in practice, a group of <a href="https://www.tensorflow.org/api_docs/python/tf/keras/Sequential">Sequential layers</a>.</p><p>The first one is the vocabulary encoder, created on the previous step. It’s used in the <a href="https://www.tensorflow.org/api_docs/python/tf/keras/layers/Embedding">Embedding layer</a>, which converts the values in the encoded vectors into a specific range.</p><p>For instance, the vocabulary in your reviews consists of 151 words, obtained by running:</p><pre>len(encoder.get_vocabulary())</pre><p>So the model takes the vocabulary size as input, via <em>input_dim</em>, and returns an output of size 64, defined using <em>output_dim</em>. And because you specified a vocabulary size of 151, the largest integer in the mapping will be 150.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*51pUxh5DRX-rolA-heiK1w.png" /><figcaption><em>Loading data and Vectorizing training dataset and Building the RNN. </em>(Image by author)</figcaption></figure><p>The next layer, <a href="https://www.tensorflow.org/api_docs/python/tf/keras/layers/Bidirectional">Bidirectional</a>, indicates you want to create a bidirectional Recurrent Neural Network. This means the input of the network is propagates forwards and backwards through the NRR layers. The <em>memories </em>the network creates over time, as it is processing the input, are not only passed forward to the following cells, but are also passed to previous cells. Now, each cell in the network has information about the past and what lies ahead in the input sequence.</p><p>The advantage of using a Bidirectional Recurrent Neural Network is that is not just the previous information in the network that contributes to the output prediction. Knowing what is coming up ahead in the sequence can have a significant influence on how the model learns.</p><p>This advantage is a double-edged sword. As information is now propagated backwards and forwards, these networks tend to be much slower, because gradients now have a much longer dependency chain.</p><p>However, your parents’ bed and breakfast reviews is a small dataset. So you’ve decided it’s worth a try!</p><p>The last two layers in the model are <a href="https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense">Dense Layers</a>. The second to last is used to process the model loss, with the hyperbolic tangent as activation. The last one reshapes the output to be of size 1, given that you want the output of the mode to be the <em>positive</em> or <em>negative class </em>index.</p><p>In this case, the RNN is created using 30 <a href="https://www.tensorflow.org/api_docs/python/tf/keras/layers/GRUCell">GRUCells</a>. These <a href="https://en.wikipedia.org/wiki/Gated_recurrent_unit">Gated Recurrent Units</a> (GRU) use the hyperbolic tangent as the activation function for recurrent step.</p><h3>Model Fitting and Evaluation</h3><p>Now that you’ve built and compiled the Recurrent Neural Network, it’s time to <a href="https://www.tensorflow.org/api_docs/python/tf/keras/Model#fit">fit it to the training dataset</a> and make some predictions.</p><p>A few parameters you can tune are:</p><ul><li><em>epochs</em> how many times you’d like the algorithm to go through the entire training set</li><li><em>shuffle</em> in case you’d like to shuffle the training data before each epoch iteration. True by default</li><li><em>validation_steps</em> the number of batches of samples to draw before the validation step is concluded, and the algorithm starts the new epoch</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nmgKG3HfCZSJ0VOnw5BsMQ.png" /><figcaption>From<em> Loading data and Vectorizing training dataset </em>to<em> Building </em>and evaluating the RNN<em>. </em>(Image by author)</figcaption></figure><h3>Accuracy and Loss Visualized</h3><p>As a final step, it’s always interesting to visualize the loss and accuracy of the model. Especially if it’s running through multiple iterations.</p><pre>import os<br>import tensorflow as tf<br>import matplotlib.pyplot as plt</pre><pre># Loading Training and Test Datasets<br>train_dir = os.path.join(&#39;&#39;, &#39;../datasets/train&#39;)</pre><pre>train_dataset = tf.keras.utils.text_dataset_from_directory(<br>    train_dir, label_mode=&#39;int&#39;, labels=&#39;inferred&#39;, follow_links = True<br>)</pre><pre>test_dir = os.path.join(&#39;&#39;, &#39;../datasets/test&#39;)</pre><pre>test_dataset = tf.keras.utils.text_dataset_from_directory(<br>    test_dir, label_mode=&#39;int&#39;, labels=&#39;inferred&#39;, follow_links = True<br>)</pre><pre># Vectorize training dataset<br>VOCAB_SIZE = 5000<br>encoder = tf.keras.layers.TextVectorization(max_tokens=VOCAB_SIZE)<br>encoder.adapt(train_dataset.map(lambda text, label: text))</pre><pre># Building the Recurrent Neural Network<br># using GRU cells and Hyperbolic tangent as activation function<br>cell = tf.keras.layers.GRUCell(30, recurrent_activation=&#39;tanh&#39;)<br>model = tf.keras.Sequential([<br>    encoder,<br>    tf.keras.layers.Embedding(<br>        input_dim=len(encoder.get_vocabulary()),<br>        output_dim=64,<br>        # Use masking to handle the variable sequence lengths<br>        mask_zero=True),<br>    tf.keras.layers.Bidirectional(tf.keras.layers.RNN(cell)),<br>    tf.keras.layers.Dense(60, activation=&#39;tanh&#39;),<br>    tf.keras.layers.Dense(1)<br>])</pre><pre># Compile model and use the algorithm Adam as optimization function<br>model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), optimizer=tf.keras.optimizers.Adam(1e-2), metrics=[&#39;accuracy&#39;])</pre><pre># Fitting the model<br>history = model.fit(train_dataset, epochs=10, validation_data=test_dataset, validation_steps=10)</pre><pre># Model Evaluation<br>test_loss, test_acc = model.evaluate(test_dataset)</pre><pre>print(&#39;Test Loss:&#39;, test_loss)<br>print(&#39;Test Accuracy:&#39;, test_acc)</pre><pre># Visualize Model Loss and Accuracy<br>def plot_graphs(history, metric):<br>  plt.plot(history.history[metric])<br>  plt.plot(history.history[&#39;val_&#39;+metric], &#39;&#39;)<br>  plt.xlabel(&quot;Epochs&quot;)<br>  plt.ylabel(metric)<br>  plt.legend([metric, &#39;val_&#39;+metric])</pre><pre>plt.figure(figsize=(16, 8))<br>plt.subplot(1, 2, 1)<br>plot_graphs(history, &#39;accuracy&#39;)<br>plt.ylim(None, 1)<br>plt.subplot(1, 2, 2)<br>plot_graphs(history, &#39;loss&#39;)<br>plt.ylim(0, None)</pre><p>Here you’re also leveraging code from the <a href="https://www.tensorflow.org/text/tutorials/text_classification_rnn#setup">handy example from TensorFlow’s documentation page</a> to plot the loss and accuracy for the training and validation datasets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OQiQgRxrMMz3jRFQubCZNg.png" /><figcaption>Plotting model loss and accuracy throughout each epoch. (Image by author)</figcaption></figure><p>After making predictions on the test dataset, the accuracy is far from perfect. It hovers around 0.5 which means your model is, technically, not much better than a random guess.</p><p>The accuracy stays very much stable at 50% throughout all evaluation epochs, and the loss starts steadily increasing after the third epoch.</p><p>But these results shouldn’t discourage you. Your dataset is very small and the RNN architecture used is very simplistic, and could definitely be refined. This is just a first run on understanding RNNs.</p><h3>Conclusion</h3><p>There are several different ways to build a recurrent neural network, depending on the task at hand.</p><p>It can have a one-to-many structure, like when the model has to create a caption for a given image. But if you’re translating English to French or vice-versa, you’ll be building a Recurrent neural network with a many-to-many structure.</p><p>For the Sentiment Analysis task or classifying all reviews from your parents’ cozy bed and breakfast, the network had a many-to-one structure, several words in a review contributing to a single output, the sentiment class. Either positive or negative.</p><p>The network you’ve created was relatively simple, and had an unimpressive 50% accuracy.</p><p>But I hope you got a better sense of what is a Recurrent Neural Network, why it is such game-changer Deep Learning network architecture, and the kinds of real-life problems it can be applied to.</p><p><em>Thanks for reading!</em></p><h3>References</h3><ol><li>Goodfellow, Ian J., Bengio, Yoshua and Courville, Aaron. Deep Learning, MIT Press, 2016</li><li><a href="https://karpathy.github.io/2015/05/21/rnn-effectiveness/">The Unreasonable Effectiveness of Recurrent Neural Networks</a></li><li>Heaton, Jeff. <a href="https://arxiv.org/abs/2009.05673">Applications of Deep Neural Networks</a></li><li>Tomas Mikolov Kai Chen Greg S. Corrado Jeffrey Dean. <a href="https://arxiv.org/abs/1301.3781">Efficient Estimation of Word Representations in Vector Space</a>. (2013)</li><li><em>Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani. (2021). An introduction to statistical learning : with applications in R. (2nd Edition) Springer</em></li><li><a href="https://www.tensorflow.org/text/tutorials/text_classification_rnn">Text classification with an RNN</a>, TensorFlow Documentation</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e8403a45f5de" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/recurrent-neural-networks-explained-with-a-real-life-example-and-python-code-e8403a45f5de">Recurrent Neural Networks Explained with a Real Life Example and Python Code</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Multilayer Perceptron Explained with a Real-Life Example and Python Code: Sentiment Analysis]]></title>
            <link>https://medium.com/data-science/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/cb408ee93141</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[editors-pick]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Tue, 21 Sep 2021 12:38:38 GMT</pubDate>
            <atom:updated>2021-09-30T04:15:17.372Z</atom:updated>
            <content:encoded><![CDATA[<h4>Multilayer Perceptron is a Neural Network that learns the relationship between linear and non-linear data</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mz7o9ths9X0WPFq_IIwd_A.png" /><figcaption>Image by author</figcaption></figure><p><em>This is the first article in a series dedicated to Deep Learning, a group of Machine Learning methods that has its roots dating back to the 1940’s. Deep Learning gained attention in the last decades for its groundbreaking application in areas like image classification, speech recognition, and machine translation.</em></p><p><em>Stay tuned if you’d like to see different Deep Learning algorithms explained with real-life examples and some Python code.</em></p><p>This series of articles focuses on <strong>Deep Learning</strong> <strong>algorithms</strong>, which have been getting a lot of attention in the last few years, as many of its applications take center stage in our day-to-day life. From self-driving cars to voice assistants, face recognition or the ability to transcribe speech into text.</p><p>These applications are just the tip of the iceberg. A long path of research and incremental applications has been paved since the early 1940’s. The improvements and widespread applications we’re seeing today are the culmination of the hardware and data availability catching up with computational demands of these complex methods.</p><h3>Why Deep Learning is Game Changing</h3><p>In traditional Machine Learning anyone who is building a model either has to be an expert in the problem area they are working on, or team up with one. Without this expert knowledge, designing and engineering features becomes an increasingly difficult challenge[1]. The quality of a Machine Learning model depends on the quality of the dataset, but also on how well features encode the patterns in the data.</p><p><strong>Deep Learning algorithms</strong> use <a href="https://en.wikipedia.org/wiki/Artificial_neural_network">Artificial Neural Networks</a> as their main structure. What sets them apart from other algorithms is that they don’t require expert input during the feature design and engineering phase. Neural Networks can <em>learn</em> the characteristics of the data.</p><p>Deep Learning algorithms take in the dataset and <em>learn </em>its patterns, they <em>learn</em> how to represent the data with features they extract on their own. Then they combine different representations of the dataset, each one identifying a specific pattern or characteristic, into a more abstract, high-level representation of the dataset[1]. This hands-off approach, without much human intervention in feature design and extraction, allows algorithms to adapt much faster to the data at hand[2].</p><p><strong>Neural Networks</strong> are inspired by, but not necessarily an exact model of, the structure of the brain. There’s a lot we still don’t know about the brain and how it works, but it has been serving as inspiration in many scientific areas due to its ability to develop intelligence. And although there are neural networks that were created with the sole purpose of understanding how brains work, Deep Learning as we know it today is not intended to replicate how the brain works. Instead, Deep Learning focuses on enabling systems that learn multiple levels of pattern composition[1].</p><p>And, as with any scientific progress, <strong>Deep Learning</strong> didn’t start off with the complex structures and widespread applications you see in recent literature.</p><p>It all started with a basic structure, one that resembles brain’s <a href="https://en.wikipedia.org/wiki/Neuron">neuron</a>.</p><h3>It all started with a Neuron</h3><p>In the early 1940’s <a href="https://en.wikipedia.org/wiki/Warren_Sturgis_McCulloch">Warren McCulloch</a>, a neurophysiologist, teamed up with logician <a href="https://en.wikipedia.org/wiki/Walter_Pitts">Walter Pitts</a> to create a model of how brains work. It was a simple linear model that produced a positive or negative output, given a set of inputs and weights.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*KAJBM4Fq-f96pibxNjusbA.png" /><figcaption>McCulloch and Pitts neuron model. (Image by author)</figcaption></figure><p>This <em>model of computation</em> was intentionally called <strong>neuron</strong>, because it tried to mimic how the core <em>building block</em> of the brain worked. Just like brain neurons receive electrical signals, McCulloch and Pitts’ neuron received inputs and, if these signals were strong enough, passed them on to other neurons.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aj8HMsImg0duogH_xeQorQ.jpeg" /><figcaption>Neuron and it’s different components. (<a href="https://en.wikipedia.org/wiki/File:Components_of_neuron.jpg">Image Credits</a>)</figcaption></figure><p>The first application of the neuron replicated a <a href="https://en.wikipedia.org/wiki/Logic_gate">logic gate</a>, where you have one or two binary inputs, and a <a href="https://en.wikipedia.org/wiki/Boolean_function">boolean function</a> that only gets activated given the right inputs and weights.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/545/1*H50XJ8vJvDoRi35Qq37BbA.png" /><figcaption>Example of the AND and OR logic gates (Image by author).</figcaption></figure><p>However, this model had a problem. It couldn’t <em>learn</em> like the brain. The only way to get the desired output was if the weights, working as catalyst in the model, were set beforehand.</p><blockquote>The nervous system is a net of neurons, each having a soma and an axon […] At any instant a neuron has some threshold, which excitation must exceed to initiate an impulse[3].</blockquote><p>It was only a decade later that <a href="https://en.wikipedia.org/wiki/Frank_Rosenblatt">Frank Rosenblatt</a> extended this model, and created an algorithm that could <em>learn</em> the weights in order to generate an output.</p><p>Building onto McCulloch and Pitt’s neuron, Rosenblatt developed the <strong>Perceptron</strong>.</p><h3>Perceptron</h3><p>Although today the <strong>Perceptron</strong> is widely recognized as an algorithm, it was initially intended as an image recognition machine. It gets its name from performing the human-like function of <em>perception</em>, seeing and recognizing images.</p><blockquote>In particular, interest has been centered on the idea of a machine which would be capable of conceptualizing inputs impinging directly from the physical environment of light, sound, temperature, etc. — the “phenomenal world” with which we are all familiar — rather than requiring the intervention of a human agent to digest and code the necessary information.[4]</blockquote><p>Rosenblatt’s perceptron machine relied on a basic unit of computation, the <strong>neuron</strong>. Just like in previous models, each neuron has a cell that receives a series of pairs of inputs and weights.</p><p>The major difference in Rosenblatt’s model is that <strong>inputs are combined in a</strong> <strong>weighted sum</strong> and, if the weighted sum exceeds a predefined threshold, the neuron fires and produces an output.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FBJqWE6AHt8HMZ7XHW9uWg.png" /><figcaption>Perceptrons neuron model (left) and threshold logic (right). (Image by author)</figcaption></figure><p>Threshold <em>T </em>represents the <strong>activation function</strong>. If the weighted sum of the inputs is greater than zero the neuron outputs the value 1, otherwise the output value is zero.</p><h3>Perceptron for Binary Classification</h3><p>With this discrete output, controlled by the activation function, the perceptron can be used as a <strong>binary classification model</strong>, defining a <strong>linear decision boundary</strong>. It finds the separating <a href="https://en.wikipedia.org/wiki/Hyperplane">hyperplane</a> that minimizes the distance between misclassified points and the decision boundary[6].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/446/1*uyiHcFxLN9y3a7A8ANsMpA.png" /><figcaption>Perceptron’s loss function. (Image by author)</figcaption></figure><p>To minimize this distance, Perceptron uses <a href="https://towardsdatascience.com/stochastic-gradient-descent-explained-in-real-life-predicting-your-pizzas-cooking-time-b7639d5e6a32">Stochastic Gradient Descent</a> as the optimization function.</p><p>If the data is linearly separable, it is guaranteed that Stochastic Gradient Descent will converge in a finite number of steps.</p><p>The last piece that Perceptron needs is the <strong>activation function</strong>, the function that determines if the neuron will fire or not.</p><p>Initial Perceptron models used <a href="https://en.wikipedia.org/wiki/Sigmoid_function">sigmoid function</a>, and just by looking at its shape, it makes a lot of sense!</p><p>The sigmoid function maps any real input to a value that is either 0 or 1, and encodes a non-linear function.</p><p>The neuron can receive <a href="https://en.wikipedia.org/wiki/Real_number">negative numbers</a> as input, and it will still be able to produce an output that is either 0 or 1.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/1*N_sariZeF-MYA2sjm6igWg.png" /><figcaption>Sigmoid function (Image by author).</figcaption></figure><p>But, if you look at Deep Learning papers and algorithms from the last decade, you’ll see the most of them use the <a href="https://en.wikipedia.org/wiki/Rectifier_(neural_networks)">Rectified Linear Unit (ReLU)</a> as the neuron’s activation function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/1*4nx_xk6qP2CcTAv6R-10dg.png" /><figcaption>ReLU function. (Image by author)</figcaption></figure><p>The reason why ReLU became more adopted is that it allows better optimization using Stochastic Gradient Descent, more efficient computation and is scale-invariant, meaning, its characteristics are not affected by the scale of the input.</p><h4>Putting it all together</h4><p>The neuron receives inputs and picks an initial set of weights a random. These are combined in weighted sum and then ReLU, the activation function, determines the value of the output.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s2_hVuUCvV7-yWGTTpiM3A.png" /><figcaption>Perceptrons neuron model (left) and activation function (right). (Image by Author)</figcaption></figure><p>But you might be wondering, <em>Doesn’t Perceptron actually learn the weights?</em></p><p>It does! Perceptron uses Stochastic Gradient Descent to find, or you might say <em>learn</em>, the set of weight that minimizes the distance between the misclassified points and the decision boundary. Once Stochastic Gradient Descent converges, the dataset is separated into two regions by a linear hyperplane.</p><p>Although it was said the Perceptron could represent any circuit and logic, the biggest criticism was that it couldn’t represent the <a href="https://en.wikipedia.org/wiki/XOR_gate">XOR gate</a>, <em>exclusive OR</em>, where the gate only returns <em>1</em> if the inputs are different.</p><p>This was proved almost a decade later by Minsky and Papert, in 1969[5] and highlights the fact that Perceptron, with only one neuron, can’t be applied to non-linear data.</p><h3>Multilayer Perceptron</h3><p>The<strong> Multilayer Perceptron</strong> was developed to tackle this limitation. It is a neural network where the mapping between inputs and output is non-linear.</p><p>A Multilayer Perceptron has input and output layers, and one or more <strong>hidden layers</strong> with many neurons stacked together. And while in the Perceptron the neuron must have an activation function that imposes a threshold, like ReLU or sigmoid, neurons in a Multilayer Perceptron can use any arbitrary activation function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*MF1q2Q3fbpYlXX8fZUiwpA.png" /><figcaption>Multilayer Perceptron. (Image by author)</figcaption></figure><p>Multilayer Perceptron falls under the category of <a href="https://en.wikipedia.org/wiki/Feedforward_neural_network">feedforward algorithms</a>, because inputs are combined with the initial weights in a weighted sum and subjected to the activation function, just like in the Perceptron. But the difference is that each linear combination is propagated to the next layer.</p><p>Each layer is <em>feeding</em> the next one with the result of their computation, their internal representation of the data. This goes all the way through the hidden layers to the output layer.</p><p>But it has more to it.</p><p>If the algorithm only computed the weighted sums in each neuron, propagated results to the output layer, and stopped there, it wouldn’t be able to <em>learn</em> the weights that minimize the cost function. If the algorithm only computed one iteration, there would be no actual learning.</p><p>This is where <a href="https://en.wikipedia.org/wiki/Backpropagation"><strong>Backpropagation</strong></a>[7] comes into play.</p><h3>Backpropagation</h3><p>Backpropagation is the learning mechanism that allows the Multilayer Perceptron to iteratively adjust the weights in the network, with the goal of minimizing the cost function.</p><p>There is one hard requirement for backpropagation to work properly. The function that combines inputs and weights in a neuron, for instance the weighted sum, and the threshold function, for instance ReLU, must be differentiable. These functions must have a <strong>bounded derivative</strong>, because <a href="https://towardsdatascience.com/stochastic-gradient-descent-explained-in-real-life-predicting-your-pizzas-cooking-time-b7639d5e6a32">Gradient Descent</a> is typically the optimization function used in MultiLayer Perceptron.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/1*tYQrcNF2rPAETvzpqGX0PA.png" /><figcaption>Multilayer Perceptron, highlighting the Feedfoward and Backpropagation steps. (Image by author)</figcaption></figure><p>In each iteration, after the weighted sums are forwarded through all layers, the gradient of the <strong>Mean Squared Error</strong> is computed across all input and output pairs. Then, to propagate it back, the weights of the first hidden layer are updated with the value of the gradient. That’s how the weights are propagated back to the starting point of the neural network!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*-ojxaaPB17oBrr9ICDPdmg.png" /><figcaption>One iteration of Gradient Descent. (Image by author)</figcaption></figure><p>This process keeps going until gradient for each input-output pair has converged, meaning the newly computed gradient hasn’t changed more than a specified <em>convergence threshold</em>, compared to the previous iteration.</p><p>Let’s see this with a real-world example.</p><h3>Using Perceptron for Sentiment Analysis</h3><p>Your parents have a cozy bed and breakfast in the countryside with the traditional guestbook in the lobby. Every guest is welcome to write a note before they leave and, so far, very few leave without writing a short note or inspirational quote. Some even leave drawings of Molly, the family dog.</p><p>Summer season is getting to a close, which means cleaning time, before work starts picking up again for the holidays. In the old storage room, you’ve stumbled upon a box full of guestbooks your parents kept over the years. Your first instinct? Let’s read everything!</p><p>After reading a few pages, you just had a much better idea. Why not try to understand if guests left a positive or negative message?</p><p>You’re a Data Scientist, so this is the perfect task for a binary classifier.</p><p>So you picked a handful of guestbooks at random, to use as training set, transcribed all the messages, gave it a classification of positive or negative sentiment, and then asked your cousins to classify them as well.</p><p>In <a href="https://en.wikipedia.org/wiki/Natural_language_processing">Natural Language Processing</a> tasks, some of the text can be ambiguous, so usually you have a corpus of text where the labels were agreed upon by 3 experts, to avoid ties.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9tBhE03KW0FUhXMh2Znn-Q.png" /><figcaption>Sample of guest messages. (Image by author)</figcaption></figure><p>With the final labels assigned to the entire corpus, you decided to fit the data to a <strong>Perceptron</strong>, the simplest neural network of all.</p><p>But before building the model itself, you needed to turn that free text into a format the Machine Learning model could work with.</p><p>In this case, you represented the text from the guestbooks as a vector using the <a href="https://en.wikipedia.org/wiki/Tf%E2%80%93idf">Term Frequency — Inverse Document Frequency (TF-IDF)</a>. This method encodes any kind of text as a statistic of how frequent each word, or term, is in each sentence and the entire document.</p><p>In Python you used <a href="https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html#sklearn.feature_extraction.text.TfidfVectorizer">TfidfVectorizer</a><strong> </strong>method from <a href="https://scikit-learn.org/stable/index.html">ScikitLearn</a>, removing English stop-words and even applying L1 normalization.</p><pre>TfidfVectorizer(stop_words=&#39;english&#39;, lowercase=True, norm=&#39;l1&#39;)</pre><p>On to binary classification with Perceptron!</p><p>To accomplish this, you used <a href="https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html">Perceptron</a> completely <em>out-of-the-box</em>, with all the default parameters.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*08hiU7ZDLNRkF24T89SLlw.png" /><figcaption>Python source code to run Perceptron on a corpus. (Image by author)</figcaption></figure><p>After vectorizing the corpus and fitting the model and testing on sentences the model has never seen before, you realize the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html#sklearn.linear_model.Perceptron.score">Mean Accuracy</a> of this model is 67%.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/343/1*wnDnCtC9YncqOhRFdA7ISA.png" /><figcaption>Mean accuracy of the Perceptron model. (Image by author)</figcaption></figure><p>That’s not bad for a simple neural network like Perceptron!</p><p>On average, Perceptron will misclassify roughly 1 in every 3 messages your parents’ guests wrote. Which makes you wonder if perhaps this data is not linearly separable and that you could also achieve a better result with a slightly more complex neural network.</p><h3>How would MultiLayer Perceptron perform in this case?</h3><p>Using <a href="https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html">SckitLearn’s MultiLayer Perceptron</a>, you decided to keep it simple and tweak just a few parameters:</p><ul><li>Activation function: ReLU, specified with the parameter <em>activation=’relu’</em></li><li>Optimization function: Stochastic Gradient Descent, specified with the parameter <em>solver=’sgd’</em></li><li>Learning rate: Inverse Scaling, specified with the parameter <em>learning_rate=’invscaling’</em></li><li>Number of iterations: 20, specified with the parameter <em>max_iter=20</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QNQZQtTAlQPnM6axuLunPQ.png" /><figcaption>Python source code to run MultiLayer Perceptron on a corpus. (Image by author)</figcaption></figure><p>By default, <strong>Multilayer Perceptron</strong> has three hidden layers, but you want to see how the number of neurons in each layer impacts performance, so you start off with 2 neurons per hidden layer, setting the parameter <em>num_neurons=2.</em></p><p>Finally, to see the value of the loss function at each iteration, you also added the parameter <em>verbose=True.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*esgzPpIWoRrpfX86W_7o3g.png" /><figcaption>Mean accuracy of the Multilayer Perceptron model with 3 hidden layers, each with 2 nodes. (Image by author)</figcaption></figure><p>In this case, the Multilayer Perceptron has 3 hidden layers with 2 nodes each, performs much worse than a simple Perceptron.</p><p>It converges relatively fast, in 24 iterations, but the mean accuracy is not good.</p><p>While the Perceptron misclassified on average 1 in every 3 sentences, this Multilayer Perceptron is kind of the opposite, on average predicts the correct label 1 in every 3 sentences.</p><p>What about if you added more <em>capacity</em> to the neural network? What happens when each hidden layer has more neurons to learn the patterns of the dataset?</p><p>Using the same method, you can simply change the <em>num_neurons </em>parameter an set it, for instance, to 5.</p><pre>buildMLPerceptron(train_features, test_features, train_targets, test_targets, num_neurons=5)</pre><p>Adding more neurons to the hidden layers definitely improved Model accuracy!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tY968kcEGczNnJkCaJH4Yg.png" /><figcaption>Mean accuracy of the Multilayer Perceptron model with 3 hidden layers, each with 5 nodes. (Image by author)</figcaption></figure><p>You kept the same neural network structure, 3 hidden layers, but with the increased computational power of the 5 neurons, the model got better at understanding the patterns in the data. It converged much faster and mean accuracy doubled!</p><p>In the end, for this specific case and dataset, the Multilayer Perceptron performs as well as a simple Perceptron. But it was definitely a great exercise to see how changing the number of neurons in each hidden-layer impacts model performance.</p><p>It’s not a perfect model, there’s possibly some room for improvement, but the next time a guest leaves a message that your parents are not sure if it’s positive or negative, you can use Perceptron to get a second opinion.</p><h3>Conclusion</h3><p>The first Deep Learning algorithm was very simple, compared to the current state-of-the-art. Perceptron is a neural network with only one neuron, and can only <em>understand</em> linear relationships between the input and output data provided.</p><p>However, with Multilayer Perceptron, horizons are expanded and now this neural network can have many layers of neurons, and ready to learn more complex patterns.</p><p>Hope you’ve enjoyed learning about algorithms!</p><p>Stay tuned for the next articles in this series, where we continue to explore Deep Learning algorithms.</p><h3>References</h3><ol><li>LeCun, Y., Bengio, Y. &amp; Hinton, G. Deep learning. <em>Nature</em> 521,<strong> </strong>436–444 (2015)</li><li>Ian Goodfellow, Yoshua Bengio, and Aaron Courville. 2016. Deep Learning. The MIT Press.</li><li>McCulloch, W.S., Pitts, W. A logical calculus of the ideas immanent in nervous activity. <em>Bulletin of Mathematical Biophysics</em> 5,<strong> </strong>115–133 (1943)</li><li>Frank Rosenblatt. The Perceptron, a Perceiving and Recognizing Automaton Project Para. <em>Cornell Aeronautical Laboratory </em>85, 460–461 (1957)</li><li>Minsky M. L. and Papert S. A. 1969. <em>Perceptrons</em>. Cambridge, MA: MIT Press.</li><li>Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani.<em> </em>(2013)<em>. </em>An introduction to statistical learning : with applications in R. New York :Springer</li><li>D. Rumelhart, G. Hinton, and R. Williams. Learning Representations by Back-propagating Errors. <em>Nature</em> 323 (6088): 533–536 (1986).</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cb408ee93141" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/multilayer-perceptron-explained-with-a-real-life-example-and-python-code-sentiment-analysis-cb408ee93141">Multilayer Perceptron Explained with a Real-Life Example and Python Code: Sentiment Analysis</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gradient Boosted Decision Trees explained with a real-life example and some Python code]]></title>
            <link>https://medium.com/data-science/gradient-boosted-decision-trees-explained-with-a-real-life-example-and-some-python-code-77cee4ccf5e?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/77cee4ccf5e</guid>
            <category><![CDATA[getting-started]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[editors-pick]]></category>
            <category><![CDATA[supervised-learning]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Thu, 19 Aug 2021 06:01:39 GMT</pubDate>
            <atom:updated>2021-08-19T20:51:36.812Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://towardsdatascience.com/tagged/getting-started">Getting Started</a></h4><h3>Gradient Boosted Decision Trees Explained with a Real-Life Example and Some Python Code</h3><h4>Gradient Boosting algorithms tackle one of the biggest problems in Machine Learning: <strong>bias</strong>.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DpupN_rVjxhCRlWA0j7Wrg.png" /><figcaption>Image by author.</figcaption></figure><p><em>This is the third and last article in a series dedicated to Tree Based Algorithms, a group of widely used Supervised Machine Learning Algorithms.</em></p><p><em>The first article was about </em><a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575"><em>Decision Trees</em></a><em>, while the second explored </em><a href="https://towardsdatascience.com/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c"><em>Random Forests</em></a><em>. Everything explained with real-life examples and some Python code.</em></p><p>Gradient Boosting algorithms tackle one of the biggest problems in Machine Learning: <strong>bias</strong>.</p><p>Decision Trees is a simple and flexible algorithm. So simple to the point it can <strong>underfit</strong> the data.</p><p>An underfit Decision Tree has low depth, meaning it splits the dataset only a few of times in an attempt to separate the data. Because it doesn’t separate the dataset into more and more distinct observations, it can’t capture the true patterns in it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a9FmRnqAiORKgVU7Yc1FMg.jpeg" /><figcaption><em>Bias of a simplistic (left) vs a complex model (right). [</em>Image by author<em>]</em></figcaption></figure><p>When it comes to tree-based algorithms <a href="https://towardsdatascience.com/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c">Random Forests</a> was revolutionary, because it used <strong>Bagging</strong> to <strong>reduce the overall variance</strong> of the model with an ensemble of random trees.</p><p>In Gradient Boosted algorithms the technique used to control bias is called <a href="https://en.wikipedia.org/wiki/Boosting_(machine_learning)">Boosting</a>.</p><p>In the late 1980’s and 1990’s, <a href="https://en.wikipedia.org/wiki/Robert_Schapire">Robert Schapire</a> and <a href="https://en.wikipedia.org/wiki/Yoav_Freund">Yoav Freund</a> developed one of the most popular <a href="https://en.wikipedia.org/wiki/Boosting_(machine_learning)">Boosting algorithms</a>, <a href="https://en.wikipedia.org/wiki/AdaBoost">AdaBoost</a>, to address underfitting and reduce bias.</p><p>But they were not alone. The field of Computer Science and Theoretical Machine Learning was riding this wave of enthusiasm and groundbreaking algorithms, and more scientists started developing Boosting approaches.</p><p>Friedman explored how Boosting can be the optimization method for an adequate loss function. While Schapire and Freund took inspiration on a question posed by <a href="https://en.wikipedia.org/wiki/Michael_Kearns_(computer_scientist)">Michael Kearns</a>, <em>Can a set of weak learners create a single strong learner?</em></p><p>In this context, a <em>weak</em> <em>learner</em> is any model that is slightly better than a random model, and will never efficiently achieve a training error of zero. A <em>strong learner </em>is the opposite, a model that can be improved and efficiently bring the training error down to zero.</p><p>Around the same time <a href="https://en.wikipedia.org/wiki/Jerome_H._Friedman">Jerome Freidman</a>, was also experimenting with Boosting. He ended up developing several new algorithms, the most popular being Gradient Boosted Decision Trees.</p><p>The ingenious efforts of these and other scientists contributed to a vibrant new chapter in Machine Learning. It generated robust and powerful algorithms. Many of which are still relevant today.</p><h3>Boosting 101</h3><p>The motto with Boosting is that the result is greater than the sum of its parts.</p><p><a href="https://en.wikipedia.org/wiki/Boosting_(machine_learning)">Boosting</a> is based on the assumption that it’s much easier to find several simple rules to make a prediction than it is to find <em>the one</em> rule that is applicable to all data and generates the best possible prediction[1].</p><p>The intuition behind Boosting is that you train the same <strong>weak learner</strong>, a model with simple rules, several times. Then combine its <em>weak </em>predictions into a single, more accurate result. The model is always of the same type same but, each time, it is trained with different weights for the observations it misclassified.</p><p>Predictions that were previously misclassified will have more weight on the next <em>weak learner</em>, so each <em>weak learner</em> focuses on the <em>hardest</em> observations[1].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7EPj_zymPU9vquOvis-3Bg.png" /><figcaption><em>Boosting algorithms attribute more weight to the observations it misclassified. (</em>Image by author<em>)</em></figcaption></figure><p>When you combine different weak learners sequentially, each one will make some incorrect predictions. But they will cover each others <em>blindspots</em>, making better predictions where other learners were not as good. Each model <em>learns slowly</em> from the errors the previous one made[2].</p><h3>What’s common across all Boosting Algorithms</h3><p>All Boosting algorithms are <strong>ensemble</strong> Classifiers or Regressors, depending on the task at hand, because they combine the results of several models.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/1*xrQg8R2S9GdipqxK40TiuA.png" /><figcaption><em>An ensemble of m weak learners. (</em>Image by author)</figcaption></figure><p>In the aggregation step of a Regression task you might compute the weighted sum of all predictions for each observation. While in a classification task, a majority vote <em>decides</em> which class to assign.</p><h3>Creating a Boosting Ensemble</h3><p>Most algorithms focus on parameter estimation, to find the parameters that minimize their loss function. Boosting algorithms focus on function estimation.</p><p>The ensemble of <em>weak learners</em> is actually a set of functions that map features to targets and minimize the loss function[3].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*oQet2rE7OvWq67eHSo23zw.png" /><figcaption>Each new <em>weak learner </em>added minimizes the ensemble’s loss function. <em>(</em>Image by author)</figcaption></figure><p>And because the optimization algorithm used to find the next <em>weak</em> <em>learner</em> is <a href="https://towardsdatascience.com/stochastic-gradient-descent-explained-in-real-life-predicting-your-pizzas-cooking-time-b7639d5e6a32">Gradient Descent</a>, the loss function must differentiable and convex.</p><p>However, this time Gradient Descent is used in a function space.</p><p>Typically, Gradient Descent starts off at a random point in a differentiable convex function, and only stops when it finds its minimum value.</p><p>The same concept is translated Boosting algorithms with a Gradient Descent, but in the function space.</p><p>The algorithm starts off with a very simple <em>weak learner</em>, for instance, always predicting the class 0.</p><p>With each <em>weak learner</em> added to the ensemble the <strong>algorithm is taking a step</strong> towards the right targets, because it only adds <em>weak learners</em> that minimizes the loss function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/618/1*dEkHpB35ayFr4H8VCtrx6w.png" /><figcaption><em>Loss function for the ensemble. (</em>Image by author)</figcaption></figure><p>The <a href="https://en.wikipedia.org/wiki/Loss_functions_for_classification">exponential loss</a> is typically used in Classification tasks while in Regression tasks it’s the Squared Loss.</p><h3>Gradient Boosted Decision Trees vs Adaboost vs …</h3><p>All Boosting algorithms share a common principle, they use Boosting to create an ensemble of learners that are later combined. But each of them has distinct characteristics that make them more suitable for particular tasks.</p><p>For instance, in <strong>Gradient Boosted Decision Trees</strong>, the <em>weak learner</em> is always a decision tree.</p><p>In <strong>Stochastic</strong> <strong>Gradient Boosting<em>, </em></strong>Friedman introduces randomness in the algorithm similarly to what happens in Bagging. At each iteration, instead of using the entire training dataset with different weights, the algorithm picks a sample of the training dataset at random without replacement and uses that to train the next learner[4].</p><p><strong>Adaboost</strong> is in many ways similar to Gradient Boosted Decision Trees, in a sense that you have the distribution of weights for each observation in the training dataset and, in each iteration the algorithm adjusts those weights based on how the previous <em>weak learner</em> performed. But its adaptive nature comes into play when, during each iteration, it chooses a new the learning rate <em>alpha </em>based on the <em>weak learner’s</em> error rate[1].</p><p>Now that you know a bit more about the different Boosting algorithms, let’s see them in practice!</p><h3>🛩🏝 Reducing model Bias with Boosting Algorithms</h3><p>Planning a vacation is challenging. The hardest part, picking a destination.</p><p>But you’re a Data Scientist. You’re confident that Machine Learning can give an algorithmic opinion on what should be your next vacation destination.</p><p>Whenever planning a vacation, you always take into account:</p><ul><li>Duration of the vacation,</li><li>Personal budget,</li><li>Weather forecast,</li><li>If your extended family is joining,</li><li>If you’re feeling adventurous and want to explore new places.</li></ul><p>When it comes to picking a classification algorithm, you know Decision Trees are said to mimic how humans make decisions. But it <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">has limitations</a>, just a single Decision Tree is not a very powerful predictor.</p><p><a href="https://towardsdatascience.com/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c">Random Forests</a> would get you better results, if you’re focused on controlling bias, not model variance. So Random Forests is not an option.</p><p>Since using a low<strong> bias</strong> model is your goal, Boosting algorithms are exactly what you’re looking for.</p><p>The firs thing you do is to go through your old notes and collect some data on how you picked previous vacation destinations. You gather all the information like your budget at the time and the duration of the vacation, and your previous destinations, which were typically a choice between Beach and Countryside.</p><p>In the code below I’m creating a synthetic dataset to simulate that data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/662/1*mKqK2WqBH81mItRRR8rB9w.png" /><figcaption>Creating a synthetic dataset with 250 observations. <em>(</em>Image by author)</figcaption></figure><h3>Spotting Model Bias</h3><p>The whole reason you want to use a Boosting algorithm is to control <a href="https://towardsdatascience.com/bias-variance-tradeoff-in-machine-learning-models-a-practical-example-cf02fb95b15d">model bias</a>.</p><p>In a Regression task, where you predict numerical values, Bias is described by this equation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*K36sh_mbp6voEnn1jPPolA.png" /></figure><p>In this case, you just need<strong> <em>plug the numbers</em></strong> in the formula.</p><p>But you’re trying to get an algorithmic opinion on your next vacation destination, a classification task.</p><p>For this purpose, you can use the misclassification rate, i.e, average of the <a href="https://en.wikipedia.org/wiki/Loss_function#0-1_loss_function">0–1 loss</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/504/1*CNAvdhN0oPn2ee1e8p1Mug.png" /><figcaption><em>(</em>Image by author)</figcaption></figure><p>If your model has a high proportion of misclassified observations in the training set, it means it has high bias.</p><p>Boosting algorithms ✅ Method to calculate Bias ✅</p><p>So you start with the the simplest algorithm Decision Trees. With ScikitLearns’ <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier">Decision Tree Classifier</a> you create a single decision tree that only splits the dataset twice. That’s why <em>max_depth=2</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/680/1*x1gqSuvqvmBKfiGzNbb7EA.png" /><figcaption>Code sample to train a Decision Tree. <em>(</em>Image by author)</figcaption></figure><p>The average misclassification rate in the training set, the <a href="https://scikit-learn.org/stable/modules/model_evaluation.html#zero-one-loss">0–1 loss</a>, is 44%. That’s almost as good as a random model! High Bias ✅</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/386/1*_xtl8AOXTguFvUxO6R44Ew.png" /><figcaption>Result of 0–1 misclassification error for the Decision Tree algorithm. <em>(</em>Image by author)</figcaption></figure><p>Now you turn to a <a href="https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html#sklearn.ensemble.GradientBoostingClassifier">Gradient Boosted Classifier</a>.</p><p>You set the depth of each<em> weak learner </em>in the ensemble to 1, using the parameter <em>max_depth once </em>again. In this case you’re training the smallest tree possible, what in the machine learning lingo it’s called a <a href="https://en.wikipedia.org/wiki/Decision_stump">decision stump</a><em>.</em></p><p>And in terms of the size of the ensemble, you picked a rather arbitrary number, 210 trees. That’s the parameter <em>n_estimators</em> in the GradientBoostingClassifier method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/933/1*6K7gwm2GOnOA0YXYjROAEw.png" /><figcaption>Code sample to train Gradient Boosted Decision Trees. <em>(</em>Image by author)</figcaption></figure><p>Gradient Boosted Decision Trees did indeed reduce Bias. A 0–1 loss of 32% is much better!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/362/1*nUTf0OwlCXM0M-NYd7Tfxw.png" /><figcaption>Result of 0–1 misclassification error for the Gradient Boosted Decision Trees algorithm. <em>(</em>Image by author)</figcaption></figure><p>Ok, you built a model with relatively low bias. But you know there are other Boosting algorithms out there, besides Gradient Boosted Decision Trees.</p><p>How much better would <a href="https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html#sklearn.ensemble.AdaBoostClassifier">Adaboost</a> be at predicting your next vacation destination?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*T-2t58U2mk4y9CzOwGBZvg.png" /><figcaption>Code sample to train an Adaboost model. <em>(</em>Image by author)</figcaption></figure><p>In the case of Adaboost, training the same number of trees didn’t reduce bias as much. But it still brought the misclassification rate down to 38%, from the 44% observed with Decision Trees.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/406/1*mQGLymJ2K3WduVsXTeA66Q.png" /><figcaption>Result of 0–1 misclassification error for the Adaboost algorithm. <em>(</em>Image by author)</figcaption></figure><p>When it goes to picking your next vacation destination, with the dataset at hand, Gradient Boosted Decision Trees is the model with lowest bias.</p><p>Now all you need to do is give the algorithm all information about your next vacation, i.e., the duration, if you’re feeling adventurous and all that.</p><p>The algorithm will tell you if your next vacation should be a Beach vacation or on the Countryside.</p><h3>Conclusion</h3><p>Now you can be confident about using Gradient Boosting Decision Trees to predict your next vacation destination. Instead of training just a single Decision Tree.</p><p>What sets Gradient Boosted Decision trees apart from other approaches is:</p><ul><li><strong>Speed</strong>, the algorithm is memory efficient so you can make predictions much faster.</li><li><strong>No preprocessing required </strong>you don’t need to prepare the data before building the model<strong>.</strong></li><li><strong>Data robustness</strong> the algorithm handles all types of data nicely.</li></ul><p>Event thought it is more complex than <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">Decision Trees</a>, it continues to share the advantages of tree-based algorithms.</p><p>But there’s always a catch. Gradient Boosted Decision Trees make two important trade-offs:</p><ul><li>Faster predictions over slower training,</li><li>Performance over interpretability.</li></ul><h3>Faster predictions vs slower training</h3><p>Even though one of the advantages mentioned above is the memory efficiency, that is when it comes to make predictions.</p><p>The algorithm is more complex and builds each tree sequentially. It’s predictions are fast, but the training phase is computationally more demanding.</p><h3>Performance over interpretability</h3><p>Similarly to what happens with Random Forests, you trade-off performance for interpretability.</p><p>You’ll no longer be able to <em>see </em>exactly how the algorithm split each tree node to reach the final prediction.</p><p>Hope you enjoyed learning about Boosting algorithms, the problems the address and what ultimately makes them unique.</p><p>Make sure to check the other two articles in this Tree-based Machine Learning algorithms series. The first one explores <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">Decision Trees</a> and the second <a href="https://towardsdatascience.com/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c">Random Forests</a>.</p><p><em>Thanks for reading!</em></p><h3>References</h3><ol><li>Schapire Robert E. (2002) The Boosting Approach to Machine Learning: An Overview</li><li><em>Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani. (2013). An introduction to statistical learning : with applications in R. New York :Springer</em></li><li><em>Friedman, J.H., 2001. Greedy function approximation: a gradient boosting machine. Annals of statistics, pp. 1189–1232.</em></li><li><em>Friedman, J.H., 1999. Stochastic Gradient Boosting. Computational Statistics and Data Analysis. 38 pp. 367–368</em></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=77cee4ccf5e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/gradient-boosted-decision-trees-explained-with-a-real-life-example-and-some-python-code-77cee4ccf5e">Gradient Boosted Decision Trees explained with a real-life example and some Python code</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Random Forests Algorithm explained with a real-life example and some Python code]]></title>
            <link>https://medium.com/data-science/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/affbfa5a942c</guid>
            <category><![CDATA[random-forest]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[deep-dives]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Mon, 12 Jul 2021 12:29:50 GMT</pubDate>
            <atom:updated>2022-01-10T03:06:17.505Z</atom:updated>
            <content:encoded><![CDATA[<h4>Random Forests is a Machine Learning algorithm that tackles one of the biggest problems with <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">Decision Trees</a>: <strong>variance</strong>.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LW04M0kPmgtY0xbhOqRJZw.png" /><figcaption>Image by author.</figcaption></figure><p><em>This is article number two in a series dedicated to Tree Based Algorithms, a group of widely used Supervised Machine Learning Algorithms.</em></p><p><em>The first article was about </em><a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575"><em>Decision Trees</em></a><em>. The next, and last article in this series, explores Gradient Boosted Decision Trees. Everything explained with real-life examples and some Python code.</em></p><p><em>Stay tuned!</em></p><p>Random Forests is a Machine Learning algorithm that tackles one of the biggest problems with <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">Decision Trees</a>: <strong>variance</strong>.</p><p>Even though Decision Trees is simple and flexible, it is <a href="https://en.wikipedia.org/wiki/Greedy_algorithm">greedy algorithm</a>. It focuses on optimizing for the node split at hand, rather than taking into account how that split impacts the entire tree. A greedy approach makes Decision Trees run faster, but makes it prone <strong>overfitting</strong>.</p><p>An overfit tree is highly optimized to predicting the values in the training dataset, resulting in a learning model with <strong>high-variance</strong>.</p><p>How you calculate variance in a Decision Tree depends on the problem you’re solving.</p><p>In a Regression task you can calculate actual <a href="https://en.wikipedia.org/wiki/Variance">variance</a> of the prediction compared to the true targets. If the tree produces results that are too far off from its true targets, it has high-variance and therefore, it is overfit.</p><blockquote>A highly overfit tree has high-variance. That means its predictions are extremely far off from the actual targets.</blockquote><p>But in a Classification task, you can’t use the same approach. The way to detect if the Decision Tree is overfit is by looking at the test error. If the tree has a high test error, meaning it’s not good at classifying observations it wasn’t trained on, it is overfit.</p><blockquote>In Regression tasks overfitting is detected by high-variance, while in Classification tasks it’s by a high generalization error.</blockquote><p>To address overfitting, and reduce the variance in Decision Trees, <a href="https://en.wikipedia.org/wiki/Leo_Breiman">Leo Breiman</a> developed the <a href="https://en.wikipedia.org/wiki/Random_forest">Random Forests</a> algorithm[1]. This was an innovative algorithm because it utilized, for the first time, the statistical technique of <a href="https://en.wikipedia.org/wiki/Bootstrapping_(statistics)">Bootstrapping</a> and combined the results of training multiple models into a single, more powerful learning model.</p><p>But before you see Random Forests in action, and code, let’s take a detour to explore what makes Random Forests unique.</p><h3>Bagging: Bootstrap Aggregation</h3><p><strong>Bagging</strong>, short for <a href="https://en.wikipedia.org/wiki/Bootstrap_aggregating">Bootstrap Aggregation</a>, is a technique developed by Leo Breiman, with the goal of reducing the variance of a learning model. Bagging is also model agnostic, so regardless of type of model you’re using, the process is the same.</p><p>The <strong>Bootstrapping</strong> part of Bagging refers to the resampling method in which several random samples are drawn with replacement from a dataset[3]. As a consequence, Bootstrapping creates multiple, smaller random datasets drawn from the same distribution.</p><p>Each of the bootstrapped datasets is used to train a model, and the outputs are then <strong>Aggregated</strong> into one final result.</p><p>But aggregation also means different things, depending on the type of problem you’re solving.</p><p>When you’re working on a Regression problem, aggregation means <em>averaging</em> the results of each observation, across all models. While in Classification aggregation means picking the most common class for each observation, like doing a <em>majority vote</em>.</p><p>This is impressive<em> </em>but,<em> how does this actually help reduce model variance?</em></p><p>Each model is trained on a <em>different </em>dataset, because they’re bootstrapped. So inevitably, each model will make <em>different </em>mistakes, and have a distinct error and variance. Both the error and variance get reduced in the aggregation step where, literally in the case of Regression, they are <em>averaged </em>out.</p><p>And because you end up with a single model, which combines the output of multiple models, Bagging is called and <strong>ensemble technique</strong>.</p><h3>Bootstrapping</h3><p>With Bootstrapping you’re following the motto of <em>doing more with less</em>. You’re taking one dataset and multiplying it into several smaller random datasets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*freUFRJ68pfjQjkw40F1LQ.png" /><figcaption>Code sample that bootstraps a dataset.</figcaption></figure><p>The initial dataset only had 10 elements, but you ended producing 5 sampled datasets of size 4.</p><p>In a way, <strong>you multiplied the dataset</strong>, going from just 10 observations to 4x5=20 observations, when you sum up the individual bootstrapped datasets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/222/1*bpikOxdjZAm_8qpEn5dd1Q.png" /><figcaption><em>Result of bootstrapping a dataset, generating 5 samples with 4 elements each.</em></figcaption></figure><p>The reason why Bootstrapping works is because you’re<strong> sampling</strong> <strong>with</strong> <strong>replacement</strong>.</p><p>You can <em>pick</em> the same datapoint multiple times, like in the last two samples, but each sampled dataset is slightly different from the previous one.</p><p>Without replacement you’d quickly run out of data points, and would only be able to generate a limited number of samples.</p><p>This detour was focused on what makes Random Forest unique.</p><p>Let’s get back to the main topic, <em>how Random Forests reduces model variance.</em></p><h3>Random Forests</h3><p>Random Forests was developed specifically to address the problem of high-variance in Decision Trees. Like the name suggests, you’re not training a single Decision Tree, you’re training an entire forest! In this case, a forest of Bagged Decision Trees.</p><p>At a high-level, in <em>pseudo-code</em>, Random Forests algorithm follows these steps:</p><ol><li>Take the original dataset and create <em>N</em> bagged samples of size <em>n</em>, with <em>n</em> smaller than the original dataset.</li><li>Train a Decision Tree with each of the <em>N</em> bagged datasets as input. But, when doing a node split, don’t explore all features in the dataset. Randomly select a smaller number, <em>M</em> features, from all the features in training set. Then pick the best split using impurity measures, like <a href="https://en.wikipedia.org/wiki/Decision_tree_learning#Gini_impurity">Gini Impurity</a> or Entropy.</li><li>Aggregate the results of the individual decision trees into a single output.</li><li>Average the values for each observation, produced by each tree, if you’re working on a Regression task.</li><li>Do a majority vote across all trees, for each observation, if you’re working on a Classification task.</li></ol><p>While <em>Forest </em>part of Random Forests refers to training multiple trees, the <em>Random</em> part is present at two different points in the algorithm.</p><p>There’s the randomness involved in the Bagging process. But then, you also pick a random subset of features to evaluate the node split. This is what guarantees that each tree is different and, therefore, ensures each model produces a slightly different result.</p><p>And while you could be thinking that randomly sampling features at each split introduces yet another <a href="https://en.wikipedia.org/wiki/Hyperparameter_(machine_learning)">hyperparameter</a> you might need to tune, that’s not the case. The model takes care of it for you!</p><p>You can certainly tune this hyperparameter. However, there’s mathematical consensus about randomly picking a number of features that is equal to the square root of the total number of available features in the dataset[2].</p><h3>Why use Random Forests?</h3><p>Random Forests has several advantages, when compared to training a single Decision Tree.</p><h4>All the advantages of Decision Trees, but more powerful</h4><p>At the core of this algorithm is a Decision Tree so, Random Forests shares all its advantages.</p><p>It’s a data robust algorithm, being able to handle different types of data, and doesn’t require any data preprocessing.</p><p>The true potential of Random Forests comes from combining the results different Decision Trees.</p><h4>Each model is different</h4><p>Like Decision Trees, the algorithm optimizes for the local split. But, instead of exploring all possible splits for each feature in the dataset, it randomly picks a subset of those features.</p><p>This reduces the number of outcomes the algorithm needs to evaluate at each split and, it makes each trained tree is slightly different.</p><h4>No holdout set required</h4><p>In Machine Learning you typically split the dataset into training and testing sets, in an effort to evaluate model performance with observations it has never seen before.</p><p>This becomes a challenging problem when you have a small dataset or the cost, and effort, of collecting more data is high.</p><p>But with Random Forests you can use the entire dataset to train and evaluate the model. The Bagging process takes care of it for you! Since you’re generating N smaller, random datasets picked with replacement, there’s always going to be a set of points that was not used to create the tree.</p><p>Take a look at the earlier example, which bootstrapped the dataset [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/222/1*bpikOxdjZAm_8qpEn5dd1Q.png" /><figcaption><em>Result of bootstrapping a dataset, generating 5 samples with 4 elements each.</em></figcaption></figure><p>If you were to use each of these samples to train a Decision Tree, there are observations the trees simply <em>don’t know about,</em> because they were not part of their training set.</p><p>With Random Forests you can use the entire dataset to train the model and calculate the test error directly from its results. You don’t need to set aside part of the dataset just for testing.</p><p>This new type of error, calculated directly from its results of the trained trees, is called the <a href="https://en.wikipedia.org/wiki/Out-of-bag_error">Out-of-bag Error</a>.</p><h3>🛩🏝 Reducing model variance with Random Forests</h3><p>Planning a vacation is challenging. This time you’re going to put your Machine Learning skills into practice and get an algorithmic opinion on what should be your next vacation destination.</p><p>Whenever you start planning a vacation, you always take into account:</p><ul><li>Duration of the vacation,</li><li>Personal budget,</li><li>Weather forecast,</li><li>If your extended family is joining,</li><li>If you’re feeling adventurous and want to explore new places.</li></ul><p>Decision Trees are said to mimic how humans make decisions. But as you’ve seen on the <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">previous article of this series</a>, a single Decision Tree is not a very powerful predictor.</p><p>Random Forests is an improvement on Decision Trees, but is it really that much better?</p><p>There’s only one way to find out!</p><p>But first, take another look at the performance of a single Decision Tree.</p><h3>Test error for a single Decision Tree</h3><p>If you train just one Decision Tree, the test error is approximately 70%.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tc9muYY5AEDANN0G0Cu_NA.png" /><figcaption>Code sample to train a single DecisionTree to predict your next vacation destination.</figcaption></figure><p>The test error, also known as generalization error, is considerably high. A sign of high variance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/311/1*E8ADqor8csxvSPQ7r3EE0g.png" /><figcaption>Test Error from the Decision Tree model.</figcaption></figure><p>Ok, you’re convinced! Decision Trees is definitely not the best algorithm to help you in the critical task of picking the next vacation destination.</p><p>Let’s train a Random Forests model using <a href="https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html">ScikitLearn</a>, completely <em>out-of-the-box</em> and without any hyperparameter tuning.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*HiDDktOqf-mORomW8_SPCw.png" /><figcaption>Code to train a Random Forest to train to predict your next vacation destination.</figcaption></figure><p>Right away Random Forests reduced the Test Error by 30%!</p><p>This is an impressive result, comparing to the performance of a single Decision Tree.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/368/1*KIcGngSsqEDnpBPxa0IuxQ.png" /><figcaption>Out-of-Bag Error, i.e., test error, from the Random Forests model.</figcaption></figure><p>One thing you noticed was that, by default the algorithm trains and combines the result of 100 bagged trees. This is one of the many hyperparameters you can tune in <a href="https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html">Random Forests</a>.</p><p>Curiosity just kicked-in!</p><p><em>Why 100 trees?</em></p><p><em>Would the algorithm perform better or worse with a different number of trees?</em></p><p><em>How much can you reduce the generalization error?</em></p><h3>Find the Optimal Number of Trees</h3><p>Instead of tuning this hyperparameter by trail and error, you decided plot the <em>Out-Of-Bag-Error </em>as a function of the number of trees in the Random Forest.</p><p>You settled on training the arbitrary number of 150 trees. But you’re starting with only 5 and slowly making your way up to 150, building a new model, each time with one additional tree.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*JTu9Y7K9aszT3uWF3BNTpA.png" /><figcaption>Code sample to plot the Out-Of-Bag error as the number of trees in the Random Forest.</figcaption></figure><p>Training a large forest doesn’t improve the model.</p><p>In the process you’ve found the performance <em>sweet spot</em> for your task. You only need 8 trees in the Random Forests to drop the generalization error to 33%.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TUFuc-2eZgUxNbS6N-Qbtw.png" /><figcaption>Output of plotting the <em>Out-of-Bag-Error </em>as a function of the number of trees in the Random Forest.</figcaption></figure><p>Looking at the plot, it’s easier to see the Out-Of-Bag Error getting worse past the <em>sweet-spot</em> of 8 trees. Then the model hits a<em> performance plateau</em>, when the <em>forest </em>gets bigger than 50 trees.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/972/1*Tb_bMkLktXeMl87b_kdRDA.png" /></figure><h3>Conclusion</h3><p>You successfully reduced the variance of your model!</p><p>Now you can be more confident about using Random Forests to predict your next vacation destination. Instead of training a single Decision Tree.</p><p>This was a simple example, but you could see the generalization error decline significantly, from 67% to 33%.</p><p>Random Forests is a powerful algorithm, but it has a clear disadvantage. You can’t <em>see</em> how the model makes decisions.</p><p>A cool aspect of Decision Trees is that, after the model is trained, you can actually visualize how the model makes decisions. With a small enough tree you can trace the entire <em>decision-making</em> process for a new observation.</p><blockquote>But with Random Forests, you trade-off interpretability for performance.</blockquote><p>As soon as you start combining the decisions of multiple trees, the <em>decision process</em> gets much more complex and impossible to visualize.</p><p>Hope you enjoyed learning about Random Forests, and why it is more powerful than <a href="https://towardsdatascience.com/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">Decision Trees</a>.</p><p><em>Stay tuned for the next article and last in this series! It’s about Gradient Boosted Decision Trees. Explained with a real-life example and some Python code.</em></p><h3>References</h3><ol><li>Breiman, L. <a href="https://link.springer.com/article/10.1023/A:1010933404324">Random Forests</a>. <em>Machine Learning</em> <strong>45, </strong>5–32 (2001)</li><li><em>Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani. (2013). An introduction to statistical learning : with applications in R. New York :Springer</em></li><li>Breiman, L. <a href="https://link.springer.com/article/10.1007/BF00058655">Bagging predictors</a>. <em>Mach Learn</em> <strong>24, </strong>123–140 (1996)</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=affbfa5a942c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c">Random Forests Algorithm explained with a real-life example and some Python code</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Decision Tree Classifier explained in real-life: picking a vacation destination]]></title>
            <link>https://medium.com/data-science/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575?source=rss-e960c0367546------2</link>
            <guid isPermaLink="false">https://medium.com/p/6226b2b60575</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[decision-tree-classifier]]></category>
            <category><![CDATA[deep-dives]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[getting-started]]></category>
            <dc:creator><![CDATA[Carolina Bento]]></dc:creator>
            <pubDate>Mon, 28 Jun 2021 13:43:30 GMT</pubDate>
            <atom:updated>2021-07-18T19:06:05.068Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://towardsdatascience.com/tagged/getting-started">Getting Started</a></h4><h4>Decision Tree is a Supervised Machine Learning Algorithm that uses a set of rules to make decisions, similarly to how humans make decisions.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uxYR0d4QSAcaEk-kh_qk4g.png" /><figcaption>Image by author.</figcaption></figure><p><em>This is article number one in a series dedicated to Tree Based Algorithms, a group of widely used Supervised Machine Learning Algorithms.</em></p><p><em>Stay tuned if you’d like to see Decision Trees, Random Forests and Gradient Boosting Decision Trees, explained with real-life examples and some Python code.</em></p><p><strong>Decision Tree</strong> is a Supervised Machine Learning Algorithm that uses a set of rules to make decisions, similarly to how humans make decisions.</p><p>One way to think of a Machine Learning classification algorithm is that it is built to make decisions.</p><p>You usually say the <em>model predicts</em> the class of the new, never-seen-before input but, behind the scenes, the algorithm has to <em>decide </em>which class to assign.</p><p>Some classification algorithms are probabilistic, like <a href="https://en.wikipedia.org/wiki/Naive_Bayes_classifier">Naive Bayes</a>, but there’s also a rule-based approach.</p><p>We humans, also make rule-based decisions all the time.</p><p>When you’re planning your next vacation, you use a rule-based approach. You might pick a different destination based on how long you’re going to be on vacation, the budget available or if your extended family is coming along.</p><p>The answer to these questions informs the final decision. And if you continually narrow down the available vacation destinations based on how you answer each question, you can visualize this decision process as a (decision)<strong> tree.</strong></p><h3>A tree that makes decisions</h3><p><strong>Decision trees</strong> can perform both classification and regression tasks, so you’ll see authors refer to them as <strong>CART algorithm: Classification and Regression Tree</strong>. This is an umbrella term, applicable to all tree-based algorithms, not just decision trees.</p><p>But let’s focus on decision trees for classification.</p><p>The intuition behind <strong>Decision Trees</strong> is that you use the dataset features to create <em>yes/no </em>questions and continually split the dataset until you isolate all data points belonging to each class.</p><p>With this process you’re organizing the data in a <strong>tree structure</strong>.</p><p>Every time you <em>ask a question</em> you’re adding a <strong>node</strong> to the tree. And the first node is called the <strong>root node</strong>.</p><p>The result of <em>asking a question</em> splits the dataset based on the value of a feature, and creates new nodes.</p><p>If you decide to stop the process after a split, the last nodes created are called <strong>leaf nodes</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/649/1*Ehq7_oHrR_eIpzTGBFcyXA.png" /><figcaption>Example of a decision tree with tree nodes, the root node and two leaf nodes. (Image by author)</figcaption></figure><p>Every time you <em>answer a question</em>, you’re also creating branches and segmenting the feature space into disjoint <strong>regions</strong>[1].</p><p>One branch of the tree has all data points corresponding to answering <em>Yes</em> to the <em>question</em> the rule in the previous node implied. The other branch has a node with the remaining data points.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CU5uGBi8LDXlP0W_H31UQQ.png" /><figcaption><em>Example of the different regions and types of nodes in a tree. </em>(Image by author)</figcaption></figure><p>This way you narrow down the feature space with each split or branch in the tree, and each data point will only belong to one region.</p><p>The goal is to continue to <em>splitting </em>the feature space, and applying rules, until you don’t have any more rules to apply or no data points left.</p><p>Then, it’s time to assign a class to all data points in each leaf node.</p><h3>Assigning a class</h3><p>The algorithm tries to completely separate the dataset such that all leaf nodes, i.e., the nodes that don’t split the data further, belong to a single class. These are called <strong>pure leaf nodes.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/614/1*BSK8Phs8td8WCuD-jwdjzA.png" /><figcaption><em>Example of a tree with only pure leaf nodes. </em>(Image by author)</figcaption></figure><p>But most times you end up with <strong>mixed leaf nodes</strong>, where not all data points have to the same class.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KOAC6DwDsSX1tpHHg-FYhQ.png" /><figcaption><em>Example of a tree with pure and mixed leaf nodes, before assigning the final classes to each node. </em>(Image by author)</figcaption></figure><p>In the end, the <strong>algorithm can only assign one class </strong>to the data points in each leaf node.</p><p>With pure leaf nodes that already taken care of, because all data points in that node have the same class.</p><p>But with mixed leaf nodes the algorithm assigns the <strong>most common class</strong> among all data points in that node.</p><h3>It’s hard to build the perfect tree</h3><p>The ideal tree is the smallest tree possible, i.e. with fewer splits, that can accurately classify all data points.</p><p>This sounds simple, but it’s actually a <a href="https://en.wikipedia.org/wiki/NP-hardness">NP hard problem</a>. Building the ideal tree would take <a href="https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time">polynomial time</a>, which increases exponentially as the dataset grows.</p><p>For example, for a dataset with only 10 data points and an algorithm with <a href="https://en.wikipedia.org/wiki/Big_O_notation">quadratic complexity</a>, O(n²), the algorithm executes 10*10 = 100 iterations to build the tree. Expand that dataset a bit more to have 100 data points, and the number of iterations the algorithm will execute jumps to 10,000.</p><blockquote>Finding <em>the</em> best tree is ideal in theory, but as the dataset grows, it becomes computationally unfeasible!</blockquote><p>To turn this NP-hard problem into something computationally feasible the algorithm uses a <a href="https://en.wikipedia.org/wiki/Greedy_algorithm"><strong>greedy approach</strong></a> to build the next best tree.</p><p>A <strong>greedy approach</strong> makes locally optimal decisions to pick the feature used in each split, instead of trying to make the best overall decision[2].</p><p>Since it optimizes for local decisions, it focuses only on the node at hand, and what’s best for that node in particular. So it doesn’t need to explore all possible splits for that node and beyond.</p><h3>Picking the best split</h3><p>On every split, the algorithm tries to divide the dataset into the smallest subset possible[2]. So, like any other Machine Learning algorithm, the goal is to <strong>minimize the loss function</strong> as much as possible.</p><p>A popular loss function for classification algorithms is <a href="https://towardsdatascience.com/stochastic-gradient-descent-explained-in-real-life-predicting-your-pizzas-cooking-time-b7639d5e6a32">Stochastic Gradient Descent</a> but, it requires the loss function to be differentiable. So, it’s not an option in this case.</p><p>But since you’re separating data points that belong to different classes, the loss function should evaluate a split based on the<em> proportion of data points belonging to each class </em>before and after the split.</p><blockquote>Decision Tree use loss functions that evaluate the split based on the <em>purity </em>of the resulting nodes.</blockquote><p>n order words, you’d want a loss function that evaluates the split based on the <em>purity </em>of the resulting nodes. A loss function that compares the class distribution before and after the split[2], like <strong>Gini Impurity</strong> and <strong>Entropy</strong>.</p><h4>Gini Impurity</h4><p><a href="https://en.wikipedia.org/wiki/Decision_tree_learning#Gini_impurity">Gini Impurity</a> is measure of variance across the different classes[1].</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/574/1*0HGZlU81sbTasamgcJUGdw.png" /><figcaption>Gini Impurity of a node.</figcaption></figure><h4>Entropy</h4><p>Similarly to Gini Impurity, Entropy is a <em>measure of chaos within the node</em>. And chaos, in the context of decision trees, is having a node where all classes are equally present in the data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/1*LOMIhf5QSCyTvsr60UCcyg.png" /><figcaption>Entropy of a node.</figcaption></figure><p>Using Entropy as loss function, a split is only performed if the Entropy of each the resulting nodes is lower than the Entropy of the parent node. Otherwise, the split is not <em>locally</em> <em>optimal</em>.</p><h3>Why you want to use Decision Trees</h3><p>Even though Decision trees is a simple algorithm, it has several advantages:</p><ul><li><strong>Interpretability</strong> you can visualize the decision tree.</li><li><strong>No preprocessing required</strong> you don’t need to prepare the data before building the model.</li><li><strong>Data robustness</strong> the algorithm handles all types of data nicely.</li></ul><h4>Interpretability: visualizing trees</h4><p>One of the biggest advantages of tree-based algorithms it that you can actually visualize the model.</p><p>You can <em>see</em> the decisions the algorithm made, and how it classified the different data points.</p><p>This is a major advantage, because most algorithms work like blackboxes, and it’s hard to clearly pinpoint what made the algorithm predict a specific result.</p><h4>No preprocessing required</h4><p>Several machine learning algorithms require feature values to be as similar as possible, so the algorithm can best interpret how the changes in those features impact the target.</p><p>The most common preprocessing requirement is feature <em>normalization, </em>so all features in the same scale and any change in those values has the same proportional weight.</p><p>The rules in tree-based algorithms are built around each individual feature, instead of considering the entire feature set. Each <em>decision</em> is made looking at one feature at a time, so their values don’t need to be normalized.</p><h4>Data robustness</h4><p>Tree-based algorithms are great at handling different data types. Your dataset can have a mix of numerical and categorical data, and you won’t need to <a href="https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html">encode</a> any of the categorial features.</p><p>This is an item on the pre-processing checklist that tree-based algorithms handle on their own.</p><h3>🛩🏝 Picking a vacation destination</h3><p>Planning the next vacation can be challenging. Vacations are never long enough, there are budget constraints, and sometimes the extended family wants to come along, which makes logistics more complicated.</p><p>You like the idea of asking for a second opinion, from an algorithm, when it’s time to make a decision that involves way too many variables to keep track of. Picking a vacation destination is a perfect example!</p><p>Whenever you start planning a vacation, you always take into account:</p><ul><li>Duration of the vacation,</li><li>Personal budget,</li><li>Weather forecast,</li><li>If your extended family is joining,</li><li>If you’re feeling adventurous and want to explore new places.</li></ul><p>Since Decision Trees are said to mimic how humans make decisions, that’s the algorithm you’re using.</p><p>The bonus piece it that, in the end, you’ll be able to visualize the decision tree and <em>see</em> how the algorithm picked the destination.</p><p>Thinking through your decision process for previous vacations and the criteria you always take into consideration, you put together a dataset.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A8u6I-QqHoKGRMMrF55zWw.png" /><figcaption>Dataset from previous vacation decision process. (Image by author)</figcaption></figure><p>Even though the Decision Tree algorithm can handle different data types, ScikitLearn’s current implementation <a href="https://github.com/scikit-learn/scikit-learn/issues/5442">doesn’t support categorical data</a>.</p><p>To use the Decision Tree classifier from <a href="https://scikit-learn.org/stable/">ScikitLearn</a>, you can’t skip the pre-processing step and need to encode all categorical features and targets before training the model.</p><pre>import numpy as np<br>from sklearn import preprocessing</pre><pre><br>def encode_feature(array):<br>    <em>&quot;&quot;&quot; Encode a categorical array into a number array<br>    <br>    :param array: array to be encoded<br>    :return: numerical array<br>    &quot;&quot;&quot;<br>  <br>    </em>encoder = preprocessing.LabelEncoder()<br>    encoder.fit(array)<br>    return encoder.transform(array)<br></pre><pre>feature_names = [&#39;number_days&#39;, &#39;family_joining&#39;, &#39;personal_budget&#39;, &#39;weather_forecast&#39;, &#39;explore_new_places&#39;]</pre><pre>class_names = [&#39;Countryside&#39;, &#39;Beach&#39;]</pre><pre>features = np.array([[10, &#39;Yes&#39;, 950, 75, &#39;Yes&#39;],<br>                     [10, &#39;Yes&#39;, 250, 78, &#39;Yes&#39;],<br>                     [7, &#39;Yes&#39;, 600, 80, &#39;No&#39;],<br>                     [8, &#39;Yes&#39;, 750, 67, &#39;Yes&#39;],<br>                     [10, &#39;Yes&#39;, 800, 73, &#39;Yes&#39;],<br>                     [8, &#39;Yes&#39;, 850, 64, &#39;Yes&#39;],<br>                     [15, &#39;No&#39;, 350, 78, &#39;No&#39;],<br>                     [8, &#39;Yes&#39;, 850, 81, &#39;Yes&#39;],<br>                     [6, &#39;No&#39;, 750, 59, &#39;Yes&#39;],<br>                     [12, &#39;Yes&#39;, 1050, 54, &#39;Yes&#39;],<br>                     [10, &#39;No&#39;, 230, 74, &#39;No&#39;],<br>                     [3, &#39;Yes&#39;, 630, 74, &#39;Yes&#39;],<br>                     [10, &#39;Yes&#39;, 830, 74, &#39;No&#39;],<br>                     [12, &#39;No&#39;, 730, 52, &#39;Yes&#39;]])<br></pre><pre># Encoding categorical features<br>features[:, 1] = encode_feature(features[:, 1])<br>features[:, 4] = encode_feature(features[:, 4])</pre><pre>targets = np.array([&#39;Countryside&#39;,&#39;Beach&#39;,&#39;Beach&#39;,&#39;Countryside&#39;,<br>                    &#39;Beach&#39;, &#39;Countryside&#39;, &#39;Beach&#39;,&#39;Countryside&#39;,<br>                    &#39;Beach&#39;, &#39;Beach&#39;, &#39;Countryside&#39;,&#39;Countryside&#39;,<br>                    &#39;Beach&#39;, &#39;Beach&#39;])</pre><pre>targets = encode_feature(targets)</pre><p>Pre-processing: Done ✅</p><p>Now it’s time to build and visualize the Decision Tree.</p><pre>import pandas as pd<br>from sklearn import tree<br>import matplotlib.pyplot as plt<br>from sklearn.model_selection import train_test_split</pre><pre><br>def print_feature_importance(names_array, importances_array):</pre><pre><em>    &quot;&quot;&quot; Prints out a feature importance array as a dataframe. &quot;&quot;&quot;</em></pre><pre>    importances = pd.DataFrame(data=names_array)<br>    importances[1] = importances_array</pre><pre>    importances = importances.T<br>    importances.drop(0, axis=0, inplace=True)<br>    importances.columns = feature_names<br>    <br>    print(str(importances.reset_index(drop=True)))</pre><pre>def build_tree(features, targets, feature_names, class_names):</pre><pre><em>    &quot;&quot;&quot; Builds a decision tree.<br>        Prints out the decision tree 1) as a plot, 2) as text.<br>        Also outputs: 1) feature importance, 2) training set and test set mean accuracy of tree<br>    <br>        :param features: model features<br>        :param targets: model targets<br>        :param feature_names: names of the dataset features<br>    &quot;&quot;&quot;<br>  <br>    </em>train_features, test_features, train_targets, test_targets = train_test_split(features, targets, test_size=0.2, random_state=123)</pre><pre><br>    decision_tree = tree.DecisionTreeClassifier(random_state=456)<br>    decision_tree = decision_tree.fit(train_features, train_targets)</pre><pre>    # Visualizing the decision tree<br>    <br>    # 1. Saving the image of the decision as a png   </pre><pre>    plt.subplots(figsize=(17, 12))<br>    tree.plot_tree(decision_tree, feature_names=feature_names, filled=True, rounded=True, class_names=class_names)<br>    plt.savefig(&quot;decision_tree.png&quot;)</pre><pre>    # 2. Output the tree as text in the console<br>    tree_as_text = tree.export_text(decision_tree, feature_names=feature_names)<br>    print(tree_as_text)</pre><pre>    # Feature Importance<br>    # Turns the feature importance array into a dataframe, so it has a table-like output format<br>    print_feature_importance(feature_names, decision_tree.feature_importances_)</pre><pre>    # Training and test mean accuracy<br>    train_error = np.round(decision_tree.score(train_features, train_targets), 2)<br>    test_error = np.round(decision_tree.score(test_features, test_targets), 2)<br>    <br>    print(&quot;Training Set Mean Accuracy = &quot; + str(train_error))<br>    print(&quot;Test Set Mean Accuracy = &quot; + str(test_error))</pre><pre><br>build_tree(features, targets, feature_names, class_names)</pre><p>This code does lots of things at once, so let’s unpack it.</p><p>It starts by <strong>splitting the dataset into training and test </strong>with the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split">train_test_split</a> function, so you can test model accuracy with data points that were not used to train the model.</p><h3>Building the model and visualizing the tree</h3><p>By default ScikitLearn uses Gini Impurity as a loss function. But you can also use Entropy as the loss function and tune other parameters in the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html">DecisionTreeClassifier</a>.</p><p>With the model trained, you can visualize the resulting decision tree with the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.plot_tree.html#sklearn.tree.plot_tree">plot_tree</a> method, and save as <em>decision_tree.png</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QUs9OK6bLm9OWDuAXbtfyg.png" /><figcaption>Decision Tree resulting from training the model. (Image by author)</figcaption></figure><p>You can also visualize the tree in the output console, you can use the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.export_text.html">export_text</a><em> </em>method<em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/515/1*I6C0TD-0BA6Kdvnp2jHq2Q.png" /><figcaption>Visualizing the Decision Tree as text, in the output console. (Image by author)</figcaption></figure><h3>Feature Importances</h3><p>But there’s something wrong with that decision tree!</p><p>You noticed the feature <em>explore_new_places</em> doesn’t show up anywhere. Even though you’re sure it’s an important part of your decision process.</p><p>To get to the bottom of this and understand why <em>explore_new_places </em>is not used in the model you lookup the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier.feature_importances_">feature_importances_</a> property in the decision tree model. This will tell you <em>how much each </em>features contributes to the accuracy of the model.</p><p>The <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier.feature_importances_">feature_importances_</a> property is simply an array of values, with each value corresponding to a feature of the model, with the same order as the input dataset.</p><p>So, for better readability, you can decided to create the function print_feature_importance and transform the value array from <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier.feature_importances_">feature_importances_</a> property into a <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html">dataframe</a> and use the feature names as headers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*x-qNDWffJOTEEwRy80q5IA.png" /><figcaption>Visualizing feature importances. (Image by author)</figcaption></figure><p><em>explore_new_places </em>has a feature importance of 0, which means it’s not used at all in the prediction.</p><p>At first glance you might be thinking, <em>I can just get rid of this feature.</em></p><p><strong>But feature importance doesn’t necessarily mean the feature is never going to be used in the model.</strong> It only means it was not used in this tree, which as a specific training-test split.</p><p>So you can’t eliminate this feature right away.</p><p>To confirm that <em>explore_new_places </em>is not relevant to the model, you can build several trees with different train-test splits f the dataset and check if <em>explore_new_places </em>still has zero importance.</p><h3>Model Performance</h3><p>Finally, to evaluate the algorithm’s performance you calculate the mean accuracy of the predictions on both the training and test sets, using the <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier.score">score</a><em> </em>method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/697/1*vp1lN2FxlVYrHjXPfYcjcA.png" /><figcaption>Mean accuracy for predictions on the training and test sets. (Image by author)</figcaption></figure><p>As you can see, this model is overfit and memorized the training set. And with a 67% of mean accuracy for the test set, it doesn’t generalize very well to observations it has never seen before.</p><h3>One Decision Tree is not enough</h3><p>Despite their advantages, Decision Trees don’t provide the same level of accuracy as other classification and regression algorithms.</p><p><strong>Decision trees are prone to overfitting</strong>. If you build a very tall tree, splitting the feature set until you get pure leaf nodes, you’re likely overfitting the training set. The resulting tree is so complex that it’s also hard to <em>read</em> and interpret.</p><p>On the other hand, if your decision tree is very small it underfits the data, resulting in high bias.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/675/1*cj-pzRLTVxrlkVc25WwtcQ.png" /><figcaption>Example of Decision trees with high bias and high variance. (Image by author)</figcaption></figure><p>Decision trees are robust in terms of the data types they can handle, but the algorithm itself is not very robust. A slight change in the data can drastically change the tree and, consequently the final results[1].</p><h3>The power hidden in the forest</h3><p>A single <strong>Decision Tree </strong>by itself has subpar accuracy, when compared to other machine learning algorithms. One tree alone typically doesn’t generate the best predictions, but the tree structure makes it easy to control the <a href="https://towardsdatascience.com/bias-variance-tradeoff-in-machine-learning-models-a-practical-example-cf02fb95b15d">bias-variance trade-off</a>.</p><blockquote>A single Decision Tree is not powerful enough, but an entire forest is!</blockquote><p>In algorithms that combine multiple trees and control for bias or variance, like <a href="https://en.wikipedia.org/wiki/Random_forest">Random Forests</a>, the model has a much better performance when compared to a single decision tree.</p><p><em>Stay tuned for the next articles in this series</em>, because they’re about Boosting and Bagging. These techniques are applied to tree-based algorithms and tackle, respectively, the issues with bias and variance.</p><h3>Conclusion</h3><p>Decision trees are a rule-based approach to classification and regression problems. They use the values in each feature to split the dataset to a point where all data points that have the same class are grouped together.</p><p>However, there’s a clear trade-off between interpretability and performance.</p><p>You can easily visualize and<em> </em>interpret a small tree, but<em> </em>it has high variance. A small change in the training set, may result in a completely different tree, and completely different predictions.</p><p>On the other hand, a tall tree with multiple splits generates better classifications. But it’s likely memorizing the training dataset. So it not good at classifying data it has never seen before.</p><p>Hope you enjoyed learning about Decision Trees!</p><p>Stay tuned for the next articles in this series! The next articles explore Tree-based Ensemble algorithms that use Boosting and Bagging techniques to control bias and variance.</p><p><em>Thanks for reading!</em></p><h3>References</h3><ol><li><em>Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani. (2013). An introduction to statistical learning : with applications in R. New York :Springer</em></li><li>P. Tan, M. Steinbach, and V. Kumar. (2005) Introduction to Data Mining. <em>Addison Wesley</em></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6226b2b60575" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/decision-tree-classifier-explained-in-real-life-picking-a-vacation-destination-6226b2b60575">Decision Tree Classifier explained in real-life: picking a vacation destination</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>