<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ashutosh Sahu</title>
    <description>The latest articles on Forem by Ashutosh Sahu (@ashuto7h).</description>
    <link>https://forem.com/ashuto7h</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F535287%2F71c1b23a-fdb9-4b26-898c-ba6721cd1840.png</url>
      <title>Forem: Ashutosh Sahu</title>
      <link>https://forem.com/ashuto7h</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ashuto7h"/>
    <language>en</language>
    <item>
      <title>Working with circular dependencies in sequelize-typescript</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Wed, 19 Feb 2025 14:36:50 +0000</pubDate>
      <link>https://forem.com/ashuto7h/working-with-circular-dependencies-in-sequelize-typescript-1b13</link>
      <guid>https://forem.com/ashuto7h/working-with-circular-dependencies-in-sequelize-typescript-1b13</guid>
      <description>&lt;p&gt;When designing relational databases, it's pretty common to run into tables that just can't stop referencing each other. These circular references can be a bit of a headache, especially when using an ORM like Sequelize. Whether you're dealing with tables that reference themselves or ones that are interdependent, knowing how to manage these circular references is crucial for maintaining a clean and functional database schema.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore what circular references are, why they happen, and how to effectively handle them in Sequelize-typescript.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are Circular References?
&lt;/h3&gt;

&lt;p&gt;Circular references happen when two or more tables reference each other, creating a loop. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Table A&lt;/strong&gt; has a foreign key pointing to &lt;strong&gt;Table B&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table B&lt;/strong&gt; has a foreign key pointing back to &lt;strong&gt;Table A&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This loop can complicate database operations like inserts, updates, and deletions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Scenarios for Circular References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-Referencing Tables&lt;/strong&gt;: A table references itself, like an &lt;code&gt;Employee&lt;/code&gt; table where each employee has a &lt;code&gt;manager_id&lt;/code&gt; referencing another employee in the same table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interdependent Tables&lt;/strong&gt;: Two or more tables reference each other, like a &lt;code&gt;User&lt;/code&gt; table and a &lt;code&gt;Team&lt;/code&gt; table where a user belongs to a team, and a team has a leader who is a user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In these cases, making the foreign keys nullable can help manage the relationships better.&lt;/p&gt;

&lt;p&gt;Got it! Let's make this straightforward and clear.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;When I started writing models for these circular references in &lt;code&gt;sequelize-typescript&lt;/code&gt;, I ran into an issue right away. Thanks to linter which helped identify issue earlier that there is a circular dependency problem in the imports. &lt;/p&gt;

&lt;p&gt;For example, I had two models: &lt;code&gt;User&lt;/code&gt; and &lt;code&gt;Team&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.model.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./team.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;allowNull&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;teamId&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;BelongsTo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;team&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// team.model.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Team&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;allowNull&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;leaderId&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;HasOne&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;leader&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the problem? The &lt;code&gt;User&lt;/code&gt; model needs to import the &lt;code&gt;Team&lt;/code&gt; model, and the &lt;code&gt;Team&lt;/code&gt; model needs to import the &lt;code&gt;User&lt;/code&gt; model. This circular dependency in imports is causing issues and preventing progress.&lt;/p&gt;

&lt;h3&gt;
  
  
  ### The Search for a Solution
&lt;/h3&gt;

&lt;p&gt;I searched high and low for a way to resolve this dependency problem, but there was no direct solution that fit my needs. Every answer on Stack Overflow seemed to say the same thing: avoid circular dependencies altogether. But my situation was unique.&lt;/p&gt;

&lt;p&gt;Then, I stumbled upon a suggestion to introduce a middleman to break the circular dependencies. For example, if A depends on B and B depends on A, you can introduce C so that A depends on C and B depends on C. &lt;/p&gt;

&lt;p&gt;But how could I split my models any further? 🤔 This was the challenge I needed to tackle. &lt;/p&gt;

&lt;h3&gt;
  
  
  Inheritance to the Rescue
&lt;/h3&gt;

&lt;p&gt;I found a solution using inheritance. Models typically contain two types of data: actual database columns and associations. So, what if I create a separate class for associations that extends the model containing the table columns?&lt;/p&gt;

&lt;p&gt;One limitation with this approach is that it doesn't support deep nested joins in code. However, I see this more as a best practice than a limitation. When defining associations, I only need access to the columns of associated tables, not their associations.&lt;/p&gt;

&lt;p&gt;For example, if I need to access the name of the team leader for a given user, Sequelize allows me to use &lt;code&gt;user.team.leader.name&lt;/code&gt;. But I'm opting out of this convenience. Instead, I'll get the &lt;code&gt;user.team.leaderId&lt;/code&gt; and then fetch the user in a second query using the leaderId.&lt;/p&gt;

&lt;p&gt;This approach solves most of the problem, but I still needed the import for defining &lt;code&gt;@ForeignKey&lt;/code&gt;. Fortunately, I discovered that the decorator isn't necessary if you provide the keys directly to the association decorators. Here's what my solution looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.table.ts&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;underscored&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserTable&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;allowNull&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;teamId&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.model.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TeamTable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./team.table.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;UserTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;BelongsTo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;foreignKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teamId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;targetKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;team&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;TeamTable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// team.table.ts&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;team&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;underscored&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TeamTable&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;allowNull&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;leaderId&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// team.model.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserTable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.table.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Team&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TeamTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;HasOne&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sourceKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;leaderId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;foreignKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;leader&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;UserTable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, I can manage circular dependencies without running into import issues.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>sequelize</category>
      <category>database</category>
      <category>javascript</category>
    </item>
    <item>
      <title>3. Designing a Microservice: choosing a DB</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Mon, 17 Feb 2025 08:03:01 +0000</pubDate>
      <link>https://forem.com/ashuto7h/3-designing-a-microservice-choosing-a-db-3231</link>
      <guid>https://forem.com/ashuto7h/3-designing-a-microservice-choosing-a-db-3231</guid>
      <description>&lt;p&gt;In the previous article, we looked into the characteristics of microservice architecture and the steps involved in their design process like domain analysis, bounding context, and selecting a communication channel along with an example of our food ordering application. This article will discuss selecting databases and applying some design patterns or scaling techniques to our microservice architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4. Selecting the Database:
&lt;/h2&gt;

&lt;p&gt;Databases are an essential part of any architecture. While selecting a database, we need to consider various factors like consistency, query performance, cost, scalability, and most importantly - the type of structure we will save in the database. Let's look at different types of databases:&lt;/p&gt;

&lt;h3&gt;
  
  
  SQL (MySQL, PostgreSQL, MSSQL)
&lt;/h3&gt;

&lt;p&gt;SQL databases are used for storing structured data that is related to one another. If your service has to store data related to customer information, financial transactions, inventory management, or other such things in which different piece of information is related to one another in some way and need to be frequently queried, then you should use an SQL database.&lt;/p&gt;

&lt;h3&gt;
  
  
  NoSQL
&lt;/h3&gt;

&lt;p&gt;NoSQL databases are used for storing unstructured or semi-structured data. They are widely used in web applications for storing user-generated content such as social media posts, comments, and reviews. NoSQL databases come in different types, each with its purpose.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key-Value Store (DynamoDB, Redis, Memcache)&lt;/strong&gt;:  Key-value stores are used for storing any data structures such as strings, integers, or objects which is tied to a key. They are widely used in caching and session management. Redis is an in-memory database, which is used for caching mainly. DynamoDB is a cloud-native database that is offered by Amazon Web Services (AWS). It is designed to handle large amounts of data and traffic while maintaining consistent and fast performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Store (MongoDB, CouchDB)&lt;/strong&gt;: Document stores are used for storing semi-structured data such as JSON documents. They are widely used in web applications for storing user-generated content. If your service needs to store data related to users which is more likely unstructured or has frequent changes and needs to be scaled easily, then MongoDb or CouchDb are good choices.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Column Store (Cassandra, HBase)&lt;/strong&gt;: Column stores are used for storing large amounts of data that can be queried quickly. They are widely used in big data applications for storing and analyzing large datasets. Column stores provide a type of structure to the NoSQL databases, making it easier to make faster queries. If you need to process real time or high volume of data, you should choose column store databases.&lt;br&gt;
Graph Store (Amazon Neptune, Neo4j): Graph stores are used for storing data that has complex relationships. They are widely used in social networking and recommendation systems. If your service is related to providing some recommendations based on users past activities then a graph store is best choice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hybrid (CockroachDB, PostgreSQL)&lt;/strong&gt;: Hybrid databases combine the benefits of SQL and NoSQL databases. They are used for storing structured and unstructured data. CockroachDB is a distributed SQL database that is designed for scalability and high availability. PostgreSQL is a hybrid database that supports both SQL and NoSQL data models.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When deciding which type of database to use, consider the following factors:&lt;br&gt;
&lt;strong&gt;Data Structure&lt;/strong&gt;: If your data is structured and related to one another, then a SQL database is a good choice. If your data is unstructured or semi-structured, then a NoSQL database is a better choice.&lt;br&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: If you need to scale your database horizontally, then a NoSQL database is a better choice. If you need to scale your database vertically, then a SQL database is a better choice.&lt;br&gt;
&lt;strong&gt;Querying&lt;/strong&gt;: If you need to perform complex queries on your data, then a SQL database is a better choice. If you need to perform simple queries on your data, then a NoSQL database is a better choice.&lt;br&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: If you need strong consistency guarantees, then a SQL database is a better choice. If you can tolerate eventual consistency, then a NoSQL database is a better choice.&lt;br&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: SQL databases are generally more expensive than NoSQL databases. If cost is a concern, then a NoSQL database is a better choice.&lt;/p&gt;




&lt;p&gt;Let's continue with assigning a database for our food ordering microservice architecture. &lt;br&gt;
For users and restaurant inventory-related data, we can use an SQL database like Postgres. &lt;br&gt;
For managing orders, we can use a NoSQL database like MongoDB.&lt;br&gt;
For real-time delivery tracking and queries, we can use Cassandra or HBase.&lt;br&gt;
For recommendation systems, we can use Neptune as a graph db.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5. Integrating Design Patterns or Techniques
&lt;/h2&gt;

&lt;p&gt;The final step is to apply some design patterns or techniques that can help us solve some common problems or challenges in a microservice architecture. They are not required at the beginning phase, but eventually, you will need them.&lt;/p&gt;

&lt;p&gt;Some common design patterns or practices are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strangler Pattern&lt;/li&gt;
&lt;li&gt;SAGA Pattern&lt;/li&gt;
&lt;li&gt;CQRS Pattern&lt;/li&gt;
&lt;li&gt;API Gateway Routing&lt;/li&gt;
&lt;li&gt;Circuit Breaker Pattern&lt;/li&gt;
&lt;li&gt;Backend for Frontend&lt;/li&gt;
&lt;li&gt;Load balancing&lt;/li&gt;
&lt;li&gt;Consistent Hashing&lt;/li&gt;
&lt;li&gt;Partitioning&lt;/li&gt;
&lt;li&gt;Replication&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Sharding&lt;/li&gt;
&lt;li&gt;Rate Limiting&lt;/li&gt;
&lt;li&gt;Locking and Idempotency handling&lt;/li&gt;
&lt;li&gt;Concurrency handling&lt;/li&gt;
&lt;li&gt;Application metrics&lt;/li&gt;
&lt;li&gt;Audit logging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will discuss them in detail later in our series.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few things to remember
&lt;/h2&gt;

&lt;p&gt;There are a few more small things that can help further in the design process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It is not always necessary to create a service if you just need separation of concern in code, you can create a library or a package instead. For example, a part of your codebase works in designing email templates and generating PDF invoices or Excel reports. These tasks are independent functions in themselves, they just need an input and are supposed to give some output. they share common util functions and imports and sometimes, are needed across different services. For such tasks, it's better to create a library/package rather than a service. Using the library, you can abstract that part of code from your services, also they are faster to serve because there is no inter-service communication involved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to make service communications unidirectional. Your microservice structure should be like a tree, with Parent and child services. where parents can send requests to children and get a response, but the reverse should be avoided as much as possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always use a centralized logging system with a standard format for easy-to-find issues among different requests. Use headers like correlation ID to see all logs related to a single transaction among all services. also log key data points like order ID to retrieve all logs related to them at any point.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stay near code, there are too many small business details that are never covered in any document. They are only in the code. No person knows them better than your code. So stay near the code or the person writing them. It's easier to draw boxes and design but harder to implement. Knowing how things like message queues, load balancers, and rate limiting are implemented and work at a low level is equally important.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;In our next article, we are going to discuss infrastructure estimations for microservice architecture, how to choose the right infrastructure and calculate costs.&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>2. Designing a microservice Architecture</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Tue, 21 Jan 2025 06:25:59 +0000</pubDate>
      <link>https://forem.com/ashuto7h/2-designing-a-microservice-architecture-2p12</link>
      <guid>https://forem.com/ashuto7h/2-designing-a-microservice-architecture-2p12</guid>
      <description>&lt;p&gt;In our last article, we have seen the differences between Microservices and monoliths, advantages, and common challenges with both architectures. In this article, we are going to dive more into how to design a microservice architecture using a Food delivery application as an example.&lt;br&gt;
There are certain characteristic principles of microservices that serve as a rule set and help us tackle some of the challenges faced in microservices. Beware that these characteristics break some conventions and principles that were followed previously in software engineering. Let's take a look at them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Characteristics to be Present in a Micro Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Single responsibility principle
&lt;/h3&gt;

