<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Santhosh Kannan on Medium]]></title>
        <description><![CDATA[Stories by Santhosh Kannan on Medium]]></description>
        <link>https://medium.com/@mail2santhoshkannan?source=rss-ca2d8a94ed95------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*MLCnFPthGokkBXw1</url>
            <title>Stories by Santhosh Kannan on Medium</title>
            <link>https://medium.com/@mail2santhoshkannan?source=rss-ca2d8a94ed95------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 23 May 2026 15:49:35 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@mail2santhoshkannan/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Text Classification Using Naive Bayes]]></title>
            <link>https://medium.com/featurepreneur/text-classification-using-naive-bayes-8e571750736e?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/8e571750736e</guid>
            <category><![CDATA[classification]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[text-classification]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <category><![CDATA[naive-bayes]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Mon, 08 May 2023 15:26:26 GMT</pubDate>
            <atom:updated>2023-05-08T15:26:26.643Z</atom:updated>
            <content:encoded><![CDATA[<h3>What is Text Classification?</h3><p>Text classification is the process of categorizing text data into predefined classes based on its content. It finds its use in many NLP applications like sentiment analysis, spam detection, and more. Text Classification is a challenging task due to the complex and nuanced nature of human language. But there are many models available to analyze and classify unstructured text data like Naive Bayes, Support Vector Machines, and neural networks.</p><h3>What is Bayes’ Theorem?</h3><p>Bayes’ theorem is used to find the probability of an event based on prior knowledge or evidence. It is based on conditional probability, which is the probability of an event occurring given that another event has occurred. Mathematically, Bayes’ theorem can be expressed as</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/454/1*Jfaixl1uM_mDnwBdzeR-FQ.png" /><figcaption>Bayes’ Theorem</figcaption></figure><p>where, P(A | B) is the conditional probability of A given B, P(B | A) is the conditional probability of B given A, P(A) is the prior probability of A, and P(B) is the prior probability of B.</p><h3>What is Naive Bayes?</h3><p>Naive Bayes is a probabilistic machine learning model that is based on Bayes’ theorem. It works by calculating the probability that a given data point belongs to a class and then selects the class with the highest probability as the predicted output.</p><h3>Text classification using Naive Bayes</h3><pre>import numpy as np<br>from sklearn.datasets import fetch_20newsgroups<br>from sklearn.feature_extraction.text import CountVectorizer<br>from sklearn.feature_extraction.text import TfidfTransformer<br>from sklearn.naive_bayes import MultinomialNB<br>from sklearn.pipeline import Pipeline<br><br>categories = [&#39;rec.motorcycles&#39;, &#39;sci.electronics&#39;,<br>              &#39;comp.graphics&#39;, &#39;sci.med&#39;]<br><br>train_data = fetch_20newsgroups(subset=&#39;train&#39;, categories=categories, shuffle=True, random_state=42)<br>test_data = fetch_20newsgroups(subset=&#39;test&#39;,<br>                               categories=categories, shuffle=True, random_state=42)<br><br>text_clf = Pipeline([<br>    (&#39;vect&#39;, CountVectorizer()),<br>    (&#39;tfidf&#39;, TfidfTransformer()),<br>    (&#39;clf&#39;, MultinomialNB()),<br>])<br><br>text_clf.fit(train_data.data, train_data.target)<br>docs_test = test_data.data<br>predicted = text_clf.predict(docs_test)<br>print(&#39;We got an accuracy of&#39;,np.mean(predicted == test_data.target)*100, &#39;% over the test data.&#39;)</pre><p>The 20 newsgroups dataset comprises around 18000 newsgroups posts on 20 topics split into two subsets: one for training and the other one for testing.</p><p>CountVectorizer is used to transform a given text into a vector on the basis of the frequency of each word that occurs in the entire text.</p><p>TF-IDF stands for Term Frequency — Inverse Document Frequency of records. It can be defined as the calculation of how relevant a word in a series or corpus is to a text. The meaning increases proportionally to the number of times in the text a word appears but is compensated by the word frequency in the corpus (data set).</p><h3>What are the advantages of using Naive Bayes for text classification?</h3><ul><li>Can be implemented quickly and efficiently</li><li>Can handle very large volumes of data and high dimensional data</li><li>Good performance on many real-world problems, often outperforming complex models</li><li>Interpretable results</li></ul><h3>What are the disadvantages of using Naive Bayes for text classification?</h3><ul><li>Assumes that the features are independent of each other which is often not the case for real-world problems.</li><li>Faces the ‘zero-frequency problem’ where it assigns zero probability to a categorical variable whose category in the test data set wasn’t available in the training dataset.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8e571750736e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/text-classification-using-naive-bayes-8e571750736e">Text Classification Using Naive Bayes</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Combating overfitting with L1 and L2 regularization]]></title>
            <link>https://medium.com/featurepreneur/combating-overfitting-with-l1-and-l2-regularization-f161e48205b?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/f161e48205b</guid>
            <category><![CDATA[regression]]></category>
            <category><![CDATA[regularization]]></category>
            <category><![CDATA[feature-selection]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <category><![CDATA[overfitting]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Mon, 08 May 2023 15:24:44 GMT</pubDate>
            <atom:updated>2023-05-08T15:24:44.351Z</atom:updated>
            <content:encoded><![CDATA[<h3>What is overfitting?</h3><p>Overfitting is a very common problem in machine learning where a model performs impressively on training data but performs poorly on new, unseen data. This is because the model has learned patterns in the training data which don’t generalize to the whole population.</p><h3>How to deal with overfitting?</h3><ul><li>Use simpler models</li><li>Collect more data</li><li>Use cross-validation</li><li>Early stopping</li><li>Regularization</li></ul><h3>What is Regularization?</h3><p>Regularization is the technique in which the model parameters are constrained or regularized, which reduces the risk of overfitting. It works by adding a penalty to the cost function the model is trying to minimize. By doing so, regularization forces the model to pay more attention to the overall structure of the model, rather than fitting the training data as closely as possible. The two common types of regularization are L1(Lasso) and L2(Ridge).</p><h3>What is L1 Regularization?</h3><p>L1 Regularization, also known as Lasso regularization, adds a penalty to the cost function that is proportional to the absolute value of the model weights.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*pEy3bSN9cvZb_hANfDKNmQ.png" /><figcaption>Loss function during L1 regularization</figcaption></figure><p>This results in a sparse model in which many weights are exactly zero. This can be helpful when the number of features is large and only a subset of important ones is to be selected. L1 regularization is also robust to noise in data, as it is less sensitive to small, outlying values.</p><p>L1 regularization is commonly used with linear models, such as linear regression. L1 regularization is sensitive to the scaling of data, hence it is a good idea to standardize the features before using L1 regularization.</p><h3>What is L2 Regularization?</h3><p>L2 Regularization, also known as Ridge regularization, adds a penalty to the cost function proportional to the square of the model weights.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/347/1*4K1b4-eZHVL2FuNTLhpFaw.png" /><figcaption>Loss function during L2 regularization</figcaption></figure><p>This results in a model with small, non-zero weights. L2 regularization is sensitive to outliers. hence outliers should be handled before using L2 regularization.</p><p>L2 Regularization is commonly used with linear models, such as linear regression. Like L1 regularization, L2 regularization is also sensitive to the scaling of data.</p><h3>Implementation of Regularization using Scikit-learn</h3><pre>import pandas as pd<br>import numpy as np<br>import pandas as pd<br>import matplotlib.pyplot as plt<br>from sklearn.linear_model import LinearRegression, Lasso, Ridge<br>from sklearn.model_selection import train_test_split<br>from sklearn.datasets import load_boston<br>from sklearn.metrics import mean_squared_error<br><br>bos = load_boston()<br>df = pd.DataFrame(bos.data, columns = bos.feature_names)<br>df[&#39;PRICE&#39;] = bos.target<br><br>x_train, x_test, y_train, y_test = train_test_split(df.drop(&quot;PRICE&quot;,axis=1),df[&quot;PRICE&quot;],test_size=.2)<br><br>lreg = LinearRegression()<br>lreg.fit(x_train,y_train)<br>lreg_y_pred = lreg.predict(x_test)<br><br>lrid = Ridge()<br>lrid.fit(x_train,y_train)<br>lrid_y_pred = lrid.predict(x_test)<br><br>lasso = Lasso()<br>lasso.fit(x_train,y_train)<br>lasso_y_pred = lasso.predict(x_test)<br><br>fig, ax = plt.subplots(figsize=(20,7))<br>x = np.arange(13)<br>ax.bar(x-0.2, lreg.coef_, width=0.2, color=&#39;b&#39;, align=&#39;center&#39;,label=&quot;Linear Regression&quot;)<br>ax.bar(x_train.columns, lrid.coef_, width=0.2, color=&#39;g&#39;, align=&#39;center&#39;, label=&quot;Ridge Regression&quot;)<br>ax.bar(x+0.2, lasso.coef_, width=0.2, color=&#39;r&#39;, align=&#39;center&#39;,label=&quot;Lasso Regression&quot;)<br>ax.spines[&#39;bottom&#39;].set_position(&#39;zero&#39;)<br>plt.style.use(&#39;ggplot&#39;)<br>plt.legend()<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KHUaGOCgzKpyxPty0VfGmg.png" /><figcaption>Coefficients for linear, ridge, and lasso regressions</figcaption></figure><h3>What are the disadvantages of Ridge Regularization?</h3><ul><li>It may not perform well when there are a lot of features.</li><li>Doesn’t perform feature selection — it keeps all the features in the model and only reduces the magnitude of their coefficients.</li></ul><h3>What are the disadvantages of Lasso Regularization?</h3><ul><li>Eliminates some of the features by setting their coefficients to zero, potentially excluding important features.</li><li>It may not perform well when there is multicollinearity between features.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f161e48205b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/combating-overfitting-with-l1-and-l2-regularization-f161e48205b">Combating overfitting with L1 and L2 regularization</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Beautify your Python code with Decorators]]></title>
            <link>https://medium.com/featurepreneur/beautify-your-python-code-with-decorators-43e9cea0dfba?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/43e9cea0dfba</guid>
            <category><![CDATA[decorators]]></category>
            <category><![CDATA[flask]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-programming]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Mon, 08 May 2023 15:23:20 GMT</pubDate>
            <atom:updated>2023-05-09T08:57:18.456Z</atom:updated>
            <content:encoded><![CDATA[<h3>What are Decorators?</h3><p>Decorators are functions that modify or add additional functionality to the behavior of other functions or classes without changing the source code of the other functions. In Python, decorators can be identified by the “@” symbol followed by the decorator&#39;s name. This is placed immediately before the definition of a function or class that is being decorated.</p><h3>What is the need for Decorators?</h3><p>Consider the user info endpoint in a website that displays the user’s information. This endpoint must display the information only if the user is logged in. If the user is not logged in, it should redirect to the login page.</p><p>One can modify the source code of this endpoint to check if the user is logged in and then decide whether to display the info or redirect. Although it seems like an easy problem to fix, consider that there are many endpoints that must work only if the user is logged in. Changing the source code for each endpoint to check and redirect leads to code duplication.</p><p>Decorators provide the best solution to this problem and allow not only code re-usability and maintenance but also various other functionalities. Let’s look at how decorators can be used to solve the above problem and a few other examples where decorators can be used.</p><h3>What is the syntax for Decorators?</h3><pre>import functools<br><br>def decorator_function(func):<br>    @functools.wraps(func)<br>    def wrapper(*args, **kwargs):<br>        # do something before the function call<br>        value = func(*args, **kwargs)<br>        # do something after the function call<br>        return value<br>    <br>    return wrapper<br><br>@decorator_function<br>def new_func():<br>    # do something</pre><p>This is the general syntax for a decorator function. The decorator_function is defined just like any other function except that it takes a function reference that needs to be wrapped as the argument.</p><p>It is a good practice to use the functools.wraps decorator to preserve the information about the original function or class, otherwise, information such as the original function’s name, docstring, arguments, etc., will be overwritten with the decorator&#39;s information.</p><p>A wrapper function that takes any number of positional and keyword arguments is defined that calls the original function with the same arguments. It does some functionality before and/or after calling the original function.</p><p>The “@” symbol along with the decorator function name can then be used to wrap any function and provide it with additional functionalities.</p><h3>What are some examples where decorators can be used?</h3><h4>1. Logging</h4><p>A simple logging decorator can be created that logs all the arguments and the return value when a function is called.</p><pre>import functools<br><br>def log_function(func):<br>    @functools.wraps(func)<br>    def wrapper(*args, **kwargs):<br>        args_repr = [repr(a) for a in args]<br>        kwargs_repr = [f&quot;{k}={v!r}&quot; for k, v in kwargs.items()]<br>        signature = &quot;, &quot;.join(args_repr + kwargs_repr)<br>        <br>        print(f&quot;Calling function {func.__name__}({signature})&quot;)<br>        <br>        value = func(*args, **kwargs)<br>        print(f&quot;function {func.__name__!r} returned {value!r}&quot;)<br>        <br>        return value<br>    <br>    return wrapper<br><br>@log_function<br>def is_prime(n):<br>    if n &lt; 2: <br>         return False<br>    if n % 2 == 0:<br>        if n==2:<br>            return True<br>        return False<br>    k = 3<br>    while k*k &lt;= n:<br>         if n % k == 0:<br>             return False<br>         k += 2<br>    return True<br><br>@log_function<br>def hello():<br>    print(&quot;Hello World&quot;)<br>    <br>hello()<br>print(is_prime(25))<br><br>#########################<br># Output: <br># <br># Calling function hello()<br># Hello World<br># function &#39;hello&#39; returned None<br># Calling function is_prime(25)<br># function &#39;is_prime&#39; returned False<br># False<br>#########################</pre><h4>2. Timing</h4><p>A timing decorator can be created that outputs the time is taken to complete the function call</p><pre>import functools<br>import time<br><br>def timer(func):<br>    @functools.wraps(func)<br>    def wrapper(*args, **kargs):<br>        start_time = time.perf_counter()<br>        value = func(*args, **kargs)<br>        end_time = time.perf_counter()<br>        run_time = end_time - start_time<br>        print(f&quot;Finished {func.__name__!r} in {run_time:.4f} secs&quot;)<br>        return value<br>    <br>    return wrapper<br><br>@timer<br>def sum_upto(n):<br>    s = 0<br>    for i in range(1,n+1):<br>        s+=i<br>    print(s)<br><br>sum_upto(100000)<br><br>#########################<br># Output: <br># <br># 5000050000<br># Finished &#39;sum_upto&#39; in 0.0029 secs<br>#########################</pre><h4>3. Login verification</h4><pre>import functools<br>from flask import *<br><br>app = Flask(__name__)<br>app.secret_key = &quot;dsajdnsakj&quot;<br><br>def require_login(func):<br>    @functools.wraps(func)<br>    def wrapper(*args, **kargs):<br>        if &quot;logged_in&quot; in session:<br>            return func(*args, **kargs)<br>        return abort(401)<br>    <br>    return wrapper<br><br>@app.route(&#39;/user_info&#39;)<br>@require_login<br>def user_info():<br>    return &quot;User Info&quot;<br><br>@app.route(&#39;/&#39;)<br>def index():<br>    return &quot;Index Page&quot;<br><br>@app.route(&#39;/login&#39;)<br>def login():<br>    session[&quot;logged_in&quot;] = True<br>    return &quot;Logged in&quot;<br><br><br>@app.route(&#39;/logout&#39;)<br>@require_login<br>def logout():<br>    session.pop(&quot;logged_in&quot;)<br>    return &quot;Logged out&quot;<br><br>if __name__== &quot;__main__&quot;:<br>    app.run(host=&quot;0.0.0.0&quot;, debug = True, port = 8000)</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=43e9cea0dfba" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/beautify-your-python-code-with-decorators-43e9cea0dfba">Beautify your Python code with Decorators</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modeling spread of infectious disease — SIR Model]]></title>
            <link>https://medium.com/featurepreneur/modeling-spread-of-infectious-disease-sir-model-82d94f7410a4?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/82d94f7410a4</guid>
            <category><![CDATA[featurepreneur]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[mathematical-modeling]]></category>
            <category><![CDATA[epidemiology]]></category>
            <category><![CDATA[sir-model]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Fri, 07 Apr 2023 06:47:24 GMT</pubDate>
            <atom:updated>2023-04-07T06:47:24.737Z</atom:updated>
            <content:encoded><![CDATA[<h3>Predicting the Spread of Infectious Disease: An SIR Model Approach</h3><h3>What is Mathematical Modeling?</h3><p>Mathematical Modeling is the process of describing a real-world system using mathematical structures, equations, and functions. It is used to describe, analyze and predict various real-world systems like the spread of infectious disease, the interaction of species in an ecosystem, design and optimization in engineering, etc.</p><h3>How is mathematical modeling used in Epidemiology?</h3><p>Mathematical modeling is used in epidemiology to study the spread of infectious diseases through the population. This helps in understanding the transmission of the disease and predicting the extent of the outbreak. It can also be used to evaluate the impact of vaccination programs, social distancing, and the use of masks.</p><h3>What is the SIR Model?</h3><p>The SIR Model is one of the most commonly used models to study the spread of infectious diseases in a population. The model gets its name from the three groups of the population according to this model — Susceptible, Infected, and Recovered. The model tracks the number of people in each group over time.</p><p>Susceptible refers to people who have not been infected yet but can get infected if they come into contact with an infected person. Infected refers to people who are currently infected with the disease and can spread it to susceptible people. Recovered refers to the people who have recovered from the disease and are no longer infectious.</p><h3>What are the equations for the SIR Model?</h3><p>Let N be the total population. Let S(t), I(t), and R(t) represent the number of susceptible, infected, and recovered people at time t respectively. The total population is spread across these three groups.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/533/1*LPxgy09wLc14nlv6rk11tQ.png" /></figure><p>Let <em>Beta </em>and<em> Gamma </em>represent the rate of infection of the susceptible population and the rate of recovery of the infected population respectively.</p><p>The rate of change of the susceptible population, infected population, and recovered population concerning time is as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/1*PgRoqNugoFCckwQO6J2LHA.png" /></figure><p>The rate of change of the susceptible population depends on the interaction between the susceptible population and the infected population and the infection rate. The negative time indicates that the susceptible population decreases over time.</p><p>The rate of change of recovered people depends on the number of infected population and the rate of recovery. The positive sign indicates that the recovered population increases over time.</p><p>The rate of change of the infected population depends on the number of people who get infected and number of people who get recovered.</p><h3>Implementation of the SIR Model in Python</h3><pre>import numpy as np<br>import matplotlib.pyplot as plt<br>from scipy.integrate import odeint<br><br>def dAdt(A,t,beta,gamma,N):<br>    S = A[0]<br>    I = A[1]<br>    R = A[2]<br>    return [<br>        -beta*S*I/N,<br>        beta*S*I/N - gamma*I,<br>        gamma*I<br>    ]<br><br>days = np.arange(0, 100, 1)<br>GAMMA = 0.1<br>N = 1e7<br>BETA = 0.39<br>S0, I0, R0 = N-500, 500, 0<br><br>sol = odeint(dAdt,y0=[S0,I0,R0], t=days,args=(BETA,GAMMA,N))<br><br>S,I,R = sol.T[0],sol.T[1],sol.T[2]<br><br>plt.plot(days,S)<br>plt.plot(days,I)<br>plt.plot(days,R)<br>plt.show()</pre><p>Here, we run the model for 100 days. The total population is taken as 10 million, the initial infected population is 500 and the initial recovered population is null.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*ZN9pZz_YFQyCdzEBu4USDA.jpeg" /></figure><h3>How does the SIR Model help?</h3><ul><li>Predicting the extent of the spread of the disease will help public health officials make informed decisions to slow or stop the spread of the disease.</li><li>It can be used to evaluate the effectiveness of measures like vaccination camps, social distancing, and quarantine policies.</li><li>Help healthcare officials to allocate resources such as beds and medical supplies to respond to the disease appropriately.</li></ul><h3>What are the limitations of the SIR Model?</h3><ul><li>Assumes that all individuals have the same likelihood of getting infected. In reality, different groups of people have different levels of susceptibility to the disease.</li><li>Assumes that the population is closed, that is, no new individuals enter or leave the population.</li><li>Assumes that all infected individuals recover from the disease and become immune to it. It does not take into consideration that people may never recover and also may get re-infected in the future.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=82d94f7410a4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/modeling-spread-of-infectious-disease-sir-model-82d94f7410a4">Modeling spread of infectious disease — SIR Model</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pandas Performance: Optimizing Your Data Analysis Workflow]]></title>
            <link>https://medium.com/featurepreneur/pandas-performance-optimizing-your-data-analysis-workflow-d46847febdf5?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/d46847febdf5</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[pandas]]></category>
            <category><![CDATA[data-analysis]]></category>
            <category><![CDATA[dataset]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Sun, 05 Mar 2023 13:20:09 GMT</pubDate>
            <atom:updated>2023-03-05T13:20:09.100Z</atom:updated>
            <content:encoded><![CDATA[<h3>Pandas Performance: Optimizing Your DataAnalysis Workflow</h3><h3>What are Pandas?</h3><p>Pandas is an open-source library for data manipulation and analysis. Its DataFrame and Series provide an easy and simple way of handling numerical tables and time series data. It has methods for filtering, grouping, and reshaping data, as well as handling missing data, and merging and visualizing the data.</p><h3>Why your Pandas code may need to be faster?</h3><p>Although Pandas is a powerful library for handling data, it can perform slower than expected in various scenarios. These include working with large datasets, complex data transformation, iterative operations, and non-vectorized operations.</p><p>But, most of the time, the slowness of Pandas arises from using unoptimized code and techniques. Here, we will look at such examples and provide the necessary correction that needs to be made to reduce the run-time of your data analysis.</p><h3>Dataset used</h3><p>The CSV files of the datasets used in the examples can be generated by running this python code.</p><pre>import pandas as pd<br>import numpy as np<br>import random<br><br>companies_list = [&quot;Amazon&quot;, &quot;Google&quot;, &quot;Infosys&quot;, &quot;Mastercard&quot;, &quot;Microsoft&quot;, <br>            &quot;Uber&quot;, &quot;IBM&quot;, &quot;Apple&quot;, &quot;Wipro&quot;, &quot;Cognizant&quot;]<br><br>jobs_list = [&quot;Software Development Engineer&quot;, &quot;Machine Learning Engineer&quot;,<br>            &quot;Data Scientist&quot;, &quot;Data Analyst&quot;, <br>            &quot;Artificial Intelligence Engineer&quot;, &quot;Back-end Developer&quot;, <br>            &quot;Front-end Developer&quot;, &quot;Research Scientist&quot;, <br>            &quot;IOS Developer&quot;, &quot;Android Developer&quot;]<br><br>cities_list = [&quot;Alberta&quot;, &quot;British Columbia&quot;, &quot;Manitoba&quot;, &quot;New Brunswick&quot;, &quot;Newfoundland and Labrador&quot;,<br>             &quot;Ontario&quot;, &quot;Quebec&quot;, &quot;Nunavut&quot;, &quot;Prince Edward Island&quot;, &quot;Northwest Territories&quot;]<br><br>data1 = []<br>data2 = []<br>for i in range(4_096_000):<br><br>    emp_id = i+1<br>    company = random.choice(companies_list)<br>    job = random.choice(jobs_list)<br>    city = random.choice(cities_list)<br>    salary = int(round(np.random.rand(), 3)*10**6)<br>    employment = random.choices([&quot;Full Time&quot;, &quot;Intern&quot;])[0]<br>    rating = round((np.random.rand()*5), 1)<br>    <br>    data1.append([emp_id,company, job, city])<br>    data2.append([emp_id, salary, employment, rating])<br>    <br>data = pd.DataFrame(data1, columns=[&quot;Employee Id&quot;, &quot;Company Name&quot;, &quot;Title&quot;,<br>                                   &quot;Location&quot;])<br>data.to_csv(&quot;dataset1.csv&quot;,index=False)<br>data = pd.DataFrame(data2, columns=[&quot;Employee Id&quot;,&quot;Employee Salary&quot;, &quot;Employment Status&quot;, &quot;Employee Rating&quot;])<br>data.to_csv(&quot;dataset2.csv&quot;,index=False)</pre><h3>1. Filtering categorical data</h3><p>We frequently have to filter out data frames and select only a part of it that satisfies a particular condition. Normally filtering is done by indexing the data frame with a boolean mask as follows</p><pre>%%timeit<br>dataset1[dataset1[&quot;Location&quot;] == &quot;Ontario&quot;]<br><br>############################################################<br># 175 ms ± 3.46 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<br>############################################################</pre><p>An optimized way of doing the same is to use the group by<strong><em>()</em></strong> method to group the dataset based on a column and obtain the individual group using the <strong><em>get_group() </em></strong>method</p><pre>data_grp = dataset1.groupby(&quot;Location&quot;)<br><br>%%timeit<br>data_grp.get_group(&quot;Ontario&quot;)<br><br>############################################################<br># 18.5 ms ± 287 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)<br>############################################################</pre><h3>2. Combining DataFrames</h3><p>Two data frames can be combined based on a common column to get a single data frame. This is similar to the join statement in SQL. Two data frames can be merged as follows:</p><pre>%%timeit<br>pd.merge(dataset1,dataset2,on=&quot;Employee Id&quot;, how=&quot;inner&quot;)<br><br>############################################################<br># 970 ms ± 32.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<br>############################################################</pre><p>A faster way to do the same is to use the<strong><em> join() </em></strong>method by setting the index of both the DataFrames as the common column to join on.</p><pre>%%timeit<br>dataset1.set_index(&quot;Employee Id&quot;).join(dataset2.set_index(&quot;Employee Id&quot;))<br><br>############################################################<br># 386 ms ± 6.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<br>############################################################</pre><h3>3. Iterative over a DataFrame</h3><p>The process of visiting every row in a data frame and performing an operation on it is called iterating or looping over a data frame. Iterating over a data frame is a costly operation and is mainly avoided altogether and vectorized operations are instead used.</p><pre>%%timeit<br>lst = []<br>for row in dataset2[&quot;Employee Salary&quot;]:<br>    lst.append(row/12)<br><br>############################################################<br># 412 ms ± 17.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<br>############################################################<br><br>%%timeit<br>lst = dataset2[&quot;Employee Salary&quot;]/12<br><br>############################################################<br># 6.08 ms ± 66.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)<br>############################################################</pre><p>However, there are situations where looping may be necessary for the execution of the operation. Pandas provide two methods to iterate through the DataFrame —<strong><em> arrows ()</em></strong> and <strong><em>itertuples(). </em></strong>Although both methods can be used to do the same operation, iter tuples<strong><em>()</em></strong> are much faster than <strong><em>iterrows()</em></strong></p><pre>%%timeit<br>lst = []<br>for row in dataset2.itertuples():<br>    lst.append(row._2/12)<br><br>############################################################<br># 2.48 s ± 160 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<br>############################################################</pre><h3>4. Mentioning the datatypes</h3><p>When Pandas reads a CSV file and converts it into a DataFrame, it infers the data type of the column and assigns the largest suitable datatype(int64,float64, etc.). In many cases, this large of a datatype is unnecessary. Hence, the datatypes for the rows can be specified when reading the csv itself by passing a datatype dict.</p><pre>dataset2 = pd.read_csv(&quot;dataset2.csv&quot;)<br>dataset2.info()<br><br>&quot;&quot;&quot;<br>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;<br>RangeIndex: 4096000 entries, 0 to 4095999<br>Data columns (total 4 columns):<br> #   Column             Dtype  <br>---  ------             -----  <br> 0   Employee Id        int64  <br> 1   Employee Salary    int64  <br> 2   Employment Status  object <br> 3   Employee Rating    float64<br>dtypes: float64(1), int64(2), object(1)<br>memory usage: 125.0+ MB<br>&quot;&quot;&quot;<br><br>dtypes = {<br>    &quot;Employee Id&quot;:&quot;uint8&quot;,<br>    &quot;Employee Salary&quot;:&quot;uint8&quot;,<br>    &quot;Employment Status&quot;:&quot;object&quot;,<br>    &quot;Employee Rating&quot;:np.float16<br>}<br>dataset2 = pd.read_csv(&quot;dataset2.csv&quot;,dtype=dtypes)<br>dataset2.info()<br><br>&quot;&quot;&quot;<br>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;<br>RangeIndex: 4096000 entries, 0 to 4095999<br>Data columns (total 4 columns):<br> #   Column             Dtype  <br>---  ------             -----  <br> 0   Employee Id        uint8  <br> 1   Employee Salary    uint8  <br> 2   Employment Status  object <br> 3   Employee Rating    float16<br>dtypes: float16(1), object(1), uint8(2)<br>memory usage: 46.9+ MB<br>&quot;&quot;&quot;</pre><p>By mentioning smaller datatypes, we were able to reduce the size of the DataFrame by nearly 3 times.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d46847febdf5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/pandas-performance-optimizing-your-data-analysis-workflow-d46847febdf5">Pandas Performance: Optimizing Your Data Analysis Workflow</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Factory Method Pattern in Python]]></title>
            <link>https://medium.com/featurepreneur/factory-method-pattern-in-python-af773419add2?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/af773419add2</guid>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <category><![CDATA[factory-method-pattern]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Sun, 26 Feb 2023 13:34:50 GMT</pubDate>
            <atom:updated>2023-02-26T13:34:50.794Z</atom:updated>
            <content:encoded><![CDATA[<h3>What are Design Patterns?</h3><p>A Design Pattern is a general solution applicable to commonly occurring problems in software design. In simpler words, it is a template for how to solve a problem, which can be used in several situations. By using design patterns, the code can be made more flexible, reusable and maintainable.</p><h3>What are the types of design patterns?</h3><ul><li>Creational Design Patterns</li><li>Structural Design Patterns</li><li>Behavioral Design Patterns</li></ul><h3>What is Creational Design Pattern?</h3><p>Creational Design Patterns deal with object creation mechanisms. This involves creating the object based on the current situation. They reduce complexities and instability by creating objects in a controlled manner.</p><h3>What is Factory Method Pattern?</h3><p>Factory design pattern provides a common interface to create objects in a superclass, but allows child classes to change the type of object that will be created. Using this, the process of creating an object is separated from the code that depends on the interface of the object.</p><p>The main object of a Factory method is to encapsulate the object creation logic in a seperate component. This component can then be used to create objects without knowing the object’s implementation details.</p><h3>How to implementation of Factory Method?</h3><ol><li>Create an abstract base class for the factory method. This class is used to implement a common interface for creating objects of a specific type, but not the actual implementation.</li><li>Create two or more child classes that implement the factory method. These classes should have the actual implementation for creating the objects.</li><li>The client code will use the factory method to create the object of a specific type without actually knowing the implementation details of how the object is created.</li></ol><h3>Example — File Writer in Python</h3><p>Let’s look at an example implementation of factory method. In this example, a file writer will be implemented which will save data in text, csv or json format.</p><h4>Creating the abstract base class</h4><pre>from abc import ABC, abstractmethod<br><br>class FileWriter(ABC):<br>    def get_writer_type(self):<br>        return self.writer_type<br>    <br>    @abstractmethod<br>    def save(self, filepath, data):<br>        pass</pre><p>The abc library provides the necessary tools to create an abstract base class. Here, we define an abstract base class FileWriter with two methods — the factory method save() and writer_type().</p><p>The factory method save() will be defined by the child classes with the actual implementation to create the files. The method writer_type() will be used to return the type of writer that was created.</p><h4>Creating the subclasses</h4><pre>import json<br><br>class TextFileWriter(FileWriter):<br>    def __init__(self):<br>        self.writer_type = &quot;txt&quot;<br>    <br>    def save(self, filepath, data):<br>        with open(filepath,&quot;w&quot;) as f:<br>            f.write(data)<br><br>class CsvFileWriter(FileWriter):<br>    def __init__(self):<br>        self.writer_type = &quot;csv&quot;<br>    <br>    def save(self, filepath, data):<br>        with open(filepath,&quot;w&quot;) as f:<br>            for row in data:<br>                f.write(&quot;,&quot;.join(row)+&quot;\n&quot;)<br><br>class JSONFileWriter(FileWriter):<br>    def __init__(self):<br>        self.writer_type = &quot;json&quot;<br>    <br>    def save(self, filepath, data):<br>        with open(filepath,&quot;w&quot;) as f:<br>            json.dump(data, f)</pre><p>Here three child classes are created which inherit from the abstract base class FileWriter — TextFileWriter, CsvFileWriter and JsonFileWriter. These child classes provide the actual implementation of the factory method to create the necessary files. The writer_type is also defined in the __init__() method with the respective format.</p><h4>Creating the Factory Class</h4><pre>class WriterFactory:<br>    <br>    def get_writer(self,format):<br>        if format == &quot;txt&quot;:<br>            return TextFileWriter()<br>        elif format == &quot;csv&quot;:<br>            return CsvFileWriter()<br>        elif format == &quot;json&quot;:<br>            return JSONFileWriter()<br>        else:<br>            raise TypeError(&quot;Specify a valid file format&quot;)</pre><p>The WriterFactory will take care of creating the necessary FileWriter from the argument of the file format. The get_writer() method will create and return the respective file writer objects. This will be used by the client code to create the file writer objects.</p><h4>The whole code</h4><pre>from abc import ABC, abstractmethod<br>import json<br><br>class FileWriter(ABC):<br>    def get_writer_type(self):<br>        return self.writer_type<br>    <br>    @abstractmethod<br>    def save(self, filepath, data):<br>        pass<br>    <br>class TextFileWriter(FileWriter):<br>    def __init__(self):<br>        self.writer_type = &quot;txt&quot;<br>    <br>    def save(self, filepath, data):<br>        with open(filepath,&quot;w&quot;) as f:<br>            f.write(data)<br><br>class CsvFileWriter(FileWriter):<br>    def __init__(self):<br>        self.writer_type = &quot;csv&quot;<br>    <br>    def save(self, filepath, data):<br>        with open(filepath,&quot;w&quot;) as f:<br>            for row in data:<br>                f.write(&quot;,&quot;.join(row)+&quot;\n&quot;)<br><br>class JSONFileWriter(FileWriter):<br>    def __init__(self):<br>        self.writer_type = &quot;json&quot;<br>    <br>    def save(self, filepath, data):<br>        with open(filepath,&quot;w&quot;) as f:<br>            json.dump(data, f)<br><br>class WriterFactory:<br>    <br>    def get_writer(self,format):<br>        if format == &quot;txt&quot;:<br>            return TextFileWriter()<br>        elif format == &quot;csv&quot;:<br>            return CsvFileWriter()<br>        elif format == &quot;json&quot;:<br>            return JSONFileWriter()<br>        else:<br>            raise TypeError(&quot;Specify a valid file format&quot;)</pre><h4>The client code</h4><pre>from FileWriterFactory import WriterFactory<br><br>writer_factory = WriterFactory()<br><br>text_writer = writer_factory.get_writer(&quot;txt&quot;)<br>print(text_writer.get_writer_type())<br>text_writer.save(&quot;data.txt&quot;,&quot;hello world!&quot;)</pre><p>The client code will import the class WriterFactory. After creating an object for the WriterFactory, the get_writer() method can be used to create the respective file writer based on the argument of the file type. The save() method can then be used to save the file with the argument of the file path and the data to be saved.</p><h3>What are the advantages of Factory Method?</h3><ul><li>Hides the actual implementation of the objects</li><li>Provides a common interface for the creation for objects with different implementations</li><li>Ensures reusability and uniformity while minimising potential code errors</li></ul><h3>What are the disadvantages of Factory Method?</h3><ul><li>Difficult to read as all the code is behind an abstraction that in turn may have more abstractions</li><li>Produces too many parallel hierarchy of classes when more number of object has to be implemented</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af773419add2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/factory-method-pattern-in-python-af773419add2">Factory Method Pattern in Python</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Speeding up image processing using multiprocessing in Python]]></title>
            <link>https://medium.com/featurepreneur/speeding-up-image-processing-using-multiprocessing-in-python-ceeced8026bf?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/ceeced8026bf</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[multiprocessing]]></category>
            <category><![CDATA[threading]]></category>
            <category><![CDATA[image-processing]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Fri, 03 Feb 2023 14:33:05 GMT</pubDate>
            <atom:updated>2023-02-03T14:33:05.809Z</atom:updated>
            <content:encoded><![CDATA[<p>When building a machine learning model, the key factor that decides how well the model will perform is the data. So it is a necessary step to always preprocess the data before using it to train the model. In the case of images, their size, orientation, color, etc., have to be adjusted into the desired format to get better results.</p><p>However, image preprocessing is a computationally expensive task. But it can be sped up with various techniques. One of the techniques is to process the images concurrently than processing them one by one. Let us look at how to process the images concurrently using multi-threading and multiprocessing using python.</p><h3>Why do we have to go for multi-threading or multiprocessing?</h3><p>Let’s say you have a function process_image that takes the image as input and returns the processed image as output. You are looping through all the images in your dataset and calling the process_image function with the image.</p><pre>processed_images = [ process_images(image) for image in dataset]</pre><p>This will process the images one by one, i.e, the next image will be processed only after the previous image has been processed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/778/1*pyjBdW_PFLE5L4PBIVtPdA.jpeg" /><figcaption>Normal flow</figcaption></figure><p>However, this can be sped up by processing the images concurrently with several images being processed simultaneously.</p><h3>What is multithreading?</h3><p>Multi-threading is the ability of the processor to break a single process into multiple threads and run them concurrently. In our example, processing all the images in the dataset is the process and it is broken into several threads where each thread processes one image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*hPjv6X7MS8pLfhqWql-MbA.jpeg" /><figcaption>Multi-threading</figcaption></figure><h3>How to implement multi-threading in python?</h3><p>Threading can be implemented by using the built-in threading module which contains the methods for creating and working with threads. However, an easier way to start a group of threads is by using the ThreadPoolExecutor which is part of the built-in concurrent. futures library.</p><pre>from concurrent.futures import ThreadPoolExecutor<br><br># import the dataset<br># define the process_images() function<br><br>with ThreadPoolExecutor() as executor:<br>    futures = []<br>    for image in dataset:<br>        futures.append(executor.submit(process_images, image))<br><br>processed_images = [] # To store the processed images<br>for future in futures:<br>    processed_images.append(future.result())</pre><h3>What is Python Global Interpreter Lock?</h3><p>Python Global Interpreter Lock or GIL is a lock that allows only one thread to hold control of the python interpreter. That means that only one thread can be in the state of execution at a time.</p><p>The GIL was introduced due to a thread-safety issue in some Python versions. The widely used version of Python(downloadable from <a href="https://www.python.org/">python.org</a>) is the C implementation. C doesn’t include built-in thread-safety mechanisms which mean that multiple threads access the same data concurrently which leads to race conditions and synchronization issues.</p><p>Therefore, even if multi-threading was implemented, GIL limits the ability of Python to fully exploit multiple processors.</p><h3>What is multi-processing?</h3><p>Multi-processing refers to the execution of a single process by multiple processors by breaking it down into multiple sub-processes, each with its own memory space to run independently of the other.</p><p>Since multi-processing doesn’t share memory and data like multi-threading, it is free from GIL and can significantly boost performance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*U4eeqso2y0hUEMMEOqhsAg.jpeg" /><figcaption>Multi-processing</figcaption></figure><h3>How to implement multi-processing in python?</h3><p>Multi-processing can be implemented by using the built-in multiprocessing module which contains the methods for creating and working with processes. However, an easier way to start a group of processes is by using the ProcessPoolExecutor which is part of the built-in concurrent. futures library.</p><pre>from concurrent.futures import ProcessPoolExecutor<br><br># import the dataset<br># define the process_images() function<br><br>with ProcessPoolExecutor() as executor:<br>    futures = []<br>    for image in dataset:<br>        futures.append(executor.submit(process_images, image))<br><br>processed_images = [] # To store the processed images<br>for future in futures:<br>    processed_images.append(future.result())</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ceeced8026bf" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/speeding-up-image-processing-using-multiprocessing-in-python-ceeced8026bf">Speeding up image processing using multiprocessing in Python</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenCV — Basic image processing in Python]]></title>
            <link>https://medium.com/featurepreneur/opencv-basic-image-processing-in-python-817c3f980663?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/817c3f980663</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[image-processing]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[opencv]]></category>
            <category><![CDATA[featurepreneur]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Tue, 17 Jan 2023 14:30:47 GMT</pubDate>
            <atom:updated>2023-01-17T14:30:47.996Z</atom:updated>
            <content:encoded><![CDATA[<h3>OpenCV — Basic image processing in Python</h3><h3>What is OpenCV?</h3><p>Open Source Computer Vision(<strong><em>OpenCV</em></strong>) is one of the widely used library for computer vision and image processing tasks. It includes various algorithms for image and video analysis, such as object detection, motion analysis, image processing, feature detection, etc.</p><h3>How to install OpenCV library?</h3><p>OpenCV can be easily install from the pip package manager as follows:</p><pre>pip install opencv-python</pre><p>The installation can be verified by running the following in python</p><pre>import cv2<br><br>print(cv2.__version__)</pre><h3>How to read an image?</h3><p>An image can be represented as a multidimensional array of pixel information, where each element is a numeric value representing the color of the pixel.</p><pre>img = cv2.imread(&quot;cat.jpg&quot;)<br>print(img)</pre><p>The output of the above code is an array of numeric values. If you print the variable type of img, it will be a <strong>numpy.ndarray.</strong> Hence the image can be manipulated by numpy methods too.</p><h3>How to display an image?</h3><p>An image which has been read by OpenCV can be displayed using matplotlib library.</p><pre>import matplotlib.pyplot as plt<br>fig = plt.imshow(img)<br>fig.axes.get_xaxis().set_visible(False)<br>fig.axes.get_yaxis().set_visible(False)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*BOofA1-w7XqRVuz3f3KgIA.png" /></figure><p>This will display the image but the color of the image will be off. This is because OpenCV reads the image in the BGR format. To convert it into RGB format:</p><pre>img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)<br>fig = plt.imshow(img)<br>fig.axes.get_xaxis().set_visible(False)<br>fig.axes.get_yaxis().set_visible(False)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*_rF_KGT9L6vkZj-ymgEnbw.png" /></figure><h3>How to get the dimensions of the image?</h3><p>The height, width and color channels of an image can be obtained by</p><pre>height, width, channels = img.shape<br>print((height, width, channels)) # (2500, 2392, 3)</pre><h3>How to resize an image?</h3><p>An image can be resized by using the resize function of OpenCV by providing the new dimensions</p><pre>resized_img = cv2.resize(img,(500,500),interpolation=cv2.INTER_AREA)<br>print(resized_img.shape) # (500, 500, 3)</pre><p>Images can also be resized by providing a scaling factor instead of the new dimensions.</p><pre>resized_img = cv2.resize(img, dsize = None,fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)<br>print(resized_img.shape) # (1250, 1196, 3)</pre><p>Here, the fx and fy represent the scaling factor by with the image will be resized in the width and height respectively. Therefore, in this example, the image is resized to half it’s original size.</p><h3>How to crop an image?</h3><p>Since an image is represented as a numpy array, the image can be easily cropped by using array slicing.</p><pre>x, y = 600, 100<br>h, w = 1500, 1300<br>cropped_img = img[y:y+h, x:x+w]<br>fig = plt.imshow(cropped_img)<br>fig.axes.get_xaxis().set_visible(False)<br>fig.axes.get_yaxis().set_visible(False)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/345/1*VPeK8wqjCArkLy0LE7BvhA.png" /></figure><p>Here, (x, y) represent the coordinate of the top-left pixel of the cropped image and h and w are the height and width of the cropped image respectively.</p><h3>How to convert a color image to grayscale?</h3><p>A color image has 3 color channels but a grayscale image has only 1 color channel.</p><pre>img = cv2.imread(&quot;cat.jpg&quot;)<br>print(&quot;color image dimensions: &quot;,img.shape)  # (2500, 2392, 3)<br>gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)<br>print(&quot;grayscale image dimensions: &quot;,gray_img.shape) # (2500, 2392)</pre><p>In order to display the grayscale image using imshow(), the cmap parameter has to be set to “gray”.</p><pre>fig = plt.imshow(gray_img, cmap=&quot;gray&quot;)<br>fig.axes.get_xaxis().set_visible(False)<br>fig.axes.get_yaxis().set_visible(False)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*83YJGEQPKNGaagt3mjxE2Q.png" /></figure><h3>How to save an image?</h3><p>Images can be save by using the imwrite() function.</p><pre>cv2.imwrite(&quot;gray_cat.jpg&quot;,gray_img)</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=817c3f980663" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/opencv-basic-image-processing-in-python-817c3f980663">OpenCV — Basic image processing in Python</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Activation functions in Neural Networks]]></title>
            <link>https://medium.com/featurepreneur/activation-functions-in-neural-networks-570dcc019559?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/570dcc019559</guid>
            <category><![CDATA[featurepreneur]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[activation-functions]]></category>
            <category><![CDATA[neural-networks]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Tue, 03 Jan 2023 13:50:24 GMT</pubDate>
            <atom:updated>2023-01-03T13:50:24.093Z</atom:updated>
            <content:encoded><![CDATA[<h3>What is an Activation Function?</h3><p>An activation function decides whether a neuron’s input is important to the neural network or not in the output prediction. It’s main function is to transform the summed input of the node into an output value that will be fed to the next layer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wObkEg0VqVYLHVi2ciG27g.png" /><figcaption>Activation function</figcaption></figure><h3>Why is an Activation Function needed?</h3><p>Activation function adds non-linearity to the neural network. Without activation function, a neuron performs only linear transformation on the inputs using the weights and bias. Thus our model will be just a linear regression model and will not be able to solve complex problems</p><h3>What are the different activation functions?</h3><h4>Linear activation function</h4><p>Linear activation function, also called the <em>identity function</em> or <em>no activation, </em>multiplies the weighted sum of inputs by 1. Thus it doesn’t transform the input and the output is same as the input.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/370/1*TGA2J3od6uWUXH8V5IuT9A.png" /><figcaption>Linear activation function</figcaption></figure><p><strong>Limitations</strong><br>1. Not possible to use backpropagation as derivative of the function is constant.<br>2. All layers of the neural network will collapse into one. Even if there are 100 layers, the last layer will be a linear function of the first layer, essentially turning the network into just 1 layer.</p><h4>Binary step function</h4><p>Binary step function decides whether the output is 0 or 1 based on a threshold value. If the weighted sum is greater than threshold, it outputs 1 else 0.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*UFV3JVnAeKsJYDgw-sGf0Q.png" /><figcaption>Binary step function</figcaption></figure><p><strong>Limitations<br></strong>1. Cannot be used for multi-class classification problems<br>2. Hinders backpropagation process as the gradient is zero</p><h4>Logistic Activation function</h4><p>Logistic Activation function transforms the input into a value between 0 and 1. The larger the input(more positive), the closer the output will be to 1 and the smaller the input(more negative), the closer the output will be to 0.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*sJTTVvNiX0_3aSuKQXZAtg.png" /><figcaption>Logistic Activation function</figcaption></figure><p><strong>Advantages</strong><br>1. Commonly used in models where probability is the output.<br>2. Prevents jumps in output values since the function has a smooth gradient.</p><p><strong>Limitations</strong><br>1. Suffers from <em>Vanishing Gradient Problem</em> where the network is unable to backpropagate useful information</p><h4>Tanh Function</h4><p>Tanh function or hyperbolic tangent function is similar to logistic function with the only main difference being that the output of tanh function is between -1 and 1. The larger the input(more positive), the closer the output will be to 1 and the smaller the input(more negative), the closer the output will be to -1.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/1*rNj6Ou_QhycVVKgwP5y2Ww.png" /><figcaption>Tanh activation function</figcaption></figure><p><strong>Advantages</strong><br>1. Output can be mapped as strongly negative, neutral and strongly positive<br>2. Has gradient 4 times greater than that of logistic function — thus giving rise to bigger learning steps when training.<br>3. Symmetric around 0, leading to faster convergence.</p><p><strong>Limitations</strong><br>1. Suffers from <em>Vanishing Gradient Problem</em> where the network is unable to backpropagate useful information</p><h4>Rectified Linear Unit(ReLU)</h4><p>Rectified Linear Unit transforms the input into 0 if it is negative or returns the input itself if it is positive. Although it seems like a linear function, ReLU has a derivative function and allows complex relationships in the data to be learned.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/585/1*U-P7kHSb1jhseQ94vt3SlA.png" /><figcaption>Rectified Linear Unit</figcaption></figure><p><strong>Advantages</strong><br>1. Doesn’t activate neurons with negative inputs, thus being computationally efficient.<br>2. Tends to show better convergence<br>3. Faster to compute than some other activation functions like logistic function</p><p><strong>Limitations</strong><br>1. Tends to blow up activation since there is no constraint to the output if the input is positive.<br>2. <em>Dying ReLU problem</em> — if too many activation get below zero, most of the neurons in a layer will output zero, creating dead neurons whose weights and biases are not updated.</p><h4>Leaky ReLU function</h4><p>Leaky ReLU is an improved version of ReLU function to solve the <em>Dying ReLU problem</em>. Instead of transforming negative values into 0 like ReLU, Leaky ReLU transforms it by multiplying with a small, non-zero constant parameter <strong><em>a(Normally 0.01)</em></strong><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/594/1*uB7DvSts0PnIwuE-cvnDhQ.png" /><figcaption>Leaky ReLU activation function</figcaption></figure><p><strong>Advantages</strong><br>1. Prevention of <em>Dying ReLU</em> problem by allowing a small gradient for negative inputs<br>2. Faster to compute than some other activation functions like logistic function</p><p><strong>Limitations</strong><br>1. Sensitive to the parameter <strong><em>a</em></strong> — A value that is too small may result in slow convergence, while a value that is too large may result in unstable behaviour<br>2. Prediction for negative input values may not be consistent</p><h4>How to choose the right activation function?</h4><p>Choosing the right activation function is an important decision in the design of a neural network, as it can significantly impact the network’s performance. Some general guidelines for choosing an activation function are</p><ol><li>The characteristics of the data and the requirements of the task: The logistic function may be more suitable for tasks that involve binary classification, while the ReLU function may be more suitable for tasks that involve large, positive input values.</li><li>The computational complexity: Activation functions with higher computational complexity may require more time and resources to compute, which can impact the overall performance of the network.</li><li>The type of layer: ReLU activation function is mostly used in the hidden layers whereas Logistic and Tanh functions are mostly used in output layers.</li><li>Trail and error: It is often a good idea to try out different activation functions and compare their performance on the specific task at hand. This can help to identify the best activation function for the task.</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=570dcc019559" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/activation-functions-in-neural-networks-570dcc019559">Activation functions in Neural Networks</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Metrics to evaluating classification models]]></title>
            <link>https://medium.com/featurepreneur/metrics-to-evaluating-classification-models-a2cf731809a2?source=rss-ca2d8a94ed95------2</link>
            <guid isPermaLink="false">https://medium.com/p/a2cf731809a2</guid>
            <category><![CDATA[metrics]]></category>
            <category><![CDATA[classification]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Santhosh Kannan]]></dc:creator>
            <pubDate>Sat, 03 Dec 2022 12:08:09 GMT</pubDate>
            <atom:updated>2022-12-03T12:08:09.190Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*HbaGeUpyjtNLWwoN" /><figcaption>Photo by <a href="https://unsplash.com/@javaistan?utm_source=medium&amp;utm_medium=referral">Afif Ramdhasuma</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Classification is a type of supervised machine learning technique used to predict the class data points belong to.</p><p>One of the most important step in any machine learning workflow is evaluation of the trained model. At this step, the trained model is used to make prediction of unseen(not used in training) labelled data. The model is judged based on how many prediction it got right.</p><p>But how many predictions a model got right will not always be a good metric to judge the model’s performance. We have to taken into account how many predictions were wrong and how they were wrong — whether a positive class was predicted as negative or vice-versa.</p><p>For example, if we are predicting if a tumour is cancerous or not, we would be okay if the model incorrectly predicted a tumour as cancerous than it missing to diagnose a cancerous one. On the other hand, if we are predicting if a email is spam or not, a model would be considered as good if it missed to identify a spam mail than to identify an important mail as spam.</p><p>So, we need to use different metrics in order to evaluate the model based on the problem at hand and optimise the trade-off between different outcomes.</p><p>Let’s look at various classification metrics and how they can be used to evaluate the model on different cases.</p><h3><strong>Accuracy</strong></h3><p>The accuracy of a model is simply the number of correct predictions divided by the total number of predictions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/394/1*-IFbYkpnINUi1iyew_6elg.png" /><figcaption>Accuracy. Image by author</figcaption></figure><p>Accuracy will be a value between 0 and 1 and a value of 1 indicates that all the predictions made by the model are correct.</p><p>Accuracy can often be misleading, as on imbalanced datasets, where the one class has large amount of entries compared to the other. For example, if our tumour dataset contains only 1% of cancerous data, then a model can predict all the data as benign and get a score of 99% accuracy. This model is useless and highly dangerous.</p><h3>Confusion Matrix</h3><p>Confusion matrix is a tabular summary of the number of correct and incorrect predictions made by a model. Confusion matrix is widely used due to the fact that they give a better understanding of the model’s performance than accuracy does.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/669/1*w5pj3B60qbtVzNYCqYq6kQ.png" /><figcaption>Confusion matrix. Image by author</figcaption></figure><ul><li><strong>True Positive: </strong>Predicted value is true and the actual value is also true</li><li><strong>False Positive:</strong> Predicted value is true but the actual value is false</li><li><strong>False Negative:</strong> Predicted value is false but the actual value is true</li><li><strong>True Negative:</strong> Predicted value is false and actual value is also false</li></ul><p>Confusion Matrix is extremely useful as it can be used to calculate other classification metrics like precision, recall, F1-score, etc.</p><h3>Precision</h3><p>Precision is used to evaluate how good a model is at identifying the positive class. In simpler terms, out of all predictions for the positive class, how many were actually right?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/364/1*RlZGFIBMEoBm1c6yaQNYTw.png" /><figcaption>Precision. Image by author</figcaption></figure><p>Precision can be used to optimise the model to reduce the number of false positives. Thus, this metric can be used in the case of email spam detection example.</p><h3>Recall</h3><p>Recall or Sensitivity measures how good a model is at correctly predicting all positive observations in the dataset. In simpler terms, out of all the actual positive class, how many were correctly identified as positive?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/332/1*A13rjNm1kIljmUjy-jWzRg.png" /><figcaption>Recall. Image by author</figcaption></figure><p>Recall can be used to optimise the model to reduce the number of false negatives. Thus, this metric can be used in the case of cancerous tumour prediction example.</p><p>Usually, precision and recall are used together by plotting a precision-recall graph to visualise the trade-off between them.</p><h3>F1-Score</h3><p>F1-Score combines the information provided by precision and recall into a single value. It is the harmonic mean between precision and recall.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/251/1*wmeXBcXKDsiUi32AezYK5A.png" /><figcaption>F1-Score. Image by author</figcaption></figure><p>F1-Score is a value between 0 and 1. High F1-Score indicates high precision and recall.</p><p>F1-score is used when there is an imbalanced dataset. It is also used to compare performance of different machine learning algorithms.</p><h3>Cohen’s Kappa statistics</h3><p>Kappa statistics compares the predictions made by the model to random guessing based on frequency of each class.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/399/1*bcxQOD3B-sYaGBxV6zQvDQ.png" /><figcaption>Cohen’s Kappa Statistics. Image by author</figcaption></figure><p>Kappa’s value is always less than 1 and can also be negative. Although there is no standardised way to interpret its value, Landis and Koch provided a way to characterise the value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/322/1*VlA0EDGW-DSA9T-DMjutTw.png" /><figcaption>Landis and Koch kappa interpretation. Image by author</figcaption></figure><p>Kappa value is used when there is an imbalanced dataset and in multi-class classification problems.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a2cf731809a2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/featurepreneur/metrics-to-evaluating-classification-models-a2cf731809a2">Metrics to evaluating classification models</a> was originally published in <a href="https://medium.com/featurepreneur">featurepreneur</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>