<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MastersInMachineLearning.org</title>
	<atom:link href="https://www.mastersinmachinelearning.org/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.mastersinmachinelearning.org</link>
	<description></description>
	<lastBuildDate>Sat, 31 May 2025 14:25:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://www.mastersinmachinelearning.org/wp-content/uploads/2025/04/MML-logo-150x150.webp</url>
	<title>MastersInMachineLearning.org</title>
	<link>https://www.mastersinmachinelearning.org</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Lets’ talk about numeric distributions : Python</title>
		<link>https://www.mastersinmachinelearning.org/blog/lets-talk-about-numeric-distributions-python/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:47 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=312</guid>

					<description><![CDATA[Why should we bother ?? Distributions plays a very crucial role in data science and analytics. Statistical distributions shows us the underlying relationship between the data points. The main purpose of checking distributions is to get an idea on how the data points of the target are spread across, so that appropriate model could be ... <a title="Lets’ talk about numeric distributions : Python" class="read-more" href="https://www.mastersinmachinelearning.org/blog/lets-talk-about-numeric-distributions-python/" aria-label="Read more about Lets’ talk about numeric distributions : Python">Read more</a>]]></description>
										<content:encoded><![CDATA[
<h3 id="why-should-we-bother" class="wp-block-heading"><strong>Why should we bother ??</strong></h3>



<p class="wp-block-paragraph">Distributions plays a very crucial role in data science and analytics. Statistical distributions shows us the underlying relationship between the data points. The main purpose of checking distributions is to get an idea on how the data points of the target are spread across, so that appropriate model could be used to fit. For non data-science folks, by target we are referring the variable upon which we are interested to do some prediction or estimation.</p>



<p class="wp-block-paragraph">The examples below will justify the need for distribution:</p>



<p class="wp-block-paragraph">The majority of popular statistical models including the most common kinds, say linear regression make an assumption of normally distributed error terms. In another example of insurance industry, if we want to see the distribution of number of claims that come for each policy then ideally it will look like Poisson distribution, as we are concerned about the count of claim, which is discrete in nature.</p>



<h3 id="blogpost-content" class="wp-block-heading">Blog-post Content</h3>



<p class="wp-block-paragraph">Although, the list of distributions are huge, but that scope of this blog-post is to cover the ones which we use more commonly in the industry. The list shortens to 5 major distributions and one bonus distribution which is very common to insurance industry. They are:</p>



<ol class="wp-block-list">
<li>Normal Distribution</li>



<li>Binomial Distribution</li>



<li>Uniform Continuous Distribution (Rectangular Distribution)</li>



<li>Poisson Distribution</li>



<li>Gamma Distribution</li>



<li>Tweedie Distribution</li>
</ol>



<p class="wp-block-paragraph">Normal, rectangular and gamma are used for continuous variables, poisson and binomial are for discrete variables and tweedie distribution is one such distribution which models both poisson and gamma together.</p>



<p class="wp-block-paragraph">For each of the distribution, we will be looking at:</p>



<ol class="wp-block-list">
<li>Brief explanation with mathematical description</li>



<li>Generating each distribution in Python.</li>



<li>Plotting with Seaborn library</li>
</ol>



<h3 id="1-normal-distribution" class="wp-block-heading">1. Normal Distribution</h3>



<p class="wp-block-paragraph">Normal distribution is one of the most common distribution and is used for continuous variables. It is bell shaped curve which is neither too skewed not too flat and has parameters:&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cmu%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\mu}">&nbsp;(mean) and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Csigma%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\sigma}">&nbsp;(Standard Deviation)</p>



<p class="wp-block-paragraph">The probability density function for normal distribution is :</p>



<figure class="wp-block-image"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BP%28X%3Dx%29%3D+%5Cfrac%7B1%7D%7B%5Csigma%5Csqrt%7B2%5Cpi%7D%7De%5E%7B%5Cfrac%7B-%28x-%5Cmu%29%5E2%7D%7B2%5Csigma%5E2%7D%7D%7D+where+%5C%3B%5C%3B+%5Cboldsymbol%7B%5Csigma%5E2%3E0%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{P(X=x)= \frac{1}{\sigma\sqrt{2\pi}}e^{\frac{-(x-\mu)^2}{2\sigma^2}}} where \;\; \boldsymbol{\sigma^2&gt;0}"/></figure>



<p class="wp-block-paragraph"><strong>Properties of Normal Distrbution</strong></p>



<ol class="wp-block-list">
<li>Symmetric around the mean i.e. all the basic summary stats: mean, median and mode lies at the center and are equal to each other</li>



<li>Standard deviation represents how closely packed or loosely floating are the data points to or away from the mean</li>



<li>Since the distribution is symmetric, so area under the curve is equal to 1</li>



<li>When <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cmu%7D+%3D0&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\mu} =0"> and <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Csigma%7D+%3D1&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\sigma} =1"> then the distribution is called standard normal distrbution</li>
</ol>



<p class="wp-block-paragraph">We will be using&nbsp;<code>np.random.normal()</code>&nbsp;from numpy package to generate random sample of normally distributed variates. The&nbsp;<code>np.random.normal()</code>&nbsp;has three parameters : loc (mean), scale (SD) and size (no.of obs to be generated).</p>



<p class="wp-block-paragraph">The below code will show how to generate random sample for normal distribution and the shape of the distribution.</p>



<pre class="wp-block-preformatted"> #Import Libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")

# Normal Distribution
#Intializing the parameters: mean and SD
mu1,sigma1 = 2,2
np.random.seed(seed=32)
s_normal= np.random.normal(mu1, sigma1, 200000)
plt.subplots(figsize=(10,5))
plot=sns.distplot(pd.DataFrame(s_normal)).set_title('Normal Distribution with $\mu$=%.1f,$\sigma$=%.1f'%(mu1,sigma1))
fig=plot.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/normal_distribution4.png?w=616" alt="normal_distribution" class="wp-image-8767"/></figure>



<p class="wp-block-paragraph">We know that&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bvar%28x%29%5C%3B%5C%2C%3D+%5Csigma%5E2%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{var(x)\;\,= \sigma^2}">. In order to find out the mean and variance in python we will use the command</p>



<pre class="wp-block-preformatted">print(np.mean(s_normal), np.var(s_normal))
</pre>



<p class="wp-block-paragraph">we are getting mean as&nbsp;<strong>2.007</strong>&nbsp;and variance as&nbsp;<strong>4.005</strong>. The values obtained here are matching with the mathematical formula given above.</p>



<pre class="wp-block-preformatted"># Standard Normal Distribution
#Initializing the parameters:mean and SD
mu,sigma=0,1
np.random.seed(seed=32)
s_stdnorm= np.random.normal(mu, sigma, 1000)
plt.subplots(figsize=(10,5))
plot=sns.distplot(pd.DataFrame(s_stdnorm)).set_title('Standard Normal Distribution with $\mu$=%.1f and $\sigma^2$=%.1f' %(mu,sigma))
fig=plot.get_figure()
</pre>



<h3 id="" class="wp-block-heading"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/standard_normal_distribution2.png?w=616" alt="standard_normal_distribution" srcset="https://appliedmachinelearning.files.wordpress.com/2018/08/standard_normal_distribution2.png 605w, https://appliedmachinelearning.files.wordpress.com/2018/08/standard_normal_distribution2.png?w=150 150w, https://appliedmachinelearning.files.wordpress.com/2018/08/standard_normal_distribution2.png?w=300 300w"></h3>



<h3 id="2-uniform-continuous-distribution" class="wp-block-heading">2. Uniform Continuous Distribution</h3>



<p class="wp-block-paragraph">In case of uniform continuous distribution, which is also know as&nbsp;<strong>rectangular distribution</strong>, the probability associated with each data points within a fixed interval is equal.</p>



<p class="wp-block-paragraph">The probability density function for uniform distribution is:</p>



<figure class="wp-block-image"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BP%28X%3Dx%29%3D+%5Cfrac%7B1%7D%7Bb-a%7D%3B+where%5C%3B+a%3C%3D+x+%3C%3D+b%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{P(X=x)= \frac{1}{b-a}; where\; a<= x <= b}"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BP%28X%3Dx%29%3D+0%3B+where%5C%3B%5C%3B+x%3Ca%5C%3B+and+%5C%3Bx%3Eb%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{P(X=x)= 0; where\;\; x<a\; and \;x&gt;b}"/></figure>



<p class="wp-block-paragraph">For example: In winter, a person can gain weight post Christmas anywhere between 1lb to 50lb. Each of the numbers between 1 to 50 are equally probable. So in this example,&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bb%7D%3D50&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{b}=50">&nbsp;and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Ba%7D%3D0&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{a}=0">. If we are interested to find out the probabilty of gaining weight anywhere between 25lb to 35lb then the above formula will turn to:</p>



<p class="wp-block-paragraph"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BP%28X%3Dx%29+%3D+%5Cfrac%7B%28d-c%29%7D%7B%28b-a%29%7D%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{P(X=x) = \frac{(d-c)}{(b-a)}}">; where&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol+%7Bc%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol {c}">&nbsp;and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bd%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{d}">&nbsp;represents 25 and 35 respectively.</p>



<p class="wp-block-paragraph"><strong>Properties of Uniform Distribution</strong></p>



<ol class="wp-block-list">
<li>Mean and median of the distribution is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cfrac%7B%28a%2Bb%29%7D%7B2%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\frac{(a+b)}{2}"></li>



<li>Since the datapoints within the interval [a,b] are equally likely, so there is no skewness present in the distribution</li>



<li>Variance of the distribution is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cfrac%7B%28b-a%29%5E2%7D%7B12%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\frac{(b-a)^2}{12}"></li>
</ol>



<p class="wp-block-paragraph">We will use the command&nbsp;<code>np.random.uniform()</code>&nbsp;to generate a random sample which follows rectangular distribution.</p>



<pre class="wp-block-preformatted">#Here parameters a and b has been assigned the values 1 and 6
s_uniform=np.random.uniform(1, 6, 500000)
np.random.seed(seed=32)
plt.subplots(figsize=(10,5))
plot=sns.distplot(pd.DataFrame(s_uniform)).set_title('Uniform Distribution with $a$=%.1f and $b$=%.1f'%(1,6))
fig=plot.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/uniform_distribution3.png?w=616" alt="uniform_distribution" class="wp-image-8769"/></figure>



<p class="wp-block-paragraph">The mean and variance of uniform distribution is calculated as</p>



<pre class="wp-block-preformatted">print(np.mean(s_uniform),np.var(s_uniform))
</pre>



<p class="wp-block-paragraph">and the values we obtain are&nbsp;<strong>3.49</strong>&nbsp;(mean) and&nbsp;<strong>2.08</strong>(variance). The values obtained here are matching with the mathematical formula given above.</p>



<h3 id="3nbspbinomial-distribution" class="wp-block-heading">3. <strong>Binomial Distribution</strong></h3>



<p class="wp-block-paragraph">Binomial Distribution is a discrete probability distribution, which gives the sum of the outcomes obtained from n Bernoulli trials. For example, if a drug’s effect of curing a cancer is being tested on a patient, the result might be a success or a failure. The same experiment when conducted on 1000 cancer patients where n (trials) is large and we are interested to see exactly 5 successful cases, then the distribution becomes a binomial distribution. Here p measures drug’s success of curing cancer.</p>



<p class="wp-block-paragraph">The probability density function of binomial distribution is:</p>



<figure class="wp-block-image"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BPr%28X%3Dk%29+%3D+%7Bn+%5Cchoose+k%7D+p%5Ek+%281-p%29%5E%7B+n-k%7D%3B+where%5C%3B+n%3E0%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{Pr(X=k) = {n \choose k} p^k (1-p)^{ n-k}; where\; n&gt;0}"/></figure>



<p class="wp-block-paragraph">The above equation is reduced to bernoulli distribution when n=k=1 and the equation becomes:</p>



<figure class="wp-block-image"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BPr%28X%3D1%29+%3Dp%281-p%29%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{Pr(X=1) =p(1-p)}"/></figure>



<p class="wp-block-paragraph"><strong>Properties of Binomial Distribution</strong></p>



<ol class="wp-block-list">
<li>The probability of success is independent in each trial which implies the samples drawn randomly have been done with replacement</li>



<li>Mean(<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cmu%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\mu}">) of the distribution is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bnp%7D+&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{np} "></li>



<li>Variance(<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Csigma%5E2%7D+&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\sigma^2} ">) of the distribution is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bnp%281-p%29%7D+&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{np(1-p)} ">. The lower the variance of the distribution, the highly skewed will be the distribution. Skewness is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cfrac%7B1-2p%7D%7B%5Csqrt%7Bnp%281-p%29%7D%7D+&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\frac{1-2p}{\sqrt{np(1-p)}} "></li>
</ol>



<p class="wp-block-paragraph"><strong>Relation between mean and variance:</strong></p>



<ol class="wp-block-list">
<li>When p=0 then <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu">=0 and <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma%5E2&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma^2">=0 which implies <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu"> = <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma%5E2&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma^2"></li>



<li>When p=1 then <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu">=n and <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma%5E2&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma^2">=0 which implies <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu"> > <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma%5E2&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma^2"></li>



<li>When 0 &lt; <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu"></li>
</ol>



<p class="wp-block-paragraph">Since the third condition can be re-modeled as&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma%5E2&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma^2">=<img decoding="async" src="https://s0.wp.com/latex.php?latex=%281-p%29%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="(1-p)\mu">, so whatever be the value of&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu">,&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma%5E2&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma^2">&nbsp;is&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%281-p%29&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="(1-p)">&nbsp;times&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu">&nbsp;and will always be less than&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu">.</p>



<p class="wp-block-paragraph">We will generate random sample which are binomially distributed using the command&nbsp;<code>np.random.binomial()</code>.</p>



<pre class="wp-block-preformatted">#Initializing the parameters 'number of trials' and 'probaility of success'
n,p = 10,0.5
np.random.seed(seed=32)
s_binomial=np.random.binomial(n,p,1000)
plt.subplots(figsize=(10,5))
plot=sns.distplot(pd.DataFrame(s_binomial)).set_title('Binomial Distribution with $n$=%.1f,$p$=%.1f' % (n,p))
fig=plot.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/binomial_distribution3.png?w=616" alt="binomial_distribution.png" class="wp-image-8680"/></figure>



<p class="wp-block-paragraph">To get the mean and variance of a distribution, we will use the below code:</p>



<pre class="wp-block-preformatted">print(np.mean(s_binomial), np.var(s_binomial))
</pre>



<p class="wp-block-paragraph">We find that mean is&nbsp;<strong>5.036</strong>&nbsp;and variance is&nbsp;<strong>2.468</strong>&nbsp;which proves that mean&gt;variance in binomial. The values obtained here are matching with the mathematical formula given above.</p>



<h3 id="4-poisson-distribution" class="wp-block-heading">4. Poisson Distribution</h3>



<p class="wp-block-paragraph">Poisson distribution is a discrete probability distribution which models number of times an event occurs in fixed time interval. It is a binomial approximated distribution which occurs when number of trials (<img decoding="async" src="https://s0.wp.com/latex.php?latex=n&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="n">) becomes sufficiently large and probability of success (<img decoding="async" src="https://s0.wp.com/latex.php?latex=p&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="p">) successively becomes small such that&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=np&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="np">&nbsp;becomes&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Clambda&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\lambda">&nbsp;(constant), the distribution becomes poisson.</p>



<p class="wp-block-paragraph">The probability density function of poisson distribution is:</p>



<figure class="wp-block-image"><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B+Pr%28X%3Dk%29+%3D+e%5E%7B-%5Clambda%7D%5Cfrac%7B%5Clambda%5Ek%7D%7Bk%21%7D%3B+%5Clambda%3E0%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{ Pr(X=k) = e^{-\lambda}\frac{\lambda^k}{k!}; \lambda&gt;0}"/></figure>



<p class="wp-block-paragraph">As an example:&nbsp;the number of file server virus infection at a data center during a 24-hour period&nbsp;is&nbsp; poisson distributed.</p>



<p class="wp-block-paragraph"><strong>Properties of Poisson Distribution</strong></p>



<ol class="wp-block-list">
<li>Probability of occurrence of one event is independent of the probability of occurrence of the other</li>



<li>Mean (<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cmu&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\mu">) and variance (<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Csigma&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\sigma">) both are equal to <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Clambda&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\lambda"></li>



<li>Skewness is represented by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cfrac%7B1%7D%7B%5Csqrt%7B%5Clambda%7D%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\frac{1}{\sqrt{\lambda}}">. The higher the constant term(<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Clambda&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\lambda">), higher would be the skewness</li>
</ol>



<p class="wp-block-paragraph">The command used to generate poisson distribution in python was&nbsp;<code>np.random.poisson()</code></p>



<pre class="wp-block-preformatted">#Intializing the parameters for Poisson distribution
mean,k=2,100000
np.random.seed(seed=32)
s_poisson = np.random.poisson(mean,k)
plt.subplots(figsize=(10,5))
plot=sns.distplot(pd.DataFrame(s_poisson)).set_title('Poisson Distribution with $\lambda$=%.1f and $k$=%.1f'%(mean,k))
fig=plot.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/poisson_plot1.png?w=616" alt="poisson_plot1.png" class="wp-image-8771"/></figure>



<p class="wp-block-paragraph">We can check the mean and variance of poisson distribution:</p>



<pre class="wp-block-preformatted">print(np.mean(s_poisson),np.var(s_poisson))
</pre>



<p class="wp-block-paragraph">We will see that values&nbsp;<strong>2.00</strong>&nbsp;(mean) and&nbsp;<strong>2.00</strong>&nbsp;(variance) are&nbsp; very close value of&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Clambda&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\lambda">&nbsp;which proves the proposition that mean and variance are equal in poisson distribution. The values obtained here are matching with the mathematical formula given above.</p>



<h3 id="5-gamma-distribution" class="wp-block-heading">5. Gamma Distribution</h3>



<p class="wp-block-paragraph">Gamma distribution is a right skewed distribution used for continuous variables. This is due to its flexibility in the choice of the shape and scale parameters. The scale parameter determines where the bulk of the observations lies and the shape parameter determines how the distribution will look.</p>



<p class="wp-block-paragraph">The probability density function of Gamma distribution:<br><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bf%28x%3B%5Calpha%2C%5Cbeta%29%3D+%5Cfrac%7B%5Cbeta%5E%5Calpha+x%5E%7B%5Calpha-1%7De%5E%7B-%5Cbeta+x%7D%7D%7B%5CGamma%28%5Calpha%29%7D%7D%2C+%5Cboldsymbol%7Bwhere+%5C%2C+%5Calpha%3E0%2C+x%3E0%2C%5Cbeta%3E0%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{f(x;\alpha,\beta)= \frac{\beta^\alpha x^{\alpha-1}e^{-\beta x}}{\Gamma(\alpha)}}, \boldsymbol{where \, \alpha>0, x>0,\beta>0}&#8221;></p>



<p class="wp-block-paragraph">Here&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Calpha%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\alpha}">&nbsp;is the shape parameter,&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cfrac%7B1%7D%7B%5Cbeta%7D%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\frac{1}{\beta}}">&nbsp;is the scale parameter and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5CGamma%28%5Calpha%29%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\Gamma(\alpha)}">&nbsp;is the gamma function.</p>



<p class="wp-block-paragraph">For example, to estimate rainfall for a location at select time interval, based on past data of the same, gamma distribution is a popular choice because of the flexibility in parameters: shape and scale.</p>



<p class="wp-block-paragraph"><strong>Properties of Gamma Distribution</strong></p>



<ol class="wp-block-list">
<li>Mean of the distribution is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cfrac%7B%5Calpha%7D%7B%5Cbeta%7D%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\frac{\alpha}{\beta}}"></li>



<li>Variance of the distribution is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cfrac%7B%5Calpha%7D%7B%5Cbeta%5E2%7D%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\frac{\alpha}{\beta^2}}"></li>



<li>Skewness is given by <img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cfrac%7B2%7D%7B%5Csqrt%7B%5Calpha%7D%7D%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\frac{2}{\sqrt{\alpha}}}">. The lesser the shape parameter, the more skewed the distribution will be</li>
</ol>



<p class="wp-block-paragraph">We will use the command&nbsp;<code>np.random.gamma()</code>&nbsp;to generate random samples which follows gamma distribution.</p>



<pre class="wp-block-preformatted">#Initializing the parameters for Gamma distribution
shape, scale = 1, 2.
plt.subplots(figsize=(10,5))
np.random.seed(seed=32)
s_gamma = np.random.gamma(shape, scale, 50000)
plot=sns.distplot(pd.DataFrame(s_gamma)).set_title('Gamma Distribution with $shape$=%.1f and $scale$=%.1f'%(shape,scale))
fig=plot.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/gamma_dist.png?w=616" alt="gamma_dist.png" class="wp-image-8696"/></figure>



<p class="wp-block-paragraph">We will compute the mean and variance by :</p>



<pre class="wp-block-preformatted">print(np.mean(s_gamma),np.var(s_gamma))
</pre>



<p class="wp-block-paragraph">and the values we obtain are&nbsp;<strong>1.994</strong>(mean) and&nbsp;<strong>3.959</strong>(variance). The values obtained here are matching with the mathematical formula given above.</p>



<p class="wp-block-paragraph">Below we will show how the change in each of the parameters&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=shape&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="shape">&nbsp;and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=scale&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="scale">, we can change shape of the distribution.</p>



<p class="wp-block-paragraph">Case1: Change in shape parameter with no change in scale parameter</p>



<pre class="wp-block-preformatted">s_gamma1=np.random.gamma(5,scale,5000)
np.random.seed(seed=32)
fig,(ax1,ax2)= plt.subplots(1,2, figsize=(15, 4))

plot=sns.distplot(pd.DataFrame(s_gamma),ax=ax1).set_title('Gamma Distribution with shape parameter =1')
fig=plot.get_figure()