&lt;p&gt;This principle helps very much in deciding what our architecture should look like. According to the single responsibility principle, microservice should be focused on a single business capability or function that it provides. We should avoid creating services that have multiple or unclear responsibilities. We should also avoid creating services that duplicate or overlap with each other's functionality.&lt;/p&gt;

&lt;p&gt;The problem with this rule is it's hard to follow. As a general rule, we should not create a service that is too small or too large. This conflicts with the Single responsibility principle and makes us ask how small or how big a service should be to be able to fulfill this principle.&lt;/p&gt;

&lt;p&gt;At the low level, there is always too much going on. A new requirement at first seems adjustable to an existing service, which also saves on the cost and time of implementation. Slowly these requirements gather up to become a large service, handling different tasks and doing too much out of the bounds breaking our single responsibility principle.&lt;/p&gt;

&lt;p&gt;The solution is to gradually split the services as we develop new features. For example, suppose you created a single service at the beginning to handle Product inventory management and searching. It also used to store prices and related discounts, so later we started adding pricing, sales, offers, and discount handling to it. At first, all of this looked like a part of inventory management. As the features grew, the pricing logic started to become complex based on seasons, analytics, previous sales, etc.   The codebase evolves around these and becomes a much bigger part of the process. Now it's time to separate Pricing into a new service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuidi2sfs711lv0v1uvy1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuidi2sfs711lv0v1uvy1.png" alt="Splitting services" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One key factor while deciding on main services is that we should always keep scopes to split a service into smaller services. So that we only have to spawn a new service and move half of the functionalities to it when required, rather than ending up in a mess, where we need to redesign the whole service architecture.&lt;/p&gt;

&lt;p&gt;The final decision on how to split into different microservices, and how big or small a service should be depends completely on your application and you. There is no hard constraint or rule for it. It's okay to compromise with some principles to gain benefits in other sectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Database one service
&lt;/h3&gt;

&lt;p&gt;A microservice should carry its data and manage its persistence and transactions separately. We should avoid sharing databases or tables among different services, as this can create coupling and inconsistency issues. We should also avoid using foreign key constraints or joins across different services, as this can create performance and scalability issues. This helps with scaling also, where you can scale a single database based on requirements.&lt;br&gt;
Now this rule breaks the conventions of a single database where we used to rely on foreign keys and transactions to maintain consistency. we were also able to do joins on different tables under a single database to pull any kind of data we needed.&lt;/p&gt;

&lt;p&gt;In an inconsistent microservice system, anything can go wrong. following are the most common cases:&lt;br&gt;
 &lt;strong&gt;Case 1&lt;/strong&gt;: you have 3 different services to manage orders, payments, and inventory. you got an order, it saved the details of the order and updated the stock in inventory, but the payment failed. Now all these services have their databases, so they all run under different transactions. Failure of payment transactions will not revert the inventory and order service transactions. So an order gets placed without a successful payment.&lt;br&gt;
&lt;strong&gt;Case 2&lt;/strong&gt;: Let's take the same example again, you got an order, you updated the inventory that an item is sold, and also mapped the order ID against that item. But before payment, the user canceled the order, it got soft deleted from the order service. Now the inventory has an item reserved for the order that does not exist. Foreign keys could have made handling such situations easier, by using delete cascades, but they are not available.&lt;/p&gt;

&lt;p&gt;These cases are the most common examples of errors happening in a microservice. They are complex to handle. If we need data consistency and want to avoid such situations, we need to implement a SAGA pattern which involves coordinating the transactions in different services using either choreography or orchestration approaches to compensate for any failures or errors by undoing or reversing the previous transactions.&lt;/p&gt;

&lt;p&gt;Similarly, if we frequently need to join queries among tables of different services, we need to use a CQRS pattern for that.&lt;br&gt;
We will discuss these patterns later in more detail in our series.&lt;/p&gt;

&lt;p&gt;Again the decision of whether to use a centralized database or go with a DB for every service is up to you. It's not completely necessary to use a database for each service. If your application is small data needs to be highly coupled or implementing SAGA or CQRS is not affordable, you can go with a centralized database. you can also go with a hybrid approach, like 5 microservices and 2 databases, 3 services are using db1 other 2 services are using db2.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;A microservice should be able to handle increasing or decreasing demand without affecting its performance or availability. We should be able to scale our services independently from each other by adding or removing instances as needed. We should also be able to scale our services across different dimensions such as load balancing, partitioning, replication, and caching. we will discuss these techniques in detail later in our series.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loosely coupled
&lt;/h3&gt;

&lt;p&gt;Microservices should be able to communicate with each other without knowing too much about their internal details or dependencies. We should use well-defined interfaces that expose only the necessary functionality and hide other implementation details. We should also use standard protocols and formats that enable interoperability and compatibility among different services.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design Process
&lt;/h2&gt;

&lt;p&gt;Now that we have understood the challenges and characteristics of a microservice architecture, let us see how we can design one for our application. The design process involves the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Business Oriented division of service&lt;/li&gt;
&lt;li&gt;Bounding Contexts&lt;/li&gt;
&lt;li&gt;Selecting a communication type&lt;/li&gt;
&lt;li&gt;Selecting a database&lt;/li&gt;
&lt;li&gt;Applying Design Pattern / Scaling&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1. Business-oriented divisions of service
&lt;/h3&gt;

&lt;p&gt;The first step is to analyze our domain and identify the business capabilities or functions that our application provides or will provide in the future. Each system is built around certain unique features. These features sometimes have the potential to completely change the architecture. To keep the system fixed within a certain architecture, It's necessary to analyze the domain.&lt;br&gt;
When gathering the domain knowledge, start with building a vocabulary and language around it. When in a team, generally the discussions are verbose, not in much detail, or often referred to with different words. Words like slider, carousel, rotating view, dynamic view, and animation, are generally mixed up. We should avoid using our jargon during such discussions and use a simplified and predefined vocabulary.&lt;br&gt;
Documenting/creating diagrams is good but only up to a point. UML and flowcharts are always better than explaining something in words. However, in a domain analysis, the vocabulary can grow over time. A diagram or document should be made as small as possible and should be divided into parts. In the beginning, there can be too frequent changes that will try to change most of the designs. Keeping track of all changes, and updating a big diagram/document based on it is hard. Eventually, with a single document, there comes a time when you cannot trust the document to gather information, You have to go through code and implementation to know what that piece is supposed to do.&lt;/p&gt;

&lt;p&gt;Let's start designing the food ordering application, by creating a vocabulary. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3c2nmn5p2l4ijylh9b4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3c2nmn5p2l4ijylh9b4.png" alt="Vocabulary" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just a basic vocabulary example. Notice how with the vocabulary, we fixed up a terminology. We also identified major entities (white circles), some functionalities (gray circles), and a soft relationship between them using arrows. Now we can pick each of these entities separately and identify its attributes, functionalities, and relationships. This analysis could introduce more entities as we go deeper into it. While doing so, maintain small documents dedicated to a specific entity only. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2. Bounding contexts
&lt;/h3&gt;

&lt;p&gt;After we are done with domain analysis, we know well the different entities, their attributes, relationships, and functionalities in our application. Now we can define bounded contexts. Bounded contexts are a grouping of related subdomains that share a common language and model. When bounding contexts, start with smaller groups of say 2 or 3 contexts. Pick an entity and assign it to a context based on the functionalities. As you start doing this, you will see there is a possibility to introduce a new context or split an existing one. If you are in doubt about whether to allow this new context in the system, then just don't add it now, but always make enough room so that it can be easily added in the future. Then assign a microservice to each context. When doing this, keep in check the characteristics that we went through earlier. Ask yourself, Is your microservice going to be scalable? Does it follow the single responsibility principle? Restructure it if you are in doubt. These questions will help you through a raw High-level design of the system.&lt;/p&gt;




&lt;p&gt;Let's start with 3 contexts for our food-ordering app&lt;br&gt;
User Context &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add customer, restaurant and  Delivery Partner,
 - manage Profile
 - authentication/authorization
 - restaurant menu/inventory CRUD
Ordering Context
 - Maintaining a Cart &lt;/li&gt;
&lt;li&gt;Order food
 - Payment confirmation
 - Cancel Order
 - Refund/Cashback
 - Delivery Partner / Dish Rating
Tracking and Navigation Context
 - Assign a Delivery Partner to Order&lt;/li&gt;
&lt;li&gt;Track Order for customer
 - Navigator for Delivery Partner.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3. Selecting the Communication type
&lt;/h3&gt;

&lt;p&gt;The next step is to choose the communication model for our microservices. There are two main types of communication models: synchronous and asynchronous&lt;/p&gt;

&lt;h4&gt;
  
  
  Synchronous Communication
&lt;/h4&gt;

&lt;p&gt;Synchronous communication is a real-time communication model, where the sender and the receiver are both active and available at the same time. Synchronous communication is usually implemented using request/response-based protocols, such as HTTP, over TCP/IP or UDP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TCP/IP&lt;/strong&gt;: This protocol is used where reliability and consistency are important. In this, each data packet sent receives an acknowledgment. It also maintains the order in which data is sent. This makes it consistent and slow. It's widely used for most of the API calls and is the default protocol in a NodeJS server.&lt;br&gt;
 &lt;br&gt;
 &lt;strong&gt;UDP&lt;/strong&gt;: This protocol is used for creating custom messaging protocols. This doesn't guarantee delivery and order of delivery of the data. That's why it is fast but also lossy and inconsistent. It's suitable for situations where it's okay to lose data, like a video or audio live stream where ensuring previous data is transferred is not needed. We constantly need to send real-time data only. NodeJS provides dgram module for creating a UDP server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST (Representational State Transfer)&lt;/strong&gt;: REST is a widely used architectural style for designing web APIs, based on the principles of statelessness, uniform interface, and resource orientation. REST uses HTTP/1.1 with verbs (GET, POST, PUT, DELETE, etc.) to perform operations on resources, identified by URIs, and exchanges data in various formats, such as JSON, XML, or plain text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;gRPC (Remote Procedure Call)&lt;/strong&gt;: gRPC is a high-performance, open-source framework for RPC communication, developed by Google. gRPC uses HTTP/2 as the underlying transport layer, and protocol buffers as the default data serialization format. Protocol buffers are binary, compact, and schema-based messages, defined by .proto files, that can be generated into native code for various languages and platforms. They are faster than REST and are preferred for inter-service communications.&lt;/p&gt;

&lt;p&gt;Generally, you should use REST for client-to-service communications and gRPC for service-to-service communications. Use synchronous communications where the user expects an immediate response or feedback from the system, such as logging in, placing an order, or doing data queries such as retrieving a product detail, a customer profile, or a report.&lt;/p&gt;

&lt;h4&gt;
  
  
  Asynchronous Communication
&lt;/h4&gt;

&lt;p&gt;Asynchronous communication is a non-blocking communication model, where the sender and the receiver are not required to be active and available at the same time. The sender sends a message and continues with its task, without waiting for the response from the receiver. The receiver processes the message and sends back the response whenever it is ready. Asynchronous communication is usually implemented using message-based protocols, such as AMQP, MQTT, or STOMP, over TCP/IP.&lt;/p&gt;

&lt;p&gt;Some of the common asynchronous communication protocols for microservices are:&lt;br&gt;
 &lt;strong&gt;Message queue&lt;/strong&gt;: A message queue is a data structure that stores and transmits messages between the sender and the receiver, using a FIFO (first-in, first-out) or a priority-based order. A message queue acts as a buffer and a mediator, decoupling the sender and the receiver, and ensuring reliable and durable delivery of the messages. A message queue can have one or more producers and consumers, but each message is delivered to exactly one consumer. Some examples of message queue technologies are Amazon SQS, RabbitMQ, ActiveMQ, and Azure Service Bus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event stream&lt;/strong&gt;: An event stream is a data structure that stores and transmits messages between the sender and the receiver, using an append-only and immutable order. An event stream acts as a log and a source of truth, capturing the history and the state of the system, and enabling event-driven communication. An event stream can have one or more producers and consumers, and messages are available for all consumers. Some examples of event stream technologies are Apache Kafka, Apache Pulsar, and Amazon Kinesis.&lt;/p&gt;

&lt;p&gt;There can be three types of routing strategies/exchanges involved in a message queue: Direct, Fan-out, and Topic.&lt;/p&gt;

&lt;h5&gt;
  
  
  Direct
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The strategy routes the messages based on the routing keys. For example, a direct exchange can bind the queue "order-service" to the routing key "order.created", and send the messages with that routing key to that queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has the advantages of simplicity and efficiency, as it delivers the messages to the exact consumers that need them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has the disadvantages of rigidity and redundancy, as it requires the producers and the consumers to agree on the routing keys, and it does not support broadcasting of the messages.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Fanout
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fanout routing is a strategy that delivers a message to all the consumers who are subscribed to the message queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The fanout exchange sends the messages to all the queues regardless of their routing keys. For example, a fanout exchange can send the same message to the queues "order-service", "inventory-service", and "notification-service", regardless of their routing keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has the advantages of flexibility and scalability, as it allows the producers and the consumers to be loosely coupled, and it supports the broadcasting of the messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It also has the disadvantages of inefficiency and waste, as it delivers the messages to the consumers that may not need them, and it consumes more network and system resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Topic
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Topic routing is a strategy that delivers a message to multiple consumers that match the topic of the message. The topic is a string that consists of words separated by dots, and it can represent a hierarchy or a category of the message. For example, a message with the topic "order.created.usa" can represent an order creation event that occurred in the USA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The topic exchange binds the queues to the topics and sends the messages to the queues that have the same or a subset of the topic as the message. The topic exchange can also use wildcards to match the topics, such as an empty string to match any single word, and a "#" to match any number of words. For example, a topic exchange can bind the queue "order-service" to the topic "order.", and send the messages with the topics "order.created", "order.updated", and "order.deleted" to that queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has the advantages of versatility and granularity, as it allows the producers and the consumers to use different levels of abstraction and specificity for the messages, and it supports filtering and grouping of the messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It also has the disadvantages of complexity and ambiguity, as it requires the producers and the consumers to understand and follow the topic conventions, and it may cause conflicts or overlaps of the topics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Asynchronous communication is suitable in cases like notifying a change in a system such as a new order, status update, or payment confirmation. they can also be used between microservices to perform actions like processing some tasks, updating the database, and sending async reports via mail based on events/messages. Asynchronous communication can ensure eventual consistency and fault tolerance, where the slow receiver can catch up with the fast sender, even if there are some delays or failures in the communication.&lt;/p&gt;




&lt;p&gt;In the next article, we will discuss selecting the database for each of our microservices and applying some design patterns and techniques for better scaling.&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>1. Designing A Microservice Architecture: Microservice vs Monolith</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Tue, 21 Jan 2025 05:42:48 +0000</pubDate>
      <link>https://forem.com/ashuto7h/1-designing-a-microservice-architecture-microservice-vs-monolith-4nn8</link>
      <guid>https://forem.com/ashuto7h/1-designing-a-microservice-architecture-microservice-vs-monolith-4nn8</guid>
      <description>&lt;p&gt;Microservices are a popular architectural style that aims to create modular, scalable, and resilient applications by breaking them into small, independent, and loosely coupled services. Each service focuses on a specific business capability and communicates with other services.&lt;/p&gt;

&lt;p&gt;However, designing a microservice architecture is not a trivial task. It involves many challenges and trade-offs that need to be carefully considered and addressed. The process of designing a microservice architecture, starts from identifying the business domains and services, to choosing the database and communication models, to applying the best practices and patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not create a monolith?
&lt;/h2&gt;

&lt;p&gt;Before going into details of microservice design, let's look at the traditional monolithic architecture, where the entire application is built as a single unit that runs on a single server.&lt;/p&gt;

&lt;p&gt;Monolithic architecture is a very simple architecture that comes with the following advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy deployment&lt;/strong&gt;: A monolithic application can be deployed as a single executable file or directory, which makes the deployment process easier and faster. There is no need to manage multiple services, dependencies, or configurations as in microservices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High performance&lt;/strong&gt;: A monolithic application can provide high performance, as it can avoid the overhead of network communication and data serialization between different services. The application can also leverage the benefits of shared memory, caching, and transactions within a single process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: A monolithic application can be simpler to develop, test, and debug, as it has a single code base and a single development environment. The application can also use common frameworks and libraries that support the entire functionality. There is no need to deal with the complexity of distributed systems, such as latency, inconsistency, concurrency, and failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cost Effective&lt;/strong&gt;: A monolithic application is cost efficient for multiple reasons like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduced infrastructure complexity as it can run on a single server&lt;/li&gt;
&lt;li&gt;Simplified operations and maintenance as it can be deployed and updated as a single unit&lt;/li&gt;
&lt;li&gt;It saves the operational overhead and costs as it can leverage the benefits of shared memory, caching, and transactions within a single process.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Recently Amazon Prime video migrated from microservice to a monolith architecture which helped in reducing their costs by about 90%. you can read more about it &lt;a href="https://www.primevideotech.com/video-streaming/scaling-up-the-prime-video-audio-video-monitoring-service-and-reducing-costs-by-90" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going through these advantages of a monolith, It's obvious to think why we need a microservice architecture in the first place.&lt;/p&gt;

&lt;p&gt;It's right, every application doesn't necessarily need to have a microservice architecture. It depends on many small factors like business requirements, how many resources are required and can be afforded, how traffic is distributed among different components of your application, etc. We will identify all such factors that will help us decide what's the right choice.&lt;/p&gt;

&lt;p&gt;Let's take a look at some common challenges in a monolithic architecture and how microservices help in solving them:&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexity
&lt;/h3&gt;

&lt;p&gt;As a monolith application grows in size and functionality, it becomes harder to understand, maintain, and test. The codebase becomes bloated with interdependent components that have multiple responsibilities and dependencies.&lt;/p&gt;

&lt;p&gt;The developer experience degrades with such a codebase, mostly for new developers, who cannot completely explore the codebase and get to know every line of code written, the business logic, and hidden behaviors. They don't know if a function already exists for doing something and ends up recreating it or what side effects will occur on doing changes at a component that is used in other modules.&lt;/p&gt;

&lt;p&gt;In a big codebase, loading all the code in an IDE, finding a suitable place to make changes, and running tests/builds on CI/CD, all require too much time and resources.&lt;/p&gt;

&lt;p&gt;Microservices can reduce the code complexity of an application by breaking it down into smaller and simpler units that focus on specific functionalities. Each microservice can be developed, tested, deployed, and maintained independently, which makes the application easier to manage and understand. Microservices also enable better separation of concerns and modularity, which improves the cohesion and coupling of the code&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;As the application receives more traffic and load, it becomes harder to scale it horizontally (by adding more servers) or vertically (by adding more resources to the existing server). Monoliths grow up in size and can utilize resources in GBs.&lt;/p&gt;

&lt;p&gt;Generally in such systems, only 30-40% of the code, resource, or components are responsible for the traffic. while the others are only for some rare tasks that don't happen very often.&lt;/p&gt;

&lt;p&gt;Taking the example of an e-commerce application, It receives many orders and product search-related queries. Most of the traffic is around these components only. The other components like customer service, and user profile management, don't receive that much traffic. But when a monolith is scaled, it is scaled as a whole unit. Suppose you are getting 5 times more traffic for orders than for customer services, But you scaled both the database and servers to keep serving the traffic. That usually ends up getting more costly because more than half of the components of your application are never going to use that many resources.&lt;/p&gt;

&lt;p&gt;In microservices, each component is built independently as a service. so they can be scaled independently according to their demand and resource consumption. This means that only the services that need more resources can be scaled up or down, without affecting the rest of the application. Microservices also enable horizontal scaling, which means adding more instances of the same service to handle more load.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reliability
&lt;/h3&gt;

&lt;p&gt;As the application consists of a single point of failure, any bug or error can bring down the entire system. The application becomes vulnerable to security breaches and data loss. The recovery process can become longer and more difficult.&lt;/p&gt;

&lt;p&gt;Microservices can enhance the reliability of an application by making it more resilient to failures and errors. Since each microservice is isolated from the others, a failure in one service does not affect the whole application, as long as there are fallback mechanisms in place. Microservices also enable faster recovery and fault tolerance, as each service can be restarted or replaced without disrupting the entire system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Innovation
&lt;/h3&gt;

&lt;p&gt;As the application is tightly coupled with a specific technology stack. Migrating/switching to a new package or library or updating an existing one, switching to a better design pattern, technology, or framework becomes so hard, that it's better to leave it as it is. The application becomes outdated and less competitive due to these factors.&lt;/p&gt;

&lt;p&gt;Each microservice can be developed and deployed independently, which reduces the risk of breaking the whole application or introducing bugs. so they enable experimentation and exploration, as new features, functionalities, libraries, or frameworks can be added or removed easily without affecting the core services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges in a Microservice
&lt;/h2&gt;

&lt;p&gt;While microservices can address many of the challenges in a monolithic architecture, they also introduce new challenges that must be tackled. Some of the common challenges in a microservice architecture are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;As the application comprises multiple services that run on different servers and communicate over the network, it becomes harder to coordinate, monitor, and troubleshoot. The system becomes distributed and asynchronous, which introduces issues such as latency, inconsistency, concurrency, and partial failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As the application relies on multiple services that depend on each other, ensuring availability and quality becomes harder. The system becomes vulnerable to network failures, service failures, data corruption, and inconsistency. The system requires robust mechanisms for fault tolerance, error handling, logging, tracing, testing, and security.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next article, we will go through the process of Designing a microservice architecture, considering various factors, problems, and tradeoffs.&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>softwareengineering</category>
      <category>learning</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Correlating the logs for tracking In NestJs</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Sat, 17 Aug 2024 13:55:02 +0000</pubDate>
      <link>https://forem.com/ashuto7h/correlating-the-logs-for-tracking-in-nestjs-98l</link>
      <guid>https://forem.com/ashuto7h/correlating-the-logs-for-tracking-in-nestjs-98l</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine you’re at the helm of an e-commerce juggernaut—a complex system with multiple services orchestrating tasks like managing user carts, processing orders, handling payments, and tracking shipments. It’s a bustling digital marketplace, and transactions flow seamlessly between these services.&lt;br&gt;
But here’s the catch: With so many moving parts, there’s bound to be a hiccup somewhere. Maybe an order fails to process, a payment gateway misbehaves, or a shipment mysteriously vanishes into the digital ether. When these glitches occur, you need to play detective and trace the breadcrumbs back to their source.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Role of Logs
&lt;/h3&gt;

&lt;p&gt;In this intricate dance of microservices, logs become our trusty companions. Each service diligently records its activities, creating a trail of events. But here’s the twist: In a distributed system, these logs converge into a single timeline—a grand mosaic of actions and reactions. It’s like assembling a jigsaw puzzle, where every piece matters.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Quest for Unique Identifiers
&lt;/h3&gt;

&lt;p&gt;When trouble strikes, we reach for our magnifying glass—the transaction ID or order ID. These unique identifiers are like cosmic coordinates, pinpointing the exact moment when things went awry. Armed with this information, we dive into the logs, hoping to unravel the mystery.&lt;br&gt;
But what if the crucial identifier isn’t there? What if it’s missing from the log where the error occurred? Suddenly, we’re lost in a labyrinth, desperately seeking context. Perhaps the error log stares back at us, cryptic and unyielding. We know something’s amiss, but without that golden thread—the transaction ID—we’re left fumbling in the dark.&lt;/p&gt;

&lt;p&gt;And so, we face the conundrum: How do we bridge the gap between logs and reality? How do we find the elusive context that ties it all together? It’s a challenge that haunts every distributed system engineer—the quest for clarity amidst chaos.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;The solution is to have a &lt;code&gt;correlation ID&lt;/code&gt;.  It’s like a golden thread woven through the fabric of your distributed system. Shared between all services involved in a request or transaction, this ID becomes our beacon. And here’s the magic: By embedding it in every log, we create a breadcrumb trail—a lifeline to the heart of the matter.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Art of Sharing IDs
&lt;/h3&gt;

&lt;p&gt;But how do we pass this mystical ID between services? Fear not; it’s simpler than deciphering ancient scrolls. Here’s the playbook:&lt;br&gt;
&lt;strong&gt;Source Generation&lt;/strong&gt;: The correlation ID starts at the source, which could be the frontend or a backend-for-frontend service. Think of it as a unique mark given to each transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Header Travel&lt;/strong&gt;: As the request travels, it carries an “x-correlation-id” header. This header is like a tiny parchment containing the secret—the essence of our journey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service Adoption&lt;/strong&gt;: Every internal service receives this sacred header. They treat it like a valuable tool, recording it in their logs.&lt;/p&gt;

&lt;p&gt;When an error occurs, we consult the logs. Armed with the correlation ID, we trace all related events through time and find out our culprit.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to do this in Nestjs?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Async local storage
&lt;/h3&gt;

&lt;p&gt;It is a powerful API that simplifies data storage and retrieval across asynchronous operations. Imagine it as a persistent context that spans multiple asynchronous calls, akin to a global variable tailored for a specific asynchronous execution context. With AsyncLocalStorage, you can seamlessly manage state and share data without the complexities of manual bookkeeping. &lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:async_hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create an instance of AsyncLocalStorage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AsyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// run an async operation with context&lt;/span&gt;
&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;isAdmin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this scenario, &lt;code&gt;createUser&lt;/code&gt; represents a sophisticated function that orchestrates multiple asynchronous tasks, such as checking for duplicate users in a database, creating the user, and triggering email verification. The beauty of &lt;code&gt;AsyncLocalStorage&lt;/code&gt; lies in its ability to maintain the &lt;code&gt;{ isAdmin: true }&lt;/code&gt; context across these asynchronous steps. At any point during the user creation process, you can effortlessly retrieve the context value using &lt;code&gt;store.getStore()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isAdmin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach ensures that critical information, like the &lt;code&gt;correlationId&lt;/code&gt;, remains accessible throughout your Node.js application. &lt;/p&gt;

&lt;p&gt;In Express or Nestjs application, you will find it suitable to add this context as a middleware&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// with-context.middleware.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:async_hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ContextStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;correlationId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ContextStore&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withCorrelationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;globalStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;correlationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-correlation-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;v4&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-correlation-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;correlationId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;globalStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are adding a middleware &lt;code&gt;withCorrelationId&lt;/code&gt; which will include the correlation id in a context and&lt;br&gt;
run the &lt;code&gt;next()&lt;/code&gt; middleware or route function within this context.  &lt;/p&gt;

&lt;p&gt;Now we need to add this middleware to our main application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;withCorrelationId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./with-context.middleware&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;debug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withCorrelationId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;// other middlewares or initializers&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port: 3000`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To add this correlation id to any log, we can create a custom logger in winston with &lt;code&gt;TRANSIENT&lt;/code&gt; scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// logging.service.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Scope&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createLogger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winston&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;globalStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./with-context.middleware&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;