plot1=sns.distplot(pd.DataFrame(s_gamma1),ax=ax2).set_title('Gamma Distribution with shape parameter =5')
fig1=plot1.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/gamma_shape_dist1.png?w=616" alt="gamma_shape_dist.png" class="wp-image-8698"/></figure>



<p class="wp-block-paragraph">It is clear from the above graph that with change in shape parameter, skewness of the distribution reduces.</p>



<p class="wp-block-paragraph">Case2: Change in scale parameter with no change in shape parameter</p>



<pre class="wp-block-preformatted">s_gamma2=np.random.gamma(shape,5,5000)
np.random.seed(seed=32)
fig, (ax1,ax2) =plt.subplots(1,2,figsize=(15,4))

plot=sns.distplot(pd.DataFrame(s_gamma),ax=ax1).set_title('Gamma Distribution with scale parameter=2')
fig=plot.get_figure()

plot1=sns.distplot(pd.DataFrame(s_gamma2),ax=ax2).set_title('Gamma Distribution with scale parameter=5')
fig1=plot1.get_figure()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/gamma_scale_distribution.png?w=616" alt="gamma_scale_distribution" class="wp-image-8699"/></figure>



<p class="wp-block-paragraph">From the above figure, we can infer that with change in scale parameter, the tails of the distribution became more elongated with no&nbsp; change in skewness.</p>



<h3 id="6-tweedie-distribution" class="wp-block-heading">6. Tweedie Distribution</h3>



<p class="wp-block-paragraph">Tweedie distributions belongs to the family of linear exponential distributions with a dispersion parameter&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cphi%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\phi}">.</p>



<p class="wp-block-paragraph">A variable Y is said to follow tweedie distribution if<br><img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bvar%28Y%29%3D+%5Cphi%2AV%28%5Cmu%29%3B+where%5C%3B%5C%3B+V%28%5Cmu%29%3D+%5Cmu%5Ep%7D+&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{var(Y)= \phi*V(\mu); where\;\; V(\mu)= \mu^p} "></p>



<p class="wp-block-paragraph">Here&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7BV%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{V}">&nbsp;refers to the mean-variance relationship of the distribution and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bp%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{p}">&nbsp;is a constant, also called as variance power. The above-mentioned distribution which belongs to the tweedie family can be achieved with a change in the parameter of the constant&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bp%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{p}">. The tweedie distribution can be achieved when the value of p belongs to the interval (1,2).</p>



<p class="wp-block-paragraph">In simple terms, the tweedie distribution can be explained as a sum of N independent gamma random variates where N follows a poisson distribution and N and gamma random variate are independent. In other words, for each poisson random variate, we are trying to find a corresponding gamma variate. For example, in case of modelling insurance claims, the number of incumbent claims can be modeled independently using poisson distribution as its a count(discrete) distribution and the severity(claim cost) associated with the claims can be modeled independently using gamma distribution as claim cost is continuous parameter, but when we look at them together then tweedie distribution views the situation as : “for a claim, it tries to find the product of poisson number of claims and gamma sized claim amount”. So if 5 claims have come, the tweedie will view these 5 claims as 5 claims with their associated claim cost.</p>



<p class="wp-block-paragraph">However, the below code is focused on Poisson-Gamma distribution.</p>



<pre class="wp-block-preformatted">def tweedie(n,p,mu,phi):
    np.random.seed(seed=32)
    #checking the value of variance power between 1-2
    if(p=2):
        print('p must be between (1,2)')
        pass
    else:
        rt=np.full(n,np.nan)
    # calculating mean of poisson distribution
        lambdaa=mu**(2-p)/(phi*(2-p))
    # shape parameter of gamma distribution
        alpha=(2-p)/(1-p)
    # scale parameter of gamma distribution
        gam= phi*(p-1)*(mu**(p-1))
    # Generating Poisson random sample
        N=np.random.poisson(lambdaa,n)
        for i in range(n):
        # Generate single data point of gamma distribution using poisson random variable
            rt[i]=np.random.gamma(N[i]*np.abs(alpha),gam,1)
        return(rt)
</pre>



<p class="wp-block-paragraph">The above function has 4 parameters: n, p, mu, phi. Here&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bn%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{n}">&nbsp;is the number of points to be generated,&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bp%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{p}">&nbsp;refers to the constant parameter.In the above function, we can’t assign values 1 or 2 to the value p.It has to be between 1 and 2, else it will throw a warning (mentioned in the code).&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7Bmu%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{mu}">&nbsp;refers to the mean and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cphi%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\phi}">&nbsp;refers to the dispersion parameter.</p>



<p class="wp-block-paragraph">Below we will see that how varying the constant parameter p between 1 and 2, the distribution moves from extreme poisson to extreme gamma distribution.</p>



<pre class="wp-block-preformatted">vals=[1.01,1.2,1.5,1.9]
fig, axes =plt.subplots(2,2, figsize=(15,6))
axes=axes.flatten()
for ax,i in zip(axes,vals):
    s_tweedie=tweedie(50000,i,3,2)
    sns.distplot(pd.DataFrame(s_tweedie),ax=ax).set_title('Tweedie Distribution with $p$=%.2f,$\mu$=%.1f and $\phi$=%.1f'%(i,3,2))
plt.tight_layout()
plt.show()
</pre>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/08/tweedie-distribution.png?w=616" alt="tweedie distribution" class="wp-image-8722"/></figure>



<p class="wp-block-paragraph">The values of&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cmu%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\mu}">&nbsp;and&nbsp;<img decoding="async" src="https://s0.wp.com/latex.php?latex=%5Cboldsymbol%7B%5Cphi%7D&amp;bg=%23ffffff&amp;fg=%23111111&amp;s=0&amp;c=20201002" alt="\boldsymbol{\phi}">&nbsp;can be changed as per required.</p>



<p class="wp-block-paragraph">&nbsp;We show here the variance of tweedie with p=1.5, which is obtained using the command</p>



<pre class="wp-block-preformatted">print(np.var(s_tweedie))
</pre>



<p class="wp-block-paragraph">The variance is&nbsp;<strong>10.40</strong>&nbsp;and the value obtained here is matching with the mathematical formula given above.</p>



<h3 id="sign-off" class="wp-block-heading">Sign off</h3>



<p class="wp-block-paragraph">There are various other distributions which can be looked for (listed&nbsp;<a href="https://en.wikipedia.org/wiki/List_of_probability_distributions" target="_blank" rel="noopener">here</a>).&nbsp;I hope the above explanations helps the readers to have a good understanding about each of these distributions. This blog-post will help beginners in their data science journey as they will be able to identify, relate and differentiate among these distributions and apply these effectively in modeling data science problems.</p>



<p class="wp-block-paragraph">If you liked the post, follow this blog to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy learning distributions&nbsp;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing finbert-embedding PyPi Package: Using Fine-tuned Open source BERT model in Financial Domain</title>
		<link>https://www.mastersinmachinelearning.org/blog/introducing-finbert-embedding-pypi-package-using-fine-tuned-open-source-bert-model-in-financial-domain/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:46 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=354</guid>

					<description><![CDATA[https://appliedmachinelearning.blog/2020/01/22/introducing-finbert-embedding-pypi-bert-language-model-fine-tuned-on-financial-data This blog-post demonstrate the&#160;finbert-embedding&#160;pypi package which extracts token and sentence level embedding from FinBERT model (BERT language model fine-tuned on financial news articles). The finbert model was trained and open sourced by Dogu Tan Araci (University of Amsterdam). BERT, published by Google, is conceptually simple and empirically powerful as it obtained state-of-the-art results on ... <a title="Introducing finbert-embedding PyPi Package: Using Fine-tuned Open source BERT model in Financial Domain" class="read-more" href="https://www.mastersinmachinelearning.org/blog/introducing-finbert-embedding-pypi-package-using-fine-tuned-open-source-bert-model-in-financial-domain/" aria-label="Read more about Introducing finbert-embedding PyPi Package: Using Fine-tuned Open source BERT model in Financial Domain">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><a href="https://appliedmachinelearning.blog/2020/01/22/introducing-finbert-embedding-pypi-bert-language-model-fine-tuned-on-financial-data" target="_blank" rel="noopener">https://appliedmachinelearning.blog/2020/01/22/introducing-finbert-embedding-pypi-bert-language-model-fine-tuned-on-financial-data</a></p>



<p class="wp-block-paragraph">This blog-post demonstrate the&nbsp;<a href="https://pypi.org/project/finbert-embedding/" target="_blank" rel="noopener">finbert-embedding</a>&nbsp;pypi package which extracts token and sentence level embedding from FinBERT model (BERT language model fine-tuned on financial news articles). The finbert model was trained and open sourced by Dogu Tan Araci (University of Amsterdam).</p>



<p class="wp-block-paragraph">BERT, published by Google, is conceptually simple and empirically powerful as it obtained state-of-the-art results on eleven natural language processing tasks.</p>



<p class="wp-block-paragraph">The objective of this project is to obtain the word or sentence embeddings from FinBERT, pre-trained model by Dogu Tan Araci. FinBERT, which is a BERT language model further trained on financial news articles for adapting financial domain. It achieved the state-of-the-art on FiQA sentiment scoring and Financial PhraseBank dataset. Paper&nbsp;<a href="https://arxiv.org/abs/1908.10063" target="_blank" rel="noopener">here</a>.</p>



<p class="wp-block-paragraph">Instead of building and perform fine-tuning for an end-to-end NLP model, You can directly utilize word embeddings from Financial BERT to build NLP models for various downstream tasks eg. Text clustering or Word clustering or Extractive summarization etc.</p>



<h2 id="features" class="wp-block-heading">Features</h2>



<ul class="wp-block-list">
<li>Creates an abstraction to remove dealing with inferencing the pre-trained FinBERT model.</li>



<li>Require only two lines of code to get sentence or token-level encoding for a text sentence.</li>



<li>The package takes care of OOVs (out of vocabulary) inherently.</li>



<li>Downloads and installs FinBERT pre-trained model (during first initialization, usage in next section).</li>
</ul>



<h2 id="install" class="wp-block-heading">Install</h2>



<p class="wp-block-paragraph">(Recommended to create a conda env to have isolation and avoid dependency clashes)</p>



<pre class="wp-block-code"><code>pip install finbert-embedding==0.1.4
</code></pre>



<p class="wp-block-paragraph">Note: If you get error in installing this package (common error with Tensorflow):</p>



<p class="wp-block-paragraph">Installing collected packages: wrapt, tensorflow<br>Found existing installation: wrapt 1.10.11<br>ERROR: Cannot uninstall ‘wrapt’. It is a distutils installed project……</p>



<p class="wp-block-paragraph">then, just do this:</p>



<pre class="wp-block-preformatted">pip install wrapt --upgrade --ignore-installed
pip install finbert-embedding==0.1.4
</pre>



<h2 id="usage-1" class="wp-block-heading">Usage 1</h2>



<p class="wp-block-paragraph"><strong>Token/Sentence Embedding Extraction</strong></p>



<p class="wp-block-paragraph">Word embeddings generated are list of 768 dimensional embeddings for each word.<br>Sentence embedding generated is 768 dimensional embedding which is average of each token.</p>



<p class="wp-block-paragraph">One can also set&nbsp;<code>model_path</code>&nbsp;parameter in&nbsp;<code>FinbertEmbedding()</code>&nbsp;class to extract token/sentence embeddings from any other fine-tuned or even original BERT model. FinBERT model automatically gets downloaded from the dropbox as the class initialization is done i.e.&nbsp;<code>finbert = FinbertEmbedding()</code></p>



<pre class="wp-block-preformatted">from finbert_embedding.embedding import FinbertEmbedding

text = "Another PSU bank, Punjab National Bank which also reported numbers managed to see a slight improvement in asset quality."

# Class Initialization (You can set default 'model_path=None' as your finetuned BERT model path while Initialization)
finbert = FinbertEmbedding()

word_embeddings = finbert.word_vector(text)
sentence_embedding = finbert.sentence_vector(text)

print("Text Tokens: ", finbert.tokens)
# Text Tokens:  ['another', 'psu', 'bank', ',', 'punjab', 'national', 'bank', 'which', 'also', 'reported', 'numbers', 'managed', 'to', 'see', 'a', 'slight', 'improvement', 'in', 'asset', 'quality', '.']

print ('Shape of Word Embeddings: %d x %d' % (len(word_embeddings), len(word_embeddings[0])))
# Shape of Word Embeddings: 21 x 768

print("Shape of Sentence Embedding = ",len(sentence_embedding))
# Shape of Sentence Embedding =  768
</pre>



<h2 id="usage-2" class="wp-block-heading">Usage 2</h2>



<p class="wp-block-paragraph"><strong>Similarity or Text Comparison</strong></p>



<p class="wp-block-paragraph">A decent representation for a downstream task doesn’t mean that it will be meaningful in terms of cosine distance. Since cosine distance is a linear space where all dimensions are weighted equally. if you want to use cosine distance anyway, then please focus on the rank not the absolute value.</p>



<p class="wp-block-paragraph">Namely, do not use:<br>if cosine(A, B) &gt; 0.9, then A and B are similar</p>



<p class="wp-block-paragraph">Please consider the following instead:<br>if cosine(A, B) &gt; cosine(A, C), then A is more similar to B than C.</p>



<pre class="wp-block-preformatted">from finbert_embedding.embedding import FinbertEmbedding

text = "After stealing money from the bank vault, the bank robber was seen fishing on the Mississippi river bank."
finbert = FinbertEmbedding()
word_embeddings = finbert.word_vector(text)

from scipy.spatial.distance import cosine
diff_bank = 1 - cosine(word_embeddings[9], word_embeddings[18])
same_bank = 1 - cosine(word_embeddings[9], word_embeddings[5])

print('Vector similarity for similar bank meanings (bank vault &amp; bank robber):  %.2f' % same_bank)
print('Vector similarity for different bank meanings (bank robber &amp; river bank):  %.2f' % diff_bank)

# Vector similarity for similar bank meanings (bank vault &amp; bank robber):  0.92
# Vector similarity for different bank meanings (bank robber &amp; river bank):  0.64
</pre>



<h3 id="warning" class="wp-block-heading">Warning</h3>



<p class="wp-block-paragraph">According to BERT author Jacob Devlin:&nbsp;<code>I'm not sure what these vectors are, since BERT does not generate meaningful sentence vectors. It seems that this is doing average pooling over the word tokens to get a sentence vector, but we never suggested that this will generate meaningful sentence representations. And even if they are decent representations when fed into a DNN trained for a downstream task, it doesn't mean that they will be meaningful in terms of cosine distance. (Since cosine distance is a linear space where all dimensions are weighted equally).</code></p>



<p class="wp-block-paragraph">However, with the [CLS] token, it does become meaningful if the model has been fine-tuned, where the last hidden layer of this token is used as the “sentence vector” for downstream sequence classification task. This package encode sentence by average pooling over all word tokens. It would be definitely good to experiment with sentence embeddings for similarity purposes.</p>



<h3 id="to-do-next-version" class="wp-block-heading">To Do (Next Version)</h3>



<ul class="wp-block-list">
<li>Extend it to give word embeddings for a paragraph/Document (Currently, it takes one sentence as input). Chunkize your paragraph or text document into sentences using Spacy or NLTK before using finbert_embedding.</li>



<li>Adding batch processing feature.</li>



<li>More ways of handing OOVs (Currently, uses average of all tokens of a OOV word).</li>
</ul>



<h3 id="future-goal" class="wp-block-heading">Future Goal</h3>



<ul class="wp-block-list">
<li>Create generic downstream framework using FinBERT language model for any financial labelled text classification task like sentiment classification, Financial news classification, Financial Document classification etc.</li>
</ul>



<p class="wp-block-paragraph">One can check the package&nbsp;<a href="https://pypi.org/project/finbert-embedding/" target="_blank" rel="noopener">here</a>&nbsp;at PyPi and codes for token/sentence embedding extraction at GitHub&nbsp;<a href="https://github.com/abhijeet3922/finbert_embedding" target="_blank" rel="noopener">here</a>.</p>



<p class="wp-block-paragraph">Happy Deep Learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Extractive Text Summarization using Glove Vectors</title>
		<link>https://www.mastersinmachinelearning.org/blog/extractive-text-summarization-using-glove-vectors/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:45 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=350</guid>

					<description><![CDATA[https://appliedmachinelearning.blog/2019/12/31/extractive-text-summarization-using-glove-vectors Text summarization is one of famous NLP application which had been researched a lot and still at its nascent stage compared to manual summarization. In simple terms, the objective is to condense unstructured text of an article into a summary automatically. There are two types of summarization techniques. Extractive Summarization Extractive summarization is extracting ... <a title="Extractive Text Summarization using Glove Vectors" class="read-more" href="https://www.mastersinmachinelearning.org/blog/extractive-text-summarization-using-glove-vectors/" aria-label="Read more about Extractive Text Summarization using Glove Vectors">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><a href="https://appliedmachinelearning.blog/2019/12/31/extractive-text-summarization-using-glove-vectors" target="_blank" rel="noopener">https://appliedmachinelearning.blog/2019/12/31/extractive-text-summarization-using-glove-vectors</a></p>



<p class="wp-block-paragraph">Text summarization is one of famous NLP application which had been researched a lot and still at its nascent stage compared to manual summarization. In simple terms, the objective is to condense unstructured text of an article into a summary automatically. There are two types of summarization techniques.</p>



<ol class="wp-block-list">
<li>Extractive Summarization</li>



<li>Abstractive Summarization</li>
</ol>



<h3 id="extractive-summarization" class="wp-block-heading">Extractive Summarization</h3>



<p class="wp-block-paragraph">Extractive summarization is extracting the most important sentences from whole document which would coherently represent the document. The number of sentences picked may depend on the compression ratio of summary. There could be multiple approaches depending on the summarization application. For example,</p>



<ul class="wp-block-list">
<li>For summarizing the reviews, we may want to pick highly positive and negative sentences as summary.</li>



<li>Another approach could be picking only the sentences which contains some object/entity (Company name, person, dates, location etc).</li>



<li>Also, if we want to summarize a report or an article, we may want to pick the important or say main sentences from the article. Here, the problem of summarization converges to the problem “How do we know the main/important sentences (Text Rank algorithm)”. This problem is very similar to “How does google searches for important web pages from so many web pages having similar content” (Page Rank algorithm). It is an unsupervised approach.</li>
</ul>



<h3 id="abstractive-summarization" class="wp-block-heading">Abstractive Summarization</h3>



<p class="wp-block-paragraph">This is a hard problem. We want to produce a summary which corresponds to how a professional writer would summarize an article. Abstractive summarizers are generative models as it may come up with a summary containing new words (as opposed to picking existing sentences). Also, an abstractive summarization requires supervised learning procedure to learn how a professionally supervised summary looks like given long articles. There are lot of deep learning models which had been researched for this purpose. Interested readers can check the links&nbsp;<a href="https://arxiv.org/abs/1602.06023" target="_blank" rel="noopener">here</a>,&nbsp;<a href="https://arxiv.org/abs/1704.04368" target="_blank" rel="noopener">here</a>&nbsp;and&nbsp;<a href="https://arxiv.org/abs/1903.10318" target="_blank" rel="noopener">here</a>. Still, it is an active area of research.</p>



<p class="wp-block-paragraph">This blog post demonstrate extractive summarization using TextRank algorithm (similar to pagerank) in an unsupervised manner. The underlying metric for calculation of ranking is similarity matrix which is similarity of each sentence with all the other sentence in article. We use glove vectors to calculating similarity scores among sentences.</p>



<h3 id="1-imports" class="wp-block-heading">1. Imports</h3>



<p class="wp-block-paragraph">I downloaded the pretrained glove vectors (1.9M vocab words, 300 dim) from&nbsp;<a href="http://nlp.stanford.edu/data/glove.42B.300d.zip" target="_blank" rel="noopener">here</a>.</p>



<pre class="wp-block-preformatted">import os
import re
import string
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
from nltk.tokenize import sent_tokenize
from nltk.stem.wordnet import WordNetLemmatizer
from sklearn.metrics.pairwise import cosine_similarity

gloveFile = "../glove.42B.300d.txt"
dim=300
</pre>



<h3 id="2-custom-functions-preprocessing" class="wp-block-heading">2. Custom Functions: Preprocessing</h3>



<p class="wp-block-paragraph">Below are the 3 python functions for:</p>



<ul class="wp-block-list">
<li>removing non-ascii characters,</li>



<li>preprocessing and cleaning stop words, punctuation marks and digits</li>



<li>creating and loading word to glove embedding dictionary.</li>
</ul>



<pre class="wp-block-preformatted">stop = set(stopwords.words('english'))
exclude = set(string.punctuation)
lemma = WordNetLemmatizer()

def rem_ascii(s):
    return "".join([c for c in s if ord(c) &lt; 128 ])

# Cleaning the text sentences so that punctuation marks, stop words and digits are removed.
def clean(doc):
    stop_free = " ".join([i for i in doc.lower().split() if i not in stop])
    punc_free = ''.join(ch for ch in stop_free if ch not in exclude)
    processed = re.sub(r"\d+","",punc_free)
    return processed

def loadGloveModel(gloveFile):
    word_embeddings = {}
    f = open(gloveFile, encoding='utf-8')
    for line in f:
        values = line.split()
        word = values[0]
        coefs = np.asarray(values[1:], dtype='float32')
        word_embeddings[word] = coefs
    f.close()
    return word_embeddings

word_embeddings = loadGloveModel(gloveFile)
</pre>



<p class="wp-block-paragraph">The above steps are important as we want to only choose important words of sentence for similarity scoring. Readers can check the vocabulary size of this glove model below (1.9M).</p>



<pre class="wp-block-preformatted">print("Vocab Size = ",len(word_embeddings))
</pre>



<pre class="wp-block-preformatted">Vocab Size =  1917494</pre>



<p class="wp-block-paragraph">Next, we chose a news article which talks about blocking of customer debit cards of certain banks from year 2020 to meet international payment standards. We used NLTK sentence tokenizer to tokenize the article paragraph into sentences.</p>



<pre class="wp-block-preformatted">text = """SBI, PNB, HDFC, ICICI,  Debit Card Customers: If you are using a bank debit card which doesn't have EMV (Europay, Mastercard and Visa), then you may have to face a problem during money withdrawal from the ATM after 31st December 2019 as your debit card may be blocked from 1st january 2020. According to the Reserve Bank of India (RBI) guidelines, all Indian banks need to replace the magnetic debit card of their customers with a new EMV card. This debit card replacement is mandatory as it is aimed at meeting the international payment standards. Hence, SBI, PNB, HDFC Bank, ICICI Bank or any other bank customers who are using a magnetic debit card are advised to replace their debit card otherwise they will have to face difficulty in money withdrawal from the ATM. The RBI guidelines say all Indian banks will have to replace all magnetic chip-based debit cards with EMV and PIN-based cards by 31st December 2019. Keeping in view of the continuing online frauds on magnetic stripe cards, the RBI has proposed to deactivate them by 31st December 2019. So, all magnetic chip-based debit cards will be deactivated from 1st January 2020 (irrespective of the validity of the existing magnetic SBI debit cards). All banks are sending messages to their customers via various means asking them to replace their magnetic chip-based debit card by a new EMV debit card. The SBI warned its debit cardholders through a tweet citing, "Apply now to change your Magnetic Stripe Debit Cards to the more secure EMV Chip and PIN-based SBI Debit card at your home branch by 31st December 2019. Safeguard yourself with guaranteed authenticity, greater security for online payments and added security against fraud". So, the SBI has made it clear that SBI debit card will be blocked if it is a magnetic card. In fact, the SBI has already started deactivating the SBI cards of those SBI accounts in which PAN or Form 60 is not updated."""
print(text)
sentences = sent_tokenize(text)
cleaned_texts = [rem_ascii(clean(sentence)) for sentence in sentences]
</pre>



<figure class="wp-block-image" id="attachment_10529"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2021/05/a25d6-news_article.png?w=616" alt="news_article" class="wp-image-10529"/><figcaption class="wp-element-caption">Text Article</figcaption></figure>



<h3 id="3-sentence-embeddings-from-glove" class="wp-block-heading">3. Sentence Embeddings from Glove</h3>



<p class="wp-block-paragraph">Idea is very simple. We simply calculate the average of embeddings of all the words present the sentence. We have already removed stop words, digits etc which do not contribute to similarity scoring.</p>



<pre class="wp-block-preformatted">sentence_vectors = []
for i in cleaned_texts:
    if len(i) != 0:
        v = sum([word_embeddings.get(w, np.zeros((dim,))) for w in i.split()])/(len(i.split())+0.001)
    else:
        v = np.zeros((dim,))
    sentence_vectors.append(v)
</pre>



<h3 id="4-similarity-matrix" class="wp-block-heading">4. Similarity Matrix</h3>



<p class="wp-block-paragraph">We have 300 dimensional vector for each sentence of article now. We create a similarity matrix which keeps cosine distance of each sentences to every other sentence. It is obvious that the matrix is symmetric in nature. Below codes produces matrix and graph to display how a similarity matrix would look like.</p>



<pre class="wp-block-preformatted">sim_mat = np.zeros([len(cleaned_texts), len(cleaned_texts)])
for i in range(len(sentences)):
    for j in range(len(sentences)):
        if i != j:
            sim_mat[i][j] = cosine_similarity(sentence_vectors[i].reshape(1,dim),sentence_vectors[j].reshape(1,dim))[0,0]
sim_mat = np.round(sim_mat,3)
print(sim_mat)

# Creating the network graph
nx_graph = nx.from_numpy_array(sim_mat)
plt.figure(figsize=(10, 10))
pos = nx.spring_layout(nx_graph)
nx.draw(nx_graph, with_labels=True, font_weight='bold')
nx.draw_networkx_edge_labels(nx_graph,pos,font_color='red')
plt.show()
</pre>


<div class="wp-block-image">
<figure class="aligncenter" id="attachment_10534"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2021/05/96fc8-sent_similarity_matrix.png?w=616" alt="sent_similarity_matrix.png" class="wp-image-10534"/><figcaption class="wp-element-caption">Similarity Matrix</figcaption></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter" id="attachment_10547"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2021/05/9f4d5-graph_network.png?w=542&amp;h=542" alt="graph_network" class="wp-image-10547"/><figcaption class="wp-element-caption">Similarity Graph (NetworkX&nbsp; pypi)</figcaption></figure>
</div>


<h3 id="5-text-rank-algorithm" class="wp-block-heading">5. Text Rank Algorithm</h3>



<p class="wp-block-paragraph">Text rank algorithm is inspired from the famous Google’s PageRank algorithm. The underlying assumption of PageRank algorithm is that more important websites are likely to receive more links from other websites. It counts the number and quality of links to a page to determine a rough estimate of how important the website is. An illustrative image (taken from wikipedia) showing the importance of webpage can be seen below.</p>



<figure class="wp-block-image" id="attachment_10544"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2021/05/ae7c1-pageranks-example.jpg?w=616" alt="PageRanks-Example" class="wp-image-10544"/><figcaption class="wp-element-caption">PageRank illustration</figcaption></figure>



<p class="wp-block-paragraph">Similar to PageRank, The underlying assumption of text rank algorithm is that the summary sentences are similar (or linked) to most of the other sentences. Essentially, it runs PageRank on similarity graph designed in previous section. It builds a graph using some set of text sentences as vertices. Edges are based on measure of semantic similarity (glove embedding based) between the text sentence vertices.</p>



<pre class="wp-block-preformatted">scores = nx.pagerank(nx_graph)
print(scores)
</pre>


<div class="wp-block-image">
<figure class="aligncenter" id="attachment_10530"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2021/05/797bc-rank_sentence.png?w=202&amp;h=196" alt="rank_sentence" class="wp-image-10530"/><figcaption class="wp-element-caption">12 sentences: Scores from PageRank</figcaption></figure>
</div>


<h3 id="6-result" class="wp-block-heading">6. Result</h3>



<p class="wp-block-paragraph">As we got the ranked score of all the 12 sentences in the article. There are simply two steps which had been implemented next.</p>



<ol class="wp-block-list">
<li>Sort the sentences in decreasing order of their score. (Also, preserve the index of sentences).</li>



<li>Choose half of the sentences from top (Compression ratio 0.5) and sort it again based on their increasing indices. This will ensure that summary is coherent with original article (picked sentences are in order).</li>
</ol>



<pre class="wp-block-preformatted">ranked_sentences = sorted(((scores[i],i) for i,s in enumerate(sentences)), reverse=True)
arranged_sentences = sorted(ranked_sentences[0:int(len(sentences)*0.5)], key=lambda x:x[1])
print("\n".join([sentences[x[1]] for x in arranged_sentences]))
</pre>



<figure class="wp-block-image" id="attachment_10531"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2021/05/ee43e-final_arraneged.png?w=616" alt="final_arraneged" class="wp-image-10531"/><figcaption class="wp-element-caption">Summarized Text (Compression = 50%)</figcaption></figure>



<h3 id="at-the-end" class="wp-block-heading">At the End</h3>



<p class="wp-block-paragraph">The application of text summarization could be limitless. The blog-post demonstrates one technique to do so. Also, this is not enough as it only picks the main (kind of) sentences. Abstractive summarization is a way to go but it’s at early stage and an activate area of research. As far as sentence based extractive summarization is concerned, The similarity measure among sentences could be one of the various metrics available. For example,</p>



<ul class="wp-block-list">
<li>tf-idf score</li>



<li>word2vec based similarity</li>



<li>doc2vec (sentence to vec)</li>



<li>word embeddings from deep learning models like ELMO or BERT based.</li>
</ul>



<p class="wp-block-paragraph">If you liked the post, follow this blog to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy machine learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Developing Factoid Question Answering System on bAbI Facebook Data-set: Python &#124; Keras (Part 1)</title>
		<link>https://www.mastersinmachinelearning.org/blog/developing-factoid-question-answering-system-on-babi-facebook-data-set-python-keras-part-1/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:44 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=330</guid>

					<description><![CDATA[Question answering system is a field of information retrieval and natural language processing which is concerned with building systems that automatically answer questions asked by a human. Ideally, the task would like a English reading comprehension task where given a passage or paragraph, system would be able to process texts, understand it and correctly answer ... <a title="Developing Factoid Question Answering System on bAbI Facebook Data-set: Python &#124; Keras (Part 1)" class="read-more" href="https://www.mastersinmachinelearning.org/blog/developing-factoid-question-answering-system-on-babi-facebook-data-set-python-keras-part-1/" aria-label="Read more about Developing Factoid Question Answering System on bAbI Facebook Data-set: Python &#124; Keras (Part 1)">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Question answering system is a field of information retrieval and natural language processing which is concerned with building systems that automatically answer questions asked by a human. Ideally, the task would like a English reading comprehension task where given a passage or paragraph, system would be able to process texts, understand it and correctly answer the questions from the passage like we human do.</p>



<p class="wp-block-paragraph">I will be covering this task in couple of blog-posts. The purpose of the blog-post series is to build the question answering toy application understanding each step and provide an insight of implementation of the same to our readers.</p>



<h3 id="the-task" class="wp-block-heading">The Task</h3>



<p class="wp-block-paragraph">In 2015, Facebook came up with a bAbI data-set and 20 toy tasks for testing text understanding and reasoning in the bAbI project. The tasks are described in detail in the paper&nbsp;<a href="https://arxiv.org/abs/1502.05698#" target="_blank" rel="noopener">here</a>&nbsp;and GitHub link&nbsp;<a href="https://github.com/facebook/bAbI-tasks" target="_blank" rel="noopener">here</a>. The aim is that each task tests a unique aspect of text and reasoning, and hence test different capabilities of learning models. In this blog-post, we will demonstrate one of the toy task named : “<em>Basic factoid QA with single supporting fact</em>“. The task is very simple illustrated below.</p>



<pre class="wp-block-preformatted">Sandra travelled to the kitchen. 
Sandra travelled to the hallway. 
Mary went to the bathroom. 
Sandra moved to the garden. 

Where is Sandra ?
Ground Truth: Garden (based on single supporting fact 4)</pre>



<p class="wp-block-paragraph">Looking at this reasoning task per se, is not generic in nature and answer is only based on single supporting fact from the story. The learning model should be able to learn the sequence of events and then answer the question “<em>Where is Actor ?</em>“.&nbsp; Factoid QA means the answer would be single word.</p>



<h3 id="babi-dataset" class="wp-block-heading">bAbI Dataset</h3>



<p class="wp-block-paragraph">For the aforementioned task, We have 10,000 training examples and 1000 testing examples.</p>



<p class="wp-block-paragraph">The file format for the task is as follows:</p>



<pre class="wp-block-preformatted">ID text
ID text
ID text
ID question[tab]answer[tab]supporting_fact ID.
...</pre>



<p class="wp-block-paragraph">Each sentence is provided with an ID. The IDs for a given “story” start at 1 and increase. When the IDs in a file reset back to 1 you can consider the following sentences as a new “story”. Supporting fact ID refer to the sentences within a “story”.</p>



<pre class="wp-block-preformatted">1 Mary moved to the bathroom.
2 John went to the hallway.
3 Where is Mary?        bathroom        <strong>1</strong>
4 Daniel went back to the hallway.
5 Sandra moved to the garden.
6 Where is Daniel?      hallway         <strong>4</strong>
7 John moved to the office.
8 Sandra journeyed to the bathroom.
9 Where is Daniel?      hallway         <strong>4</strong>
10 Mary moved to the hallway.
11 Daniel travelled to the office.
12 Where is Daniel?     office          <strong>11</strong>
13 John went back to the garden.
14 John moved to the bedroom.
15 Where is Sandra?     bathroom        <strong>8</strong>
1 Sandra travelled to the office.
2 Sandra went to the bathroom.
3 Where is Sandra?      bathroom        <strong>2</strong></pre>



<p class="wp-block-paragraph">Further in the following sections, we will go step by step from</p>



<ul class="wp-block-list">
<li>Getting data</li>



<li>Getting User Stories : Pre-Processing</li>



<li>Feature Extraction</li>



<li>Building Memory Network model</li>



<li>Train the Model</li>



<li>Tests &amp; Results</li>
</ul>



<h3 id="1-getting-data" class="wp-block-heading">1. Getting Data</h3>



<p class="wp-block-paragraph"><strong>Importing Libraries</strong></p>



<pre class="wp-block-preformatted">import re
import tarfile
import numpy as np
from functools import reduce
from keras.utils.data_utils import get_file
from keras.preprocessing.sequence import pad_sequences
</pre>



<p class="wp-block-paragraph"><strong>Downloading Data</strong></p>



<pre class="wp-block-preformatted">try:
    #tar.gz data-set get saved on "~/.keras/datasets/" path
    path = get_file('babi-tasks-v1-2.tar.gz', origin='https://s3.amazonaws.com/text-datasets/babi_tasks_1-20_v1-2.tar.gz')
except:
    print('Error downloading dataset, please download it manually:\n'
          '$ wget http://www.thespermwhale.com/jaseweston/babi/tasks_1-20_v1-2.tar.gz\n'
          '$ mv tasks_1-20_v1-2.tar.gz ~/.keras/datasets/babi-tasks-v1-2.tar.gz')
    raise

#reading a tar.gz file
tar = tarfile.open(path)
</pre>



<p class="wp-block-paragraph">If you are not able to download, The data-set can be downloaded from&nbsp;<a href="https://www.dropbox.com/s/iglkh5xswzr1dqj/en-10k.zip?dl=0" target="_blank" rel="noopener">here</a>&nbsp;manually.</p>



<h3 id="2-getting-user-stories-preprocessing" class="wp-block-heading">2. Getting User Stories : Pre-processing</h3>



<p class="wp-block-paragraph">This is a crucial step where we need to ingest the train and test file and extract stories out of it. The raw format in which text stories, questions and answers are kept is aforementioned. Initially, we will write some helper functions.</p>



<pre class="wp-block-preformatted">def tokenize(sent):
    '''
    argument: a sentence string
    returns a list of tokens(words)
    '''
    return [ x.strip() for x in re.split('(\W+)?', sent) if x.strip()]

def parse_stories(lines):
    '''
    - Parse stories provided in the bAbI tasks format
    - A story starts from line 1 to line 15. Every 3rd line,
      there is a question &amp;amp;amp;amp; answer.
    - Function extracts sub-stories within a story and
      creates tuples
    '''
    data = []
    story = []
    for line in lines:
        line = line.decode('utf-8').strip()
        nid, line = line.split(' ', 1)
        nid = int(nid)
        if nid == 1:
            # reset story when line ID=1 (start of new story)
            story = []
        if '\t' in line:
            # this line is tab separated Q, A &amp;amp;amp;amp; support fact ID
            q, a, supporting = line.split('\t')
            # tokenize the words of question
            q = tokenize(q)
            # Provide all the sub-stories till this question
            substory = [x for x in story if x]
            # A story ends and is appended to global story data-set
            data.append((substory, q, a))
            story.append('')
        else:
            # this line is a sentence of story
            sent = tokenize(line)
            story.append(sent)
    return data

def get_stories(f):
    '''
    argument: filename
    returns list of all stories in the argument data-set file
    '''
    # read the data file and parse 10k stories
    data = parse_stories(f.readlines())
    # lambda func to flatten the list of sentences into one list
    flatten = lambda data: reduce(lambda x, y: x + y, data)
    # creating list of tuples for each story
    data = [(flatten(story), q, answer) for story, q, answer in data]
    return data
</pre>



<p class="wp-block-paragraph">Further, we use the above helper functions to get the train and test stories.</p>



<pre class="wp-block-preformatted">challenge = 'tasks_1-20_v1-2/en-10k/qa1_single-supporting-fact_{}.txt'
print('Extracting stories for the challenge: single_supporting_fact_10k')
# Extracting train stories
train_stories = get_stories(tar.extractfile(challenge.format('train')))
# Extracting test stories
test_stories = get_stories(tar.extractfile(challenge.format('test')))
</pre>



<p class="wp-block-paragraph">To validate that the stories are extracted properly, we can simply check the number of stories in train and test stories variables. Also, let us see how a story looks like as of now.</p>



<pre class="wp-block-preformatted">print('Number of training stories:', len(train_stories))
print('Number of test stories:', len(test_stories))
train_stories[0]
</pre>



<figure class="wp-block-image" id="attachment_9232"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/train_user_story-1.png?w=616" alt="user story bAbI dataset" class="wp-image-9232"/><figcaption class="wp-element-caption">bAbI data-set story sample</figcaption></figure>



<h3 id="3-feature-extraction" class="wp-block-heading">3. Feature Extraction</h3>



<p class="wp-block-paragraph">Let us first write a helper function to vectorize each stories in order to fetch it to memory network model which we will be creating later.</p>



<pre class="wp-block-preformatted">def vectorize_stories(data, word_idx, story_maxlen, query_maxlen):
    # story vector initialization
    X = []
    # query vector initialization
    Xq = []
    # answer vector intialization
    Y = []
    for story, query, answer in data:
        # creating list of story word indices
        x = [word_idx[w] for w in story]
        # creating list of query word indices
        xq = [word_idx[w] for w in query]
        # let's not forget that index 0 is reserved
        y = np.zeros(len(word_idx) + 1)
        # creating label 1 for the answer word index
        y[word_idx] = 1
        X.append(x)
        Xq.append(xq)
        Y.append(y)
    return (pad_sequences(X, maxlen=story_maxlen),
            pad_sequences(Xq, maxlen=query_maxlen), np.array(Y))
</pre>



<p class="wp-block-paragraph">The following snippet creates a vocabulary dictionary and extract word indices vectors as input features.</p>



<pre class="wp-block-preformatted"># creating vocabulary of words in train and test set
vocab = set()
for story, q, answer in train_stories + test_stories:
    vocab |= set(story + q + [answer])

# sorting the vocabulary
vocab = sorted(vocab)

# Reserve 0 for masking via pad_sequences
vocab_size = len(vocab) + 1

# calculate maximum length of story
story_maxlen = max(map(len, (x for x, _, _ in train_stories + test_stories)))

# calculate maximum length of question/query
query_maxlen = max(map(len, (x for _, x, _ in train_stories + test_stories)))

# creating word to index dictionary
word_idx = dict((c, i + 1) for i, c in enumerate(vocab))

# creating index to word dictionary
idx_word = dict((i+1, c) for i,c in enumerate(vocab))

# vectorize train story, query and answer sentences/word using vocab
inputs_train, queries_train, answers_train = vectorize_stories(train_stories,
                                                               word_idx,
                                                               story_maxlen,
                                                               query_maxlen)
# vectorize test story, query and answer sentences/word using vocab
inputs_test, queries_test, answers_test = vectorize_stories(test_stories,
                                                            word_idx,
                                                            story_maxlen,
                                                            query_maxlen)
</pre>



<p class="wp-block-paragraph">We have prepared the feature vectors for our toy question and answering system. Let us display some analysis on the extracted vectors. The below python code snippets are used to explore and see how these vectors and vocabulary looks like.</p>



<pre class="wp-block-preformatted">print('-------------------------')
print('Vocabulary:\n',vocab,"\n")
print('Vocab size:', vocab_size, 'unique words')
print('Story max length:', story_maxlen, 'words')
print('Query max length:', query_maxlen, 'words')
print('Number of training stories:', len(train_stories))
print('Number of test stories:', len(test_stories))
print('-------------------------')
</pre>



<figure class="wp-block-image" id="attachment_9228"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/vocab.png?w=616" alt="vocabulary bAbI dataset" class="wp-image-9228"/><figcaption class="wp-element-caption">vocabulary list</figcaption></figure>



<pre class="wp-block-preformatted">print('-------------------------')
print('inputs: integer tensor of shape (samples, max_length)')
print('inputs_train shape:', inputs_train.shape)
print('inputs_test shape:', inputs_test.shape)
print('input train sample', inputs_train[0,:])
print('-------------------------')
</pre>



<figure class="wp-block-image" id="attachment_9227"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/story_vector.png?w=616" alt="story vector" class="wp-image-9227"/><figcaption class="wp-element-caption">story vector with word indices</figcaption></figure>



<pre class="wp-block-preformatted">print('-------------------------')
print('queries: integer tensor of shape (samples, max_length)')
print('queries_train shape:', queries_train.shape)
print('queries_test shape:', queries_test.shape)
print('query train sample', queries_train[0,:])
print('-------------------------')
</pre>



<figure class="wp-block-image" id="attachment_9229"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/query_vector.png?w=616" alt="query vector" class="wp-image-9229"/><figcaption class="wp-element-caption">question vector with word indices</figcaption></figure>



<pre class="wp-block-preformatted">print('-------------------------')
print('answers: binary (1 or 0) tensor o&amp;amp;amp;lt;span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"&amp;amp;amp;gt;&amp;amp;amp;lt;/span&amp;amp;amp;gt;f shape (samples, vocab_size)')
print('answers_train shape:', answers_train.shape)
print('answers_test shape:', answers_test.shape)
print('answer train sample', answers_train[0,:])
print('-------------------------')
</pre>



<figure class="wp-block-image" id="attachment_9230"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/answer_vector.png?w=616" alt="answer vector" class="wp-image-9230"/><figcaption class="wp-element-caption">one hot encoded answer vector</figcaption></figure>



<h3 id="whats-next" class="wp-block-heading">What’s Next ?</h3>



<p class="wp-block-paragraph">Hope it was easy to go through tutorial as I have tried to keep each step precisely and explainable in order to understand and reproduce (till feature extraction). Most of the codes are commented to make the logic clear. In the subsequent blog-post (<a href="https://appliedmachinelearning.wordpress.com/2019/05/02/building-end-to-end-memory-network-for-qa-system-on-babi-facebook-data-set-python-keras-part-2/" target="_blank" rel="noopener">PART 2</a>), we will walk through the following steps using Keras to train a neural network model for question answering system.</p>



<ol class="wp-block-list">
<li>Understanding &amp; Building Memory Network Model</li>



<li>Training the Model</li>



<li>Visualization</li>



<li>Tests Results &amp; Demo</li>
</ol>



<p class="wp-block-paragraph">If you liked the post,&nbsp;<em><strong>follow this blog</strong></em>&nbsp;to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy deep learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Developing a fast Indexing and Full text Search Engine with Whoosh: A Pure-Python Library</title>
		<link>https://www.mastersinmachinelearning.org/blog/developing-a-fast-indexing-and-full-text-search-engine-with-whoosh-a-pure-python-library/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:43 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=310</guid>

					<description><![CDATA[Problem Statement: To simply put, You have 1 million text files in a directory and your application must cater text query search on all files within few seconds (say ~1-2 seconds). How will you develop such system !!. Motivation: The idea came from my previous post “Performing OCR by running parallel instances of Tesseract 4.0 ... <a title="Developing a fast Indexing and Full text Search Engine with Whoosh: A Pure-Python Library" class="read-more" href="https://www.mastersinmachinelearning.org/blog/developing-a-fast-indexing-and-full-text-search-engine-with-whoosh-a-pure-python-library/" aria-label="Read more about Developing a fast Indexing and Full text Search Engine with Whoosh: A Pure-Python Library">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Problem Statement: To simply put, You have 1 million text files in a directory and your application must cater text query search on all files within few seconds (say ~1-2 seconds). How will you develop such system !!.</p>



<p class="wp-block-paragraph">Motivation: The idea came from my previous post “<a href="https://atomic-temporary-123006597.wpcomstaging.com/2018/06/30/performing-ocr-by-running-parallel-instances-of-tesseract-4-0-python/" target="_blank" rel="noopener">Performing OCR by running parallel instances of Tesseract 4.0 :&nbsp;Python</a>“. Saying that following could be some use cases where you may have to build such search engine on top of other applications. e.g.</p>



<ul class="wp-block-list">
<li>You have built an OCR app and converted millions of images into text files. You may want to build a search engine over converted text files to search contents of images.</li>



<li>You have built a speech to text system where you are converting thousands of recorded audios into text data. You may like to search contents of audio in real time.</li>
</ul>



<p class="wp-block-paragraph">Here is a video demonstration of an desktop app developed in QT. It is a whoosh python implementation working in back end.</p>



<h3 id="introduction-whoosh" class="wp-block-heading">Introduction: Whoosh</h3>



<p class="wp-block-paragraph">Some of you might have heard about a popular java based library “<a href="https://lucene.apache.org/core/" target="_blank" rel="noopener">Lucene</a>” which is a search engine library written entirely in Java. You may find a python wrapper for Lucene. If you are looking for similar pythonic library, “Whoosh” is the one. Whoosh is a fast, featureful full-text indexing and searching library implemented in pure Python. Programmers can use it to easily add search functionality to their applications and websites.</p>



<p class="wp-block-paragraph">Whoosh pypi package can simply be installed with pip:<br><code>pip install Whoosh</code></p>



<p class="wp-block-paragraph">For the example demonstrated in this blog-post, You can download&nbsp; a data-set of 70,000 text files which were taken from simple wiki articles from&nbsp;.</p>



<h3 id="1-creating-indexed-data-whoosh" class="wp-block-heading">1. Creating Indexed Data: Whoosh</h3>



<p class="wp-block-paragraph">It is easy to index all your text files with Whoosh. Initially, the schema of the index has to be defined. Schema defines list of fields to be indexed or stored for each text file. It’s similar to how we define it for database. A field is a piece of information for each document in the index, such as its title or text content. Indexing of a field means it can be searched and it is also returned with results if defined as argument (stored=True) in schema. You only need to create the schema once while creating the index.</p>



<p class="wp-block-paragraph">Finally, all the text documents are added to index writer in loop. Documents are indexed as per schema and has to be added as per schema design. Below is the python implementation for indexing&nbsp; all the text documents of a directory.</p>



<pre class="wp-block-preformatted">import os
from whoosh.index import create_in
from whoosh.fields import Schema, TEXT, ID
import sys

def createSearchableData(root):   

    '''
    Schema definition: title(name of file), path(as ID), content(indexed
    but not stored),textdata (stored text content)
    '''
    schema = Schema(title=TEXT(stored=True),path=ID(stored=True),\
              content=TEXT,textdata=TEXT(stored=True))
    if not os.path.exists("indexdir"):
        os.mkdir("indexdir")

    # Creating a index writer to add document as per schema
    ix = create_in("indexdir",schema)
    writer = ix.writer()

    filepaths = [os.path.join(root,i) for i in os.listdir(root)]
    for path in filepaths:
        fp = open(path,'r')
        print(path)
        text = fp.read()
        writer.add_document(title=path.split("\\")[1], path=path,\
          content=text,textdata=text)
        fp.close()
    writer.commit()

root = "corpus"
createSearchableData(root)
</pre>



<h3 id="2-querying-indexed-data-whoosh" class="wp-block-heading">2. Querying Indexed Data : Whoosh</h3>



<p class="wp-block-paragraph">Querying a indexed data has two important parts which you may like to look upon.</p>



<p class="wp-block-paragraph"><strong>Query String</strong>&nbsp;: It is passed while searching the indexed data. Query string can be a single word, a single sentence to be matched exactly, multiple words with ‘AND’, multiple words with ‘OR’ etc. For examples –</p>



<p class="wp-block-paragraph">Query : politics (returns if the word occurs)Query : sports OR games OR play (returns if any one of the strings occur)<br>Query : alpha beta gamma (return if a document contains all strings)<br>Query :&nbsp;<strong>“</strong>alpha beta gamma<strong>“</strong>&nbsp;(returns if all strings occur together in a document).</p>



<p class="wp-block-paragraph"><strong>Scoring</strong>&nbsp;: Each document is ranked according to a scoring function. There are quite a few types of scoring function supported by whoosh.</p>



<ol class="wp-block-list">
<li>Frequency : It simply returns the count of the terms occurred in the document. It does not perform any normalization or weighting.</li>



<li>Tf-Idf scores : It returns tf * idf scores of each document. To know more read <a href="https://atomic-temporary-123006597.wpcomstaging.com/2017/02/12/sentiment-analysis-using-tf-idf-weighting-pythonscikit-learn/" target="_blank" rel="noopener">here</a> or wiki page <a href="https://en.wikipedia.org/wiki/Tf%E2%80%93idf" target="_blank" rel="noopener">here</a>.</li>



<li>BM25F scoring : It is the by default ranking function used by whoosh. BM stands for best matching. It is based on tf-idf along with bunch of factors like length of document in words, average length of documents in the collection. It also has free parameters k = 1.2 and b = 0.75. To read more check <a href="https://en.wikipedia.org/wiki/Okapi_BM25" target="_blank" rel="noopener">here</a>.</li>



<li>Cosine scoring : It is useful for finding document similar to your search query.</li>
</ol>



<p class="wp-block-paragraph">There are few more scoring algorithms which has been implemented. Check&nbsp;<a href="https://github.com/jerem/Whoosh/blob/master/src/whoosh/scoring.py" target="_blank" rel="noopener">here</a>&nbsp;to know more.</p>



<p class="wp-block-paragraph">Below is the python implementation for searching a query in the indexed database.</p>



<pre class="wp-block-preformatted">from whoosh.qparser import QueryParser
from whoosh import scoring
from whoosh.index import open_dir

ix = open_dir("indexdir")

# query_str is query string
query_str = sys.argv[1]
# Top 'n' documents as result
topN = int(sys.argv[2])

with ix.searcher(weighting=scoring.Frequency) as searcher:
    query = QueryParser("content", ix.schema).parse(query_str)
results = searcher.search(query,limit=topN)
for i in range(topN):
    print(results[i]['title'], str(results[i].score), results[i]['textdata'])
</pre>



<p class="wp-block-paragraph">QueryParser class of whoosh implements query language very similar to java Lucene’s.</p>



<h3 id="3-glossary" class="wp-block-heading">3. Glossary</h3>



<p class="wp-block-paragraph">Below are the basic terminologies you will always come across in discussions involving searching and indexing documents (taken from whoosh&nbsp;<a href="https://whoosh.readthedocs.io/en/latest/glossary.html" target="_blank" rel="noopener">docs</a>).</p>



<p class="wp-block-paragraph"><strong>Corpus<br></strong>The set of documents you are indexing.</p>



<p class="wp-block-paragraph"><strong>Documents<br></strong>The individual pieces of content you want to make searchable. The word “documents” might imply files, but the data source could really be anything – articles in a content management system, blog posts in a blogging system, chunks of a very large file, rows returned from an SQL query, individual email messages from a mailbox file, or whatever. When you get search results from Whoosh, the results are a list of documents, whatever “documents” means in your search engine.</p>



<p class="wp-block-paragraph"><strong>Fields<br></strong>Each document contains a set of fields. Typical fields might be “title”, “content”, “url”, “keywords”, “status”, “date”, etc. Fields can be indexed (so they’re searchable) and/or stored with the document. Storing the field makes it available in search results. For example, you typically want to store the “title” field so your search results can display it.</p>



<p class="wp-block-paragraph"><strong>Forward index<br></strong>A table listing every document and the words that appear in the document. Whoosh lets you store&nbsp;<em>term vectors</em>&nbsp;that are a kind of forward index.</p>



<p class="wp-block-paragraph"><strong>Indexing<br></strong>The process of examining documents in the corpus and adding them to the&nbsp;<em>reverse index</em>.</p>



<p class="wp-block-paragraph"><strong>Postings<br></strong>The&nbsp;<em>reverse index</em>&nbsp;lists every word in the corpus, and for each word, a list of documents in which that word appears, along with some optional information (such as the number of times the word appears in that document). These items in the list, containing a document number and any extra information, are called&nbsp;<em>postings</em>. In Whoosh the information stored in postings is customizable for each&nbsp;<em>field</em>.</p>



<p class="wp-block-paragraph"><strong>Reverse Index<br></strong>Basically a table listing every word in the corpus, and for each word, the list of documents in which it appears. It can be more complicated (the index can also list how many times the word appears in each document, the positions at which it appears, etc.) but that’s how it basically works.</p>



<p class="wp-block-paragraph"><strong>Schema<br></strong>Whoosh requires that you specify the&nbsp;<em>fields</em>&nbsp;of the index before you begin indexing. The Schema associates field names with metadata about the field, such as the format of the&nbsp;<em>postings</em>&nbsp;and whether the contents of the field are stored in the index.</p>



<p class="wp-block-paragraph"><strong>Term vector<br></strong>A&nbsp;<em>forward index</em>&nbsp;for a certain field in a certain document. You can specify in the Schema that a given field should store term vectors.</p>



<h3 id="at-the-end" class="wp-block-heading">At the End</h3>



<p class="wp-block-paragraph">Hope it was an easy read and good heads-up to start with. So, what can we do more from here:</p>



<ol class="wp-block-list">
<li>Searching for alike documents instead of exact term searches only.</li>



<li>Exploring hierarchical search in file system.</li>



<li>Correcting errors in the queries. Did you mean…?</li>



<li>Search N-grams for getting fast, “search as you type” functionality</li>
</ol>



<p class="wp-block-paragraph">Update: Readers can download the backup of QT application built from below link. It was a old work and don’t have a working app now. You may have to figure out codes in order to reproduce it. Good luck with that.</p>



<p class="wp-block-paragraph">If you liked the post,&nbsp;<em><strong>follow this blog</strong></em>&nbsp;to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy machine learning&nbsp;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Demonstration of Facial Emotion Recognition on Real Time Video Using CNN : Python &#038; Keras</title>
		<link>https://www.mastersinmachinelearning.org/blog/demonstration-of-facial-emotion-recognition-on-real-time-video-using-cnn-python-keras/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:42 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=318</guid>

					<description><![CDATA[his blog-post presents building a demonstration of emotion recognition from the detected bounded face in a real time video or images. Introduction An face emotion recognition system comprises of two step process i.e. face detection (bounded face) in image followed by emotion detection on the detected bounded face. The following two techniques are used for ... <a title="Demonstration of Facial Emotion Recognition on Real Time Video Using CNN : Python &#38; Keras" class="read-more" href="https://www.mastersinmachinelearning.org/blog/demonstration-of-facial-emotion-recognition-on-real-time-video-using-cnn-python-keras/" aria-label="Read more about Demonstration of Facial Emotion Recognition on Real Time Video Using CNN : Python &#38; Keras">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">his blog-post presents building a demonstration of emotion recognition from the detected bounded face in a real time video or images.</p>



<h3 id="introduction" class="wp-block-heading">Introduction</h3>



<p class="wp-block-paragraph">An face emotion recognition system comprises of two step process i.e. face detection (bounded face) in image followed by emotion detection on the detected bounded face. The following two techniques are used for respective mentioned tasks in face recognition system.</p>



<ol class="wp-block-list">
<li>Haar feature-based cascade classifiers : It detects frontal face in an image well. It is real time and faster in comparison to other face detector. This blog-post uses an implementation from Open-CV.</li>



<li>Xception CNN Model (<a href="https://arxiv.org/pdf/1710.07557.pdf" target="_blank" rel="noopener">Mini_Xception, 2017</a>) : We will train a classification CNN model architecture which takes bounded face (48*48 pixels) as input and predicts probabilities of 7 emotions in the output layer.</li>
</ol>



<h3 id="dataset" class="wp-block-heading">Data-set</h3>



<p class="wp-block-paragraph">One can download the facial expression recognition (FER) data-set from Kaggle challenge&nbsp;<a href="https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge/data" target="_blank" rel="noopener">here</a>. The data consists of 48×48 pixel gray scale images of faces. The faces have been automatically registered so that the face is more or less centered and occupies about the same amount of space in each image. The task is to categorize each face based on the emotion shown in the facial expression in to one of seven categories (0=Angry, 1=Disgust, 2=Fear, 3=Happy, 4=Sad, 5=Surprise, 6=Neutral).</p>



<p class="wp-block-paragraph">The training set consists of 35,888 examples. train.csv contains two columns, “emotion” and “pixels”. The “emotion” column contains a numeric code ranging from 0 to 6, inclusive, for the emotion that is present in the image. The “pixels” column contains a string surrounded in quotes for each image. The contents of this string a space-separated pixel values in row major order</p>



<h3 id="loading-fer-dataset" class="wp-block-heading">Loading FER Data-set</h3>



<p class="wp-block-paragraph">The below code loads the data-set and pre-process the images for feeding it to CNN model. There are two definitions in the code snippet here:</p>



<p class="wp-block-paragraph">1.&nbsp;<code>def load_fer2013</code>&nbsp;: It reads the csv file and convert pixel sequence of each row in image of dimension 48*48. It returns faces and emotion labels.</p>



<p class="wp-block-paragraph">2.&nbsp;<code>def preprocess_input</code>: It is a standard way to pre-process images by scaling them between -1 to 1. Images is scaled to [0,1] by dividing it by 255. Further, subtraction by 0.5 and multiplication by 2 changes the range to [-1,1]. [-1,1] has been found a better range for neural network models in computer vision problems.</p>



<pre class="wp-block-preformatted">import pandas as pd
import cv2
import numpy as np

dataset_path = 'fer2013/fer2013.csv'
image_size=(48,48)

def load_fer2013():
        data = pd.read_csv(dataset_path)
        pixels = data['pixels'].tolist()
        width, height = 48, 48
        faces = []
        for pixel_sequence in pixels:
                face = [int(pixel) for pixel in pixel_sequence.split(' ')]
                face = np.asarray(face).reshape(width, height)
                face = cv2.resize(face.astype('uint8'),image_size)
                faces.append(face.astype('float32'))
        faces = np.asarray(faces)
        faces = np.expand_dims(faces, -1)
        emotions = pd.get_dummies(data['emotion']).as_matrix()
        return faces, emotions

def preprocess_input(x, v2=True):
    x = x.astype('float32')
    x = x / 255.0
    if v2:
        x = x - 0.5
        x = x * 2.0
    return x

faces, emotions = load_fer2013()
faces = preprocess_input(faces)
xtrain, xtest,ytrain,ytest = train_test_split(faces, emotions,test_size=0.2,shuffle=True)
</pre>



<p class="wp-block-paragraph">5 expression samples of each of the 7 emotions in the data-set can be seen below.</p>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/8_3.jpg?w=119&amp;h=119&amp;crop=1" alt="8_3" title="8_3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/9_3.jpg?w=119&amp;h=119&amp;crop=1" alt="9_3" title="9_3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/15_3.jpg?w=119&amp;h=119&amp;crop=1" alt="15_3" title="15_3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28688_3.jpg?w=119&amp;h=119&amp;crop=1" alt="28688_3" title="28688_3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28690_3.jpg?w=119&amp;h=119&amp;crop=1" alt="28690_3" title="28690_3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/23_0.jpg?w=119&amp;h=119&amp;crop=1" alt="23_0" title="23_0"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/24_0.jpg?w=119&amp;h=119&amp;crop=1" alt="24_0" title="24_0"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/41_0.jpg?w=119&amp;h=119&amp;crop=1" alt="41_0" title="41_0"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28687_0.jpg?w=119&amp;h=119&amp;crop=1" alt="28687_0" title="28687_0"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28708_0.jpg?w=119&amp;h=119&amp;crop=1" alt="28708_0" title="28708_0"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/160_4.jpg?w=119&amp;h=119&amp;crop=1" alt="160_4" title="160_4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/164_4.jpg?w=119&amp;h=119&amp;crop=1" alt="164_4" title="164_4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/167_4.jpg?w=119&amp;h=119&amp;crop=1" alt="167_4" title="167_4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28707_4.jpg?w=119&amp;h=119&amp;crop=1" alt="28707_4" title="28707_4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28709_4.jpg?w=119&amp;h=119&amp;crop=1" alt="28709_4" title="28709_4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/300_1.jpg?w=119&amp;h=119&amp;crop=1" alt="300_1" title="300_1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/389_1.jpg?w=119&amp;h=119&amp;crop=1" alt="389_1" title="389_1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/417_1.jpg?w=119&amp;h=119&amp;crop=1" alt="417_1" title="417_1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28651_1.jpg?w=119&amp;h=119&amp;crop=1" alt="28651_1" title="28651_1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28599_1.jpg?w=119&amp;h=119&amp;crop=1" alt="28599_1" title="28599_1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/5_6.jpg?w=119&amp;h=119&amp;crop=1" alt="5_6" title="5_6"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/36_6.jpg?w=119&amp;h=119&amp;crop=1" alt="36_6" title="36_6"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/37_6.jpg?w=119&amp;h=119&amp;crop=1" alt="37_6" title="37_6"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28700_6.jpg?w=119&amp;h=119&amp;crop=1" alt="28700_6" title="28700_6"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28694_6.jpg?w=119&amp;h=119&amp;crop=1" alt="28694_6" title="28694_6"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/182_2.jpg?w=119&amp;h=119&amp;crop=1" alt="182_2" title="182_2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/225_2.jpg?w=119&amp;h=119&amp;crop=1" alt="225_2" title="225_2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/256_2.jpg?w=119&amp;h=119&amp;crop=1" alt="256_2" title="256_2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28691_2.jpg?w=119&amp;h=119&amp;crop=1" alt="28691_2" title="28691_2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28696_2.jpg?w=119&amp;h=119&amp;crop=1" alt="28696_2" title="28696_2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/258_5.jpg?w=119&amp;h=119&amp;crop=1" alt="258_5" title="258_5"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/277_5.jpg?w=119&amp;h=119&amp;crop=1" alt="277_5" title="277_5"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/280_5.jpg?w=119&amp;h=119&amp;crop=1" alt="280_5" title="280_5"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28672_5.jpg?w=119&amp;h=119&amp;crop=1" alt="28672_5" title="28672_5"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/28704_5.jpg?w=119&amp;h=119&amp;crop=1" alt="28704_5" title="28704_5"/></figure>



<p class="wp-block-paragraph">Originally in the dataset provided in kaggle link, each image is given as string which is a row 1×2304 which is 48×48 image stored as row vector. The strings in the .csv files can be converted into images using the code in github link&nbsp;<a href="https://github.com/abhijeet3922/FaceEmotion_ID/blob/master/csv_to_images.py" target="_blank" rel="noopener">here</a>.</p>



<h3 id="training-cnn-model-mini-xception" class="wp-block-heading">Training CNN model : Mini Xception</h3>



<p class="wp-block-paragraph">Here comes the exciting architecture which is comparatively small and achieves almost state-of-art performance of classifying emotion on this data-set. The below architecture was proposed by Octavio Arragia et al. in this&nbsp;<a href="https://arxiv.org/pdf/1710.07557.pdf" target="_blank" rel="noopener">paper</a>.</p>



<figure class="wp-block-image" id="attachment_8967"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/mini_exception_cnn_model.png?w=616" alt="mini_exception_cnn_model" class="wp-image-8967"/><figcaption class="wp-element-caption">Proposed Mini_Xception architecture for emotion classification</figcaption></figure>



<p class="wp-block-paragraph">One can notice that the center block is repeated 4 times in the design. This architecture is different from the most common CNN architecture like one used in the blog-post&nbsp;<a href="https://appliedmachinelearning.wordpress.com/2018/03/24/achieving-90-accuracy-in-object-recognition-task-on-cifar-10-dataset-with-keras-convolutional-neural-networks/" target="_blank" rel="noopener">here</a>. Common architectures uses fully connected layers at the end where most of parameters resides. Also, they use standard convolutions. Modern CNN architectures such as Xception leverage from the combination of two of the most successful experimental assumptions in CNNs: the use of residual modules and depth-wise separable convolutions.</p>



<p class="wp-block-paragraph">There are various techniques that can be kept in mind while building a deep neural network and is applicable in most of the computer vision problems. Below are few of those techniques which are used while training the CNN model below.</p>



<ol class="wp-block-list">
<li><strong>Data Augmentation</strong> : More data is generated using the training set by applying transformations. It is required if the training set is not sufficient enough to learn representation. The image data is generated by transforming the actual training images by rotation, crop, shifts, shear, zoom, flip, reflection, normalization etc.</li>



<li><strong>Kernel_regularizer </strong> : It allows to apply penalties on layer parameters during optimization. These penalties are incorporated in the loss function that the network optimizes. Argument in convolution layer  is nothing but <code>L2 regularisation</code> of the weights. This penalizes peaky weights and makes sure that all the inputs are considered.</li>



<li><strong>BatchNormalization</strong> : It normalizes the activation of the previous layer at each batch, i.e. applies a transformation that maintains the mean activation close to 0 and the activation standard deviation close to 1. It addresses the problem of internal covariate shift. It also acts as a regularizer, in some cases eliminating the need for Dropout. It helps in speeding up the training process.</li>



<li><strong>Global Average Pooling</strong> : It reduces each feature map into a scalar value by taking the average over all elements in the feature map. The average operation forces the network to extract global features from the input image.</li>



<li><strong>Depthwise Separable Convolution</strong> : These convolutions are composed of two different layers: depth-wise convolutions and point-wise convolutions. Depth-wise separable convolutions reduces the computation with respect to the standard convolutions by reducing the number of parameters. A very nice and visual explanation of the difference between standard and depth-wise separable convolution is given in the <a href="https://arxiv.org/pdf/1710.07557.pdf" target="_blank" rel="noopener">paper</a>.</li>
</ol>



<p class="wp-block-paragraph">Below python codes implements the above architecture in Keras.</p>



<pre class="wp-block-preformatted">from keras.callbacks import CSVLogger, ModelCheckpoint, EarlyStopping
from keras.callbacks import ReduceLROnPlateau
from keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
from keras.layers import Activation, Convolution2D, Dropout, Conv2D
from keras.layers import AveragePooling2D, BatchNormalization
from keras.layers import GlobalAveragePooling2D
from keras.models import Sequential
from keras.layers import Flatten
from keras.models import Model
from keras.layers import Input
from keras.layers import MaxPooling2D
from keras.layers import SeparableConv2D
from keras import layers
from keras.regularizers import l2
import pandas as pd
import cv2
import numpy as np

# parameters
batch_size = 32
num_epochs = 110
input_shape = (48, 48, 1)
verbose = 1
num_classes = 7
patience = 50
base_path = 'models/'
l2_regularization=0.01

# data generator
data_generator = ImageDataGenerator(
                        featurewise_center=False,
                        featurewise_std_normalization=False,
                        rotation_range=10,
                        width_shift_range=0.1,
                        height_shift_range=0.1,
                        zoom_range=.1,
                        horizontal_flip=True)

# model parameters
regularization = l2(l2_regularization)

# base
img_input = Input(input_shape)
x = Conv2D(8, (3, 3), strides=(1, 1), kernel_regularizer=regularization, use_bias=False)(img_input)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(8, (3, 3), strides=(1, 1), kernel_regularizer=regularization, use_bias=False)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)

# module 1
residual = Conv2D(16, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
residual = BatchNormalization()(residual)
x = SeparableConv2D(16, (3, 3), padding='same', kernel_regularizer=regularization, use_bias=False)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(16, (3, 3), padding='same', kernel_regularizer=regularization, use_bias=False)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
x = layers.add([x, residual])

# module 2
residual = Conv2D(32, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
residual = BatchNormalization()(residual)
x = SeparableConv2D(32, (3, 3), padding='same', kernel_regularizer=regularization, use_bias=False)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(32, (3, 3), padding='same', kernel_regularizer=regularization, use_bias=False)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
x = layers.add([x, residual])

# module 3
residual = Conv2D(64, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)
residual = BatchNormalization()(residual)
x = SeparableConv2D(64, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(64, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
x = layers.add([x, residual])

# module 4
residual = Conv2D(128, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)
residual = BatchNormalization()(residual)
x = SeparableConv2D(128, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(128, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
x = layers.add([x, residual])
x = Conv2D(num_classes, (3, 3), padding='same')(x)
x = GlobalAveragePooling2D()(x)
output = Activation('softmax',name='predictions')(x)

model = Model(img_input, output)
model.compile(optimizer='adam', loss='categorical_crossentropy',metrics=['accuracy'])
model.summary()

# callbacks
log_file_path = base_path + '_emotion_training.log'
csv_logger = CSVLogger(log_file_path, append=False)
early_stop = EarlyStopping('val_loss', patience=patience)
reduce_lr = ReduceLROnPlateau('val_loss', factor=0.1, patience=int(patience/4), verbose=1)
trained_models_path = base_path + '_mini_XCEPTION'
model_names = trained_models_path + '.{epoch:02d}-{val_acc:.2f}.hdf5'
model_checkpoint = ModelCheckpoint(model_names, 'val_loss', verbose=1,save_best_only=True)
callbacks = [model_checkpoint, csv_logger, early_stop, reduce_lr]

model.fit_generator(data_generator.flow(xtrain, ytrain,batch_size),
                        steps_per_epoch=len(xtrain) / batch_size,
                        epochs=num_epochs, verbose=1, callbacks=callbacks,
                        validation_data=(xtest,ytest))

</pre>



<p class="wp-block-paragraph">The model gives 65-66% accuracy on validation set while training the model. The CNN model learns the representation features of emotions from the training images. Below are few epochs of training process with batch size of 64.</p>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/training_validation_loss.png?w=616" alt="training_validation_loss" class="wp-image-8970"/></figure>



<h3 id="testing-the-model" class="wp-block-heading">Testing the Model</h3>



<p class="wp-block-paragraph"><strong>On Images</strong></p>



<p class="wp-block-paragraph">While performing tests on the trained model, I felt that model detects the emotion of faces as neutral if the expressions are not made distinguishable enough. The model gives probabilities of each emotion class in the output layer of trained mini_xception CNN model. Below are the 18 facial expressions taken from google images to validate the trained model.</p>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/sad1.jpeg?w=201&amp;h=201&amp;crop=1" alt="sad1" title="sad1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/surprise4.jpeg?w=201&amp;h=201&amp;crop=1" alt="surprise4" title="surprise4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/surprise2.jpeg?w=201&amp;h=201&amp;crop=1" alt="surprise2" title="surprise2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/angry2.jpeg?w=201&amp;h=201&amp;crop=1" alt="angry2" title="angry2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/sad2.jpeg?w=201&amp;h=201&amp;crop=1" alt="sad2" title="sad2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/happy1.jpg?w=201&amp;h=201&amp;crop=1" alt="happy1" title="happy1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/scared2.jpeg?w=201&amp;h=201&amp;crop=1" alt="scared2" title="scared2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/scared1.jpeg?w=201&amp;h=201&amp;crop=1" alt="scared1" title="scared1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/surprise1.jpeg?w=201&amp;h=201&amp;crop=1" alt="surprise1" title="surprise1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/disgust2.jpeg?w=201&amp;h=201&amp;crop=1" alt="disgust2" title="disgust2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/nuetral1.jpg?w=201&amp;h=201&amp;crop=1" alt="nuetral1" title="nuetral1"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/happy2.jpeg?w=201&amp;h=201&amp;crop=1" alt="happy2" title="happy2"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/surprise3.jpeg?w=201&amp;h=201&amp;crop=1" alt="surprise3" title="surprise3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/angry3.jpeg?w=201&amp;h=201&amp;crop=1" alt="angry3" title="angry3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/sad4.jpeg?w=201&amp;h=201&amp;crop=1" alt="sad4" title="sad4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/disgust3.jpeg?w=201&amp;h=201&amp;crop=1" alt="disgust3" title="disgust3"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/disgust4.jpeg?w=201&amp;h=201&amp;crop=1" alt="disgust4" title="disgust4"/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/11/happy3.jpeg?w=201&amp;h=201&amp;crop=1" alt="happy3" title="happy3"/></figure>



<p class="wp-block-paragraph">In order to detect emotion in a single image, one can execute the python code below.</p>



<pre class="wp-block-preformatted">from keras.preprocessing.image import img_to_array
from keras.models import load_model
import imutils
import cv2
import numpy as np
import sys

# parameters for loading data and images
detection_model_path = 'haarcascade_files/haarcascade_frontalface_default.xml'
emotion_model_path = 'models/_mini_XCEPTION.106-0.65.hdf5'
img_path = sys.argv[1]

# hyper-parameters for bounding boxes shape
# loading models
face_detection = cv2.CascadeClassifier(detection_model_path)
emotion_classifier = load_model(emotion_model_path, compile=False)
EMOTIONS = ["angry","disgust","scared", "happy", "sad", "surprised","neutral"]

#reading the frame
orig_frame = cv2.imread(img_path)
frame = cv2.imread(img_path,0)
faces = face_detection.detectMultiScale(frame,scaleFactor=1.1,minNeighbors=5,minSize=(30,30),flags=cv2.CASCADE_SCALE_IMAGE)

if len(faces) &amp;amp;gt; 0:
    faces = sorted(faces, reverse=True,key=lambda x: (x[2] - x[0]) * (x[3] - x[1]))[0]
    (fX, fY, fW, fH) = faces
    roi = frame[fY:fY + fH, fX:fX + fW]
    roi = cv2.resize(roi, (48, 48))
    roi = roi.astype("float") / 255.0
    roi = img_to_array(roi)
    roi = np.expand_dims(roi, axis=0)
    preds = emotion_classifier.predict(roi)[0]
    emotion_probability = np.max(preds)
    label = EMOTIONS[preds.argmax()]
    cv2.putText(orig_frame, label, (fX, fY - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
    cv2.rectangle(orig_frame, (fX, fY), (fX + fW, fY + fH),(0, 0, 255), 2)

cv2.imshow('test_face', orig_frame)
cv2.imwrite('test_output/'+img_path.split('/')[-1],orig_frame)
if (cv2.waitKey(2000) &amp;amp;amp; 0xFF == ord('q')):
    sys.exit("Thanks")
cv2.destroyAllWindows()
</pre>



<p class="wp-block-paragraph"><strong>On Video</strong></p>



<p class="wp-block-paragraph">In order to detect emotion in webcam, one can execute the python code&nbsp;<a href="https://github.com/abhijeet3922/FaceEmotion_ID/blob/master/real_time_video.py" target="_blank" rel="noopener">here</a>.</p>



<h3 id="references" class="wp-block-heading">References</h3>



<p class="wp-block-paragraph">The demonstration codes has been ingested from following sources.</p>



<p class="wp-block-paragraph">[1]&nbsp;<a href="https://github.com/oarriaga/face_classification" target="_blank" rel="noopener">https://github.com/oarriaga/face_classification</a><br>[2]&nbsp;<a href="https://github.com/omar178/Emotion-recognition" target="_blank" rel="noopener">https://github.com/omar178/Emotion-recognition</a><br>[3]&nbsp;<a href="https://arxiv.org/pdf/1710.07557.pdf" target="_blank" rel="noopener">Real-time Convolutional Neural Networks for Emotion and Gender Classification</a></p>



<p class="wp-block-paragraph">If you liked the post, follow this blog to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy deep learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Data Analytics and Modeling with XGBoost Classifier : WNS Hackathon Challenge</title>
		<link>https://www.mastersinmachinelearning.org/blog/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:41 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=314</guid>

					<description><![CDATA[Table of Contents HR Analytics : Hackathon Challenge I participated in WNS Analytics Wizard hackathon, “To predict whether an employee will be promoted or not” and hence I am coming up with this blog-post of the solution submitted which ranked me 138 (Top 11%) in the challenge. The leader board ranking was decided on the ... <a title="Data Analytics and Modeling with XGBoost Classifier : WNS Hackathon Challenge" class="read-more" href="https://www.mastersinmachinelearning.org/blog/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/" aria-label="Read more about Data Analytics and Modeling with XGBoost Classifier : WNS Hackathon Challenge">Read more</a>]]></description>
										<content:encoded><![CDATA[
<h3 id="table-of-contents" class="wp-block-heading">Table of Contents</h3>



<ul class="wp-block-list">
<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Importing-Libraries" target="_blank" rel="noopener">1  Importing Libraries</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#User-Defined-Functions" target="_blank" rel="noopener">2  User Defined Functions</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Reading-Data" target="_blank" rel="noopener">3  Reading Data</a>
<ul class="wp-block-list">
<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Checking-the-event-rate" target="_blank" rel="noopener">3.1  Checking the event rate</a></li>
</ul>
</li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Displaying-the-attributes" target="_blank" rel="noopener">4  Displaying the attributes</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Checking-Data-Quality" target="_blank" rel="noopener">5  Checking Data Quality</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Missing-Value-Treatment" target="_blank" rel="noopener">6  Missing Value Treatment</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Looking-at-attributes-(EDA)" target="_blank" rel="noopener">7  Looking at attributes (EDA)</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Preparing-Data-for-Modeling" target="_blank" rel="noopener">8  Preparing Data for Modeling</a></li>



<li><a href="https://appliedmachinelearning.blog/2018/09/23/data-analytics-and-modeling-with-xgboost-classifier-wns-hackathon-challenge/#Model-1---XGB-Classifier" target="_blank" rel="noopener">9  Model 1 – XGB Classifier</a>
<ul class="wp-block-list">
<li></li>
</ul>
</li>
</ul>



<h3 class="wp-block-heading" id="HR-Analytics-:-Hackathon-Challenge">HR Analytics : Hackathon Challenge</h3>



<p class="wp-block-paragraph">I participated in WNS Analytics Wizard hackathon, “To predict whether an employee will be promoted or not” and hence I am coming up with this blog-post of the solution submitted which ranked me 138 (Top 11%) in the challenge. The leader board ranking was decided on the F1-score which is harmonic mean of precision and recall.</p>



<p class="wp-block-paragraph"><strong>About Data</strong><br>The data-set consists of 54808 rows where each row had 14 attributes including target variable (i.e “is_promoted”). There are 4668 cases where employees have been promoted (8.5%). The data-set is provided in GitHub link&nbsp;<a href="https://github.com/abhijeet3922/WNS-DS-Hackathon" target="_blank" rel="noopener">here</a>.</p>



<p class="wp-block-paragraph">Let’s get started in building the data analytics pipeline end to end.</p>



<h3 class="wp-block-heading" id="Importing-Libraries">Importing Libraries</h3>



<pre class="wp-block-preformatted">import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import display

from sklearn.metrics import confusion_matrix, f1_score, precision_recall_curve
from sklearn.model_selection import GridSearchCV, train_test_split,cross_val_score

import xgboost as xgb
import lightgbm as lgb

import warnings
warnings.filterwarnings("ignore")

# Set all options
%matplotlib inline
plt.style.use('seaborn-notebook')
plt.rcParams["figure.figsize"] = (20, 3)
pd.options.display.float_format = '{:20,.4f}'.format
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
sns.set(context="paper", font="monospace")
</pre>



<h3 class="wp-block-heading" id="User-Defined-Functions">User Defined Functions</h3>



<pre class="wp-block-preformatted">def convert_categorical_to_dummies(d_convert):

    """
    Author: Abhijeet Kumar
    Description: returns Dataframe with all categorical variables converted into dummies
    Arguments: Dataframe (having categorical variables)
    """

    df = d_convert.copy()
    list_to_drop = []
    for col in df.columns:
        if df[col].dtype == 'object':
            list_to_drop.append(col)
            df = pd.concat([df,pd.get_dummies(df[col],prefix=col,prefix_sep='_', drop_first=False)], axis=1)
            df = df.drop(list_to_drop,axis=1)
    return df

def quality_report(df):

    """
    Author: Abhijeet Kumar
    Description: Displays quality of data in terms of missing values, unique numbers, datatypes etc.
    Arguments: Dataframe
    """
    dtypes = df.dtypes
    nuniq = df.T.apply(lambda x: x.nunique(), axis=1)
    total = df.isnull().sum().sort_values(ascending = False)
    percent = (df.isnull().sum()/df.isnull().count()*100).sort_values(ascending = False)
    quality_df = pd.concat([total, percent, nuniq, dtypes], axis=1, keys=['Total', 'Percent','Nunique', 'Dtype'])
    display(quality_df)

def score_on_test_set(model, file_name, out_name):

    """
    Author: Abhijeet Kumar
    Description : It runs same steps of preprocessing as in training, scores
    on the test data provided in hackathon and generates the submission file.
    Argument : model, test data file, submission file
    """

    test_data = pd.read_csv(file_name)

    # Treating the missing values of education as a separate category
    test_data['education'] = test_data['education'].replace(np.NaN, 'NA')

    # Treating the missing values of education as a separate category
    test_data['previous_year_rating'] = test_data['previous_year_rating'].fillna(0)

    # Creating dummy variables for all the categorical columns, droping that column
    master_test_data = convert_categorical_to_dummies(test_data)

    # Removing the id attributes
    df_test_data = master_test_data.drop(['employee_id'],axis=1)
    if out_name == "submission_lightgbm.csv":
        y_pred = model.predict_proba(df_test_data.values, num_iteration=model.best_iteration_)
    else:
        y_pred = model.predict_proba(df_test_data.values)
    submission_df = pd.DataFrame({'employee_id':master_test_data['employee_id'],'is_promoted':y_pred[:,1]})
    submission_df.to_csv(out_name, index=False)

    score = model.predict_proba(df_test_data.values)
    return test_data,score
</pre>



<h3 class="wp-block-heading" id="Reading-Data">Reading Data</h3>



<pre class="wp-block-preformatted">data = pd.read_csv("train.csv")
print("Shape of Data = ",data.shape)
data.sample(5)
</pre>



<pre class="wp-block-preformatted">Shape of Data =  (54808, 14)
</pre>



<h3 class="wp-block-heading" id="Checking-the-event-rate">Checking the event rate</h3>



<pre class="wp-block-preformatted">plt.figure(figsize=(6,3))
sns.countplot(x='is_promoted',data=data)
plt.show()

# Checking the event rate : event is when claim is made
data['is_promoted'].value_counts()
</pre>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/09/event-rate.png?w=616" alt="event-rate" class="wp-image-8827"/></figure>
</div>


<pre class="wp-block-preformatted">0    50140
1     4668
Name: is_promoted, dtype: int64</pre>



<h3 class="wp-block-heading" id="Displaying-the-attributes">Displaying the attributes</h3>



<pre class="wp-block-preformatted"># Checking the attribute names
pd.DataFrame(data.columns)
</pre>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><th>0</th><td>employee_id</td></tr><tr><th>1</th><td>department</td></tr><tr><th>2</th><td>region</td></tr><tr><th>3</th><td>education</td></tr><tr><th>4</th><td>gender</td></tr><tr><th>5</th><td>recruitment_channel</td></tr><tr><th>6</th><td>no_of_trainings</td></tr><tr><th>7</th><td>age</td></tr><tr><th>8</th><td>previous_year_rating</td></tr><tr><th>9</th><td>length_of_service</td></tr><tr><th>10</th><td>KPIs_met &gt;80%</td></tr><tr><th>11</th><td>awards_won?</td></tr><tr><th>12</th><td>avg_training_score</td></tr><tr><th>13</th><td>is_promoted</td></tr></tbody></table></figure>



<h3 class="wp-block-heading" id="Checking-Data-Quality">Checking Data Quality</h3>



<pre class="wp-block-preformatted"># checking missing data
quality_report(data)
</pre>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Attributes</th><th>Total</th><th>Percent</th><th>Nunique</th><th>Dtype</th></tr></thead><tbody><tr><th>KPIs_met &gt;80%</th><td>0</td><td>0.0000</td><td>2</td><td>int64</td></tr><tr><th>age</th><td>0</td><td>0.0000</td><td>41</td><td>int64</td></tr><tr><th>avg_training_score</th><td>0</td><td>0.0000</td><td>61</td><td>int64</td></tr><tr><th>awards_won?</th><td>0</td><td>0.0000</td><td>2</td><td>int64</td></tr><tr><th>department</th><td>0</td><td>0.0000</td><td>9</td><td>object</td></tr><tr><th>education</th><td>2409</td><td>4.3953</td><td>3</td><td>object</td></tr><tr><th>employee_id</th><td>0</td><td>0.0000</td><td>54808</td><td>int64</td></tr><tr><th>gender</th><td>0</td><td>0.0000</td><td>2</td><td>object</td></tr><tr><th>is_promoted</th><td>0</td><td>0.0000</td><td>2</td><td>int64</td></tr><tr><th>length_of_service</th><td>0</td><td>0.0000</td><td>35</td><td>int64</td></tr><tr><th>no_of_trainings</th><td>0</td><td>0.0000</td><td>10</td><td>int64</td></tr><tr><th>previous_year_rating</th><td>4124</td><td>7.5244</td><td>5</td><td>float64</td></tr><tr><th>recruitment_channel</th><td>0</td><td>0.0000</td><td>3</td><td>object</td></tr><tr><th>region</th><td>0</td><td>0.0000</td><td>34</td><td>object</td></tr></tbody></table></figure>



<h3 class="wp-block-heading" id="Missing-Value-Treatment">Missing Value Treatment</h3>



<pre class="wp-block-preformatted"># Treating the missing values of education as a separate category
data['education'] = data['education'].replace(np.NaN, 'NA')

# Treating the missing values of previous year rating as 0
data['previous_year_rating'] = data['previous_year_rating'].fillna(0)
</pre>



<h3 class="wp-block-heading" id="Looking-at-attributes-(EDA)">Looking at attributes (EDA)</h3>



<p class="wp-block-paragraph">Can we make some inferences from EDA ?</p>



<ul class="wp-block-list">
<li>Promotions are worst in Legal department (5.1%). Best promotions are in technology department (10.7%).</li>



<li>Region 9 is worst (1.9%) and region 4 is best (14.4%) in terms of promotions.</li>



<li>Although Master’s &amp; above has greater promotion percentage but difference is not much.</li>



<li>Employees having previous years rating greater than 5 will have better chances of promotion than others.</li>



<li>Employess having KPI greater than 80% has good chances of promotions (16%)</li>



<li>Employees winning awards are promoted more (44%).</li>
</ul>



<pre class="wp-block-preformatted">for col in data.drop('is_promoted',axis=1).columns:
    if data[col].dtype == 'object' or data[col].nunique()
        xx = data.groupby(col)['is_promoted'].value_counts().unstack(1)
        per_not_promoted = xx.iloc[:, 0] *100/xx.apply(lambda x: x.sum(), axis=1)
        per_promoted = xx.iloc[:, 1]*100/xx.apply(lambda x: x.sum(), axis=1)
        xx['%_0'] = per_not_promoted
        xx['%_1'] = per_promoted
        display(xx)
</pre>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>department</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>Analytics</th><td>4840</td><td>512</td><td>90.4335</td><td>9.5665</td></tr><tr><th>Finance</th><td>2330</td><td>206</td><td>91.8770</td><td>8.1230</td></tr><tr><th>HR</th><td>2282</td><td>136</td><td>94.3755</td><td>5.6245</td></tr><tr><th>Legal</th><td>986</td><td>53</td><td>94.8989</td><td>5.1011</td></tr><tr><th>Operations</th><td>10325</td><td>1023</td><td>90.9852</td><td>9.0148</td></tr><tr><th>Procurement</th><td>6450</td><td>688</td><td>90.3614</td><td>9.6386</td></tr><tr><th>R&amp;D</th><td>930</td><td>69</td><td>93.0931</td><td>6.9069</td></tr><tr><th>Sales &amp; Marketing</th><td>15627</td><td>1213</td><td>92.7969</td><td>7.2031</td></tr><tr><th>Technology</th><td>6370</td><td>768</td><td>89.2407</td><td>10.7593</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>region</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>region_1</th><td>552</td><td>58</td><td>90.4918</td><td>9.5082</td></tr><tr><th>region_10</th><td>597</td><td>51</td><td>92.1296</td><td>7.8704</td></tr><tr><th>region_11</th><td>1241</td><td>74</td><td>94.3726</td><td>5.6274</td></tr><tr><th>region_12</th><td>467</td><td>33</td><td>93.4000</td><td>6.6000</td></tr><tr><th>region_13</th><td>2418</td><td>230</td><td>91.3142</td><td>8.6858</td></tr><tr><th>region_14</th><td>765</td><td>62</td><td>92.5030</td><td>7.4970</td></tr><tr><th>region_15</th><td>2586</td><td>222</td><td>92.0940</td><td>7.9060</td></tr><tr><th>region_16</th><td>1363</td><td>102</td><td>93.0375</td><td>6.9625</td></tr><tr><th>region_17</th><td>687</td><td>109</td><td>86.3065</td><td>13.6935</td></tr><tr><th>region_18</th><td>30</td><td>1</td><td>96.7742</td><td>3.2258</td></tr><tr><th>region_19</th><td>821</td><td>53</td><td>93.9359</td><td>6.0641</td></tr><tr><th>region_2</th><td>11354</td><td>989</td><td>91.9874</td><td>8.0126</td></tr><tr><th>region_20</th><td>801</td><td>49</td><td>94.2353</td><td>5.7647</td></tr><tr><th>region_21</th><td>393</td><td>18</td><td>95.6204</td><td>4.3796</td></tr><tr><th>region_22</th><td>5694</td><td>734</td><td>88.5812</td><td>11.4188</td></tr><tr><th>region_23</th><td>1038</td><td>137</td><td>88.3404</td><td>11.6596</td></tr><tr><th>region_24</th><td>490</td><td>18</td><td>96.4567</td><td>3.5433</td></tr><tr><th>region_25</th><td>716</td><td>103</td><td>87.4237</td><td>12.5763</td></tr><tr><th>region_26</th><td>2117</td><td>143</td><td>93.6726</td><td>6.3274</td></tr><tr><th>region_27</th><td>1528</td><td>131</td><td>92.1037</td><td>7.8963</td></tr><tr><th>region_28</th><td>1164</td><td>154</td><td>88.3156</td><td>11.6844</td></tr><tr><th>region_29</th><td>951</td><td>43</td><td>95.6740</td><td>4.3260</td></tr><tr><th>region_3</th><td>309</td><td>37</td><td>89.3064</td><td>10.6936</td></tr><tr><th>region_30</th><td>598</td><td>59</td><td>91.0198</td><td>8.9802</td></tr><tr><th>region_31</th><td>1825</td><td>110</td><td>94.3152</td><td>5.6848</td></tr><tr><th>region_32</th><td>905</td><td>40</td><td>95.7672</td><td>4.2328</td></tr><tr><th>region_33</th><td>259</td><td>10</td><td>96.2825</td><td>3.7175</td></tr><tr><th>region_34</th><td>284</td><td>8</td><td>97.2603</td><td>2.7397</td></tr><tr><th>region_4</th><td>1457</td><td>246</td><td>85.5549</td><td>14.4451</td></tr><tr><th>region_5</th><td>731</td><td>35</td><td>95.4308</td><td>4.5692</td></tr><tr><th>region_6</th><td>658</td><td>32</td><td>95.3623</td><td>4.6377</td></tr><tr><th>region_7</th><td>4327</td><td>516</td><td>89.3454</td><td>10.6546</td></tr><tr><th>region_8</th><td>602</td><td>53</td><td>91.9084</td><td>8.0916</td></tr><tr><th>region_9</th><td>412</td><td>8</td><td>98.0952</td><td>1.9048</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>education</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>Bachelor’s</th><td>33661</td><td>3008</td><td>91.7969</td><td>8.2031</td></tr><tr><th>Below Secondary</th><td>738</td><td>67</td><td>91.6770</td><td>8.3230</td></tr><tr><th>Master’s &amp; above</th><td>13454</td><td>1471</td><td>90.1441</td><td>9.8559</td></tr><tr><th>NA</th><td>2287</td><td>122</td><td>94.9357</td><td>5.0643</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>gender</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>f</th><td>14845</td><td>1467</td><td>91.0066</td><td>8.9934</td></tr><tr><th>m</th><td>35295</td><td>3201</td><td>91.6849</td><td>8.3151</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>recruitment_channel</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>other</th><td>27890</td><td>2556</td><td>91.6048</td><td>8.3952</td></tr><tr><th>referred</th><td>1004</td><td>138</td><td>87.9159</td><td>12.0841</td></tr><tr><th>sourcing</th><td>21246</td><td>1974</td><td>91.4987</td><td>8.5013</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>previous_year_rating</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>0.0000</th><td>3785</td><td>339</td><td>91.7798</td><td>8.2202</td></tr><tr><th>1.0000</th><td>6135</td><td>88</td><td>98.5859</td><td>1.4141</td></tr><tr><th>2.0000</th><td>4044</td><td>181</td><td>95.7160</td><td>4.2840</td></tr><tr><th>3.0000</th><td>17263</td><td>1355</td><td>92.7221</td><td>7.2779</td></tr><tr><th>4.0000</th><td>9093</td><td>784</td><td>92.0624</td><td>7.9376</td></tr><tr><th>5.0000</th><td>9820</td><td>1921</td><td>83.6385</td><td>16.3615</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>KPIs_met &gt;80%</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>0</th><td>34111</td><td>1406</td><td>96.0413</td><td>3.9587</td></tr><tr><th>1</th><td>16029</td><td>3262</td><td>83.0906</td><td>16.9094</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>is_promoted</th><th>0</th><th>1</th><th>%_0</th><th>%_1</th></tr><tr><th>awards_won?</th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><th>0</th><td>49429</td><td>4109</td><td>92.3251</td><td>7.6749</td></tr><tr><th>1</th><td>711</td><td>559</td><td>55.9843</td><td>44.0157</td></tr></tbody></table></figure>



<h3 class="wp-block-heading" id="Preparing-Data-for-Modeling">Preparing Data for Modeling</h3>



<pre class="wp-block-preformatted"># Creating dummy variables for all the categorical columns, droping that column
master_data = convert_categorical_to_dummies(data)
print("Total shape of Data :",master_data.shape)

# dropping the target from dataset
labels = np.array(master_data['is_promoted'].tolist())

# Removing the id attributes
df_data = master_data.drop(['is_promoted','employee_id'],axis=1)
print("Shape of Data:",df_data.shape)
df = df_data.values
</pre>



<pre class="wp-block-preformatted">Total shape of Data : (54808, 61)
Shape of Data: (54808, 59)</pre>



<h3 class="wp-block-heading" id="Model-1---XGB-Classifier">Model 1 – XGB Classifier</h3>



<pre class="wp-block-preformatted">xgb_model = xgb.XGBClassifier()
print(xgb_model)

# Cross validation scores
f1_scores = cross_val_score(xgb_model, df, labels, cv=5, scoring='f1')
print("F1-score = ",f1_scores," Mean F1 score = ",np.mean(f1_scores))

# Training the models
xgb_model.fit(df,labels)

# Scoring on test set
test_data,score_xgb = score_on_test_set(xgb_model,"test.csv","submission_xgb.csv")
</pre>



<pre class="wp-block-preformatted">XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
       colsample_bytree=1, gamma=0, learning_rate=0.1, max_delta_step=0,
       max_depth=3, min_child_weight=1, missing=None, n_estimators=100,
       n_jobs=1, nthread=None, objective='binary:logistic', random_state=0,
       reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
       silent=True, subsample=1)
F1-score = [ 0.4526749   0.41547519  0.43579122  0.43012552  0.43427621]  
Mean F1 score =  0.433668606717</pre>



<h3 class="wp-block-heading" id="XGB-Classifier-:-Parameter-Tuning">XGB Classifier : Parameter Tuning</h3>



<p class="wp-block-paragraph">Our goal is usually to set the model parameters to optimal values that enable a model to complete learning task in the best way possible. Thus, tuning XGboost classifier can optimize the parameters that impact the model in order to enable the algorithm to perform the best.<br>I performed lot of iterations patiently which led to fine tuning of parameters: n_estimators, max_depth and L1 regularization. A norm is to take baby steps to learn (small learning rate) and tune the parameters. Here, I found that with large number of trees (n_estimators), the F1-scores were improving.</p>



<pre class="wp-block-preformatted"># Create parameters to search
params = {
     'learning_rate': [0.01],
     'n_estimators': [900,1000,1100],
     'max_depth':[7,8,9],
     'reg_alpha':[0.3,0.4,0.5]
    }

# Initializing the XGBoost Regressor
xgb_model = xgb.XGBClassifier()

# Gridsearch initializaation
gsearch = GridSearchCV(xgb_model, params,
                    verbose=True,
                    cv=5,
                    n_jobs=2)

gsearch.fit(df, labels)

#Printing the best chosen params
print("Best Parameters :",gsearch.best_params_)

params = {'objective':'binary:logistic', 'booster':'gbtree'}

# Updating the parameter as per grid search
params.update(gsearch.best_params_)

# Initializing the XGBoost Regressor
xgb_model = xgb.XGBClassifier(**params)
print(xgb_model)

# Cross validation scores
f1_scores = cross_val_score(xgb_model, df, labels, cv=5, scoring='f1',n_jobs=2)
print("F1_scores per fold : ",f1_scores," \nMean F1_score= ",np.mean(f1_scores))

# Fitting model on tuned parameters
xgb_model.fit(df, labels)

# Scoring on test set
test_data,score_xgb_tuned = score_on_test_set(xgb_model,"test.csv","submission_xgb_tuned.csv")
</pre>



<pre class="wp-block-preformatted">Fitting 5 folds for each of 1 candidates, totalling 5 fits</pre>



<pre class="wp-block-preformatted">[Parallel(n_jobs=2)]: Done   5 out of   5 | elapsed: 13.0min finished</pre>



<pre class="wp-block-preformatted">Best Parameters :{'learning_rate': 0.01, 'max_depth': 8, 'n_estimators': 1000, 'reg_alpha': 0.4}

XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
       colsample_bytree=1, gamma=0, learning_rate=0.01, max_delta_step=0,
       max_depth=8, min_child_weight=1, missing=None, n_estimators=1000,
       n_jobs=1, nthread=None, objective='binary:logistic', random_state=0,
       reg_alpha=0.4, reg_lambda=1, scale_pos_weight=1, seed=None,
       silent=True, subsample=1)
F1_scores per fold : [ 0.51014041  0.48657188  0.49528302  0.53054911  0.51130164]  
Mean F1_score= 0.506769210361</pre>



<h3 class="wp-block-heading" id="XGB-Classifier-:-Setting-threshold">XGB Classifier : Setting threshold</h3>



<p class="wp-block-paragraph">How does XGBoost classifier predicts the class (‘promoted’ or ‘not promoted’) ? It predicts a probability between 0 and 1 for the unseen cases. Further, it predicts 0 and 1 by putting a threshold at 0.5 by default (1 if probability &gt; 0.5). In unbalance data-set as in here, it may be a biased setting as it would be difficult to capture rare event with 0.5 threshold.</p>



<ul class="wp-block-list">
<li>We can change the by default threshold of 0.5 by finding the optimal threshold to increase F1-score.</li>



<li>We need to find the threshold where f1-score is highest.</li>



<li>I tried submissions on few optimal cut-offs to get maximum possible improved F1-score.</li>
</ul>



<p class="wp-block-paragraph">The following python code splits the data in 90:10 and trains XGBoost classifier with tuned parameters. It calculates precision and recall at different thresholds and plots the precision recall curve. Further, we calculate F1-score for the same using precision and recall values.</p>



<pre class="wp-block-preformatted"># Splitting the dataset in order to use early stopping round
X_train, X_test, y_train, y_test = train_test_split(df, labels, test_size=0.10, stratify=labels)

xgb_model = xgb.XGBClassifier(**params)

# Training the models
xgb_model.fit(X_train, y_train)
y_pred = xgb_model.predict_proba(X_test)
precision, recall, thresholds = precision_recall_curve(y_test, y_pred[:,1])

thresholds = np.append(thresholds, 1)
f1_scores = 2*(precision*recall)/(precision+recall)
plt.step(recall, precision, color='b', alpha=0.4, where='post')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.ylim([0.0, 1.05])
plt.xlim([0.0, 1.0])
plt.title('2-class Precision-Recall curve')
plt.show()
</pre>



<h4 id="" class="wp-block-heading"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/09/prcurve.png?w=616" alt="prcurve" srcset="https://appliedmachinelearning.files.wordpress.com/2018/09/prcurve.png 389w, https://appliedmachinelearning.files.wordpress.com/2018/09/prcurve.png?w=150 150w, https://appliedmachinelearning.files.wordpress.com/2018/09/prcurve.png?w=300 300w"></h4>



<h4 class="wp-block-heading" id="Getting-optimal-threshold">Getting optimal threshold</h4>



<p class="wp-block-paragraph">We plot F1-scores with respect to threshold in x-axis to check the F1-score peak. The below python codes gets the threshold value where the F1-score was highest.</p>



<pre class="wp-block-preformatted">scrs = pd.DataFrame({'precision' : precision, 'recal' : recall, 'thresholds' : thresholds, 'f1_score':f1_scores})
print("Threshold cutoff: ",scrs.loc[scrs['f1_score'] == scrs.f1_score.max(),'thresholds'].iloc[0])
print("Max F1-score at cut-off : ",scrs.f1_score.max())
scrs.plot(x='thresholds', y='f1_score')
</pre>



<pre class="wp-block-preformatted">Threshold cutoff:  0.340377241373
Max F1-score at cut-off :  0.53791130186</pre>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/09/f1_threshold1.png?w=616" alt="f1_threshold" class="wp-image-8833"/></figure>
</div>


<p class="wp-block-paragraph">Once you get the optimal threshold, use it for test set probability predictions as a cutoff to predict class labels 0 and 1 for the final submission.</p>



<h3 id="what-did-not-work" class="wp-block-heading">What did not work ?</h3>



<p class="wp-block-paragraph">I tried the following other techniques which did not work and hence my final submissions were based on single model “XGBoost classifier” as described in this post.</p>



<ul class="wp-block-list">
<li>I tried logistic regression and SVM, f1 score was low (less than 0.4).</li>



<li>I tried Random Forest. F1-score was comparatively low.</li>



<li>I tried LightGBM model. In default setting, It gave 0.50 f1-score but somehow it was not improving with parameter tuning. Little improvement was there when early_stopping_rounds was used. We consider best iteration for predictions on test set.</li>



<li>I created some interaction variables like <code>if previous_year_rating == 5 and KPI > 80 == 1 then 1 else 0</code>, <code>if awards_won? == 1 and KPI > 80 == 1 then 1 else 0</code>. It did not help.</li>



<li>Finally, I took the best tuned params of all three (RF, XGboost and LightGBM) and stacked them with ‘Logistics Regression’ as classifier. It did not gave better f1 than individual XGB Classifier model.</li>
</ul>



<h3 id="at-the-end" class="wp-block-heading">At the End</h3>



<p class="wp-block-paragraph">Readers are also encouraged to download the data-set and check if they can reproduce the results. Also, I would love to check in comments if you can surpass the F1-score achieved here in the blog-post. There are following other things which one can try.</p>



<ul class="wp-block-list">
<li>Generally, Stacking improves scores when there are lot of models. One can train say 100s of models of XGBoost and LightGBM (with different close by parameters) and then apply logistic regression on top of that (I tried with only 3 models, failed).</li>



<li>Also, one can try an interaction variable by calculating total score achieved in training (Number of training * Avg. training score).</li>



<li>One can try setting “<em>early_stopping_rounds”  </em>in XGBoost classifier training which I did not tried. It prevents over-fitting and can improve results.</li>
</ul>



<p class="wp-block-paragraph">The full implementation of the followed approach along with LightGBM model example (jupyter notebook) can be downloaded from GitHub link&nbsp;<a href="https://github.com/abhijeet3922/WNS-DS-Hackathon" target="_blank" rel="noopener">here</a>.</p>



<p class="wp-block-paragraph">If you liked the post, follow this blog to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy data analytics&nbsp;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Conventional Approach to Text Classification &#038; Clustering using K-Nearest Neighbor &#038; K-Means: Python Implementation</title>
		<link>https://www.mastersinmachinelearning.org/blog/conventional-approach-to-text-classification-clustering-using-k-nearest-neighbor-k-means-python-implementation/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:40 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=296</guid>

					<description><![CDATA[Text classification is a problem where we have fixed set of classes/categories and any given text is assigned to one of these categories. In contrast,&#160;Text clustering is the task of grouping a set of unlabeled&#160;texts&#160;in such a way that&#160;texts&#160;in the same group (called a&#160;cluster) are more similar to each other than to those in other ... <a title="Conventional Approach to Text Classification &#38; Clustering using K-Nearest Neighbor &#38; K-Means: Python Implementation" class="read-more" href="https://www.mastersinmachinelearning.org/blog/conventional-approach-to-text-classification-clustering-using-k-nearest-neighbor-k-means-python-implementation/" aria-label="Read more about Conventional Approach to Text Classification &#38; Clustering using K-Nearest Neighbor &#38; K-Means: Python Implementation">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Text classification is a problem where we have fixed set of classes/categories and any given text is assigned to one of these categories. In contrast,&nbsp;Text clustering is the task of grouping a set of unlabeled&nbsp;texts&nbsp;in such a way that&nbsp;texts&nbsp;in the same group (called a&nbsp;<em>cluster</em>) are more similar to each other than to those in other clusters.</p>



<p class="wp-block-paragraph">This blog-post implements the above two tasks using well-known machine algorithms: K-NN and K-Means respectively. We will walk through the following steps:</p>



<p class="wp-block-paragraph">1. A simple text cleaning definition.<br>2. Feature Extraction.<br>3. Training the models.<br>4. Testing the models.</p>



<p class="wp-block-paragraph">For training K-NN and K-Means models, the following 30 sentences were collected from 3 categories, namely Cricket, Artificial Intelligence and Chemistry.</p>



<pre class="wp-block-preformatted">1. Cricket is a bat and ball game played between two teams of eleven players each on a cricket field.
2. Each phase of play is called an innings during which one team bats, attempting to score as many runs as possible.
3. The teams have one or two innings apiece and, when the first innings ends, the teams swap roles for the next innings
4. Before a match begins, the two team captains meet on the pitch for the toss of a coin to determine which team will bat first.
5. Two batsmen and eleven fielders then enter the field and play begins when a member of the fielding team, known as the bowler, delivers the ball.
6. The most common dismissal in cricket match are bowled, when the bowler hits the stumps directly with the ball and dislodges the bails. Batsman gets out.
7. Runs are scored by two main methods: either by hitting the ball hard enough for it to cross the boundary, or by the two batsmen swapping ends.
8. The main objective of each team is to score more runs than their opponents.
9. If the team batting last is all out having scored fewer runs than their opponents, they are said to have "lost by n runs".
10. The role of striker batsman is to prevent the ball from hitting the stumps by using his bat and, simultaneously, to strike it well enough to score runs
11. Artificial intelligence is intelligence exhibited by machines, rather than humans or other animals. 
12. the field of AI research defines itself as the study of "intelligent agents": any device that perceives its environment and takes actions that maximize its chance of success at some goal
13. The overall research goal of artificial intelligence is to create technology that allows computers and machines to function in an intelligent manner.
14. Natural language processing[77] gives machines the ability to read and understand human language and extract intelligence from it.
15. AI researchers developed sophisticated mathematical tools to solve specific subproblems. These tools are truly scientific, in the sense that their results are both measurable and verifiable.
16. An intelligent agent is a system that perceives its environment and takes actions which maximize its chances of success.
17. AI techniques have become an essential part of the technology industry, helping to solve many challenging problems in computer science.
18. Recent advancements in AI, and specifically in machine learning, have contributed to the growth of Autonomous Things such as drones and self-driving cars.
19. AI research was revived by the commercial success of expert systems,[28] a form of AI program that simulated the knowledge and analytical skills of human experts.
20. Advanced statistical techniques (loosely known as deep learning), access to large amounts of data and faster computers enabled advances in machine learning and perception.
21. A compound is a pure chemical substance composed of more than one element and the properties of a compound bear little similarity to those of its elements.
22. Since the properties of an element are mostly determined by its electron configuration, the properties of the elements likewise show recurring patterns or periodic behaviour.
23. The property of inertness of noble gases makes them very suitable in chemicals where reactions are not wanted.
24. The atom is also the smallest entity that can be envisaged to retain the chemical properties of the element, such as electronegativity, ionization potential and preferred oxidation state.
25. The nucleus is made up of positively charged protons and uncharged neutrons (together called nucleons), while the electron cloud consists of negatively charged electrons which orbit the nucleus
26. The atom is the basic unit of chemistry. It consists of a dense core called the atomic nucleus surrounded by a space called the electron cloud.
27. A chemical reaction is a transformation of some substances into one or more different substances.
28. Chemistry is sometimes called the central science because it bridges other natural sciences, including physics, geology and biology.
29. Chemistry includes topics such as the properties of individual atoms and how atoms form chemical bonds to create chemical compounds.
30. Chemistry is a branch of physical science that studies the composition, structure of atoms, properties and change of matter.
</pre>



<p class="wp-block-paragraph">A very simple step by step procedure to build the pipeline for training a machine learning model for text analytics applications can be followed like this:</p>



<p class="wp-block-paragraph"><em>Texts</em>&nbsp; ==&gt;&nbsp;&nbsp;<em>Stop words removal</em>&nbsp;==&gt;&nbsp;<em>Punctuation free</em>&nbsp;==&gt;&nbsp;<em>Word Lemmatization</em>&nbsp;==&gt;&nbsp;<em>Digit removal</em>&nbsp;==&gt;&nbsp;<em>Feature Extraction (Tf-Idf)</em>&nbsp;==&gt;&nbsp;<em>Model training</em><em></em></p>



<p class="wp-block-paragraph">Lets start building the pipeline in Python.</p>



<h3 id="1-a-text-cleaning-definition" class="wp-block-heading">1. A Text cleaning definition.</h3>



<p class="wp-block-paragraph">Data pre-processing (a.k.a data cleaning) is one of the most significant step in text analytics. The purpose is to remove any unwanted words or characters which are written for human readability, but won’t contribute to the classification or clustering task in any way.<br>In general, there are mainly 4 cleaning steps that need to be done on text sentences:</p>



<p class="wp-block-paragraph">a)&nbsp;<em><strong>Removal of stop words</strong></em>&nbsp;– Stop words like “and”, “if”, “the”, etc are very common in all English sentences and are not very meaningful in deciding the theme of the article, so these words can be removed from the articles.</p>



<p class="wp-block-paragraph">b)&nbsp;<em><strong>Removal of Punctuation Characters</strong></em>&nbsp;– Exclude&nbsp;all punctuation marks from the set([‘!’, ‘#’, ‘”‘, ‘%’, ‘$’, “‘”, ‘&amp;’, ‘)’, ‘(‘, ‘+’, ‘*’, ‘-‘, ‘,’, ‘/’, ‘.’, ‘;’, ‘:’, ‘=’, ‘&lt;‘, ‘?’, ‘&gt;’, ‘@’, ‘[‘, ‘]’, ‘\\’, ‘_’, ‘^’, ‘`’, ‘{‘, ‘}’, ‘|’, ‘~’]).</p>



<p class="wp-block-paragraph">c)&nbsp;<em><strong>Lemmatization</strong></em>&nbsp;– It is the process of grouping together the different inflected forms of a word so they can be analyzed as a single item. For example, “include”, “includes,” and “included” would all be represented as “include”. The context of the sentence is also preserved in lemmatization as opposed to stemming (another buzz word in text mining which does not consider the meaning of the sentence).</p>



<p class="wp-block-paragraph">d)&nbsp;<em><strong>Removal of digits</strong></em>&nbsp;from the text sentence.</p>



<p class="wp-block-paragraph">The following Python code defines a function&nbsp;<code>clean()</code>&nbsp;for cleaning the text article passed as an argument to it:</p>



<pre class="wp-block-preformatted"># Importing libraries
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.cluster import KMeans
from nltk.corpus import stopwords
from nltk.stem.wordnet import WordNetLemmatizer
import string
import re
import numpy as np
from collections import Counter

stop = set(stopwords.words('english'))
exclude = set(string.punctuation)
lemma = WordNetLemmatizer()

# Cleaning the text sentences so that punctuation marks, stop words &amp; digits are removed
def clean(doc):
    stop_free = " ".join([i for i in doc.lower().split() if i not in stop])
    punc_free = ''.join(ch for ch in stop_free if ch not in exclude)
    normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split())
    processed = re.sub(r"\d+","",normalized)
    y = processed.split()
    return y
</pre>



<h3 id="2-tfidf-feature-extraction" class="wp-block-heading">2. Tf-Idf Feature Extraction.</h3>



<p class="wp-block-paragraph">The most popular and widely used word weighing scheme in text mining problems,&nbsp;<strong>term frequency and inverse document frequency&nbsp;</strong>(tf-idf), is a numerical statistic that is intended to reflect how important a word is to a&nbsp;document&nbsp;in a collection or&nbsp;corpus.&nbsp;The tf-idf value increases&nbsp;proportionally&nbsp;to the number of times a word appears in the document (tf), but is often offset by the frequency of the word in the whole corpus (idf), which helps to adjust for the fact that some words appear more frequently in general. I have explained tf-idf weighing scheme in detail in this&nbsp;<a href="https://appliedmachinelearning.wordpress.com/2017/02/12/sentiment-analysis-using-tf-idf-weighting-pythonscikit-learn/" target="_blank" rel="noopener">blog-post</a>&nbsp;of sentiment analysis application. The following Python code cleanses the text sentences using the definition provided in Section 1. Further, it extracts tf-idf features using scikit-learn library.</p>



<pre class="wp-block-preformatted">print "There are 10 sentences of following three classes on which K-NN classification and K-means clustering"\
         " is performed : \n1. Cricket \n2. Artificial Intelligence \n3. Chemistry"
path = "Sentences.txt"

train_clean_sentences = []
fp = open(path,'r')
for line in fp:
    line = line.strip()
    cleaned = clean(line)
    cleaned = ' '.join(cleaned)
    train_clean_sentences.append(cleaned)

vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(train_clean_sentences)

# Creating true labels for 30 training sentences
y_train = np.zeros(30)
y_train[10:20] = 1
y_train[20:30] = 2
</pre>



<h3 id="3-training-the-classification-knn-amp-clustering-kmeans-models" class="wp-block-heading">3. Training the Classification (K-NN) &amp; Clustering (K-Means) models.</h3>



<p class="wp-block-paragraph">As we have discussed earlier also, Text classification is a supervised learning task, whereas text clustering is an unsupervised task. We are investigating two machine learning algorithms here: K-NN classifier and K-Means clustering.<br>In&nbsp;<em>k-NN classification</em>, the output is a category membership. A text is classified by a majority vote of its neighbors, with the text being assigned to the class most common among its&nbsp;<em>k</em>&nbsp;nearest neighbors.<br>The goal of clustering is to determine the intrinsic grouping in a set of unlabeled data (feature vectors). In&nbsp;<em>K-Means clustering</em>, ‘K’ cluster centers are discovered which is centroid of data points belonging to that cluster. A test data (feature-vector) is assigned to that cluster whose centroid is at minimum Euclidean distance from it.</p>



<p class="wp-block-paragraph">The following Python code snippet trains both the models using scikit-learn library from the tf-idf features extracted in Section 2.</p>



<pre class="wp-block-preformatted"># Clustering the document with KNN classifier
modelknn = KNeighborsClassifier(n_neighbors=5)
modelknn.fit(X,y_train)

# Clustering the training 30 sentences with K-means technique
modelkmeans = KMeans(n_clusters=3, init='k-means++', max_iter=200, n_init=100)
modelkmeans.fit(X)
</pre>



<h3 id="4-testing-on-unseen-texts" class="wp-block-heading">4. Testing on Unseen Texts.</h3>



<p class="wp-block-paragraph">Once the model has been trained,&nbsp; we&nbsp;demonstrate the concept of classification and clustering with above conventional methods. We tested it on the following few unseen text sentences.</p>



<p class="wp-block-paragraph">Chemical compounds are used for preparing bombs based on some reactions.<br>Cricket is a boring game where the batsman only enjoys the game.<br>Machine learning is a area of Artificial intelligence.</p>



<pre class="wp-block-preformatted"># Predicting it on test data : Testing Phase
test_sentences = ["Chemical compunds are used for preparing bombs based on some reactions",\
"Cricket is a boring game where the batsman only enjoys the game",\
"Machine learning is a area of Artificial intelligence"]

test_clean_sentence = []
for test in test_sentences:
cleaned_test = clean(test)
cleaned = ' '.join(cleaned_test)
cleaned = re.sub(r"\d+","",cleaned)
test_clean_sentence.append(cleaned)

Test = vectorizer.transform(test_clean_sentence)

true_test_labels = ['Cricket','AI','Chemistry']
predicted_labels_knn = modelknn.predict(Test)
predicted_labels_kmeans = modelkmeans.predict(Test)

print "\nBelow 3 sentences will be predicted against the learned nieghbourhood and learned clusters:\n1. ",\
test_sentences[0],"\n2. ",test_sentences[1],"\n3. ",test_sentences[2]
print "\n-------------------------------PREDICTIONS BY KNN------------------------------------------"
print "\n",test_sentences[0],":",true_test_labels[np.int(predicted_labels_knn[0])],\
"\n",test_sentences[1],":",true_test_labels[np.int(predicted_labels_knn[1])],\
"\n",test_sentences[2],":",true_test_labels[np.int(predicted_labels_knn[2])]

print "\n-------------------------------PREDICTIONS BY K-Means--------------------------------------"
print "\nIndex of Cricket cluster : ",Counter(modelkmeans.labels_[0:10]).most_common(1)[0][0]
print "Index of Artificial Intelligence cluster : ",Counter(modelkmeans.labels_[10:20]).most_common(1)[0][0]
print "Index of Chemistry cluster : ",Counter(modelkmeans.labels_[20:30]).most_common(1)[0][0]

print "\n",test_sentences[0],":",predicted_labels_kmeans[0],\
"\n",test_sentences[1],":",predicted_labels_kmeans[1],\
"\n",test_sentences[2],":",predicted_labels_kmeans[2]
</pre>



<p class="wp-block-paragraph">While testing, we simply follow the same steps as those in training. Once the sentences have been cleaned, the tf-idf weighted features are extracted from text sentences using the pre-trained dictionary. The feature vectors are then assigned (predicted) to a category (in case of classification) or to a group (in case of&nbsp; clustering).</p>



<p class="wp-block-paragraph">The output snippet of the sequentially combined code from section 1, 2, 3 and 4 is given below:</p>



<p class="wp-block-paragraph"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2018/01/text-classification-and-clustering.png?w=616" alt="Text classification and clustering" srcset="https://appliedmachinelearning.files.wordpress.com/2018/01/text-classification-and-clustering.png?w=616 616w, https://appliedmachinelearning.files.wordpress.com/2018/01/text-classification-and-clustering.png?w=150 150w, https://appliedmachinelearning.files.wordpress.com/2018/01/text-classification-and-clustering.png?w=300 300w, https://appliedmachinelearning.files.wordpress.com/2018/01/text-classification-and-clustering.png?w=768 768w, https://appliedmachinelearning.files.wordpress.com/2018/01/text-classification-and-clustering.png 892w">One can easily observe that all the three sentences are classified as well as clustered in correct categories.</p>



<h3 id="summary" class="wp-block-heading">Summary</h3>



<p class="wp-block-paragraph">Hope it was very easy for readers to follow the implementation of text classification and clustering task. If you have gone through it well, you might have understood by now the basic difference between&nbsp; supervised (K-NN) and unsupervised (K-Means) learning. In supervised learning, the category of the input text can be identified whereas in unsupervised model, only the similar group can be found.</p>



<p class="wp-block-paragraph">For text classification or clustering tasks, these above posted methods are conventional. Much recently, a lot of methods and text representations using deep learning have been proposed and had provided state-of-the-art results for the same task. Few of the approaches that one can explore after having a basic understanding of this blog-post are:</p>



<p class="wp-block-paragraph">1. Word2Vec text representation<br>2. Glove vectors text representation<br>3. FastText n-gram representation<br>4. Deep learning techniques for classification (Fully Connected, 1-D CNN, LSTM etc.)</p>



<p class="wp-block-paragraph">You can get the full python implementation of this blog-post from GitHub link&nbsp;<a href="https://github.com/abhijeet3922/Text-classification-and-clustering" target="_blank" rel="noopener">here</a>.</p>



<p class="wp-block-paragraph">If you liked the post, follow this blog to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy machine learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Building Personal Deep Learning System from Scratch: On-Premise Vs Cloud Comparison</title>
		<link>https://www.mastersinmachinelearning.org/blog/building-personal-deep-learning-system-from-scratch-on-premise-vs-cloud-comparison/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:39 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=324</guid>

					<description><![CDATA[Much recently, I built a system for pursuing deep learning (DL) exercises. Let me give a heads-up that it is purely based on requirement or use cases on what one wants to achieve. For example: I am not a big fan of cloud based DL as it is expensive if you are using it for ... <a title="Building Personal Deep Learning System from Scratch: On-Premise Vs Cloud Comparison" class="read-more" href="https://www.mastersinmachinelearning.org/blog/building-personal-deep-learning-system-from-scratch-on-premise-vs-cloud-comparison/" aria-label="Read more about Building Personal Deep Learning System from Scratch: On-Premise Vs Cloud Comparison">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Much recently, I built a system for pursuing deep learning (DL) exercises. Let me give a heads-up that it is purely based on requirement or use cases on what one wants to achieve. For example:</p>



<ol class="wp-block-list">
<li>If you want to develop large scale AI applications then the hardware configuration would be high-end server based with multi GPU system (mostly for commercial applications).</li>



<li>If you want to learn, develop prototypes and experiment with open source data-sets a lot (mostly for personal usage) then a single GPU based system would suffice.</li>



<li>For a novice, who has started to get into deep learning, I would suggest to get started with free resources like Google Colab or Kaggle Kernels.</li>
</ol>



<p class="wp-block-paragraph">I am not a big fan of cloud based DL as it is expensive if you are using it for personal/research purposes. At times, we need to run lot of experiments in order to conclude or come up with an accurate model. Going for cloud based GPUs may incur huge cost. A comparison between AWS cloud and on-premise DL system has been penned down in last section of this blog-post.</p>



<p class="wp-block-paragraph">Through this concise blog-post, I will share my personal experience of building a deep learning based system which may help people who want to purchase the same for personal usage. This hardware set up is intended for learning, prototyping and research purposes.</p>



<h3 id="1-configuration" class="wp-block-heading">1. Configuration</h3>



<p class="wp-block-paragraph">We will see each component individually which are required for building a deep learning desktop.</p>



<h4 id="processor" class="wp-block-heading"><em><strong>Processor</strong>:</em></h4>



<p class="wp-block-paragraph">I purchased&nbsp;<a href="https://ark.intel.com/products/126686/Intel-Core-i7-8700-Processor-12M-Cache-up-to-4-60-GHz-" target="_blank" rel="noopener">Intel Core i7 8700</a>&nbsp;processor. This processor is 12 hyper-threaded with 6 physical cores. With base frequency of 3.20 GHz and maximum turbo frequency of 4.60 GHz, this one would be a good choice in Intel family. Also, for a multi-GPU based system, one should consider processor like&nbsp;<a href="https://ark.intel.com/products/92981/Intel-Xeon-Processor-E5-2630-v4-25M-Cache-2_20-GHz" target="_blank" rel="noopener">Intel</a>&nbsp;<a href="https://ark.intel.com/products/92981/Intel-Xeon-Processor-E5-2630-v4-25M-Cache-2_20-GHz" target="_blank" rel="noopener">Xeon Processor E5-2630 v4</a>&nbsp;which is 20 hyper-threaded with 10 physical cores.</p>



<p class="wp-block-paragraph">It is important to note that Intel Core i7 8700 has&nbsp;<a>16 PCI Express lanes</a>&nbsp;which would be sufficient for single GPU. Processor and graphic card (GPU) communicate or push data over 1X16 or 2X8 lanes. For dual-GPU system, It is better to have Intel Xeon E5 V4 processor as it has 40 PCI lanes and it can accommodate parallel communications with GPUs.&nbsp;</p>



<p class="wp-block-paragraph">For my usage, I went with Intel core I7 8700 processor as I built a single GPU system and had budget constraints. Also, there are cheaper multi-core AMD processors which one can consider but there are lots of packages, libraries or software which are Intel compatible by default (not AMD compatible by default).</p>



<h4 id="gpu" class="wp-block-heading"><strong><em>GPU:</em></strong></h4>



<p class="wp-block-paragraph">Nvidia GTX-1080 Ti. Depending on your budget, one can purchase GPU. I would suggest to get at least GTX 1080 (Video RAM 8GB) in order to set up deep learning experiments. I got ZOTAX MINI GTX 1080TI (Video RAM 11 GB).</p>



<h4 id="motherboard" class="wp-block-heading"><em><strong>Motherboard</strong></em>:</h4>



<p class="wp-block-paragraph">I bought “<a href="https://www.msi.com/Motherboard/Z370-PC-PRO.html" target="_blank" rel="noopener">MSI Z 370 PC PRO</a>” which supports Intel 8th gen processors along with 2 Graphics card slots.&nbsp; The board comes with two PCIe x16 slots, of which one comes with 16 lanes connected to the chipset (processor), while the other uses four lanes. So, it offers the option of installing multiple graphics cards. The extra PCI express lanes accommodates communication with other peripherals like SSD cards.</p>



<h4 id="cabinetnbsp" class="wp-block-heading"><em><strong>Cabinet: </strong></em></h4>



<p class="wp-block-paragraph">Bought “<a href="http://www.coolermaster.com/case/mid-tower/cm593/" target="_blank" rel="noopener">Cooler Master 590 III</a>&nbsp;Black Window” computer case.&nbsp;Pre-installed with front blue LED 120mm x 2 Fan Support. This would be good enough to accommodate for single GPU based system.</p>



<h4 id="smps" class="wp-block-heading"><em><strong>SMPS:</strong></em></h4>



<p class="wp-block-paragraph">SMPS (switched-mode power supply) is an electronic power supply that incorporates a switching regulator to convert electrical power efficiently. 500W SMPS would be sufficient enough to regulate power supply for RAM (10W), GPU(250W), I7 processor (70W), SSD, HDD and other circuits in Motherboard. I purchased “Cooler Master GOLD 750W” SMPS.</p>



<h4 id="ram" class="wp-block-heading"><em><strong>RAM:</strong></em></h4>



<p class="wp-block-paragraph">I bought 32 GB RAM consisting two Corsair RAM 16GB DDR4 3000MHz.</p>



<h4 id="ssd" class="wp-block-heading"><em><strong>SSD:</strong></em></h4>



<p class="wp-block-paragraph">One of the important recommendations for deep learning system is solid state drive because it fastens read write operations from disk. One may have to work on experiments where you need to access a million audios/images from disk. Moreover, It is recommended to install operating system on SSD. Also, as obvious, all the working data-sets can be kept in SSD. One can keep the other archived data-sets in HDD.</p>



<p class="wp-block-paragraph">The two types of SSD are SATA based SSD and PCI-E based SSD NVME. NVMe drives are much faster than SATA SSD because it uses the PCI-E bus which has greater speed. I bought Western Digital 240GB SATA SSD (did not know about SATA vs NVME difference at that time). One can purchase 500GB NVME SSD if budget allows.</p>



<h4 id="harddisk" class="wp-block-heading"><em><strong>Hard-Disk:</strong></em></h4>



<p class="wp-block-paragraph">Purchased Western Digital 1TB HDD. Again, if budget allows, go for 2 TB. It’s worth it as there are large data-sets out there which occupies HDD quickly.</p>



<h4 id="monitor" class="wp-block-heading"><em><strong>Monitor:</strong></em></h4>



<p class="wp-block-paragraph">As per choice you can take one. I bought “L.G 22 INCH MONITOR”. Look out for monitors which can be connected to the system with HDMI cable. You may not want a monitor with only VGA port which has to be connected with VGA-to-HDMI converter in order to connect to the system cabinet.</p>



<h4 id="ups" class="wp-block-heading"><em><strong>UPS:</strong></em></h4>



<p class="wp-block-paragraph">Got “APC UPS 1100VA”<em><strong>.</strong></em>&nbsp;For GPU based system, It is important to take at least 1100 VA which can give backup to 600W devices for 5 minutes. You will have enough time to safely abort the process and shutdown the system.</p>



<p class="wp-block-paragraph">Finally, do not forget to include sound and Wi-Fi cards in your system.</p>



<h3 id="2-installations" class="wp-block-heading">2. Installations</h3>



<p class="wp-block-paragraph">Once all the installations are done, you may want to install linux operating system (I prefer ubuntu),&nbsp; nvidia drivers, CUDA, CuDNN and finally the neural network frameworks like tensorflow or pytorch. Additionally, readers can follow these links to set up the deep learning systems from scratch.</p>



<ol class="wp-block-list">
<li><a href="https://hackernoon.com/ubuntu-18-04-deep-learning-environment-setup-345ba0b11892" target="_blank" rel="noopener">Ubuntu 18.04 Deep Learning Environment Setup</a><br>2. <a href="https://hackernoon.com/up-and-running-with-ubuntu-nvidia-cuda-cudnn-tensorflow-and-pytorch-a54ec2ec907d" target="_blank" rel="noopener">Up and Running with Ubuntu, Nvidia, Cuda, CuDNN, TensorFlow, and PyTorch</a></li>



<li>Github <a href="https://github.com/ViswanathRavindran/DeepLearningMachineSetup/blob/master/DL_Setup" target="_blank" rel="noopener">link</a></li>
</ol>



<h3 id="3-cloud-gpu-vs-onpremise-gpu-comparison" class="wp-block-heading">3. Cloud GPU Vs On-Premise GPU Comparison</h3>



<p class="wp-block-paragraph">Here is a comparison of running same task of training a “Deepspeech” BiLSTM model for automatic speech recognition on AWS cloud as well as my personal deep learning system. The data-set used was 260 hours of telephonic conversations and its transcripts from switchboard data-set. For bench-marking purpose, we kept all the parameters of the model same. For example, number of layers, number of hidden nodes in each layer and train, development, test batch size etc.</p>



<h4 id="performance" class="wp-block-heading">Performance</h4>



<p class="wp-block-paragraph">The task took approximately 20 minutes on GTX-1080Ti (above specified DL system in blog-post). Below screenshot shows the elapsed time.</p>



<figure class="wp-block-image" id="attachment_9082"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/02/on-premise.png?w=616" alt="On-premise performance" class="wp-image-9082"/><figcaption class="wp-element-caption">On-premise GTX-10801Ti (11 GB VRAM)</figcaption></figure>



<p class="wp-block-paragraph">The task took approximately 10 minutes on AWS Cloud P2.8xlarge instance with 8 K-80 GPU cards in parallel and 32 vCPUs system. Below screenshot shows the same.</p>



<figure class="wp-block-image" id="attachment_9083"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/02/cloud.png?w=616" alt="On Cloud performance" class="wp-image-9083"/><figcaption class="wp-element-caption">AWS Cloud P2.8xlarge (8 K-80 cards &amp; 32 vCPUs)</figcaption></figure>



<p class="wp-block-paragraph">We can conclude that AWS cloud P2.8Xlarge instance with 8 parallel K-80 cards are 2X faster than the on-premise single GPU GTX 1080Ti system. Note that we get only twice the performance even after using 8 GPU cards on AWS cloud.</p>



<h4 id="cost" class="wp-block-heading">Cost</h4>



<p class="wp-block-paragraph">The cost of running above AWS instance for 65 hours (up till now) is approximately 500 US dollars (It will be 1000 US dollars if using instance from ‘Asia Mumbai’ region).<br>The cost of building a DL system specified in this blog-post is 2500 US dollars only. It is including all the components mentioned.</p>



<p class="wp-block-paragraph">In a months time, the cost incurred on AWS cloud will surpass the whole purchasing cost of DL system. In return, we are only getting twice the performance with AWS cloud instance. Note that life of on-premise system will be a resource for few years. I do concur that cloud would always be a faster option as far as the concern is deployment and setting up the machine.</p>



<p class="wp-block-paragraph">If you liked the post, follow this blog to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy deep learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Building End to End Memory Network for Question Answering System on bAbI Facebook Data-set: Python &#124; Keras (Part 2)</title>
		<link>https://www.mastersinmachinelearning.org/blog/building-end-to-end-memory-network-for-question-answering-system-on-babi-facebook-data-set-python-keras-part-2/</link>
		
		<dc:creator><![CDATA[wpx_mastersMLM]]></dc:creator>
		<pubDate>Sat, 31 May 2025 14:25:38 +0000</pubDate>
				<category><![CDATA[Machine Learning Blog]]></category>
		<guid isPermaLink="false">https://www.mastersinmachinelearning.org/?page_id=335</guid>

					<description><![CDATA[This blog-post is the subsequent part of my previous&#160;blog-post&#160;on developing question answering system on Facebook bAbI data-set. In my previous article, I described the bAbI data-set and we have extracted features for building the model. If you have directly landed on this blog-post then I would suggest you to read the previous&#160;Developing factoid question answering ... <a title="Building End to End Memory Network for Question Answering System on bAbI Facebook Data-set: Python &#124; Keras (Part 2)" class="read-more" href="https://www.mastersinmachinelearning.org/blog/building-end-to-end-memory-network-for-question-answering-system-on-babi-facebook-data-set-python-keras-part-2/" aria-label="Read more about Building End to End Memory Network for Question Answering System on bAbI Facebook Data-set: Python &#124; Keras (Part 2)">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">This blog-post is the subsequent part of my previous&nbsp;<a href="https://appliedmachinelearning.wordpress.com/2019/05/01/developing-factoid-question-answering-system-on-babi-facebook-data-set-python-keras-part-1/" target="_blank" rel="noopener">blog-post</a>&nbsp;on developing question answering system on Facebook bAbI data-set. In my previous article, I described the bAbI data-set and we have extracted features for building the model. If you have directly landed on this blog-post then I would suggest you to read the previous&nbsp;<a href="https://appliedmachinelearning.wordpress.com/2019/05/01/developing-factoid-question-answering-system-on-babi-facebook-data-set-python-keras-part-1/" target="_blank" rel="noopener">Developing factoid question answering system on bAbI facebook data-set</a>. In this article, we will focus on writing python implementation of end to end memory neural network model using Keras.</p>



<p class="wp-block-paragraph">So, let’s start with understanding and building the model proposed by Facebook AI research in 2015 in this paper “<a href="https://arxiv.org/abs/1503.08895" target="_blank" rel="noopener">End to End Memory Networks</a>“.</p>



<h3 id="1-understanding-memory-network-model" class="wp-block-heading">1. Understanding Memory Network Model</h3>



<p class="wp-block-paragraph">To understand the end to end memory network model, let us define few memory representation vectors and its computation first.</p>



<h4 id="input-memory-representation" class="wp-block-heading">Input Memory Representation</h4>



<p class="wp-block-paragraph">The story vectors derived from vocabulary (previous article) are converted into memory vectors of dimension ‘d’ (here, assume embedding_size ‘d’=50) computed by embedding layer. An embedding layer takes story vector (max length 68) as input and generates a fixed ‘d’ dimensional vector for each input story vector. Let us call this embedding ‘m’. Dimension of ‘m’ would be (max_story_length, embedding_size) i.e. (68,50).</p>



<h4 id="question-memory-representation" class="wp-block-heading">Question Memory Representation</h4>



<p class="wp-block-paragraph">The query vector is also embedded (again, via another embedding layer in keras with the same dimensions as ‘d’ (here d=50) to obtain an embedding ‘q’. The embedding layer takes query vector (max length 4) as input and generates an embedding ‘q’ of ‘d’ dimension. Dimension of ‘q’ would be (query_length, embedding_size) i.e. (4,50).</p>



<p class="wp-block-paragraph">Further, In the embedding space, we compute the probability vector ‘p’ i.e. match between ‘q’ and each memory ‘m’ by taking the inner product followed by a softmax function:</p>



<p class="wp-block-paragraph"><strong><em>p = Softmax(dot(m,q))</em></strong></p>



<p class="wp-block-paragraph">Dimension of ‘p’ would be (max_story_length, query_length) i.e. (68,4)</p>



<h4 id="output-memory-representation" class="wp-block-heading">Output Memory Representation</h4>



<p class="wp-block-paragraph">The story vector are also converted into memory vector of dimension query max length i.e. 4 computed by a separate embedding layer. This embedding layer takes story vector (max length 68) vector as input and generates an embedding of ‘max length=4’ dimension. Let us call this embedding ‘c’. Dimension of ‘c’ would be (max_story_length, query_length) i.e. (68,4).</p>



<p class="wp-block-paragraph">The output vector or response vector&nbsp; ‘o’ is then calculated by sum over the transformed embedding ‘c’ , weighted by the probability vector ‘p’ calculated earlier:</p>



<p class="wp-block-paragraph"><em><strong>o = add(c,p)</strong></em></p>



<p class="wp-block-paragraph">Dimension of ‘o’ would be (max_story_length, query_length) i.e. (68,4)</p>



<h4 id="final-prediction" class="wp-block-heading">Final Prediction</h4>



<p class="wp-block-paragraph">The output or response vector ‘o’ and the input vector ‘m’ are concatenated to form a result vector ‘r’ which is further passed to LSTM layer and finally to output Dense layer of vocabulary size which gives softmax probability of each word in the vocab. We consider the word predicted with greater accuracy as answer word. Dimension after concatenation would be (query_length,&nbsp; embedding_size + max_story_length) i.e. (4, 118).</p>



<p class="wp-block-paragraph"><em><strong>answer = Softmax(Dense(LSTM(concat(o,q))))</strong></em></p>



<p class="wp-block-paragraph">or we can write it as</p>



<p class="wp-block-paragraph"><em><strong>answer = Softmax(W(concat(o,q)))</strong></em></p>



<p class="wp-block-paragraph">A below pictorial diagram showcases the above procedure of building the model.</p>



<figure class="wp-block-image" id="attachment_9248"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/single_layer_mmn.png?w=616" alt="Question answer system memory network model" class="wp-image-9248"/><figcaption class="wp-element-caption">Single layer end to end memory network [1]</figcaption></figure>



<h3 id="2-building-the-model" class="wp-block-heading">2. Building the Model</h3>



<p class="wp-block-paragraph">Hope the above section gave pretty clear illustration on prediction of answer word through the memory network model. Let us quickly build an end to end single layer memory network model.</p>



<h4 id="importing-libraries" class="wp-block-heading"><strong>Importing Libraries</strong></h4>



<pre class="wp-block-preformatted">import IPython
import matplotlib.pyplot as plt
import pandas as pd

import keras
from keras.models import Sequential, Model
from keras.layers.embeddings import Embedding
from keras.layers import Permute, dot, add, concatenate
from keras.layers import LSTM, Dense, Dropout, Input, Activation
</pre>



<h4 id="config-file-parameters" class="wp-block-heading"><strong>Config file (Parameters)</strong></h4>



<pre class="wp-block-preformatted"># number of epochs to run
train_epochs = 100
# Training batch size
batch_size = 32
# Hidden embedding size
embed_size = 50
# number of nodes in LSTM layer
lstm_size = 64
# dropout rate
dropout_rate = 0.30
</pre>



<h4 id="defining-the-model" class="wp-block-heading"><strong>Defining the Model</strong></h4>



<pre class="wp-block-preformatted"># placeholders
input_sequence = Input((story_maxlen,))
question = Input((query_maxlen,))

print('Input sequence:', input_sequence)
print('Question:', question)

# encoders
# embed the input sequence into a sequence of vectors
input_encoder_m = Sequential()
input_encoder_m.add(Embedding(input_dim=vocab_size,
                              output_dim=embed_size))
input_encoder_m.add(Dropout(dropout_rate))
# output: (samples, story_maxlen, embedding_dim)

# embed the input into a sequence of vectors of size query_maxlen
input_encoder_c = Sequential()
input_encoder_c.add(Embedding(input_dim=vocab_size,
                              output_dim=query_maxlen))
input_encoder_c.add(Dropout(dropout_rate))
# output: (samples, story_maxlen, query_maxlen)

# embed the question into a sequence of vectors
question_encoder = Sequential()
question_encoder.add(Embedding(input_dim=vocab_size,
                               output_dim=embed_size,
                               input_length=query_maxlen))
question_encoder.add(Dropout(dropout_rate))
# output: (samples, query_maxlen, embedding_dim)

# encode input sequence and questions (which are indices)
# to sequences of dense vectors
input_encoded_m = input_encoder_m(input_sequence)
print('Input encoded m', input_encoded_m)
input_encoded_c = input_encoder_c(input_sequence)
print('Input encoded c', input_encoded_c)
question_encoded = question_encoder(question)
print('Question encoded', question_encoded)

# compute a 'match' between the first input vector sequence
# and the question vector sequence
# shape: `(samples, story_maxlen, query_maxlen)
match = dot([input_encoded_m, question_encoded], axes=-1, normalize=False)
print(match.shape)
match = Activation('softmax')(match)
print('Match shape', match)

# add the match matrix with the second input vector sequence
response = add([match, input_encoded_c])  # (samples, story_maxlen, query_maxlen)
response = Permute((2, 1))(response)  # (samples, query_maxlen, story_maxlen)
print('Response shape', response)

# concatenate the response vector with the question vector sequence
answer = concatenate([response, question_encoded])
print('Answer shape', answer)

answer = LSTM(lstm_size)(answer)  # Generate tensors of shape 32
answer = Dropout(dropout_rate)(answer)
answer = Dense(vocab_size)(answer)  # (samples, vocab_size)
# we output a probability distribution over the vocabulary
answer = Activation('softmax')(answer)
</pre>



<figure class="wp-block-image" id="attachment_9255"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/tensors.png?w=616" alt="tensors" class="wp-image-9255"/><figcaption class="wp-element-caption">Shape of Tensors in Memory Network Model</figcaption></figure>



<p class="wp-block-paragraph">In the above code snippet, you can see we have two inputs : input_sequence (story) and question (query). Also, we have ‘answer’ as a final model which combines response model and encoded query as input and predicts the answer word.</p>



<h3 id="3-training-the-model" class="wp-block-heading">3. Training the Model</h3>



<p class="wp-block-paragraph">The below codes complies the model and train it using input features vectors as well as labels extracted in the&nbsp;<a href="https://appliedmachinelearning.wordpress.com/2019/05/01/developing-factoid-question-answering-system-on-babi-facebook-data-set-python-keras-part-1/" target="_blank" rel="noopener">first part</a>&nbsp;of this blog-post series.</p>



<pre class="wp-block-preformatted"># build the final model
model = Model([input_sequence, question], answer)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy',
              metrics=['accuracy'])

print(model.summary())

# start training the model
model.fit([inputs_train, queries_train],
         answers_train, batch_size, train_epochs,
         callbacks=[TrainingVisualizer()],
         validation_data=([inputs_test, queries_test], answers_test))

# save model
model.save('model.h5')
</pre>


<div class="wp-block-image">
<figure class="aligncenter" id="attachment_9256"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/model_summary.png?w=616" alt="model_summary" class="wp-image-9256"/><figcaption class="wp-element-caption">Model Summary</figcaption></figure>
</div>


<h3 id="4-visualization" class="wp-block-heading">4. Visualization</h3>



<p class="wp-block-paragraph">The below python function shows visualization of training and validation categorical cross entropy loss as well as&nbsp; train and validation accuracy over iterations. It is a callback function while model training.</p>



<pre class="wp-block-preformatted">class TrainingVisualizer(keras.callbacks.History):
    def on_epoch_end(self, epoch, logs={}):
        super().on_epoch_end(epoch, logs)
        IPython.display.clear_output(wait=True)
        pd.DataFrame({key: value for key, value in self.history.items() if key.endswith('loss')}).plot()
        axes = pd.DataFrame({key: value for key, value in self.history.items() if key.endswith('acc')}).plot()
        axes.set_ylim([0, 1])
        plt.show()
</pre>



<figure class="wp-block-image" id="attachment_9257"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/loss_plot.png?w=616" alt="loss plot" class="wp-image-9257"/><figcaption class="wp-element-caption">Training and Validation Loss</figcaption></figure>



<figure class="wp-block-image" id="attachment_9258"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/val_accuracy_plot.png?w=616" alt="accuracy plot" class="wp-image-9258"/><figcaption class="wp-element-caption">Training and Validation Accuracy</figcaption></figure>


<div class="wp-block-image">
<figure class="aligncenter" id="attachment_9264"><img decoding="async" src="https://appliedmachinelearning.files.wordpress.com/2019/04/last_iteration.png?w=693&amp;h=54" alt="last_iteration" class="wp-image-9264"/><figcaption class="wp-element-caption">Result: Epoch 100</figcaption></figure>
</div>


<h3 id="5-tests-results" class="wp-block-heading">5. Tests Results</h3>



<p class="wp-block-paragraph">I hope you have enjoyed the model building process till now. Let us check few of the test stories and see how the model performs in predicting the right answer to the query.</p>



<pre class="wp-block-preformatted">for i in range(0,10):
    current_inp = test_stories[i]
    current_story, current_query, current_answer = vectorize_stories([current_inp], word_idx, story_maxlen, query_maxlen)
    current_prediction = model.predict([current_story, current_query])
    current_prediction = idx_word[np.argmax(current_prediction)]
    print(' '.join(current_inp[0]), ' '.join(current_inp[1]), '| Prediction:', current_prediction, '| Ground Truth:', current_inp[2])
    print("--------------------------------------------------------------")
</pre>



<pre class="wp-block-preformatted">John travelled to the hallway . Mary journeyed to the bathroom . Where is John ? | Prediction: hallway | Ground Truth: hallway
---------------------------------------------------------------------
John travelled to the hallway . Mary journeyed to the bathroom . Daniel went back to the bathroom . John moved to the bedroom . Where is Mary ? | Prediction: bathroom | Ground Truth: bathroom
---------------------------------------------------------------------
John travelled to the hallway . Mary journeyed to the bathroom . Daniel went back to the bathroom . John moved to the bedroom . John went to the hallway . Sandra journeyed to the kitchen . Where is Sandra ? | Prediction: kitchen | Ground Truth: kitchen
---------------------------------------------------------------------
John travelled to the hallway . Mary journeyed to the bathroom . Daniel went back to the bathroom . John moved to the bedroom . John went to the hallway . Sandra journeyed to the kitchen . Sandra travelled to the hallway . John went to the garden . Where is Sandra ? | Prediction: hallway | Ground Truth: hallway
---------------------------------------------------------------------
John travelled to the hallway . Mary journeyed to the bathroom . Daniel went back to the bathroom . John moved to the bedroom . John went to the hallway . Sandra journeyed to the kitchen . Sandra travelled to the hallway . John went to the garden . Sandra went back to the bathroom . Sandra moved to the kitchen . Where is Sandra ? | Prediction: kitchen | Ground Truth: kitchen
---------------------------------------------------------------------
Sandra travelled to the kitchen . Sandra travelled to the hallway . Where is Sandra ? | Prediction: hallway | Ground Truth: hallway
---------------------------------------------------------------------
Sandra travelled to the kitchen . Sandra travelled to the hallway . Mary went to the bathroom . Sandra moved to the garden . Where is Sandra ? | Prediction: garden | Ground Truth: garden
---------------------------------------------------------------------
Sandra travelled to the kitchen . Sandra travelled to the hallway . Mary went to the bathroom . Sandra moved to the garden . Sandra travelled to the office . Daniel journeyed to the hallway . Where is Daniel ? | Prediction: hallway | Ground Truth: hallway
---------------------------------------------------------------------
Sandra travelled to the kitchen . Sandra travelled to the hallway . Mary went to the bathroom . Sandra moved to the garden . Sandra travelled to the office . Daniel journeyed to the hallway . Daniel journeyed to the office . John moved to the hallway . Where is Sandra ? | Prediction: office | Ground Truth: office
---------------------------------------------------------------------
Sandra travelled to the kitchen . Sandra travelled to the hallway . Mary went to the bathroom . Sandra moved to the garden . Sandra travelled to the office . Daniel journeyed to the hallway . Daniel journeyed to the office . John moved to the hallway . John travelled to the bathroom . John journeyed to the office . Where is Daniel ? | Prediction: office | Ground Truth: office
---------------------------------------------------------------------
</pre>



<h3 id="reference" class="wp-block-heading">Reference</h3>



<p class="wp-block-paragraph">[1]&nbsp;<a href="https://arxiv.org/abs/1503.08895" target="_blank" rel="noopener">End to End Memory Networks</a><br>[2]&nbsp;<a href="https://arxiv.org/abs/1502.05698" target="_blank" rel="noopener">Towards AI-Complete Question Answering: A Set of Prerequisite Toy Tasks</a><br>[3]&nbsp;<a href="https://github.com/keras-team/keras/blob/master/examples/babi_rnn.py" target="_blank" rel="noopener">Example code : bAbI_rnn.py from</a>&nbsp;<a href="https://github.com/keras-team/keras/blob/master/examples/babi_rnn.py" target="_blank" rel="noopener">keras-team/keras</a>&nbsp;<a href="https://github.com/keras-team/keras/blob/master/examples/babi_rnn.py" target="_blank" rel="noopener">GitHub repository</a></p>



<h3 id="final-thoughts" class="wp-block-heading">Final Thoughts</h3>



<p class="wp-block-paragraph">Hope it was easy to follow this blog-post series on developing question and answering system for a toy task on bAbI data-set. If you are totally unaware of neural networks or Q&amp;A systems then I would suggest to first read more on question answering system from the abundant material available online. Before signing off,&nbsp; I would like to put few more thoughts on this post and for future:</p>



<ul class="wp-block-list">
<li>The data-set is a synthetic data-set with limited data (10k stories only) and has a very limited vocabulary of 22 unique words.</li>



<li>It would be great to check the performance on reasoning tasks where prediction is based on multiple facts.</li>



<li>A more generic Q&amp;A system should allow machine reading comprehension (MRC) abilities where system should be able to predict span of words (sentence) from reading a paragraph (based on multiple supporting facts).</li>



<li>Readers who are encouraged to explore Q&amp;A systems more can check an open source <a href="https://rajpurkar.github.io/SQuAD-explorer/" target="_blank" rel="noopener">SQUAD2.0</a> data-set which is much more rigorous task and would require further research.</li>
</ul>



<p class="wp-block-paragraph">You can get the full python implementation (jupyter notebook) from GitHub link&nbsp;<a href="https://github.com/abhijeet3922/QA-system-memory-networks-bAbI-dataset" target="_blank" rel="noopener">here</a>.</p>



<p class="wp-block-paragraph">Intent of this blog-post series was to perform experiments and demonstrate a fair idea of question answering system. Personally, I am more interested in MRC application where the answer to every question is a segment of text, or&nbsp;<em>span</em>, from the corresponding reading passage, or the question might be unanswerable. Hopefully, I will be writing solution to MRC task on Squad data-set in near future. Stay tuned !!.</p>



<p class="wp-block-paragraph">If you liked the post,&nbsp;<strong><em>follow this blog</em></strong>&nbsp;to get updates about upcoming articles. Also, share it so that it can reach out to the readers who can actually gain from this. Please feel free to discuss anything regarding the post. I would love to hear feedback from you.</p>



<p class="wp-block-paragraph">Happy deep learning <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: www.mastersinmachinelearning.org @ 2026-07-22 23:22:36 by W3 Total Cache
-->