&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TRANSIENT&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoggingService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;rootLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createLogger&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

     &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
         &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;correlationId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;globalStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;childLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rootLogger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;child&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="nx"&gt;correlationId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;childLogger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;[]){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;// other log level implementations&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there we have our logger. Use it like a normal logger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;YourService&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoggingService&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

    &lt;span class="nf"&gt;someFunction&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;someAsyncOp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;some error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way we never needed to get the context in every service file. it gets auto logged. &lt;br&gt;
You can also use the context to attach some additional ids or any kind of data to the logging in the middle of the process without passing the data directly to each next function.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>nestjs</category>
      <category>backend</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why do we use OTP libraries when we can just do Math.random()</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Sat, 17 Aug 2024 11:57:57 +0000</pubDate>
      <link>https://forem.com/ashuto7h/why-do-we-use-otp-libraries-when-we-can-just-do-mathrandom-21gg</link>
      <guid>https://forem.com/ashuto7h/why-do-we-use-otp-libraries-when-we-can-just-do-mathrandom-21gg</guid>
      <description>&lt;p&gt;One-time passwords (OTPs) are widely used for authentication and verification purposes in various applications and services. A server usually generates them and sends them to the user via SMS, email, or other channels. The user then enters the OTP to confirm their identity or perform an action.&lt;/p&gt;

&lt;p&gt;I got a task where we had to implement OTP-based verification in Node JS. Before integrating something like this, I am sure most of us developers/engineers look on the Internet for best practices, tutorials, recent technical trends, and problems other major software systems face during their implementations. So I did it, and the thing that most attracted my attention was libraries like &lt;code&gt;otp-lib&lt;/code&gt;, and &lt;code&gt;otp-generator&lt;/code&gt;, whose only function was to generate an OTP. The rest of the tasks like sending it over an SMS or email still need to be done by other means. The first question that comes to mind after knowing that such libraries exist is why we have to go to such lengths to use a library to generate OTP when all we have to do is write a one-liner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;otp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this blog post, I will explain what I learned during our small research for OTP generators, why using Math.random() to generate OTPs is a bad idea, what are other ways to generate an OTP, and why a library should be used for such a task?&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of random numbers
&lt;/h2&gt;

&lt;p&gt;There are mainly two types of random numbers: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pseudo-Random Numbers (PRN)
&lt;/li&gt;
&lt;li&gt;Cryptographic Random Numbers (CRN).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pseudo-Random Numbers
&lt;/h3&gt;

&lt;p&gt;Pseudo-random numbers are generated by an algorithm that takes an initial value, called a seed, and produces a sequence of numbers that appear to be random. However, the algorithm is deterministic, meaning that if you know the seed and the algorithm, you can predict the next number in the sequence. Javascript's &lt;code&gt;Math.random()&lt;/code&gt; and Python's &lt;code&gt;random.randInt()&lt;/code&gt; are an example of a pseudo-random number generator.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cryptographic Random Numbers
&lt;/h3&gt;

&lt;p&gt;Cryptographic random numbers are generated by a process that is unpredictable and cannot be reproduced or guessed. They are usually based on some physical phenomenon, such as atmospheric noise, thermal noise, or quantum effects.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Math.random() works?
&lt;/h2&gt;

&lt;p&gt;Different Javascript engines behave a little differently when generating a random number, but it all essentially comes down to a single algorithm &lt;code&gt;XorShift128+&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;XorShift is a deterministic algorithm, which uses addition as a faster non-linear transformation solution. Compared to its peers, which use multiplication, this algorithm is faster. It also has less chance of failure than Mersenne Twister (used by Python's random module)&lt;/p&gt;

&lt;p&gt;The algorithm takes in two state variables, applies some XOR and shift on them, and returns the sum of the updated state variables which is an Integer. The states are generally seeded using the system clock because that is a good source for a unique number.&lt;/p&gt;

&lt;p&gt;An implementation of XOR shift plus in javascript looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;state0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;state1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;xorShiftPlus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;s0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nx"&gt;state0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="nx"&gt;s0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="nx"&gt;s0&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;state1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned integer is converted to a double using OR operation with a constant. You can find the detailed implementation on &lt;a href="https://chromium.googlesource.com/v8/v8/+/6d706ae3a0153cf0272760132b775ae06ef13b1a/src/base/utils/random-number-generator.h#111" rel="noopener noreferrer"&gt;chrome source code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to predict a random number generated by Math.random()
&lt;/h2&gt;

&lt;p&gt;Predicting the outcome of &lt;code&gt;Math.random()&lt;/code&gt; is hard, however, it is not completely impossible. Knowing the algorithm, you can easily regenerate the same random numbers if you know the values of &lt;code&gt;state0&lt;/code&gt; and &lt;code&gt;state1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Reverse engineering XorShift128+ Using a &lt;a href="https://en.wikipedia.org/wiki/Z3_Theorem_Prover" rel="noopener noreferrer"&gt;Z3 theorem prover&lt;/a&gt; you can find the value of &lt;code&gt;state0&lt;/code&gt; and &lt;code&gt;state1&lt;/code&gt; by providing 3 consecutive random numbers generated by a server.&lt;/p&gt;

&lt;p&gt;The implementation of the Z3 solver can be found &lt;a href="https://github.com/douggard/XorShift128Plus/blob/master/xs128p.py" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now the question comes how to get those 3 random numbers from a server. That's the hard part, and can be obtained in some of the following cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If an API returns a randomly generated number in its response or headers, it can easily be obtained by sending requests at set intervals.&lt;/li&gt;
&lt;li&gt;API documentation like OpenAPI/Swagger in modern applications is generated on the server. Sometimes their responses can contain an example value that uses a random number.&lt;/li&gt;
&lt;li&gt;With frameworks like NextJS that use server-side rendering while also being capable of handling backend API integrations, there are high chances of getting randomly generated numbers from the content served by them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another approach to exploit a random number is using the fact that &lt;code&gt;Math.random()&lt;/code&gt; only returns numbers between 0 and 1 with 16 decimal places. This means that there are only 10^16 possible values that &lt;code&gt;Math.random()&lt;/code&gt; can return. This is a very small space compared to the space of possible OTPs. if your OTP has 6 digits, there are 10^6 possible values. This &lt;a href="https://github.com/lordpoint/xorshift-sandbox-and-visualizer" rel="noopener noreferrer"&gt;visualizer&lt;/a&gt; shows that there is a pattern to the numbers generated. Using it, the possibilities can be reduced by 30%. Therefore, if you can guess or brute-force some of the digits of the OTP, you can reduce the space of possible values and increase your chances of finding the correct OTP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating a Cryptographic Random Number in NodeJS
&lt;/h2&gt;

&lt;p&gt;As mentioned previously, cryptographic random numbers are non-deterministic because they depend on the physical factors of a system. Every programming language can access those factors using low-level OS kernel calls.&lt;/p&gt;

&lt;p&gt;NodeJS provides its inbuilt crypto module, which we can use to generate randomBytes and then convert them to a number. These random bytes are cryptographic and purely random in nature. The generated number can easily be truncated to the exact number of digits we want in OTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// num.toString().slice(0,4)  // truncate to 4 digits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NodeJS 14.10+ provides another function from crypto to generate a random number in a given min-max range.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even after knowing the vulnerability of &lt;code&gt;Math.random()&lt;/code&gt; and finding a more secure way to generate a random number cryptographically, we still remain with the same question from the beginning. Why do we have to go to such lengths to use a library to generate OTP when all we have to do is write a one-liner?&lt;/p&gt;

&lt;p&gt;Before answering this questions, let's take a look at what is the inconvenience faced while handling and storing an OTP. The problem with using the above method to generate OTPs is that you have to store them in the database in order to verify them later. Storing the OTP in the database is not a good practice for the following reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Storing OTPs in the database creates a lot of garbage data that has to be cleaned up periodically. OTP means a one-time password that can expire after a single use. It can also expire if not used for a specific duration or a new OTP is requested without using the previous one. This mainly adds unnecessary overhead to the database operations for maintaining valid OTPs while also consuming storage space.&lt;/li&gt;
&lt;li&gt;Storing OTPs in the database poses a security risk if the database is compromised. An attacker who gains access to the database can read the OTPs and use them to bypass the authentication or verification process. This can lead to account takeover, identity theft, or fraud.&lt;/li&gt;
&lt;li&gt;Storing OTPs in the database makes them vulnerable to replay attacks. A replay attack is when an attacker intercepts an incoming valid OTP and uses it again before it expires. This can allow the attacker to perform unauthorised actions or access sensitive information.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What do the OTP libraries do differently?
&lt;/h2&gt;

&lt;p&gt;The OTP libraries use different algorithms and techniques to generate and verify OTPs that behave similarly to a Cryptographic random OTP, while also removing the overhead to store the OTP in a database.&lt;/p&gt;

&lt;p&gt;There are mainly two types of OTP implementation techniques.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HOTP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;HOTP stands for HMAC-based One-Time Password. It is an algorithm that generates an OTP based on a secret key and a counter. The secret key is a random string that is shared between the server and the user. The counter is an integer that increments every time an OTP is generated or verified.&lt;/p&gt;

&lt;p&gt;The algorithm works as follows:&lt;/p&gt;

&lt;p&gt;• The server and the user generate the same OTP by applying a cryptographic hash function, such as SHA-1, to the concatenation of the secret key and the counter.&lt;br&gt;
• The server and the user truncate the hash value to obtain a fixed-length OTP, usually 6 or 8 digits.&lt;br&gt;
• The user sends the OTP to the server for verification.&lt;br&gt;
• The server compares the OTP with its own generated OTP and verifies it if they match.&lt;br&gt;
• The server and the user increment their counters by one.&lt;/p&gt;

&lt;p&gt;HOTP is mostly used in hardware token-based authentication like &lt;a href="https://www.yubico.com/products/how-the-yubikey-works/" rel="noopener noreferrer"&gt;Yubikey&lt;/a&gt;. Yubikey is basically a programmed hardware key that you can connect physically to your computer or phone. Instead of receiving a code from SMS, or email, you can just press a button on Yubikey to verify and authenticate yourself.&lt;/p&gt;

&lt;h4&gt;
  
  
  The advantages of HOTP are:
&lt;/h4&gt;

&lt;p&gt;• It does not require storing the OTP in the database, as it can be generated and verified on the fly.&lt;br&gt;
• It does not rely on pseudo-random numbers, as it uses a cryptographic hash function that is unpredictable and irreversible.&lt;br&gt;
• It is resistant to replay attacks, as each OTP is valid only once.&lt;/p&gt;

&lt;h4&gt;
  
  
  The disadvantages of HOTP are:
&lt;/h4&gt;

&lt;p&gt;• It requires synchronization between the server and the user's counters. If they are out of sync, due to network delays, transmission errors, or device loss, the verification will fail.&lt;br&gt;
• It remains valid as long as a newly generated HOTP is not used, that can be a vulnerability.&lt;br&gt;
• It requires a secure way to distribute and store the secret keys. If the secret keys are leaked or stolen, the OTPs can be compromised.&lt;/p&gt;

&lt;h3&gt;
  
  
  TOTP
&lt;/h3&gt;

&lt;p&gt;TOTP stands for Time-based One-Time Password. It is an algorithm that generates an OTP based on a secret key, timestamp, and epoch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The secret key is a random string that is shared between the server and the user. It can be created uniquely for each user by generating &lt;code&gt;SHA1( "secretvalue" + user_id )&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;  The timestamp is an integer that represents the current time in seconds&lt;/li&gt;
&lt;li&gt;  The epoch is the duration for which the algorithm will generate the same result. generally, it is kept between 30 sec - 1 min.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The algorithm works as follows:&lt;br&gt;
• The server decides a secret key for the user and shares it over a medium like Authenticator apps.&lt;br&gt;
• The server can directly generate an OTP and send it to the user by mail or SMS, or it can ask the user to use an Authenticator to generate an OTP using the shared key.&lt;br&gt;
• The user can directly send the OTP received by mail or SMS or can generate it in the authenticator app in case of 2FA in a fixed time window.&lt;br&gt;
• The server compares the OTP with its own generated OTP and verifies it if they are close enough in the epoch time range.&lt;/p&gt;

&lt;h4&gt;
  
  
  The advantages of TOTP are:
&lt;/h4&gt;

&lt;p&gt;• It does not require storing the OTP in the database, as it can be generated and verified on the fly.&lt;br&gt;
• It does not rely on pseudo-random numbers, as it uses a cryptographic hash function that is unpredictable and irreversible.&lt;br&gt;
• It is resistant to replay attacks, as each OTP is valid only for a short period of time.&lt;br&gt;
• It does not require synchronisation between the server and the user's timestamps. As long as they have reasonably accurate clocks, they can generate and verify OTPs independently.&lt;/p&gt;

&lt;h4&gt;
  
  
  The disadvantages of TOTP are:
&lt;/h4&gt;

&lt;p&gt;• It requires a secure way to distribute and store the secret keys. If the secret keys are leaked or stolen, the OTPs can be compromised.&lt;br&gt;
• It requires a reliable source of time for both the server and the user. If their clocks are skewed or tampered with, the verification will fail.&lt;br&gt;
• The server has to consider the time drift or delay in processing the requests, so it should maintain a slightly greater epoch than the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Through our little research journey on the OTP, we came to know that &lt;code&gt;Math.random()&lt;/code&gt; can be predicted, exploited, and replayed. We also got to know that storing OTPs in the database is not a good practice.&lt;/p&gt;

&lt;p&gt;TOTP can generate secure and efficient OTPs, and can also verify them. It can generate an OTP offline as well as online, does not require synchronization or storage, and is resistant to replay attacks. Thus it solves most of our concerns related to best practices, security, and reliability.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>node</category>
    </item>
    <item>
      <title>Creating a Chess Engine from Scratch</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Sat, 23 Mar 2024 06:04:03 +0000</pubDate>
      <link>https://forem.com/ashuto7h/creating-a-chess-engine-from-scratch-hcf</link>
      <guid>https://forem.com/ashuto7h/creating-a-chess-engine-from-scratch-hcf</guid>
      <description>&lt;p&gt;I am writing this article as a Journal to keep a record of my progress so far in this experimental project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory and Inspiration
&lt;/h2&gt;

&lt;p&gt;I have been dumb at playing chess since childhood. I never won against a good opponent. even at the easiest level in a mobile game. I found some system design notes and problems. I enjoyed solving LLD (low-level design) problems in my mind and then reading the solution to check the depth of my knowledge. I came across designing a chess board game. And the design was very much what I thought, from creating an abstract class for a Piece, and inheriting other Pieces from it, each class will have its methods to move a piece and calculate the score on moving that Piece. Still, I have many questions unanswered after that like: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is chess so simple to design using OOP concepts? Do modern games do it like this?

&lt;ul&gt;
&lt;li&gt;I think it is what they do. What other ways could be there?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;How do they manage levels in a chess game?

&lt;ul&gt;
&lt;li&gt;If I had to guess, they take the top 10 moves with high scores and based on level choose the move to play.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Is chess AI nothing, only a set of rules to decide a move with a high score?

&lt;ul&gt;
&lt;li&gt;This is something I had to discover, and I found that there is nothing like AI, it's just some advanced algorithms like minimax/negamax, alpha-beta pruning, etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyway, I decided that I would test myself If I could make a chess game that beats me. I chose &lt;strong&gt;Go&lt;/strong&gt; as the programming language because I have only learned the basics of it, and this would enhance my skills. I chose fyne.io as the GUI framework because It was the only one with some good looking easy documentation. &lt;/p&gt;

&lt;h2&gt;
  
  
  Finding the best move
&lt;/h2&gt;

&lt;p&gt;I want to keep it simple in the beginning. We will go with only 1 layer, searching for all the next possible moves&lt;br&gt;
I found two cases where I need to calculate the score:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A piece shouldn't move&lt;/li&gt;
&lt;li&gt;A piece should move &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think We eventually have to move a piece. so to simplify it, I came up with the following idea.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if a piece moves

&lt;ul&gt;
&lt;li&gt;calculate its score&lt;/li&gt;
&lt;li&gt;calculate other pieces loss if this one moves.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;final score = sum of both scores&lt;/li&gt;
&lt;li&gt;move the piece with the highest score&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scoring mechanism
&lt;/h2&gt;

&lt;p&gt;I searched for scoring in chess and found that Rook is given more importance than the horse and bishop. &lt;br&gt;
I think this choice is different from player to player. from my point of view, I will give my Rook to capture the opponent's Knight or Bishop. so they all should have equal scores.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a piece gives check to king +20&lt;/li&gt;
&lt;li&gt;a piece captures pawn +20&lt;/li&gt;
&lt;li&gt;a piece captures rook +30&lt;/li&gt;
&lt;li&gt;a piece captures horse +30&lt;/li&gt;
&lt;li&gt;a piece captures bishop +30&lt;/li&gt;
&lt;li&gt;a piece captures queen +40&lt;/li&gt;
&lt;li&gt;a piece captures king +50&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a piece removes check on king +50&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pawn reaches last row +20&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pawn has a threat from someone on reaching a position -30&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rook, Bishop, Knight has threat on reaching a position -40&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Queen has a threat on reaching a position -40&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;King has a threat on reaching a position -50&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Giving check to the king is only 20 points because what if your Queen is giving check to the king, but is also in danger. so I kept it minimum.&lt;br&gt;
Initially, I started scoring from 10 points but changed it to 20. I realized that there will be a situation when the Pieces will try to keep their distance from one another, and this will result in a draw. so I will calculate the absolute distance of a piece from its nearest enemy and subtract its score from that distance.&lt;br&gt;
Getting yourself captured is considered a loss, and to minimize it, I increased the loss score by +10&lt;br&gt;
That's simple to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  March 17, 2024
&lt;/h2&gt;

&lt;p&gt;I decided that I wanted to make a cross-platform application, with a stack that I don't know. so that I will be able to learn it. I spent the whole day creating the board design in Fyne. It's not that simple, the framework is evolving but It doesn't give me what I wanted. I tried to put 64 cells in an 8x8 grid and resize all cells to 50x50 but the resize was not working. I checked many answers on stack overflow related to resizing but nothing worked. Later I found a video on YouTube, the person there did something different from what I was doing (still using the resize function) and it worked. I got super annoyed by it. As you can see I have so much going on in mind related to chess scoring, capturing pieces, and designing with the software principles I learned, and I am stuck on a UI issue. With this, I will not be able to go anywhere.&lt;/p&gt;

&lt;p&gt;So I went to look for other options the other day. The next language is Python. I found QT and Tkinter frameworks. I have made a small tik-tak-toe game in Tkinter in the past, and it's good too. But QT is the most advanced and popular, so I went to look at its documentation and It's nothing in comparison to React UI libraries / tkinter / Fyne / Flutter. There is no good visual tutorial, only references to the API, and It's huge. I don't want to go with tkinter because it's very basic, like fyne and I am afraid I will get stuck there too. &lt;/p&gt;

&lt;p&gt;The next I know is flutter/dart. I have worked previously on it and it's great. It now supports build for desktops too and has very flexible widgets that you can style as you want. But I need to reinstall and set it for desktop and mobile builds. I can't do that, because it will take a whole day also and I will not be able to put my ideas into code. I needed something fast. So I decided that I would fall to React/JS for making the game and then rewrite the logic on Flutter later. &lt;/p&gt;

&lt;p&gt;And I think I made the right choice. Making the game on React was so fast because designing the chess board was very easy due to all the HTML and CSS. I made all chess piece classes, wrote the move and scoring logic for all of them, and made it run. So far, everything in my head is in the code now. Now I can take a sleep.&lt;/p&gt;

&lt;p&gt;The game is very nice, playing by the rules. It can beat me at this point, just like any other Chess game out there. For debugging I added the score so when I click on a piece, it shows me the score of that piece if it moves to one of the movable cells.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2pz8mwc58u7g2t1zac9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2pz8mwc58u7g2t1zac9.png" alt="Chess game progress 1" width="606" height="588"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkgf94uz5vehllnxq3of.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkgf94uz5vehllnxq3of.png" alt="Chess game progress 2" width="587" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a few things left to add to it like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adding the castling (king and rook interchange position) move&lt;/li&gt;
&lt;li&gt;detecting a checkmate or draw and stopping the game there&lt;/li&gt;
&lt;li&gt;adding the history of moves and undo functionality&lt;/li&gt;
&lt;li&gt;adding animation for a move&lt;/li&gt;
&lt;li&gt;load the game from a saved file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I realized I am missing 1 thing, which is the motivation to move a pawn. moving it forward will help to promote it, but for the time it needs to be protected well too. That is hard to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  March 18, 2024
&lt;/h2&gt;

&lt;p&gt;Last night, my game was almost complete, so now I had the question can It beat any other chess AI out there? Of course not. Now I have two more questions to answer: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What do other chess game engines do differently?&lt;/li&gt;
&lt;li&gt;Is chess AI a real thing or it's just some more better algorithm?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I spent the whole night on Internet looking for answers. I found that other chess engines have different scoring mechanisms than mine and different strategies to decide the moves. &lt;/p&gt;

&lt;p&gt;One such &lt;a href="https://andreasstckl.medium.com/writing-a-chess-program-in-one-day-30daff4610ec"&gt;implementation&lt;/a&gt; is to assign a fixed score to every position for a piece, then for each move calculate the sum of all your scores and your opponent score. subtract them to get your score for that move. I am not going with that idea because I cannot understand the &lt;a href="https://www.chessprogramming.org/Simplified_Evaluation_Function"&gt;piece square table&lt;/a&gt;. As this is a stationary table and pieces can move anywhere on the board. &lt;/p&gt;

&lt;p&gt;But this gave me the idea of making my algorithm better. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;trial 1&lt;/strong&gt;: I will try to find all moves, for each move, calculate your and the enemy's total score from all pieces, and subtract them to get the final score.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Implementation also uses minimax and alpha-beta pruning which I am not going to use until I understand those two completely.&lt;/p&gt;




&lt;p&gt;I keep looking for AI Chess engine implementation and found about &lt;a href="https://stockfishchess.org/"&gt;Stockfish&lt;/a&gt;, and &lt;a href="https://lczero.org/"&gt;Leela Chess Zero(LC0)&lt;/a&gt;. I found that LC0 uses MCTS (Mont-Carlo Tree Search). It's another term I don't want to know about. Because when I hear AI, I want to hear tensorflow/keras in play.&lt;/p&gt;

&lt;p&gt;And so I changed the search prompt a little to "Neural Network Based Chess Engine". &lt;br&gt;
I found this &lt;a href="https://github.com/undera/chess-engine-nn"&gt;repository&lt;/a&gt; which has the Journal of the Chess Engine Progress, I liked reading it and decided that I will maintain my journal too. And so I am writing all this stuff.&lt;/p&gt;

&lt;p&gt;At first, I wasn't clear about the way he had implemented it. For creating a neural network, what I need is an input layer, output layer, optimizer, and loss function. I was able to get all those from his Journal except the output layer. I was thinking what will be the target we have to predict and what will the output layer give us? How the NN will help us find the best move? Then I found &lt;a href="https://erikbern.com/2014/11/29/deep-learning-for-chess"&gt;DeepPink&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was a similar implementation as his journal. I found the output is in the form of -1,0,1, where -1 is lose, 0 is draw, and 1 is win. &lt;br&gt;
Still after reading all this. I am not able to completely grab everything, like the evaluation function they used. It's just that I don't understand that level of mathematics. &lt;/p&gt;

&lt;p&gt;Also about the dataset, they use PGN format, It's good, but I am not sure how to make my matrix using that format now. For now, I will generate my own data, if I need more data then I will think of visiting PGN again.&lt;/p&gt;




&lt;p&gt;Here is what I am going to do:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;trial 3&lt;/strong&gt;: The data is going to be generated by keeping a record of all moves of both the players in 8 x 8 x 12 matrix form which tells the position of 12 pieces across an 8x8 board. after the result of the game, there will be three targets assigned to the moves: 'win', 'lose', 'draw'&lt;br&gt;
example: if p1 wins, all moves of p1 will be labelled as win.&lt;/p&gt;

&lt;p&gt;I will train it using relu, categorical cross entropy, hidden layers not decided, the output will be dense(3)&lt;/p&gt;

&lt;p&gt;For prediction, I will find all 1st-level possible moves from the current state of the board. I am not going deeper to get more moves. I will feed all those moves to my NN. for each prediction output will be three numbers, showing the probability of win, lose, and draw. if a win is available, the highest win probability is selected. else if the draw is available, the highest draw probability move is selected, and else lowest loss probability move is selected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before I do that, I want to try other classification algorithms, like decision trees. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;trial 2&lt;/strong&gt;: for that I will convert the data to 2d table, with 1 hot encoding all the dimensions of 8x8x12 and drop 1 column. this will give me 7+7+11 = 25 features&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also had the thought to use the score as a parameter in training, but then the results will be highly biased towards the score. so I am dropping this Idea.&lt;/p&gt;




&lt;h2&gt;
  
  
  March 19, 2024
&lt;/h2&gt;

&lt;p&gt;Woke up this morning with a new Idea. Chess is a sequence of moves, where you can play a certain move only based on the outcomes of all previous moves. so it's like an NLP problem, isn't it? We can represent the chess board in the form of a long sentence and for each move, we will have to predict the next word in that sentence. &lt;br&gt;
For this, I am going to make the data repetitive. like if a game has 10 moves, I will make 10 strings, adding 1 move to the previous one. and then annotate them with a win, lose, or draw based on what player played the move. &lt;br&gt;
The problem now is how can I represent the whole board as a sentence, and if I get the next word in a sentence, how will I convert it back to a move? Was looking on the internet for any such approach and found this &lt;a href="https://towardsdatascience.com/watching-a-language-model-learning-play-chess-f6e6c0e094c"&gt;article&lt;/a&gt; and some other research papers. It's simply a PGN format. However, the format itself is a little ambiguous to me. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;trial 4&lt;/strong&gt;  I will modify the PGN format a little to include the piece type at the beginning of the word. Since training a case-sensitive model is not good enough, I will change the piece type notation from k K to bk wk for representing black king and white king. &lt;br&gt;
A problem that I identified with NLP is what if the predicted word is impossible move? While training, we will add a custom loss function that will increase the loss if the generated move is impossible. and if an impossible move occurs in prediction, we will have to fall back to best best-scoring move. I will not use transfer learning for this, because I think I am feeding a completely different language, one which is not used for communicating.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>deeplearning</category>
      <category>machinelearning</category>
      <category>go</category>
      <category>react</category>
    </item>
    <item>
      <title>#P5 - Data Visualization</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Fri, 23 Jul 2021 06:52:25 +0000</pubDate>
      <link>https://forem.com/ashuto7h/p4-data-visualization-264p</link>
      <guid>https://forem.com/ashuto7h/p4-data-visualization-264p</guid>
      <description>&lt;p&gt;Data visualization is the graphical representation of information and data by means of various graphs, charts and diagrams that helps to understand and get relevant information from data. We will see how they help to get various informations.&lt;/p&gt;

&lt;p&gt;In python, there are some libraries that provide data visualization utilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Matplotlib
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//github.com/matplotlib/matplotlib"&gt;view on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Matplotlib is a plotting library for the Python programming language and its numerical mathematics extension NumPy. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits like Tkinter, wxPython, Qt, or GTK. SciPy, Pandas and seaborn are another libraries that depends on Matplotlib.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Seaborn
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/mwaskom/seaborn" rel="noopener noreferrer"&gt;view on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seaborn is just a wrapper library based on matplotlib. It provides a high-level interface for drawing attractive and informative statistical graphics. Means you can draw the graphs similar to seaborn with matplotlib, with just some extra piece of code. It provides various color schemes and themes.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Plotly
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/plotly/plotly.py" rel="noopener noreferrer"&gt;view on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plotly is an interactive graphing library that provides you the ability to interact with the graph, such as getting x and y axis by hovering the objects, enlarging, reducing, highlighting an area etc.. It is the best analytical tool as compared to above two, but also slow and much more resource consuming. &lt;/p&gt;

&lt;p&gt;You can check their well versed documentations for various customization in graph. This article contains very few code examples.&lt;/p&gt;

&lt;h1&gt;
  
  
  Types of Plots and Charts
&lt;/h1&gt;

&lt;p&gt;Almost everyday we see some analytics in a newspaper, TV, mobile application or on some website. Commonly we know about bar charts or pie charts, but there are many other types of visualization plots. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Scatter Plot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scatterplot visualize the scatter of data values of two features.&lt;/li&gt;
&lt;li&gt;It Used to find a relationship in a bivariate data, more commonly used to find correlations between two continuous variables.
```py
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;import seaborn&lt;br&gt;
import matplotlib.pyplot as pyplot&lt;br&gt;
seaborn.scatterplot(data = df, x = 'col1' y = 'col2')&lt;br&gt;
pyplot.show()&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qlnpxarca43pzdqhcqf.png)

## 2. Line Plot
- Line Plot is a univariate analysis plot. It creates a line that connects all data points.
- It is very useful for the observation of trend and time series analysis. 
```py


sns.lineplot(data=df, x="year", y="passengers")


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eocpti3dz56gso5asad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eocpti3dz56gso5asad.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Bar Plot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bar Plots use bars with different height to represent data values.&lt;/li&gt;
&lt;li&gt;They are used mainly for ranking values.&lt;/li&gt;
&lt;li&gt;They are mostly used with data having less distinct values. 
```py
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;sns.barplot(x="tips", y="day", data=df) &lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjysdb6xngyc2y5h04m5.png)

## Histogram (Hist Plot)
- histograms are used to observe the distribution for a single variable.
- They are used to identify the type of data distribution of a variable.

```py


seaborn.histplot(data, x="distance")


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgxmv2w5zkexl4x73nrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgxmv2w5zkexl4x73nrg.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
You can also see the kernel density estimation in Histplot by passing parameter kde=True.&lt;/p&gt;
&lt;h2&gt;
  
  
  Box Plot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A box plot also called a Whisker and box plot displays the five-number summary of a set of data, including  minimum, 25th quartile, median, 75th quartile, and maximum. &lt;/li&gt;
&lt;li&gt;It helps in various kind of analysis like outliers.
```py
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;seaborn.boxplot(data, x = "day", y = "total bill")&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6enmmmj7s5e7qmh3e72h.png)

## Violin Plot
- A violin plot is a more comprehensive box plot containing the KDE (kernel density estimation) lines alongsides the whiskers.
```py


seaborn.violinplot(data, x = 'cat_var', y = 'num_var')


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzao5eqo0apsdntibn8om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzao5eqo0apsdntibn8om.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Pair Plot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A pair plot shows all numerical pair relations along with their frequency distribution at diagonals.
```py
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;seaborn.pairplot(df, hue = 'species')&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13rerr0cpdo227m30v84.png)

## Heatmap
- The heatmap is already demonstrated in previous article of this series. It can take any 2d data and show it in form of grid of various color intensity.

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvx64ar9yixbi0czh7oy.png) 

There are many other type of visualizations which can be used as per the need, but above these are the most informative ones.

## Subplots
There is a good article on subplots, you can see it here

&lt;div class="ltag__link"&gt;
  &lt;a href="/thalesbruno" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F188803%2F4dbbca19-5163-4e50-958e-bf13b0c0dcae.jpg" alt="thalesbruno"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/thalesbruno/subplotting-with-matplotlib-and-seaborn-5ei8" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Subplotting with matplotlib and seaborn&lt;/h2&gt;
      &lt;h3&gt;Thales Bruno ・ Jun 21 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#datascience&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;Or you can go with the subplot constructors&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pyplot&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seaborn&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pyplot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;pyplot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;seaborn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;violinplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pyplot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;seaborn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;violinplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pyplot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;seaborn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;violinplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>datascience</category>
    </item>
    <item>
      <title>#P4 - Data Preprocessing</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Fri, 11 Jun 2021 08:30:50 +0000</pubDate>
      <link>https://forem.com/ashuto7h/p4-data-preprocessing-44lo</link>
      <guid>https://forem.com/ashuto7h/p4-data-preprocessing-44lo</guid>
      <description>&lt;p&gt;In the previous articles, we have seen a simple example of how machine learning helps us to predict a target. There are many algorithms and ways to train a model, but all they need is data. whenever we take data from the real world, it always contains some irregularities. Data preprocessing is the first and foremost step after acquiring data which is used to put data in the desired format so that the model can be trained on it.&lt;/p&gt;

&lt;p&gt;The whole process is known as EDA (Exploratory Data Analysis). EDA also includes visualizing data using various types of visualization techniques. we will cover them in the next part.&lt;/p&gt;

&lt;p&gt;There is a great article on data preprocessing &lt;a href="https://towardsdatascience.com/data-preprocessing-concepts-fa946d11c825"&gt;see it here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When we talk about data in Machine learning, we always think of data in form of a table consisting of rows and columns. columns depict features and rows depict attributes of these features.&lt;/li&gt;
&lt;li&gt;There are other types of data like JSON files, they contain information in the form of embedded documents and fields.&lt;/li&gt;
&lt;li&gt;There is one more type of data that is completely unstructured, unlike the above two types. i.e. image, video, and other such files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;here we are only discussing the first type of data and its preprocessing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Steps of Data preprocessing
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Gathering Business Knowledge
&lt;/h2&gt;

&lt;p&gt;Business knowledge is the most important thing while preprocessing data. It is often underestimated, but it matters most of the time.&lt;br&gt;
Let's consider that a dataset contains a feature country. In that feature, Some entries are written as the &lt;code&gt;UK&lt;/code&gt; while others are written as &lt;code&gt;United Kingdom&lt;/code&gt;. Now both are the same, but if we don't have business knowledge then we can not figure this thing out, and this will eventually lead to wrong training.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Data Exploration
&lt;/h2&gt;

&lt;p&gt;Data Exploration means exploring various aspects of data. following are certain ways to do so in python - &lt;/p&gt;
&lt;h3&gt;
  
  
  a. describe()
&lt;/h3&gt;

&lt;p&gt;when we import a dataset in python using pandas, it is stored in an object called DataFrame. the DataFrame object has various inbuilt methods among which describe() function gives the detailed statistics of numerical features of the dataset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;path/to/csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The describe() function returns a dataframe object in following format.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8i4p1cab89gk0w3llota.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8i4p1cab89gk0w3llota.png" alt="describe" width="449" height="277"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, It tells about &lt;code&gt;count&lt;/code&gt;, &lt;code&gt;mean&lt;/code&gt;, &lt;code&gt;standard deviation(std)&lt;/code&gt;, &lt;code&gt;mode&lt;/code&gt;,&lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt; and spread of values at 25%, 50%, 75%.&lt;/p&gt;
&lt;h3&gt;
  
  
  b. info()
&lt;/h3&gt;

&lt;p&gt;info() is another function provided by the dataframe object, which shows all the features with their data types and no. of values in each feature.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyvy1vfqe651k2e86wvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyvy1vfqe651k2e86wvh.png" alt="info" width="461" height="364"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  c. Pandas Profiling
&lt;/h3&gt;

&lt;p&gt;This is a much better way than the above two because it extracts almost all the information required to better explore the data. pandas profiling is a separate library from pandas.&lt;/p&gt;

&lt;p&gt;To install or upgrade it, use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pandas-profiling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then use it as follows -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;profile_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;explorative&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;filename&amp;gt;.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the pandas profiling generates an HTML report format that gives you various insights for each feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Missing Values Imputation
&lt;/h2&gt;

&lt;p&gt;It is very common to have missing values in the datasets. Mostly they are caused because peoples do not like to fill every detail of the form. Sometimes it can also be caused by machine errors such as irregular functioning of a sensor or a device collecting data.&lt;br&gt;
Be aware, because many times, the missing values can appear in other forms than an empty cell in a table.&lt;br&gt;
Mostly when some fields are marked necessary, and people don't want to fill them, they use characters like &lt;code&gt;-&lt;/code&gt; or &lt;code&gt;?&lt;/code&gt; or &lt;code&gt;NIL&lt;/code&gt;. In the case of data gathered by devices, they have some default values in place of null like &lt;code&gt;-1&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;-99&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Look for frequencies of such values. if they mostly occur in your dataset, you can consider them as &lt;code&gt;NaN (Not a Number)&lt;/code&gt;. You can replace these values with NaN or can directly interpret them as NaN while loading the dataset for the first time with pandas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;na_values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;na_values&lt;/code&gt; replaces all values that match in given list and change them to NaN.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting count of all missing values.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isna&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Handling missing values
&lt;/h3&gt;

&lt;p&gt;There are mainly two ways to handle such values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remove the observations(rows) containing them.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# select only those observation for a given column that 
# don't have a Null or Nan value.
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;column&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;notna&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this option should be used when we have a very large dataset, and no. of rows removed after this operation will not affect much.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remove the whole column.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This option should be used only when the no. of missing values are too much ( &amp;gt; 50%) in a column.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Impute missing values with the central tendencies of data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;central tendency is a central or typical value for a probability distribution. It may also be assumed that the whole data lies at the center or location of the distribution.&lt;/p&gt;

&lt;h4&gt;
  
  
  When data is numerical
&lt;/h4&gt;

&lt;p&gt;there are two ways to find the central tendency. Mean and Median.&lt;br&gt;
Mean should be chosen only when the data is distributed uniformly. Suppose if you have most of the values like 100,150,200,250 and only few like 800 then mean of these values will be 300, but median will be 200. Now, if we see, the metric which can approximately give us the central tendency is median in this case.&lt;br&gt;
so whenever, there is a large difference in mean and median, we should choose median.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  When data is categorical
&lt;/h4&gt;

&lt;p&gt;Central tendency lies with most frequent category in such cases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Outlier Treatment
&lt;/h2&gt;

&lt;p&gt;an outlier is a data point that differs significantly from other observations. &lt;/p&gt;

&lt;p&gt;Outlier in scatter plot -&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx6y6soex6q9w8bg8crs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx6y6soex6q9w8bg8crs.png" alt="scatter" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outlier in Box plot -&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzvnlnrcifad4m15aftq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzvnlnrcifad4m15aftq.png" alt="box" width="560" height="420"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;image source: google&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;we will cover the plotting of these graphs in next part.&lt;br&gt;
Outliers can decrease performance of model. They should be removed or treated.&lt;br&gt;
&lt;strong&gt;IQR (Inter-Quartile Range):&lt;/strong&gt; The Inter-Quartile Range is just the range of the quartiles: the distance from the largest quartile to the smallest quartile, &lt;br&gt;
largest quartile is median of upper half of data and lowest quartile is median of lower half of data. We remove the values which exceeds this range.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5q7xpotcksngt6p3ee90.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5q7xpotcksngt6p3ee90.png" alt="iqr" width="443" height="165"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;image source: google&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lowest quartile 
&lt;/span&gt;&lt;span class="n"&gt;q1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;quantile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;q2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;quantile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;q3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;quantile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;iqr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;q1&lt;/span&gt; 

&lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;iqr&lt;/span&gt;
&lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;qr&lt;/span&gt;

&lt;span class="c1"&gt;# remove
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="ow"&gt;or&lt;/span&gt; 
&lt;span class="c1"&gt;# replace with median
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Variable Transformation
&lt;/h2&gt;

&lt;p&gt;Sometimes, a single feature or attribute contains multiple values. &lt;br&gt;
example -&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgi03z273sjajq859aqq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgi03z273sjajq859aqq9.png" alt="value example" width="155" height="57"&gt;&lt;/a&gt;&lt;br&gt;
Normalization is a concept in DBMS in which a database is said to be in first normal form, if it contains atomic values (value that cannot be divided). To solve such kind of problems, you can refer to &lt;a href="https://stackoverflow.com/questions/12680754/split-explode-pandas-dataframe-string-entry-to-separate-rows"&gt;stackoverflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another problem that is observed is dealing with dates. A date object is always represented in form of strings. we can use pandas to extract year, month, day, week etc from the date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;year&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;month&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;day&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;week&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;week&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Seasonality
&lt;/h2&gt;

&lt;p&gt;Seasonality is a characteristic of a time series in which the data experiences regular and predictable changes that recur every calendar year. Any predictable fluctuation or pattern that recurs or repeats over a one-year period is said to be seasonal. The most easy example is Rainfall.&lt;/p&gt;

&lt;p&gt;Any feature of dateset that shows seasonality with time, can cause instability to the model because it never shows a clear relationship with output. So if the target is itself not a seasonal value (models exist for such predictions) then we should remove seasonality from such data. &lt;/p&gt;

&lt;p&gt;A common way to deal with seasonal data is to use differencing. If the season lasts for a week, then we can remove it on an observation today by subtracting the value from last week.&lt;br&gt;
Similarly, if a season cycles in a year, like rainfall then we can substract the daily maximum rainfall from same day last year to correct seasonality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;seasonality&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9duagsuw8jj015g6jc4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9duagsuw8jj015g6jc4n.png" alt="seasonality" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;after removing seasonality&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3iqz3c9g90x3l221e07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3iqz3c9g90x3l221e07.png" alt="sremove" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;image source :&lt;/strong&gt; &lt;a href="https://machinelearningmastery.com/time-series-seasonality-with-python/"&gt;machinelearningmastery.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  7. Bivariate / Correlation Analysis
&lt;/h2&gt;

&lt;p&gt;Bivariate analysis is a quantitative analysis, which involves two variables for determining the empirical relationship between them.&lt;br&gt;
This can be done drawing plots between two variables and check their distributions.&lt;/p&gt;

&lt;p&gt;correlation or dependence is a statistical relationship between two variables or bivariate data. Correlation referes to the degree to which a pair of variables are linearly related. a positive correlation shows that the variables are directly proportional while negetive shows that they are inversely proportional. Value of correlation coefficient lies between -1 to 1 only. &lt;br&gt;
&lt;strong&gt;correlation formula&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmy9la6tcaipe5wkckig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmy9la6tcaipe5wkckig.png" alt="correlation" width="367" height="279"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  why should we remove higher correlation features?
&lt;/h3&gt;

&lt;p&gt;correlation measures only the association between the two variables. It doesn't tells causation. i.e., large values of y is not caused by large values of x. When we have highly correlated features in the dataset, the variance will also become high. this causes instability in model. The model becomes sensitive towards these values and slight changes in them affects the whole model.&lt;br&gt;
So it is better to drop any one feature if two features are showing a higher correlation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pyplot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;seaborn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heatmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;corr&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;annot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.2f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;linewidths&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Dark2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;output&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fdvk0xqcn8lywxjrvvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fdvk0xqcn8lywxjrvvh.png" alt="correlation" width="711" height="645"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;image source : google&lt;/strong&gt;&lt;br&gt;
The heatmap shows the correlation values of all the features with others. We can analyse which two feature are highly correlated and remove any one of them.&lt;/p&gt;
&lt;h2&gt;
  
  
  8. Label Encoding
&lt;/h2&gt;

&lt;p&gt;Before moving further we have to recognise what categorical data is. Many times we think that if a variable is in the form of objects(strings) then it is a categorical variable. &lt;br&gt;
suppose a dataset contains a feature year, which depicts only 3 distinct years - 2008, 2009, 2010. Are these values categorical or numerical? &lt;br&gt;
They are categorical values, but their numerical interpretation is a problem for model. Also the model can only work over numerical data. That means we cannot use categorical data containing strings. To use such features, we have to transforming them into numerical form.&lt;br&gt;
For example, we map our categorical data to simple counting numbers like 0,1,2,3...&lt;br&gt;
This is called label encoding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LabelEncoder&lt;/span&gt;
&lt;span class="n"&gt;le&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LabelEncoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;year&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;le&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;year&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if the categories are ordinal? we have to encode them in an order. example, if a dataset contains some grades from &lt;code&gt;A&lt;/code&gt;to &lt;code&gt;D&lt;/code&gt;, which are correlated to marks. &lt;code&gt;A&lt;/code&gt; means good marks, &lt;code&gt;D&lt;/code&gt; means bad marks. then this is a ordinal variable. we have to encode it in same order that it follows. means &lt;code&gt;A = 0, B = 1, C = 2, D = 3&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;le&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grade_A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grade_B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grade_C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grade_D&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;le&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classes_&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grades&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;le&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grades&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. One Hot Encoding
&lt;/h2&gt;

&lt;p&gt;A one hot encoding allows the representation of categorical data to be more expressive. Many machine learning algorithms cannot work with categorical data directly. When a one hot encoding is used it may offer a more nuanced set of predictions than a single label&lt;br&gt;
In one hot encoding, the label encoded variable is removed and a new binary variable is added for each unique label value. &lt;br&gt;
Visuals are better than explaining.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdseny4yh9gm7avoahoi4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdseny4yh9gm7avoahoi4.png" alt="ohe" width="359" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, one hot encoding causes higher correlation between its values. so we should drop a feature after one hot encoding.&lt;br&gt;
Scikit learn provides this inbuilt functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OneHotEncoder&lt;/span&gt;
&lt;span class="n"&gt;df_enc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OneHotEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grades&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pandas also provide OHE by its get_dummies() function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df_enc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_dummies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;year&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grades&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;drop_first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Scaling
&lt;/h2&gt;

&lt;p&gt;Scaling means fitting the data values under a common scale (range).&lt;br&gt;
suppose we have a dataset having two features on completely different scale. one feature lies in range 1 to 30, while other lies in range 4000 to 100000. Now there are some algorithms like K nearest neighbor, which classify data points based on distances between their features. In such algorithm, values of feature having small range will not be going to affect the distance majorly. So, having such a feature is meaningless. Almost every algorithm in ML deals with such kind of geometrical distances, except decision tree category algorithms.&lt;br&gt;
You can refer to &lt;a href="https://www.analyticsvidhya.com/blog/2020/04/feature-scaling-machine-learning-normalization-standardization/"&gt;this article&lt;/a&gt; for more info about algorithms. &lt;br&gt;
So there is a need to bring them on a common scale.&lt;/p&gt;

&lt;p&gt;There are mainly two types of scaling techniques.&lt;/p&gt;
&lt;h3&gt;
  
  
  Standardization
&lt;/h3&gt;

&lt;p&gt;Standardization is used to center the values around the mean with a unit standard deviation. this makes the mean to becomes zero with a unit standard deviation.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewwlnff9655oa0402itx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewwlnff9655oa0402itx.png" alt="standard formula" width="97" height="37"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StandardScaler&lt;/span&gt;
&lt;span class="n"&gt;scaler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;expenses&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;expenses&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;before and after standardization&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89qd1cochhxaosutx2u3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89qd1cochhxaosutx2u3.png" alt="after standard" width="692" height="656"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;image source : google&lt;/strong&gt;&lt;br&gt;
Standardization should be done when the data shows a bell curve a.k.a Normal Distribution or Gaussian Distribution.&lt;/p&gt;
&lt;h3&gt;
  
  
  Normalisation
&lt;/h3&gt;

&lt;p&gt;Normalization is used to scale the data of an attribute so that it falls in a smaller range, most commonly a range between 0 to 1.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23y5a8sg685innf9y31d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23y5a8sg685innf9y31d.png" alt="norm formula" width="150" height="39"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MinMaxScaler&lt;/span&gt;
&lt;span class="n"&gt;scaler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MinMaxScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;expenses&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;expenses&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2hbevcozt3nt9wkc3gi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2hbevcozt3nt9wkc3gi.png" alt="normalization" width="224" height="224"&gt;&lt;/a&gt;&lt;br&gt;
Normalization is well suited when data values appear to be continuously increasing or decreasing. &lt;/p&gt;
&lt;h2&gt;
  
  
  11. Oversampling
&lt;/h2&gt;

&lt;p&gt;In around 2018, Amazon crafted an AI recruiting tool that review the job applicant's resume and give them ratings, similar to the amazon shopping ratings. The AI was trained on the basis of previous applicant's data, most of which are men. The AI became bias towards men and taught itself that men candidates are mostly preffered. The gender of candidate was not explicitely given to him, but he found that by their resume finding words like women, female chess champion, etc and rated them low for job.&lt;br&gt;
This all happened because the training data was imbalanced. There are two ways to handle imbalanced data. &lt;/p&gt;
&lt;h3&gt;
  
  
  Undersampling
&lt;/h3&gt;

&lt;p&gt;Reduce number of samples of a class having higher number of samples. This method is used when we have a very large dataset and removing instances doesn't cause much loss of data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Oversampling
&lt;/h3&gt;

&lt;p&gt;Increase the number of samples of class having lower number of samples. It is also known as data augmentation.&lt;br&gt;
There are again two major algorithms for oversampling.&lt;/p&gt;
&lt;h4&gt;
  
  
  SMOTE (Synthetic Minority Oversampling Technique)
&lt;/h4&gt;

&lt;p&gt;SMOTE works by selecting examples that are close in the feature space, drawing a line between the examples in the feature space and drawing a new sample at a point along that line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# x = all features except y, y = imbalanced feature
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;imblearn.over_sampling&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SMOTE&lt;/span&gt;
&lt;span class="n"&gt;smote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SMOTE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;os_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;os_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ADASYN (Adaptive Synthetic)
&lt;/h4&gt;

&lt;p&gt;ADASYN is a generalized form of the SMOTE algorithm. Only difference in SMOTE and ADASYN is that it considers the density distribution, which decides the no. of synthetic instances generated for samples. It helps to find those samples which are difficult to learn. Due to this, it helps in adaptively changing the decision boundaries based on the samples difficult to learn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;imblearn.over_sampling&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ADASYN&lt;/span&gt;
&lt;span class="n"&gt;adasyn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ADASYN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;os_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adasyn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit_resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;We will see different visualization techniques and plots using matplotlib and seaborn in next article.&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>#P3 - Linear Regression</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Fri, 01 Jan 2021 09:35:25 +0000</pubDate>
      <link>https://forem.com/ashuto7h/p3-linear-regression-242</link>
      <guid>https://forem.com/ashuto7h/p3-linear-regression-242</guid>
      <description>&lt;p&gt;Linear regression attempts to find the relationship between two variables by fitting a linear equation to observed data. One variable is considered to be an independent variable, and the other is considered to be a dependent variable.&lt;br&gt;
The dependent variable is also known as the &lt;code&gt;criterion variable&lt;/code&gt; and the independent variable is also known as the &lt;code&gt;predictor variable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here our task is to find how the dependent variable(Y) can be predicted on the basis of the Independent variable(X). for this, we consider that all the set of points (x,y) lies on a straight line, which means there is a linear relationship between them.&lt;/p&gt;

&lt;p&gt;But how it is possible to get accurate results by such an assumption? It is true that some points don't lie on the line and there will always be an error in our result, but you cannot expect a machine to be fully accurate. we will get good accuracy with a huge dataset.&lt;/p&gt;

&lt;p&gt;so now we have to find the line which well satisfies the following conditions - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The line should pass through the point(x,y)
or&lt;/li&gt;
&lt;li&gt;The distance between the line and the point should be minimum.
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fukyl4xqvlpdg65l3tqn4.gif" alt="Alt Text" width="600" height="450"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;
  
  
  source - google
&lt;/h6&gt;

&lt;p&gt;now the question arises that how to find such a line. No, we don't have to take a paper and start plotting all the points.&lt;br&gt;
Recall geometry, which states that the equation of a line is &lt;br&gt;
&lt;code&gt;y = a + bx&lt;/code&gt;, where &lt;code&gt;b&lt;/code&gt; is the &lt;code&gt;slope (gradient)&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; is the &lt;code&gt;y-intercept&lt;/code&gt;. if we can find the value of a and b, we can find a value for y according to the given x. in this way we will be able to predict the value of y.&lt;/p&gt;

&lt;p&gt;value of a and b can be calculated by the given formula&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffc06y7s1hvo25bv1ybx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffc06y7s1hvo25bv1ybx4.png" alt="Alt Text" width="229" height="97"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  source - &lt;a href="https://www.statisticshowto.com/probability-and-statistics/regression-analysis/find-a-linear-regression-equation/#FindaLinear"&gt;click here&lt;/a&gt;
&lt;/h6&gt;

&lt;p&gt;What we have discussed till now was based on simple linear regression, in which the value of y depends on one independent variable x.&lt;/p&gt;
&lt;h3&gt;
  
  
  Multiple Linear Regression
&lt;/h3&gt;

&lt;p&gt;When the dependent variable is dependent on more than one independent variable then Multiple linear regression is used.&lt;br&gt;
Here we have to fit a regression line through a multidimensional space of data points&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftsjxikihdyxbk1dyr773.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftsjxikihdyxbk1dyr773.png" alt="Alt Text" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The equation of line is given by&lt;br&gt;
&lt;code&gt;y = b0 + b1.x1 + b2.x2  + ......&lt;/code&gt;&lt;br&gt;
where &lt;code&gt;x1,x2,...&lt;/code&gt; are the independent variables, &lt;code&gt;b0&lt;/code&gt; is the y-intercept, and &lt;code&gt;b1, b2,...&lt;/code&gt; are slopes.&lt;br&gt;
finding values of &lt;code&gt;b0,b1,b2&lt;/code&gt; in such case is done by using some matrix algebra.&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps for training a model
&lt;/h3&gt;
&lt;h5&gt;
  
  
  Prerequisite - Python, Google Colab or Jupyter
&lt;/h5&gt;
&lt;h4&gt;
  
  
  The Environment
&lt;/h4&gt;

&lt;p&gt;You can use Jupyter Notebooks along with Anaconda or simply the google colab. If you are using google colab you have to import the file from Github or via google.colab module. colab has some good accessibility features. Jupyter runs on your local machine so if you are low on resources, you should go for google colab.&lt;/p&gt;
&lt;h4&gt;
  
  
  Data Collection
&lt;/h4&gt;

&lt;p&gt;The first step for getting a model trained is to collect data. I prefer using &lt;a href="https://www.kaggle.com"&gt;Kaggle&lt;/a&gt; or &lt;a href="https://archive.ics.uci.edu/ml/index.php"&gt;UCI Machine Learning Repository&lt;/a&gt; which provides various types of datasets. datasets are mostly available in form of CSV files(comma-separated values).&lt;/p&gt;
&lt;h5&gt;
  
  
  About Dataset
&lt;/h5&gt;

&lt;p&gt;The dataset that we have taken for Multiple Linear Regression is from the UCI Machine Learning Repository.&lt;br&gt;
you can get the CSV files from &lt;strong&gt;&lt;a href="https://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Plant"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The dataset contains 9568 data points collected from a Combined Cycle Power Plant over 6 years (2006-2011) when the power plant was set to work with a full load. Features consist of hourly average ambient variables Temperature (T), Ambient Pressure (AP), Relative Humidity (RH), and Exhaust Vacuum (V) to predict the net hourly electrical energy output (EP) of the plant.&lt;/p&gt;
&lt;h5&gt;
  
  
  Attribute Information:
&lt;/h5&gt;

&lt;p&gt;Features consist of hourly average ambient variables&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Temperature (AT) in the range 1.81°C and 37.11°C,&lt;br&gt;
    Ambient Pressure (AP) in the range 992.89-1033.30 millibar,&lt;br&gt;
    Relative Humidity (RH) in the range of 25.56% to 100.16%&lt;br&gt;
    Exhaust Vacuum (V) in the range 25.36-81.56 cm Hg&lt;br&gt;
    Net hourly electrical energy output (PE) 420.26-495.76 MW&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The averages are taken from various sensors located around the plant that record the ambient variables every second. The variables are given without &lt;strong&gt;Normalization&lt;/strong&gt;. &lt;br&gt;
We have to train the model for the prediction of PE&lt;/p&gt;
&lt;h5&gt;
  
  
  Importing the dataset
&lt;/h5&gt;

&lt;p&gt;pandas is a python library that can help you to convert CSV, excel, list, dict, NumPy array to dataframe. &lt;br&gt;
we will use it to import our csv file.&lt;br&gt;
if you are using colab, first upload your CSV file to colab then its path will be available as '/content/file_name.csv'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;
&lt;span class="c1"&gt;# enter your CSV file path here
&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path\to\csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;dataframe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;info() gives you info about your dataframe and head(5) returns first 5 rows of the dataframe.&lt;/p&gt;

&lt;h4&gt;
  
  
  Separating Independent and Dependent variables
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;[  14.96   41.76 1024.07   73.17] &lt;br&gt;
 463.26&lt;/code&gt;&lt;br&gt;
loc is a property of dataframe that is used to select rows and columns. it can also take boolean values. &lt;code&gt;:&lt;/code&gt; is used to select all rows or columns.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Preprocessing
&lt;/h3&gt;

&lt;p&gt;Before training a model for any type of data, the data needs to be preprocessed to make it ready for training. we will cover all the types of preprocessing techniques in the next article.&lt;/p&gt;

&lt;p&gt;Our dataset currently doesn't require any preprocessing, except for feature scaling, but that is also managed internally by &lt;code&gt;sklearn&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Splitting training and test data
&lt;/h4&gt;

&lt;p&gt;In any Supervised learning model, we divide the whole dataset into two types, training dataset, and testing dataset. We train the model on the basis of the training dataset and then test it by test dataset. generally, the training dataset occupies about 70% to 80% of the whole dataset.&lt;br&gt;
Scikit-learn(sklearn) is a library in Python that provides many unsupervised and supervised learning algorithms. It's built upon NumPy, pandas, and Matplotlib.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.model_selection&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;train_test_split&lt;/span&gt;
&lt;span class="n"&gt;x_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;test_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here &lt;code&gt;test_size&lt;/code&gt; determines the size of test data. in this case test data is 20% of the whole data. &lt;code&gt;random_state&lt;/code&gt; determines how the random function will work.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fitting the model and predicting the values.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.linear_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LinearRegression&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LinearRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# predictions
&lt;/span&gt;&lt;span class="n"&gt;y_pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;actual  |  predicted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{:.2f}  |  {:.2f}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;actual  |  predicted&lt;br&gt;
431.23  |  431.43&lt;br&gt;
460.01  |  458.56&lt;br&gt;
461.14  |  462.75&lt;br&gt;
445.90  |  448.60&lt;br&gt;
451.29  |  457.87&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And Here is your model trained.&lt;br&gt;
you can see how nearly it predicts the values of "PE".&lt;/p&gt;
&lt;h4&gt;
  
  
  Calculating R-Square, Intercept, Slopes
&lt;/h4&gt;

&lt;p&gt;R-squared is a statistical measure of how close the data are to the fitted regression line. It is also known as the coefficient of determination, or the coefficient of multiple determination for multiple regression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;r_sq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r_sq_train&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r_sq_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r_sq : &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r_sq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r_sq_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r_sq_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;r_sq&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;intercept :&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;intercept_&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;slope :&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coef_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;r_sq :  0.9286947104407257 0.9277253998587902 0.9325315554761303&lt;br&gt;
intercept : 452.8410371616384&lt;br&gt;
slope : [-1.97313099 -0.23649993  0.06387891 -0.15807019]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;model.score()&lt;/code&gt; calculates the R square value.&lt;br&gt;
In this case, the value of r_sq tells that the accuracy of the whole model is 92.86% while that of the training set is 92.77% and of the test set is 93.25%&lt;br&gt;
&lt;code&gt;model.intercept_&lt;/code&gt; returns the intercept value &lt;code&gt;b0&lt;/code&gt;&lt;br&gt;
&lt;code&gt;model.coef_&lt;/code&gt; returns the list of coefficients (slopes) &lt;code&gt;b1 b2 b3....&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Feature Selection
&lt;/h2&gt;

&lt;p&gt;Feature selection is the process of reducing the number of independent variables when creating a predictive model. It is desirable to reduce the number of input variables to both reduce the computational cost of modeling and to improve the performance of the model.&lt;/p&gt;
&lt;h3&gt;
  
  
  Backward Elimination Method
&lt;/h3&gt;

&lt;p&gt;it is one of the methods used for Feature Selection.&lt;br&gt;
Steps :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select a Significance level (P-value) generally (SL = 0.05)&lt;/li&gt;
&lt;li&gt;fit the model with all possible predictors&lt;/li&gt;
&lt;li&gt;find p-values of all predictors&lt;/li&gt;
&lt;li&gt;remove the predictor with the highest p-value then fit the model again and repeat the process till the p-value is greater than 0.05&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is one thing to take care of.&lt;br&gt;
&lt;code&gt;y = b0 + b1.x1 + b2.x2 + b3.x3 ...&lt;/code&gt;&lt;br&gt;
In the above equation, if you notice that every &lt;code&gt;Xn&lt;/code&gt; has a multiplier &lt;code&gt;bn&lt;/code&gt; but not the constant &lt;code&gt;b0&lt;/code&gt;. The package statsmodel only considers a multiplier if it has a feature value. If there is no feature value then it would not get picked up while creating the model. So the &lt;code&gt;b0&lt;/code&gt; would be dropped. but if you have a &lt;code&gt;x0&lt;/code&gt; and set it to &lt;code&gt;1&lt;/code&gt; that will solve the problem. Hence we need to create a feature with value = 1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;statsmodels.regression.linear_model&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sm&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c1"&gt;# add a column of values = 1 (int)
&lt;/span&gt;&lt;span class="n"&gt;be_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;9568&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;be_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# finding significance level
&lt;/span&gt;&lt;span class="n"&gt;x_opt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;be_x&lt;/span&gt;&lt;span class="p"&gt;[:,[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="n"&gt;ols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;OLS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x_opt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ols&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9qtdfwpo56f0yxj0zbiu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9qtdfwpo56f0yxj0zbiu.png" alt="Alt Text" width="673" height="548"&gt;&lt;/a&gt;&lt;br&gt;
if you see the &lt;code&gt;P &amp;gt; |t|&lt;/code&gt; column there is no value, that is greater than 0.05. so there is no useless feature in our model.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's Next
&lt;/h4&gt;

&lt;p&gt;Practice by yourself. choose a dataset and try to fit the model for it. Remember that we have not dealt with various factors like categorical variables and null values yet. they all will be covered in the next article on data preprocessing. Choose your dataset wisely. &lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>#P2 - ML Types</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Thu, 31 Dec 2020 07:38:30 +0000</pubDate>
      <link>https://forem.com/ashuto7h/p2-ml-types-44ed</link>
      <guid>https://forem.com/ashuto7h/p2-ml-types-44ed</guid>
      <description>&lt;p&gt;There are three types of Machine Learning&lt;/p&gt;

&lt;h2&gt;
  
  
  Supervised Machine Learning
&lt;/h2&gt;

&lt;p&gt;It is Task-Oriented learning where you provide various input and output samples. the machine then tries to learn from the given samples and figure out a relation (tries to map between the input and output). At a certain point, it has learned too much from those samples so that it can predict nearly the correct output of the new input.&lt;/p&gt;

&lt;p&gt;There are two types of Supervised Learnings&lt;br&gt;
&lt;strong&gt;1. Regression&lt;/strong&gt;&lt;br&gt;
It deals with predictions related to Numerical Data. Here you have to predict a numerical (continuous) value as an output.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;example - &lt;br&gt;
you are given the sum of marks of a student over the last 7 years, and you have to predict the sum for this year.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;2. Classification&lt;/strong&gt;&lt;br&gt;
It deals with predictions related to Categorical Data. Here you have to predict a category to which the data belongs on the basis of input.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;example - Sentiment analysis&lt;br&gt;
You are given the facial properties of a person and you have to identify his sentiments(happy, sad, angry).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Unsupervised Machine Learning
&lt;/h2&gt;

&lt;p&gt;In this learning, we just have input but no output by which we can apply supervised learning. here the data is processed for all the possible ways to group it in various types called labels(classes), and assigning a class to a member of this data is called labeling.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;example - Buying habits of people&lt;br&gt;
here various people have various needs and interests and its hard to group them. by applying unsupervised learning, we can identify new trends in buying habits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reinforcement Learning
&lt;/h2&gt;

&lt;p&gt;It is a mixed version of learning where improvements on a previously learned model are continuously made to improve it. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;example - an action game goes hard as you play it. &lt;br&gt;
I am not sure but this can be an example of Reinforcement Learning. When I play shadow fight 3 I found that it gives suggestions like - your opponent is learning your moves, use different moves. so I think that it could be related to reinforcement learning.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>#P1 - Introduction</title>
      <dc:creator>Ashutosh Sahu</dc:creator>
      <pubDate>Thu, 31 Dec 2020 06:43:31 +0000</pubDate>
      <link>https://forem.com/ashuto7h/p1-introduction-4ma4</link>
      <guid>https://forem.com/ashuto7h/p1-introduction-4ma4</guid>
      <description>&lt;h2&gt;
  
  
  Machine learning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Arthur Samuel&lt;/strong&gt; First coined the term and described it as: “the field of study that gives computers the ability to learn without being explicitly programmed.” &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tom Mitchell&lt;/strong&gt; provided a more formal definition:&lt;br&gt;
“A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P, if its performance at tasks in T, as measured by P, improves with experience E.”&lt;/p&gt;

&lt;p&gt;Sounds both interesting and confusing at the same time. isn't it?&lt;/p&gt;

&lt;p&gt;One another question that comes in mind is that why there are so many terms related to it like Deep learning, Artificial Intelligence, Neural Networks? Are they all same or something different?&lt;/p&gt;

&lt;h2&gt;
  
  
  Artificial Intelligence
&lt;/h2&gt;

&lt;p&gt;Artificial intelligence (AI) refers to the simulation of human intelligence in machines that exhibits traits associated with a human mind such as learning and problem-solving. &lt;br&gt;
In simple words, when you see a machine taking decisions like a human, it is an AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Learning
&lt;/h2&gt;

&lt;p&gt;Deep learning is the functioning of AI which mimics the workings of the human brain in processing data for use in detecting objects, recognizing speech, translating languages, and making decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Neural Networks
&lt;/h2&gt;

&lt;p&gt;Neural networks are a series of algorithms that mimic the operations of a human brain to recognize relationships between vast amounts of data. &lt;/p&gt;

&lt;p&gt;You can relate the above all terms by the given image.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fopfqzb8zpd0tbxodp2ra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fopfqzb8zpd0tbxodp2ra.png" alt="Alt Text" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  courtesy: Google
&lt;/h6&gt;

&lt;h3&gt;
  
  
  My Opinions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Should we go for ML or Development ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to me, ML is one of the most overrated topic of the decade. Development is now becoming underrated, only because of the cool things that you can do with ML. &lt;br&gt;
Actually, its hard to Develop something completely from scratch, and it is nowhere comparable to ML.&lt;br&gt;
Just by learning how to use a python library and applying it on a dataset to create a model, you cannot say that you know Machine Learning.&lt;br&gt;
So while choosing anyone of them, you should have to depend on other factors.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
