<?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 Emine Bozkus, PhD on Medium]]></title>
        <description><![CDATA[Stories by Emine Bozkus, PhD on Medium]]></description>
        <link>https://medium.com/@eminebozkus?source=rss-151d1cbb89fd------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*oOmOiy5doKYHZ9ZsPwh3Ug.jpeg</url>
            <title>Stories by Emine Bozkus, PhD on Medium</title>
            <link>https://medium.com/@eminebozkus?source=rss-151d1cbb89fd------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 15:00:39 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@eminebozkus/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[AI’s Silent Revolution: How Data Scientists Are Evolving (and Thriving)]]></title>
            <link>https://medium.datadriveninvestor.com/ais-silent-revolution-how-data-scientists-are-evolving-and-thriving-7aaeeab2b09f?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/7aaeeab2b09f</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[data]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Wed, 14 May 2025 13:16:28 GMT</pubDate>
            <atom:updated>2025-05-15T04:26:08.073Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>The world of data science is undergoing a profound, yet often unremarked, “silent transformation” driven by Artificial Intelligence (AI). This isn’t about AI replacing data scientists; it’s about AI reshaping their roles, tools, and the very value they bring to the table. Far from a distant future, this AI-driven evolution is happening now, subtly integrating into daily workflows and fundamentally altering how data work gets done.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/1*VOGdgYG529zb_bz7Ixi-Ow.png" /><figcaption>Fig 1. The Evolving Role of Data Scientists in the AI Era (created by the author using Napkin.ai)</figcaption></figure><h3>1. AI Automation: Data Science Tasks, Streamlined</h3><p>AI is now a powerhouse for automating the once labor-intensive aspects of data science.</p><ul><li><strong>Smarter Data Prep:</strong> AI tools, including AutoML platforms like Google AutoML and generative AI, are automating significant chunks of data cleaning, preprocessing, and even feature engineering. Generative AI can create synthetic data to bolster limited datasets, improving model accuracy and reducing bias.</li><li><strong>Effortless Model Building:</strong> AI excels at automated model selection and hyperparameter tuning, sifting through countless options faster than any human.</li><li><strong>AI-Assisted Coding:</strong> Tools like OpenAI’s Codex and GitHub Copilot generate code snippets, speeding up development and allowing data scientists to focus on higher-level problem-solving.</li><li><strong>Automated Insights:</strong> AI analytics can now perform root cause analysis and generate reports with natural language narratives, making complex data understandable to a wider audience. This automation frees up data scientists from 30–50% of routine tasks, allowing them to tackle more strategic challenges.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*iiywnz2PILuI91U1g7p8dg.png" /><figcaption>Fig 2. AI automation benefits (created by the author using Napkin.ai)</figcaption></figure><h3>2. Beyond Algorithms: The New Premium on Human Skills</h3><p>As AI handles the mechanics, the data scientist’s role elevates. The new focus is on:</p><ul><li><strong>Strategic Problem Formulation:</strong> Identifying <em>which</em> business problems to solve with AI and <em>why</em> becomes paramount.</li><li><strong>Critical Thinking &amp; Interpretation:</strong> Evaluating AI outputs, understanding their limitations, and providing nuanced contextual interpretation is key.</li><li><strong>Compelling Data Storytelling:</strong> Translating complex AI-driven insights into clear, actionable narratives for non-technical stakeholders is crucial.</li><li><strong>Collaboration &amp; Domain Expertise:</strong> Working across teams and leveraging deep industry knowledge ensures AI solutions are relevant and impactful. These “soft skills” are becoming the hard differentiators in the AI era.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/885/1*fZ3JoTwAnXHXaArykd8jpg.png" /><figcaption>Fig 3. Essential Skills for AI-Era Data Scientists</figcaption></figure><h3>3. The AI-Augmented Toolkit: Essential New Competencies</h3><p>While foundational skills (Python, SQL, R, statistics) remain vital , new technical skills are essential for the AI-augmented data scientist:</p><ul><li><strong>Prompt Engineering:</strong> Skillfully guiding LLMs and generative AI tools to produce desired outputs is a new cornerstone.</li><li><strong>MLOps Understanding:</strong> Familiarity with deploying, monitoring, and managing models in production is non-negotiable.</li><li><strong>AI Model Interpretability (XAI):</strong> Using tools like LIME and SHAP to understand and explain “black box” AI decisions is critical for trust, fairness, and debugging.</li><li><strong>Advanced AI/ML Techniques:</strong> Expertise in deep learning, NLP, and frameworks like PyTorch and TensorFlow is increasingly demanded.</li><li><strong>Cloud Computing:</strong> Proficiency with AWS, Azure, or GCP is standard for handling the scale of modern AI.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/840/1*BmGnXrTmI6CpRptC89rkCw.png" /><figcaption>Fig 4. Essential New Competencies</figcaption></figure><h3>4. The Evolving Mandate: Driving Value, Guarding Ethics</h3><p>The data scientist’s mission is expanding:</p><ul><li><strong>Delivering Measurable Business Value:</strong> The focus is shifting from technical outputs to driving tangible business growth and innovation through AI. Companies with clear AI strategies, often shaped by data scientists, see significantly better ROI.</li><li><strong>Championing Ethical AI:</strong> Proactively addressing fairness, transparency, bias, and accountability in AI systems is now a core responsibility. This includes being aware of AI’s potential to perpetuate societal biases or generate misleading information.</li><li><strong>Shaping Data &amp; AI Governance:</strong> Data scientists are increasingly involved in defining data quality standards, AI-readiness, and ethical AI frameworks.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/756/1*5ADEqCqfSz7fkigSI3RqaQ.png" /><figcaption>Fig 5. Evolving Data Science Responsibilities</figcaption></figure><h3>5. The Data Scientist of Tomorrow: Intelligent Collaboration</h3><p>The future is about human-AI collaboration, not competition. This synergy is creating new and evolving roles:</p><ul><li><strong>Lead/Principal Data Scientist:</strong> Focusing on AI strategy, team leadership, and ethical oversight.</li><li><strong>AI Ethicist:</strong> Specializing in guiding responsible AI development and deployment.</li><li><strong>MLOps Engineer:</strong> Ensuring the smooth operationalization of machine learning models.</li><li><strong>AI Solutions Architect:</strong> Designing end-to-end AI systems for specific business needs. Continuous learning and adaptability are crucial, as some analyses suggest up to 40% of roles may need redefinition due to AI.</li></ul><h3>Conclusion: Embrace the AI Metamorphosis</h3><p>The silent transformation of the data scientist is an evolution, not an extinction. AI amplifies human capabilities, allowing data scientists to focus on more strategic, impactful, and ethically complex work. To thrive, data scientists must:</p><ul><li><strong>Commit to Lifelong Learning:</strong> Stay ahead of rapid AI advancements.</li><li><strong>Cultivate Human-Centric Skills:</strong> Double down on strategy, critical thinking, communication, and ethics</li><li><strong>Become Strategic Influencers:</strong> Guide AI adoption responsibly and drive real business value.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/594/1*HZUJWW3kYdffWx4PDG0vWQ.png" /><figcaption>Fig 6. Balancing Technical and Human Skills in AI</figcaption></figure><p>The AI era calls for data scientists who are not just technically proficient but are also insightful strategists, compelling communicators, and ethical guardians. By embracing this metamorphosis, data scientists will continue to be indispensable in shaping an AI-powered future.</p><p><em>Thanks for reading this article. You can access the detailed codes of the project and other projects on </em><a href="https://github.com/bozkusemine"><em>my Github account</em></a><em> or </em><a href="https://www.kaggle.com/emineyetm"><em>Kaggle account</em></a><em>. Happy coding!</em></p><p><em>Please feel free to </em><a href="https://www.linkedin.com/in/eminebozkus/"><em>contact me</em></a><em> if you need any further information.</em></p><p>Visit us at <a href="https://www.datadriveninvestor.com/"><em>DataDrivenInvestor.com</em></a></p><p>Subscribe to DDIntel <a href="https://www.ddintel.com/"><em>here</em></a>.</p><p>Join our creator ecosystem <a href="https://join.datadriveninvestor.com/"><em>here</em></a>.</p><p>DDI Official Telegram Channel: <a href="https://t.me/+tafUp6ecEys4YjQ1">https://t.me/+tafUp6ecEys4YjQ1</a></p><p>Follow us on <a href="https://www.linkedin.com/company/data-driven-investor"><em>LinkedIn</em></a>, <a href="https://twitter.com/@DDInvestorHQ"><em>Twitter</em></a>, <a href="https://www.youtube.com/c/datadriveninvestor"><em>YouTube</em></a>, and <a href="https://www.facebook.com/datadriveninvestor"><em>Facebook</em></a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7aaeeab2b09f" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/ais-silent-revolution-how-data-scientists-are-evolving-and-thriving-7aaeeab2b09f">AI’s Silent Revolution: How Data Scientists Are Evolving (and Thriving)</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Comprehensive Analysis of Pima Indians Diabetes]]></title>
            <link>https://medium.datadriveninvestor.com/a-comprehensive-analysis-of-pima-indians-diabetes-f5cf9f73785f?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/f5cf9f73785f</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[diabetes]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[kaggle]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Sun, 12 Feb 2023 12:29:17 GMT</pubDate>
            <atom:updated>2023-02-13T03:17:46.348Z</atom:updated>
            <content:encoded><![CDATA[<p>Diabetes is a major health concern worldwide, and its incidence is increasing rapidly. In this article, we present a comprehensive analysis of the Pima Indians Diabetes dataset, which contains medical information about Pima Indians, including the presence or absence of diabetes. We aim to explore the relationships between different variables and the incidence of diabetes and build predictive models to classify patients as diabetic or non-diabetic.</p><p>Let’s implement it in python.</p><h3>About Dataset</h3><p><strong>Context</strong></p><p>This dataset is originally from the National Institute of Diabetes and Digestive and Kidney Diseases. The objective of the dataset is to diagnostically predict whether or not a patient has diabetes, based on certain diagnostic measurements included in the dataset. Several constraints were placed on the selection of these instances from a larger database. In particular, all patients here are females at least 21 years old of Pima Indian heritage.</p><p><strong>Content</strong></p><p>The datasets consists of several medical predictor variables and one target variable, Outcome. Predictor variables includes the number of pregnancies the patient has had, their BMI, insulin level, age, and so on.</p><p><strong><em>Can you build a machine learning model to accurately predict whether or not the patients in the dataset have diabetes or not?</em></strong></p><h3>1. Importing the libraries</h3><pre>import joblib<br>import pandas as pd<br>import seaborn as sns<br>from matplotlib import pyplot as plt<br>from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier, VotingClassifier, AdaBoostClassifier<br>from sklearn.linear_model import LogisticRegression<br>from sklearn.model_selection import cross_validate, GridSearchCV<br>from sklearn.neighbors import KNeighborsClassifier<br>from sklearn.svm import SVC<br>from sklearn.tree import DecisionTreeClassifier<br>from sklearn.preprocessing import StandardScaler<br><br>from xgboost import XGBClassifier<br>from lightgbm import LGBMClassifier<br>from catboost import CatBoostClassifier<br>pd.set_option(&#39;display.max_columns&#39;, None)<br>pd.set_option(&#39;display.width&#39;, 500)<br>import warnings<br>warnings.filterwarnings(&#39;ignore&#39;)</pre><h3>2. Importing the dataset</h3><pre>df = pd.read_csv(&#39;/kaggle/input/pima-indians-diabetes-database/diabetes.csv&#39;)</pre><pre># Checking the dataset<br>df.head()</pre><pre>Pregnancies Glucose BloodPressure SkinThickness Insulin BMI DiabetesPedigreeFunction Age Outcome<br>0               6       148         72 35 0 33.6 0.627 50 1<br>1               1       85          66 29 0 26.6 0.351 31 0<br>2               8       183         64 0 0 23.3 0.672 32 1<br>3               1       89          66 23 94 28.1 0.167 21 0<br>4               0       137         40 35 168 43.1 2.288 33 1</pre><h3>3. Exploratory Data Analysis</h3><p>This is a basic function that provides a high-level overview of a dataframe. The function “check_df” takes two arguments: a dataframe and the number of head and tail rows to be displayed (default value is 5).</p><p>The function prints the shape of the dataframe, the data types of each column, the first five and last five rows of the dataframe, the count of missing values in each column, and the quantiles of each column. The output provides a quick way to check for basic issues such as missing values, data types, and distributions of the columns in the dataframe.</p><pre>def check_df(dataframe, head=5):<br>    print(&quot;##################### Shape #####################&quot;)<br>    print(dataframe.shape)<br>    print(&quot;##################### Types #####################&quot;)<br>    print(dataframe.dtypes)<br>    print(&quot;##################### Head #####################&quot;)<br>    print(dataframe.head(head))<br>    print(&quot;##################### Tail #####################&quot;)<br>    print(dataframe.tail(head))<br>    print(&quot;##################### NA #####################&quot;)<br>    print(dataframe.isnull().sum())<br>    print(&quot;##################### Quantiles #####################&quot;)<br>    print(dataframe.quantile([0, 0.05, 0.50, 0.95, 0.99, 1]).T)<br>check_df(df)</pre><pre>##################### Shape #####################<br>(768, 9)<br>##################### Types #####################<br>Pregnancies                   int64<br>Glucose                       int64<br>BloodPressure                 int64<br>SkinThickness                 int64<br>Insulin                       int64<br>BMI                         float64<br>DiabetesPedigreeFunction    float64<br>Age                           int64<br>Outcome                       int64<br>dtype: object<br>##################### Head #####################<br>   Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  DiabetesPedigreeFunction  Age  Outcome<br>0            6      148             72             35        0  33.6                     0.627   50        1<br>1            1       85             66             29        0  26.6                     0.351   31        0<br>2            8      183             64              0        0  23.3                     0.672   32        1<br>3            1       89             66             23       94  28.1                     0.167   21        0<br>4            0      137             40             35      168  43.1                     2.288   33        1<br>##################### Tail #####################<br>     Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  DiabetesPedigreeFunction  Age  Outcome<br>763           10      101             76             48      180  32.9                     0.171   63        0<br>764            2      122             70             27        0  36.8                     0.340   27        0<br>765            5      121             72             23      112  26.2                     0.245   30        0<br>766            1      126             60              0        0  30.1                     0.349   47        1<br>767            1       93             70             31        0  30.4                     0.315   23        0<br>##################### NA #####################<br>Pregnancies                 0<br>Glucose                     0<br>BloodPressure               0<br>SkinThickness               0<br>Insulin                     0<br>BMI                         0<br>DiabetesPedigreeFunction    0<br>Age                         0<br>Outcome                     0<br>dtype: int64<br>##################### Quantiles #####################<br>                            0.00      0.05      0.50       0.95       0.99    1.00<br>Pregnancies                0.000   0.00000    3.0000   10.00000   13.00000   17.00<br>Glucose                    0.000  79.00000  117.0000  181.00000  196.00000  199.00<br>BloodPressure              0.000  38.70000   72.0000   90.00000  106.00000  122.00<br>SkinThickness              0.000   0.00000   23.0000   44.00000   51.33000   99.00<br>Insulin                    0.000   0.00000   30.5000  293.00000  519.90000  846.00<br>BMI                        0.000  21.80000   32.0000   44.39500   50.75900   67.10<br>DiabetesPedigreeFunction   0.078   0.14035    0.3725    1.13285    1.69833    2.42<br>Age                       21.000  21.00000   29.0000   58.00000   67.00000   81.00<br>Outcome                    0.000   0.00000    0.0000    1.00000    1.00000    1.00</pre><h3>Pandas Profiling</h3><p>pandas-profiling primary goal is to provide a one-line Exploratory Data Analysis (EDA) experience in a consistent and fast solution. Like pandas df.describe() function, that is so handy, pandas-profiling delivers an extended analysis of a DataFrame while alllowing the data analysis to be exported in different formats such as html and json.</p><pre>!pip install pandas-profiling<br>import pandas_profiling<br>pandas_profiling.ProfileReport(df)</pre><h3>Correlations</h3><h4>Spearman’s ρ</h4><p>The Spearman’s rank correlation coefficient (<em>ρ</em>) is a measure of monotonic correlation between two variables, and is therefore better in catching nonlinear monotonic correlations than Pearson’s <em>r</em>. It’s value lies between -1 and +1, -1 indicating total negative monotonic correlation, 0 indicating no monotonic correlation and 1 indicating total positive monotonic correlation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/876/1*rmjpGaLIXlHmXCFOn-CMUw.jpeg" /></figure><p>To calculate <em>ρ</em> for two variables <em>X</em> and <em>Y</em>, one divides the covariance of the rank variables of <em>X</em> and <em>Y</em> by the product of their standard deviations.</p><h3>Skimpy</h3><p>A light weight tool for creating summary statistics from dataframes.</p><p><strong><em>skimpy</em></strong> is a light weight tool that provides summary statistics about variables in data frames within the console or your interactive Python window. Think of it as a super-charged version of df.describe(). You can find the documentation <a href="https://aeturrell.github.io/skimpy/">here</a>.</p><p>You can install the latest release of skimpy via pip from PyPI:</p><pre>!pip install skimpy</pre><p>skim a dataframe and produce summary statistics within the console using:</p><pre>from skimpy import skim<br>skim(df)</pre><h3>4. Data Preprocessing &amp; Feature Engineering</h3><ol><li>outlier_thresholds: This function calculates the lower and upper limits for identifying outliers in a given column of a dataframe. It takes in the dataframe and the name of the col_name to calculate the limits for. The q1 and q3 parameters define the quartiles to be used for calculating the lower and upper limits and their default values are 0.25 and 0.75 respectively.</li><li>replace_with_thresholds: This function replaces the values in a given column of the dataframe that fall outside the lower and upper limits calculated in outlier_thresholds with the corresponding limit. It takes in the dataframe and the name of the column to replace values in as variable.</li><li>check_outlier: This function checks if there are any outliers in a given column of the dataframe. It returns True if there are any outliers, and False otherwise.</li><li>one_hot_encoder: This function applies one-hot encoding to a set of categorical columns in a dataframe. It takes in the dataframe and a list of categorical_cols to be one-hot encoded, as well as a boolean flag drop_first that determines whether or not to drop the first column of each categorical variable.</li><li>df.head(): This line displays the first 5 rows of the df dataframe, including the columns and their values in each row.</li></ol><pre>def outlier_thresholds(dataframe, col_name, q1=0.25, q3=0.75):<br>    quartile1 = dataframe[col_name].quantile(q1)<br>    quartile3 = dataframe[col_name].quantile(q3)<br>    interquantile_range = quartile3 - quartile1<br>    up_limit = quartile3 + 1.5 * interquantile_range<br>    low_limit = quartile1 - 1.5 * interquantile_range<br>    return low_limit, up_limit<br><br>def replace_with_thresholds(dataframe, variable):<br>    low_limit, up_limit = outlier_thresholds(dataframe, variable)<br>    dataframe.loc[(dataframe[variable] &lt; low_limit), variable] = low_limit<br>    dataframe.loc[(dataframe[variable] &gt; up_limit), variable] = up_limit<br><br>def check_outlier(dataframe, col_name, q1=0.25, q3=0.75):<br>    low_limit, up_limit = outlier_thresholds(dataframe, col_name, q1, q3)<br>    if dataframe[(dataframe[col_name] &gt; up_limit) | (dataframe[col_name] &lt; low_limit)].any(axis=None):<br>        return True<br>    else:<br>        return False<br><br>def one_hot_encoder(dataframe, categorical_cols, drop_first=False):<br>    dataframe = pd.get_dummies(dataframe, columns=categorical_cols, drop_first=drop_first)<br>    return dataframe<br><br>df.head()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5bnIjqGhOMCHSAOOwjOm1A.jpeg" /></figure><pre>df.columns = [col.upper() for col in df.columns]</pre><pre>df[&#39;NEW_GLUCOSE_CAT&#39;] = pd.cut(x=df[&#39;GLUCOSE&#39;], bins=[-1, 139, 200], labels=[&quot;normal&quot;, &quot;prediabetes&quot;])<br><br># Age<br>df.loc[(df[&#39;AGE&#39;] &lt; 35), &quot;NEW_AGE_CAT&quot;] = &#39;young&#39;<br>df.loc[(df[&#39;AGE&#39;] &gt;= 35) &amp; (df[&#39;AGE&#39;] &lt;= 55), &quot;NEW_AGE_CAT&quot;] = &#39;middleage&#39;<br>df.loc[(df[&#39;AGE&#39;] &gt; 55), &quot;NEW_AGE_CAT&quot;] = &#39;old&#39;<br><br># BMI<br>df[&#39;NEW_BMI_RANGE&#39;] = pd.cut(x=df[&#39;BMI&#39;], bins=[-1, 18.5, 24.9, 29.9, 100],<br>                             labels=[&quot;underweight&quot;, &quot;healty&quot;, &quot;overweight&quot;, &quot;obese&quot;])<br><br># BloodPressure<br>df[&#39;NEW_BLOODPRESSURE&#39;] = pd.cut(x=df[&#39;BLOODPRESSURE&#39;], bins=[-1, 79, 89, 123], labels=[&quot;normal&quot;, &quot;hs1&quot;, &quot;hs2&quot;])<br><br>check_df(df)</pre><pre>##################### Shape #####################<br>(768, 13)<br>##################### Types #####################<br>PREGNANCIES                    int64<br>GLUCOSE                        int64<br>BLOODPRESSURE                  int64<br>SKINTHICKNESS                  int64<br>INSULIN                        int64<br>BMI                          float64<br>DIABETESPEDIGREEFUNCTION     float64<br>AGE                            int64<br>OUTCOME                        int64<br>NEW_GLUCOSE_CAT             category<br>NEW_AGE_CAT                   object<br>NEW_BMI_RANGE               category<br>NEW_BLOODPRESSURE           category<br>dtype: object<br>##################### Head #####################<br>   PREGNANCIES  GLUCOSE  BLOODPRESSURE  SKINTHICKNESS  INSULIN   BMI  DIABETESPEDIGREEFUNCTION  AGE  OUTCOME NEW_GLUCOSE_CAT NEW_AGE_CAT NEW_BMI_RANGE NEW_BLOODPRESSURE<br>0            6      148             72             35        0  33.6                     0.627   50        1     prediabetes   middleage         obese            normal<br>1            1       85             66             29        0  26.6                     0.351   31        0          normal       young    overweight            normal<br>2            8      183             64              0        0  23.3                     0.672   32        1     prediabetes       young        healty            normal<br>3            1       89             66             23       94  28.1                     0.167   21        0          normal       young    overweight            normal<br>4            0      137             40             35      168  43.1                     2.288   33        1          normal       young         obese            normal<br>##################### Tail #####################<br>     PREGNANCIES  GLUCOSE  BLOODPRESSURE  SKINTHICKNESS  INSULIN   BMI  DIABETESPEDIGREEFUNCTION  AGE  OUTCOME NEW_GLUCOSE_CAT NEW_AGE_CAT NEW_BMI_RANGE NEW_BLOODPRESSURE<br>763           10      101             76             48      180  32.9                     0.171   63        0          normal         old         obese            normal<br>764            2      122             70             27        0  36.8                     0.340   27        0          normal       young         obese            normal<br>765            5      121             72             23      112  26.2                     0.245   30        0          normal       young    overweight            normal<br>766            1      126             60              0        0  30.1                     0.349   47        1          normal   middleage         obese            normal<br>767            1       93             70             31        0  30.4                     0.315   23        0          normal       young         obese            normal<br>##################### NA #####################<br>PREGNANCIES                 0<br>GLUCOSE                     0<br>BLOODPRESSURE               0<br>SKINTHICKNESS               0<br>INSULIN                     0<br>BMI                         0<br>DIABETESPEDIGREEFUNCTION    0<br>AGE                         0<br>OUTCOME                     0<br>NEW_GLUCOSE_CAT             0<br>NEW_AGE_CAT                 0<br>NEW_BMI_RANGE               0<br>NEW_BLOODPRESSURE           0<br>dtype: int64<br>##################### Quantiles #####################<br>                            0.00      0.05      0.50       0.95       0.99    1.00<br>PREGNANCIES                0.000   0.00000    3.0000   10.00000   13.00000   17.00<br>GLUCOSE                    0.000  79.00000  117.0000  181.00000  196.00000  199.00<br>BLOODPRESSURE              0.000  38.70000   72.0000   90.00000  106.00000  122.00<br>SKINTHICKNESS              0.000   0.00000   23.0000   44.00000   51.33000   99.00<br>INSULIN                    0.000   0.00000   30.5000  293.00000  519.90000  846.00<br>BMI                        0.000  21.80000   32.0000   44.39500   50.75900   67.10<br>DIABETESPEDIGREEFUNCTION   0.078   0.14035    0.3725    1.13285    1.69833    2.42<br>AGE                       21.000  21.00000   29.0000   58.00000   67.00000   81.00<br>OUTCOME                    0.000   0.00000    0.0000    1.00000    1.00000    1.00</pre><pre>def grab_col_names(dataframe, cat_th=10, car_th=20):<br><br>    # cat_cols, cat_but_car<br>    cat_cols = [col for col in dataframe.columns if dataframe[col].dtypes == &quot;O&quot;]<br>    num_but_cat = [col for col in dataframe.columns if dataframe[col].nunique() &lt; cat_th and<br>                   dataframe[col].dtypes != &quot;O&quot;]<br>    cat_but_car = [col for col in dataframe.columns if dataframe[col].nunique() &gt; car_th and<br>                   dataframe[col].dtypes == &quot;O&quot;]<br>    cat_cols = cat_cols + num_but_cat<br>    cat_cols = [col for col in cat_cols if col not in cat_but_car]<br><br>    # num_cols<br>    num_cols = [col for col in dataframe.columns if dataframe[col].dtypes != &quot;O&quot;]<br>    num_cols = [col for col in num_cols if col not in num_but_cat]<br><br>    return cat_cols, num_cols, cat_but_car<br><br>check_df(df)</pre><pre>cat_cols, num_cols, cat_but_car = grab_col_names(df, cat_th=5, car_th=20)<br>cat_cols = [col for col in cat_cols if &quot;OUTCOME&quot; not in col]<br><br>for col in num_cols:<br>    print(col, check_outlier(df, col, 0.05, 0.95))<br><br>replace_with_thresholds(df, &quot;INSULIN&quot;)</pre><pre>PREGNANCIES False<br>GLUCOSE False<br>BLOODPRESSURE False<br>SKINTHICKNESS False<br>INSULIN True<br>BMI False<br>DIABETESPEDIGREEFUNCTION False<br>AGE False</pre><pre>cat_cols, num_cols, cat_but_car = grab_col_names(df, cat_th=5, car_th=20)</pre><pre># Examination of categorical variables<br>for col in cat_cols:<br>    cat_summary(df, col)</pre><pre>NEW_AGE_CAT      Ratio<br>young              488  63.541667<br>middleage          230  29.947917<br>old                 50   6.510417<br>##########################################<br>   OUTCOME      Ratio<br>0      500  65.104167<br>1      268  34.895833<br>##########################################<br>             NEW_GLUCOSE_CAT      Ratio<br>normal                   571  74.348958<br>prediabetes              197  25.651042<br>##########################################<br>             NEW_BMI_RANGE      Ratio<br>obese                  472  61.458333<br>overweight             179  23.307292<br>healty                 102  13.281250<br>underweight             15   1.953125<br>##########################################<br>        NEW_BLOODPRESSURE      Ratio<br>normal                563  73.307292<br>hs1                   145  18.880208<br>hs2                    60   7.812500</pre><pre># Examination of numerical variables<br>df[num_cols].describe().T</pre><h3>Standardization</h3><p>The code provided is used to prepare data for a machine learning model. It is processing a dataframe, “df,” which contains information about patients who have been diagnosed with diabetes. The first step is to standardize the numerical columns in the dataframe using the StandardScaler from the scikit-learn library. Then the target variable, “OUTCOME”, is separated from the rest of the data, and stored in the “y” variable. The input variables, without the outcome, are stored in the “X” variable.</p><p>The “diabetes_data_prep” function takes in a dataframe as an argument and performs various data preparation steps on the input data. It starts by converting the column names of the dataframe to uppercase. Then it creates new columns in the dataframe by categorizing some of the numerical columns, such as “GLUCOSE,” “AGE,” “BMI,” and “BLOODPRESSURE.” These categorical columns are then one-hot encoded and the resulting dataframe is standardized. Finally, the function returns the input data, X, and the target variable, y.</p><pre># Standardization<br>X_scaled = StandardScaler().fit_transform(df[num_cols])<br>df[num_cols] = pd.DataFrame(X_scaled, columns=df[num_cols].columns)<br><br>y = df[&quot;OUTCOME&quot;]<br>X = df.drop([&quot;OUTCOME&quot;], axis=1)<br><br>check_df(X)<br><br>def diabetes_data_prep(dataframe):<br>    dataframe.columns = [col.upper() for col in dataframe.columns]<br><br>    # Glucose<br>    dataframe[&#39;NEW_GLUCOSE_CAT&#39;] = pd.cut(x=dataframe[&#39;GLUCOSE&#39;], bins=[-1, 139, 200], labels=[&quot;normal&quot;, &quot;prediabetes&quot;])<br><br>    # Age<br>    dataframe.loc[(dataframe[&#39;AGE&#39;] &lt; 35), &quot;NEW_AGE_CAT&quot;] = &#39;young&#39;<br>    dataframe.loc[(dataframe[&#39;AGE&#39;] &gt;= 35) &amp; (dataframe[&#39;AGE&#39;] &lt;= 55), &quot;NEW_AGE_CAT&quot;] = &#39;middleage&#39;<br>    dataframe.loc[(dataframe[&#39;AGE&#39;] &gt; 55), &quot;NEW_AGE_CAT&quot;] = &#39;old&#39;<br><br>    # BMI<br>    dataframe[&#39;NEW_BMI_RANGE&#39;] = pd.cut(x=dataframe[&#39;BMI&#39;], bins=[-1, 18.5, 24.9, 29.9, 100],<br>                                        labels=[&quot;underweight&quot;, &quot;healty&quot;, &quot;overweight&quot;, &quot;obese&quot;])<br><br>    # BloodPressure<br>    dataframe[&#39;NEW_BLOODPRESSURE&#39;] = pd.cut(x=dataframe[&#39;BLOODPRESSURE&#39;], bins=[-1, 79, 89, 123],<br>                                            labels=[&quot;normal&quot;, &quot;hs1&quot;, &quot;hs2&quot;])<br><br>    cat_cols, num_cols, cat_but_car = grab_col_names(dataframe, cat_th=5, car_th=20)<br><br>    cat_cols = [col for col in cat_cols if &quot;OUTCOME&quot; not in col]<br><br>    df = one_hot_encoder(dataframe, cat_cols, drop_first=True)<br><br>    df.columns = [col.upper() for col in df.columns]<br><br>    cat_cols, num_cols, cat_but_car = grab_col_names(df, cat_th=5, car_th=20)<br><br>    cat_cols = [col for col in cat_cols if &quot;OUTCOME&quot; not in col]<br><br>    replace_with_thresholds(df, &quot;INSULIN&quot;)<br><br>    X_scaled = StandardScaler().fit_transform(df[num_cols])<br>    df[num_cols] = pd.DataFrame(X_scaled, columns=df[num_cols].columns)<br><br>    y = df[&quot;OUTCOME&quot;]<br>    X = df.drop([&quot;OUTCOME&quot;], axis=1)<br><br>    return X, y<br><br>check_df(df)<br><br>X, y = diabetes_data_prep(df)<br><br>check_df(X)</pre><h3>5. Base Models</h3><pre>def base_models(X, y, scoring=&quot;roc_auc&quot;):<br>    print(&quot;Base Models....&quot;)<br>    classifiers = [(&#39;LR&#39;, LogisticRegression()),<br>                   (&#39;KNN&#39;, KNeighborsClassifier()),<br>                   (&quot;SVC&quot;, SVC()),<br>                   (&quot;CART&quot;, DecisionTreeClassifier()),<br>                   (&quot;RF&quot;, RandomForestClassifier()),<br>                   (&#39;Adaboost&#39;, AdaBoostClassifier()),<br>                   (&#39;GBM&#39;, GradientBoostingClassifier()),<br>                   (&#39;XGBoost&#39;, XGBClassifier(use_label_encoder=False, eval_metric=&#39;logloss&#39;)),<br>                   (&#39;LightGBM&#39;, LGBMClassifier()),<br>                   (&#39;CatBoost&#39;, CatBoostClassifier(verbose=False))]<br><br>    for name, classifier in classifiers:<br>        cv_results = cross_validate(classifier, X, y, cv=3, scoring=scoring)<br>        print(f&quot;{scoring}: {round(cv_results[&#39;test_score&#39;].mean(), 4)} ({name}) &quot;)<br><br>base_models(X, y, scoring=&quot;accuracy&quot;)</pre><pre>Base Models....<br>accuracy: 0.7734 (LR) <br>accuracy: 0.7409 (KNN) <br>accuracy: 0.776 (SVC) <br>accuracy: 0.6797 (CART) <br>accuracy: 0.7643 (RF) <br>accuracy: 0.7695 (Adaboost) <br>accuracy: 0.7682 (GBM) <br>accuracy: 0.7422 (XGBoost) <br>accuracy: 0.7292 (LightGBM) <br>accuracy: 0.7539 (CatBoost)</pre><h3>6. Automated Hyperparameter Optimization</h3><pre>knn_params = {&quot;n_neighbors&quot;: range(2, 50)}<br><br>cart_params = {&#39;max_depth&#39;: range(1, 20),<br>               &quot;min_samples_split&quot;: range(2, 30)}<br><br>rf_params = {&quot;max_depth&quot;: [8, 15, None],<br>             &quot;max_features&quot;: [5, 7, &quot;auto&quot;],<br>             &quot;min_samples_split&quot;: [15, 20],<br>             &quot;n_estimators&quot;: [200, 300]}<br><br>xgboost_params = {&quot;learning_rate&quot;: [0.1, 0.01],<br>                  &quot;max_depth&quot;: [5, 8],<br>                  &quot;n_estimators&quot;: [100, 200]}<br><br>lightgbm_params = {&quot;learning_rate&quot;: [0.01, 0.1],<br>                   &quot;n_estimators&quot;: [300, 500]}<br><br><br>classifiers = [(&#39;KNN&#39;, KNeighborsClassifier(), knn_params),<br>               (&quot;CART&quot;, DecisionTreeClassifier(), cart_params),<br>               (&quot;RF&quot;, RandomForestClassifier(), rf_params),<br>               (&#39;XGBoost&#39;, XGBClassifier(use_label_encoder=False, eval_metric=&#39;logloss&#39;), xgboost_params),<br>               (&#39;LightGBM&#39;, LGBMClassifier(), lightgbm_params)]</pre><pre>def hyperparameter_optimization(X, y, cv=3, scoring=&quot;roc_auc&quot;):<br>    print(&quot;Hyperparameter Optimization....&quot;)<br>    best_models = {}<br>    for name, classifier, params in classifiers:<br>        print(f&quot;########## {name} ##########&quot;)<br>        cv_results = cross_validate(classifier, X, y, cv=cv, scoring=scoring)<br>        print(f&quot;{scoring} (Before): {round(cv_results[&#39;test_score&#39;].mean(), 4)}&quot;)<br><br>        gs_best = GridSearchCV(classifier, params, cv=cv, n_jobs=-1, verbose=False).fit(X, y)<br>        final_model = classifier.set_params(**gs_best.best_params_)<br><br>        cv_results = cross_validate(final_model, X, y, cv=cv, scoring=scoring)<br>        print(f&quot;{scoring} (After): {round(cv_results[&#39;test_score&#39;].mean(), 4)}&quot;)<br>        print(f&quot;{name} best params: {gs_best.best_params_}&quot;, end=&quot;\n\n&quot;)<br>        best_models[name] = final_model<br>    return best_models<br><br>best_models = hyperparameter_optimization(X, y)</pre><pre>Hyperparameter Optimization....<br>########## KNN ##########<br>roc_auc (Before): 0.7671<br>roc_auc (After): 0.8026<br>KNN best params: {&#39;n_neighbors&#39;: 17}<br><br>########## CART ##########<br>roc_auc (Before): 0.6392<br>roc_auc (After): 0.7943<br>CART best params: {&#39;max_depth&#39;: 6, &#39;min_samples_split&#39;: 23}<br><br>########## RF ##########<br>roc_auc (Before): 0.8268<br>roc_auc (After): 0.8337<br>RF best params: {&#39;max_depth&#39;: 8, &#39;max_features&#39;: &#39;auto&#39;, &#39;min_samples_split&#39;: 20, &#39;n_estimators&#39;: 200}<br><br>########## XGBoost ##########<br>roc_auc (Before): 0.7978<br>roc_auc (After): 0.8064<br>XGBoost best params: {&#39;learning_rate&#39;: 0.1, &#39;max_depth&#39;: 5, &#39;n_estimators&#39;: 200}<br><br>########## LightGBM ##########<br>roc_auc (Before): 0.8009<br>roc_auc (After): 0.8139<br>LightGBM best params: {&#39;learning_rate&#39;: 0.01, &#39;n_estimators&#39;: 300}</pre><h3>5. Stacking &amp; Ensemble Learning</h3><p>Ensemble techniques are the methods that use multiple learning algorithms or models to produce one optimal predictive model. The model produced has better performance than the base learners taken alone.</p><p>This code uses the VotingClassifier class from scikit-learn to build an ensemble classifier. It uses the best models found in the hyperparameter optimization step, which are ‘KNN’, ‘RF’, and ‘LightGBM’, as the individual models in the ensemble. The ensemble uses a “soft” voting method, where the predictions of the individual models are averaged. The function then fits the voting classifier on the input features X and target variable y. Finally, the function performs 3-fold cross-validation on the voting classifier and calculates the mean accuracy, F1 score, and ROC-AUC. The results are then printed to the console.</p><pre>def voting_classifier(best_models, X, y):<br>    print(&quot;Voting Classifier...&quot;)<br><br>    voting_clf = VotingClassifier(estimators=[(&#39;KNN&#39;, best_models[&quot;KNN&quot;]),<br>                                              (&#39;RF&#39;, best_models[&quot;RF&quot;]),<br>                                              (&#39;LightGBM&#39;, best_models[&quot;LightGBM&quot;])],<br>                                  voting=&#39;soft&#39;).fit(X, y)<br><br>    cv_results = cross_validate(voting_clf, X, y, cv=3, scoring=[&quot;accuracy&quot;, &quot;f1&quot;, &quot;roc_auc&quot;])<br>    print(f&quot;Accuracy: {cv_results[&#39;test_accuracy&#39;].mean()}&quot;)<br>    print(f&quot;F1Score: {cv_results[&#39;test_f1&#39;].mean()}&quot;)<br>    print(f&quot;ROC_AUC: {cv_results[&#39;test_roc_auc&#39;].mean()}&quot;)<br>    return voting_clf<br><br>voting_clf = voting_classifier(best_models, X, y)</pre><pre>Voting Classifier...<br>Accuracy: 0.7643229166666666<br>F1Score: 0.6162162162162161<br>ROC_AUC: 0.8291571182800231</pre><h3>7. Prediction for a New Observation</h3><pre>X.columns<br>random_user = X.sample(1, random_state=45)<br>voting_clf.predict(random_user)<br><br>joblib.dump(voting_clf, &quot;voting_clf2.pkl&quot;)<br><br>new_model = joblib.load(&quot;voting_clf2.pkl&quot;)<br>new_model.predict(random_user)</pre><pre>array([1])</pre><p>This code first gets the column names of the dataframe X by calling X.columns. Then, it samples a random row from X and assigns it to the variable random_user. The predict method is called on the voting_classifier object voting_clf using the random user data as input. The trained classifier model voting_clf is then saved using the joblib.dump function, with the file name “voting_clf2.pkl”. Finally, the saved model is loaded back into memory using joblib.load and the predict method is called again on the loaded model using the same random user data, which returns the predicted class.</p><pre>def main():<br>    df = pd.read_csv(&quot;/kaggle/input/pima-indians-diabetes-database/diabetes.csv&quot;)<br>    X, y = diabetes_data_prep(df)<br>    base_models(X, y)<br>    best_models = hyperparameter_optimization(X, y)<br>    voting_clf = voting_classifier(best_models, X, y)<br>    joblib.dump(voting_clf, &quot;voting_clf.pkl&quot;)<br>    return voting_clf<br><br>if __name__ == &quot;__main__&quot;:<br>    print(&quot;Process started&quot;)<br>    main()</pre><pre>Process started<br>Base Models....<br>roc_auc: 0.8409 (LR) <br>roc_auc: 0.791 (KNN) <br>roc_auc: 0.8355 (SVC) <br>roc_auc: 0.6717 (CART) <br>roc_auc: 0.8246 (RF) <br>roc_auc: 0.8196 (Adaboost) <br>roc_auc: 0.8244 (GBM) <br>roc_auc: 0.8015 (XGBoost) <br>roc_auc: 0.807 (LightGBM) <br>roc_auc: 0.8349 (CatBoost) <br>Hyperparameter Optimization....<br>########## KNN ##########<br>roc_auc (Before): 0.8191<br>roc_auc (After): 0.8211<br>KNN best params: {&#39;n_neighbors&#39;: 20}<br><br>########## CART ##########<br>roc_auc (Before): 0.7943<br>roc_auc (After): 0.7943<br>CART best params: {&#39;max_depth&#39;: 6, &#39;min_samples_split&#39;: 23}<br><br>########## RF ##########<br>roc_auc (Before): 0.8397<br>roc_auc (After): 0.8351<br>RF best params: {&#39;max_depth&#39;: 8, &#39;max_features&#39;: 5, &#39;min_samples_split&#39;: 15, &#39;n_estimators&#39;: 200}<br><br>########## XGBoost ##########<br>roc_auc (Before): 0.8067<br>roc_auc (After): 0.8179<br>XGBoost best params: {&#39;learning_rate&#39;: 0.01, &#39;max_depth&#39;: 5, &#39;n_estimators&#39;: 200}<br><br>########## LightGBM ##########<br>roc_auc (Before): 0.8185<br>roc_auc (After): 0.8185<br>LightGBM best params: {&#39;learning_rate&#39;: 0.01, &#39;n_estimators&#39;: 300}<br><br>Voting Classifier...<br>Accuracy: 0.7708333333333334<br>F1Score: 0.6371707388656541<br>ROC_AUC: 0.8366793164869816</pre><p>The code provided is for training a machine learning model using the Pima Indians Diabetes dataset. The code performs the following steps:</p><p>Reads the diabetes dataset from the specified file path into a Pandas dataframe Performs data preparation by extracting the feature matrix (X) and target vector (y) Runs a base model selection process using various machine learning algorithms Performs hyperparameter optimization to select the best models among the base models Creates a voting classifier using the best models, which makes predictions by aggregating the outputs of the individual classifiers Saves the voting classifier to a file using the joblib library Finally, the function returns the trained voting classifier. The code also checks if the script is being executed as the main program, in which case it will run the main function and print the message &quot;Process started&quot;.</p><h3>Conclusion</h3><p>In conclusion, the comprehensive analysis of Pima Indians Diabetes provides a comprehensive understanding of the relationship between different variables and the incidence of diabetes. The predictive models built in this study can be used to classify patients as diabetic or non-diabetic and to guide the development of more effective treatment and prevention strategies.</p><p><strong><em>You can find all the details of the project in my </em></strong><a href="https://www.kaggle.com/code/emineyetm/a-comprehensive-analysis-of-pima-indians-diabetes/notebook"><strong><em>kaggle notebook.</em></strong></a></p><p>🔔 <strong><em>If you’d like to get in touch, you can find me on Linkedin, drop me an email or follow me</em></strong> 👇</p><ul><li><strong>Follow me:</strong> <a href="https://www.linkedin.com/in/eminebozkus/">LinkedIn</a> | <a href="https://www.kaggle.com/emineyetm">Kaggle</a> | <a href="https://github.com/bozkusemine">Github</a></li></ul><h3>References</h3><ol><li><a href="https://www.miuul.com/">https://www.miuul.com/</a></li><li><a href="https://aeturrell.github.io/skimpy/">https://aeturrell.github.io/skimpy/</a></li><li><a href="https://github.com/AutoViML/AutoViz">https://github.com/AutoViML/AutoViz</a></li></ol><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f5cf9f73785f" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/a-comprehensive-analysis-of-pima-indians-diabetes-f5cf9f73785f">A Comprehensive Analysis of Pima Indians Diabetes</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Machine Learning for Time Series Forecasting]]></title>
            <link>https://medium.datadriveninvestor.com/using-machine-learning-for-time-series-forecasting-db94e523d42a?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/db94e523d42a</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[time-series-analysis]]></category>
            <category><![CDATA[time-series-forecasting]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Fri, 10 Feb 2023 12:34:14 GMT</pubDate>
            <atom:updated>2023-02-11T05:56:01.367Z</atom:updated>
            <content:encoded><![CDATA[<p>Time series forecasting involves predicting future values based on past data points. Machine learning can be used to perform time series forecasting by training models on historical data to make predictions.</p><p>In this article, we will implement the application on the data set on the <a href="https://www.kaggle.com/competitions/demand-forecasting-kernels-only">Kaggle</a> platform. This competition is provided as a way to explore different time series techniques on a relatively simple and clean dataset. You are given 5 years of store-item sales data, and asked to predict 3 months of sales for 50 different items at 10 different stores.</p><h3>Dataset Description</h3><p>The objective of this competition is to predict 3 months of item-level sales data at different store locations.</p><h3>File descriptions</h3><ul><li><strong>train.csv</strong> — Training data</li><li><strong>test.csv</strong> — Test data (Note: the Public/Private split is time based)</li><li><strong>sample_submission.csv</strong> — a sample submission file in the correct format</li></ul><h3>Data fields</h3><ul><li><strong>date</strong> — Date of the sale data. There are no holiday effects or store closures.</li><li><strong>store</strong> — Store ID</li><li><strong>item</strong> — Item ID</li><li><strong>sales</strong> — Number of items sold at a particular store on a particular date.</li></ul><h3>Import Libraries</h3><pre>import time    # To time our operations<br>import numpy as np  # linear algebra<br>import pandas as pd     # data processing, CSV file I/O (e.g. pd.read_csv)<br>from matplotlib import pyplot as plt        # To visualize<br>import seaborn as sns       # To visualize<br>import lightgbm as lgb      # To train our model<br>import warnings     # To ignore some warnings that we don&#39;t care<br>warnings.filterwarnings(&#39;ignore&#39;)   <br>pd.set_option(&#39;display.max_columns&#39;, None)  # Unlimited columns<br>pd.set_option(&#39;display.width&#39;, 500)     # Width of the display in the notebook</pre><h3>Loading the data</h3><pre>train = pd.read_csv(&#39;/kaggle/input/demand-forecasting-kernels-only/train.csv&#39;, parse_dates=[&#39;date&#39;])    # parse_dates: Converts the date column to datetime format.<br>test = pd.read_csv(&#39;/kaggle/input/demand-forecasting-kernels-only/test.csv&#39;, parse_dates=[&#39;date&#39;])<br>sample_sub = pd.read_csv(&#39;/kaggle/input/demand-forecasting-kernels-only/sample_submission.csv&#39;)</pre><ul><li>We combined train and test data with concat.</li><li>One of the reasons we combine train and test data is to avoid class differences and size differences.</li></ul><pre>df = pd.concat([train, test], sort=False)</pre><h3>EDA (Exploratory Data Analysis)</h3><pre>def check_df(dataframe, head=5):<br>    print(&quot;##################### Shape #####################&quot;)<br>    print(dataframe.shape)<br>    print(&quot;##################### Types #####################&quot;)<br>    print(dataframe.dtypes)<br>    print(&quot;##################### Head #####################&quot;)<br>    print(dataframe.head(head))<br>    print(&quot;##################### Tail #####################&quot;)<br>    print(dataframe.tail(head))<br>    print(&quot;##################### NA #####################&quot;)<br>    print(dataframe.isnull().sum())<br>    print(&quot;##################### Quantiles #####################&quot;)<br>    print(dataframe.quantile([0, 0.05, 0.50, 0.95, 0.99, 1]).T)</pre><p>This function is used to perform basic exploratory data analysis (EDA) on a pandas dataframe. The function prints the shape of the dataframe, the data types of the columns, the first and last few rows of the dataframe, the number of missing values (NA) in each column, and the quantiles of the columns. The optional head parameter allows you to specify how many rows to display when printing the first and last few rows of the dataframe. By providing this information, the function helps in understanding the structure, contents and quality of the data.</p><pre>df[&quot;date&quot;].min(), df[&quot;date&quot;].max()            # First and last dates in the dataset</pre><pre>(Timestamp(&#39;2013-01-01 00:00:00&#39;), Timestamp(&#39;2018-03-31 00:00:00&#39;))</pre><pre>check_df(df)</pre><pre>##################### Shape #####################<br>(958000, 5)<br>##################### Types #####################<br>date     datetime64[ns]<br>store             int64<br>item              int64<br>sales           float64<br>id              float64<br>dtype: object<br>##################### Head #####################<br>        date  store  item  sales  id<br>0 2013-01-01      1     1   13.0 NaN<br>1 2013-01-02      1     1   11.0 NaN<br>2 2013-01-03      1     1   14.0 NaN<br>3 2013-01-04      1     1   13.0 NaN<br>4 2013-01-05      1     1   10.0 NaN<br>##################### Tail #####################<br>            date  store  item  sales       id<br>44995 2018-03-27     10    50    NaN  44995.0<br>44996 2018-03-28     10    50    NaN  44996.0<br>44997 2018-03-29     10    50    NaN  44997.0<br>44998 2018-03-30     10    50    NaN  44998.0<br>44999 2018-03-31     10    50    NaN  44999.0<br>##################### NA #####################<br>date          0<br>store         0<br>item          0<br>sales     45000<br>id       913000<br>dtype: int64<br>##################### Quantiles #####################<br>       0.00     0.05     0.50      0.95      0.99     1.00<br>store   1.0     1.00      5.5     10.00     10.00     10.0<br>item    1.0     3.00     25.5     48.00     50.00     50.0<br>sales   0.0    16.00     47.0    107.00    135.00    231.0<br>id      0.0  2249.95  22499.5  42749.05  44549.01  44999.0</pre><pre>df[[&quot;store&quot;]].nunique()      # Number of stores</pre><pre>store    10<br>dtype: int64</pre><pre>df[[&quot;item&quot;]].nunique()       # Number of products</pre><pre>item    50<br>dtype: int64</pre><pre>df.groupby([&quot;store&quot;])[&quot;item&quot;].nunique()    # Number of products in store breakdown</pre><pre>store<br>1     50<br>2     50<br>3     50<br>4     50<br>5     50<br>6     50<br>7     50<br>8     50<br>9     50<br>10    50<br>Name: item, dtype: int64</pre><pre>df.groupby([&quot;store&quot;, &quot;item&quot;]).agg({&quot;sales&quot;: [&quot;sum&quot;]})     # Total sales in store and product breakdown</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/362/1*vt0Zv18SoCru5KA1cni6DQ.png" /></figure><pre>df.groupby([&quot;store&quot;, &quot;item&quot;]).agg({&quot;sales&quot;: [&quot;sum&quot;, &quot;mean&quot;, &quot;median&quot;, &quot;std&quot;]})          # Total sales, average sales, median sales and standard deviation in store and product breakdown</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/956/1*3BYQxvtjAYbczTiby5v15g.png" /></figure><h3>Feature Engineering</h3><pre>def create_date_features(df):<br>    df[&#39;month&#39;] = df.date.dt.month<br>    df[&#39;day_of_month&#39;] = df.date.dt.day<br>    df[&#39;day_of_year&#39;] = df.date.dt.dayofyear<br>    df[&#39;week_of_year&#39;] = df.date.dt.weekofyear<br>    df[&#39;day_of_week&#39;] = df.date.dt.dayofweek<br>    df[&#39;year&#39;] = df.date.dt.year<br>    df[&quot;is_wknd&quot;] = df.date.dt.weekday // 4<br>    df[&#39;is_month_start&#39;] = df.date.dt.is_month_start.astype(int)<br>    df[&#39;is_month_end&#39;] = df.date.dt.is_month_end.astype(int)<br>    return df<br><br>df = create_date_features(df)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ss22wDIFjlZMa1izCbMEcA.png" /></figure><p>This function create_date_features creates various date-related features from the ‘date’ column of a given dataframe df. It returns the modified dataframe with the following additional columns:</p><ul><li>‘month’: month of the year (1–12)</li><li>‘day_of_month’: day of the month (1–31)</li><li>‘day_of_year’: day of the year (1–365 or 1–366 in a leap year)</li><li>‘week_of_year’: week of the year (1–52)</li><li>‘day_of_week’: day of the week (0–6, where Monday is 0 and Sunday is 6)</li><li>‘year’: year</li><li>‘is_wknd’: a binary variable indicating whether the day is a weekend (0 or 1)</li><li>‘is_month_start’: a binary variable indicating whether the day is the first day of a month (0 or 1)</li><li>‘is_month_end’: a binary variable indicating whether the day is the last day of a month (0 or 1)</li></ul><pre>df.groupby([&quot;store&quot;, &quot;item&quot;, &quot;month&quot;]).agg({&quot;sales&quot;: [&quot;sum&quot;, &quot;mean&quot;, &quot;median&quot;, &quot;std&quot;]})</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*eQA_3ayEDWyrMgEB8upt0w.png" /></figure><h3><strong>Autoviz</strong></h3><p>One of the key features of <strong>Autoviz</strong> is its ability to handle large and complex datasets. It can quickly identify patterns and relationships within the data, making it an ideal tool for data exploration and discovery. Additionally, Autoviz is highly customizable, allowing users to specify the types of visualizations they want to generate, as well as the color schemes and layouts of the charts.</p><pre>pip install autoviz</pre><pre>from autoviz.AutoViz_Class import AutoViz_Class<br>AV = AutoViz_Class()<br><br>%matplotlib inline <br># Generate visualizations<br>AV.AutoViz(&quot;/kaggle/input/demand-forecasting-kernels-only/test.csv&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JFN24oe0TgOHXbOklndy9g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/0*sAErRb65Z1S6mIK3.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*EFzmFifwKtayGnkA.png" /></figure><h3>Random Noise</h3><pre>def random_noise(dataframe):<br>    return np.random.normal(scale=1.6, size=(len(dataframe),))</pre><h3>Lag/Shifted Features</h3><p>Lag or shifted features are a commonly used feature engineering technique for time series forecasting. Lag features involve shifting the time series data by a specified number of time steps and using the shifted values as input features for the forecasting model.</p><p>For example, in a time series forecasting problem, the target variable may be the sales of a product in a given time period. To include information from past time periods, we can create lag features by shifting the sales data by one or more time steps and using the shifted values as input features. This provides the model with additional information about past trends and patterns that may be useful for making predictions.</p><p>Lag features can be created for multiple lags, such as a lag of 1, 2, 3, etc. The choice of how many lags to include and which lags to include depends on the characteristics of the time series data and the goals of the forecasting. It is also possible to create lag features for other related variables, such as prices, competitor data, etc.</p><p>Including lag features can be a powerful tool for improving the performance of time series forecasting models, but it can also lead to overfitting if not used carefully. It is important to carefully evaluate the impact of lag features on the model performance and to use appropriate methods, such as cross-validation, to avoid overfitting.</p><pre>df.sort_values(by=[&#39;store&#39;, &#39;item&#39;, &#39;date&#39;], axis=0, inplace=True)<br><br>pd.DataFrame({&quot;sales&quot;: df[&quot;sales&quot;].values[0:10],    # first 10 values in sales column<br>              &quot;lag1&quot;: df[&quot;sales&quot;].shift(1).values[0:10],    # The previous values of the first 10 values in the sales column<br>              &quot;lag2&quot;: df[&quot;sales&quot;].shift(2).values[0:10],    # The two previous values of the first 10 values in the sales column<br>              &quot;lag3&quot;: df[&quot;sales&quot;].shift(3).values[0:10],    # three previous values of the first 10 values in the sales column<br>              &quot;lag4&quot;: df[&quot;sales&quot;].shift(4).values[0:10]})   # four previous values of the first 10 values in the sales column<br><br>df.groupby([&quot;store&quot;, &quot;item&quot;])[&#39;sales&#39;].head()0         13.0<br>1         11.0<br>2         14.0<br>3         13.0<br>4         10.0<br>          ... <br>911174    33.0<br>911175    37.0<br>911176    46.0<br>911177    51.0<br>911178    41.0<br>Name: sales, Length: 2500, dtype: float64</pre><pre>0         13.0<br>1         11.0<br>2         14.0<br>3         13.0<br>4         10.0<br>          ... <br>911174    33.0<br>911175    37.0<br>911176    46.0<br>911177    51.0<br>911178    41.0<br>Name: sales, Length: 2500, dtype: float64</pre><pre>df.groupby([&quot;store&quot;, &quot;item&quot;])[&#39;sales&#39;].transform(lambda x: x.shift(1))      # Replaces the values in the sales column with the previous values.</pre><pre>0         NaN<br>1        13.0<br>2        11.0<br>3        14.0<br>4        13.0<br>         ... <br>44995     NaN<br>44996     NaN<br>44997     NaN<br>44998     NaN<br>44999     NaN<br>Name: sales, Length: 958000, dtype: float64</pre><pre>def lag_features(dataframe, lags):<br>    for lag in lags:<br>        dataframe[&#39;sales_lag_&#39; + str(lag)] = dataframe.groupby([&quot;store&quot;, &quot;item&quot;])[&#39;sales&#39;].transform(<br>            lambda x: x.shift(lag)) + random_noise(dataframe)<br>    return dataframe<br><br>df = lag_features(df, [91, 98, 105, 112, 119, 126, 182, 364, 546, 728])<br><br>check_df(df)</pre><p>The lag_features function is a feature engineering function that creates lag features for a given time series dataframe. The function takes in a dataframe and a list of lags, and for each lag in the list, it creates a new feature in the dataframe that is the sales data shifted by the specified number of time steps. The new feature is created using the shift function in pandas, which shifts the values in the sales column by the specified number of time steps. The shifted values are then grouped by the store and item columns using the groupby function and transformed using a lambda function that adds random noise to the shifted values. The check_df function is used to inspect the resulting dataframe to ensure that the lag features have been created correctly. The exact purpose of this function is not clear from the code provided, but it may be used to check the shape, data types, or values in the dataframe.</p><h3>Rolling Mean Features</h3><p>Rolling mean features are another commonly used feature engineering technique for time series forecasting. Rolling mean features involve calculating the mean of the time series data over a specified window size and using the mean values as input features for the forecasting model. The window size can be specified in terms of the number of time steps or in terms of a time span, such as a number of days or weeks. The choice of window size depends on the characteristics of the time series data and the goals of the forecasting.</p><p>Including rolling mean features can be a useful tool for improving the performance of time series forecasting models, but it is important to use appropriate methods to avoid overfitting. It is also important to carefully evaluate the impact of the rolling mean feature on the model performance and to consider alternative feature engineering techniques, such as lag features, as well.</p><pre>pd.DataFrame({&quot;sales&quot;: df[&quot;sales&quot;].values[0:10],<br>              &quot;roll2&quot;: df[&quot;sales&quot;].rolling(window=2).mean().values[0:10],<br>              &quot;roll3&quot;: df[&quot;sales&quot;].rolling(window=3).mean().values[0:10],<br>              &quot;roll5&quot;: df[&quot;sales&quot;].rolling(window=5).mean().values[0:10]})<br><br>pd.DataFrame({&quot;sales&quot;: df[&quot;sales&quot;].values[0:10],<br>              &quot;roll2&quot;: df[&quot;sales&quot;].shift(1).rolling(window=2).mean().values[0:10],<br>              &quot;roll3&quot;: df[&quot;sales&quot;].shift(1).rolling(window=3).mean().values[0:10],<br>              &quot;roll5&quot;: df[&quot;sales&quot;].shift(1).rolling(window=5).mean().values[0:10]})<br><br><br>def roll_mean_features(dataframe, windows):<br>    for window in windows:<br>        dataframe[&#39;sales_roll_mean_&#39; + str(window)] = dataframe.groupby([&quot;store&quot;, &quot;item&quot;])[&#39;sales&#39;]. \<br>                                                          transform(<br>            lambda x: x.shift(1).rolling(window=window, min_periods=10, win_type=&quot;triang&quot;).mean()) + random_noise(<br>            dataframe)<br>    return dataframe<br><br><br>df = roll_mean_features(df, [365, 546])</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RRJqDZrYwVc4qs5gXW8CLQ.png" /></figure><h3>Exponentially Weighted Mean Features</h3><p>Exponentially weighted mean features are similar to rolling mean features, but instead of using a fixed window size to calculate the mean, they use an exponentially decaying weighting scheme to give more importance to recent observations and less importance to older observations.</p><p>The decay factor in the weighting scheme can be specified to control the importance given to recent observations. A smaller decay factor will give more importance to recent observations, while a larger decay factor will give more importance to older observations. The choice of decay factor depends on the characteristics of the time series data and the goals of the forecasting.</p><p>Including exponentially weighted mean features can be a useful tool for improving the performance of time series forecasting models, but it is important to use appropriate methods to avoid overfitting. It is also important to carefully evaluate the impact of the exponentially weighted mean feature on the model performance and to consider alternative feature engineering techniques, such as lag features or rolling mean features, as well.</p><pre>pd.DataFrame({&quot;sales&quot;: df[&quot;sales&quot;].values[0:10],<br>              &quot;roll2&quot;: df[&quot;sales&quot;].shift(1).rolling(window=2).mean().values[0:10],<br>              &quot;ewm099&quot;: df[&quot;sales&quot;].shift(1).ewm(alpha=0.99).mean().values[0:10],<br>              &quot;ewm095&quot;: df[&quot;sales&quot;].shift(1).ewm(alpha=0.95).mean().values[0:10],<br>              &quot;ewm07&quot;: df[&quot;sales&quot;].shift(1).ewm(alpha=0.7).mean().values[0:10],<br>              &quot;ewm02&quot;: df[&quot;sales&quot;].shift(1).ewm(alpha=0.1).mean().values[0:10]})<br><br>def ewm_features(dataframe, alphas, lags):<br>    for alpha in alphas:<br>        for lag in lags:<br>            dataframe[&#39;sales_ewm_alpha_&#39; + str(alpha).replace(&quot;.&quot;, &quot;&quot;) + &quot;_lag_&quot; + str(lag)] = \<br>                dataframe.groupby([&quot;store&quot;, &quot;item&quot;])[&#39;sales&#39;].transform(lambda x: x.shift(lag).ewm(alpha=alpha).mean())<br>    return dataframe<br><br>alphas = [0.95, 0.9, 0.8, 0.7, 0.5]<br>lags = [91, 98, 105, 112, 180, 270, 365, 546, 728]<br><br>df = ewm_features(df, alphas, lags)<br>check_df(df)</pre><h3>One-Hot Encoding</h3><p>The code uses the pd.get_dummies function from the pandas library to perform one-hot encoding on several columns in the dataframe df. One-hot encoding is a common preprocessing step in machine learning, and it is used to convert categorical variables into numerical representations that can be used as input features for models.</p><p>The columns parameter of pd.get_dummies is used to specify which columns in the dataframe should be one-hot encoded. In this case, the store, item, day_of_week, and month columns are selected for one-hot encoding.</p><p>One-hot encoding creates a new binary column for each unique category in the specified columns. For example, if the store column has three unique categories, then three new columns will be created, one for each category, with a value of 1 or 0 indicating whether or not that category is present in the data.</p><p>The purpose of one-hot encoding is to allow categorical variables to be used as input features for machine learning models, which typically expect numerical inputs. By one-hot encoding the categorical variables, the information contained in the categories is transformed into a numerical representation that can be used by the models.</p><p>The check_df function is used to inspect the resulting dataframe to ensure that the one-hot encoding has been applied correctly. The exact purpose of this function is not clear from the code provided, but it may be used to check the shape, data types, or values in the dataframe.</p><pre>df = pd.get_dummies(df, columns=[&#39;store&#39;, &#39;item&#39;, &#39;day_of_week&#39;, &#39;month&#39;])<br>check_df(df)</pre><h3>Converting sales to log(1+sales)</h3><pre>df[&#39;sales&#39;] = np.log1p(df[&quot;sales&quot;].values)<br>check_df(df)</pre><p>The code above applies a log transformation to the sales data in the dataframe df. The log transformation is performed using the np.log1p function from the NumPy library, which calculates the logarithm of (1 + x) for an input array x.</p><p>The log transformation is a common preprocessing step for time series data, as it can help to stabilize the variance in the data and make it more suitable for modeling. By transforming the sales data into the log-space, the influence of large fluctuations in the sales data is reduced, and the relationships between the features and the target variable become clearer.</p><h3>Model</h3><pre># MAE: mean absolute error<br># MAPE: mean absolute percentage error<br># SMAPE: Symmetric mean absolute percentage error (adjusted MAPE)<br><br><br>def smape(preds, target):<br>    n = len(preds)<br>    masked_arr = ~((preds == 0) &amp; (target == 0))<br>    preds, target = preds[masked_arr], target[masked_arr]<br>    num = np.abs(preds - target)<br>    denom = np.abs(preds) + np.abs(target)<br>    smape_val = (200 * np.sum(num / denom)) / n<br>    return smape_val<br><br>def lgbm_smape(preds, train_data):<br>    labels = train_data.get_label()<br>    smape_val = smape(np.expm1(preds), np.expm1(labels))<br>    return &#39;SMAPE&#39;, smape_val, False</pre><p>The code above defines a custom metric for evaluating the performance of machine learning models, called the symmetric mean absolute percentage error (SMAPE). The SMAPE metric is used to measure the percentage error between predicted values and actual target values.</p><p>The smape function takes two arrays as input, preds and target, which represent the predicted values and actual target values, respectively. The function first checks for cases where both the predicted value and the target value are zero and masks these cases from further calculation.</p><p>Next, the absolute difference between the predicted and target values is calculated, and this is divided by the sum of the absolute values of the predicted and target values. The SMAPE value is calculated as the average of these ratios across all data points. The SMAPE value is expressed as a percentage, with a value of 0 indicating a perfect prediction and a value greater than 0 indicating an error.</p><p>The SMAPE metric is a symmetric metric, meaning that it treats over-prediction and under-prediction equally. This makes it useful for evaluating the performance of models on data that may have both positive and negative values, as well as for data with a skewed distribution, where one type of prediction error is more common than the other.</p><h3>Time-Based Validation Sets</h3><pre>train<br>test</pre><pre># Train set until the beginning of 2017 (until the end of 2016).<br>train = df.loc[(df[&quot;date&quot;] &lt; &quot;2017-01-01&quot;), :]<br># First 3 months of 2017 validation set.<br>val = df.loc[(df[&quot;date&quot;] &gt;= &quot;2017-01-01&quot;) &amp; (df[&quot;date&quot;] &lt; &quot;2017-04-01&quot;), :]</pre><pre>cols = [col for col in train.columns if col not in [&#39;date&#39;, &#39;id&#39;, &quot;sales&quot;, &quot;year&quot;]]<br><br>Y_train = train[&#39;sales&#39;]<br>X_train = train[cols]<br><br>Y_val = val[&#39;sales&#39;]<br>X_val = val[cols]<br><br>Y_train.shape, X_train.shape, Y_val.shape, X_val.shape</pre><pre>((730500,), (730500, 142), (45000,), (45000, 142))</pre><h3>Time Series Model with LightGBM</h3><pre># LightGBM parameters<br>lgb_params = {&#39;num_leaves&#39;: 10,<br>              &#39;learning_rate&#39;: 0.02,<br>              &#39;feature_fraction&#39;: 0.8,<br>              &#39;max_depth&#39;: 5,<br>              &#39;verbose&#39;: 0,<br>              &#39;num_boost_round&#39;: 1000,<br>              &#39;early_stopping_rounds&#39;: 200,<br>              &#39;nthread&#39;: -1}</pre><pre># metric mae: l1, absolute loss, mean_absolute_error, regression_l1<br># mse: l2, square loss, mean_squared_error, mse, regression_l2, regression<br># rmse, root square loss, root_mean_squared_error, l2_root<br># mape, MAPE loss, mean_absolute_percentage_error<br>lgbtrain = lgb.Dataset(data=X_train, label=Y_train, feature_name=cols)<br>lgbval = lgb.Dataset(data=X_val, label=Y_val, reference=lgbtrain, feature_name=cols)</pre><pre>model = lgb.train(lgb_params, lgbtrain,<br>                  valid_sets=[lgbtrain, lgbval],<br>                  num_boost_round=lgb_params[&#39;num_boost_round&#39;],<br>                  early_stopping_rounds=lgb_params[&#39;early_stopping_rounds&#39;],<br>                  feval=lgbm_smape,<br>                  verbose_eval=100)</pre><pre>[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.371499 seconds.<br>You can set `force_col_wise=true` to remove the overhead.<br>Training until validation scores don&#39;t improve for 200 rounds<br>[100]	training&#39;s l2: 0.0512913	training&#39;s SMAPE: 17.5863	valid_1&#39;s l2: 0.0529452	valid_1&#39;s SMAPE: 17.4429<br>[200]	training&#39;s l2: 0.0352035	training&#39;s SMAPE: 14.5662	valid_1&#39;s l2: 0.0369583	valid_1&#39;s SMAPE: 14.8761<br>[300]	training&#39;s l2: 0.0324151	training&#39;s SMAPE: 14.0096	valid_1&#39;s l2: 0.0341202	valid_1&#39;s SMAPE: 14.4213<br>[400]	training&#39;s l2: 0.0313431	training&#39;s SMAPE: 13.7968	valid_1&#39;s l2: 0.0332429	valid_1&#39;s SMAPE: 14.2604<br>[500]	training&#39;s l2: 0.0306813	training&#39;s SMAPE: 13.6622	valid_1&#39;s l2: 0.0326193	valid_1&#39;s SMAPE: 14.1237<br>[600]	training&#39;s l2: 0.0302368	training&#39;s SMAPE: 13.5684	valid_1&#39;s l2: 0.032161	valid_1&#39;s SMAPE: 14.0164<br>[700]	training&#39;s l2: 0.0298809	training&#39;s SMAPE: 13.4971	valid_1&#39;s l2: 0.031855	valid_1&#39;s SMAPE: 13.9461<br>[800]	training&#39;s l2: 0.0295966	training&#39;s SMAPE: 13.4403	valid_1&#39;s l2: 0.0316245	valid_1&#39;s SMAPE: 13.8914<br>[900]	training&#39;s l2: 0.0293529	training&#39;s SMAPE: 13.3908	valid_1&#39;s l2: 0.0314269	valid_1&#39;s SMAPE: 13.8454<br>[1000]	training&#39;s l2: 0.0291449	training&#39;s SMAPE: 13.3487	valid_1&#39;s l2: 0.031298	valid_1&#39;s SMAPE: 13.8149<br>Did not meet early stopping. Best iteration is:<br>[1000]	training&#39;s l2: 0.0291449	training&#39;s SMAPE: 13.3487	valid_1&#39;s l2: 0.031298	valid_1&#39;s SMAPE: 13.8149</pre><pre>y_pred_val = model.predict(X_val, num_iteration=model.best_iteration)<br>smape(np.expm1(y_pred_val), np.expm1(Y_val))</pre><pre>13.814874270278832</pre><h3>Feature Importance Levels</h3><pre>def plot_lgb_importances(model, plot=False, num=10):<br>    gain = model.feature_importance(&#39;gain&#39;)<br>    feat_imp = pd.DataFrame({&#39;feature&#39;: model.feature_name(),<br>                             &#39;split&#39;: model.feature_importance(&#39;split&#39;),<br>                             &#39;gain&#39;: 100 * gain / gain.sum()}).sort_values(&#39;gain&#39;, ascending=False)<br>    if plot:<br>        plt.figure(figsize=(10, 10))<br>        sns.set(font_scale=1)<br>        sns.barplot(x=&quot;gain&quot;, y=&quot;feature&quot;, data=feat_imp[0:25])<br>        plt.title(&#39;feature&#39;)<br>        plt.tight_layout()<br>        plt.show()<br>    else:<br>        print(feat_imp.head(num))<br>    return feat_imp<br><br>plot_lgb_importances(model, num=200)</pre><pre>                feature          split       gain<br>17          sales_roll_mean_546    936  54.465207<br>13                sales_lag_364   1271  13.219649<br>16          sales_roll_mean_365    606   9.754873<br>60   sales_ewm_alpha_05_lag_365    384   4.890732<br>18   sales_ewm_alpha_095_lag_91     81   2.518718<br>..                          ...    ...        ...<br>66                      store_4      0   0.000000<br>83                      item_11      0   0.000000<br>111                     item_39      0   0.000000<br>74                       item_2      0   0.000000<br>71                      store_9      0   0.000000<br><br>[142 rows x 3 columns]</pre><pre>plot_lgb_importances(model, num=30, plot=True)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/708/0*26_hFt7LBa2_uGBl.png" /></figure><pre>importance_zero = feat_imp[feat_imp[&quot;gain&quot;] == 0][&quot;feature&quot;].values<br>imp_feats = [col for col in cols if col not in importance_zero]<br>len(imp_feats)</pre><pre>110</pre><h3>Final Model</h3><pre>train = df.loc[~df.sales.isna()]<br>Y_train = train[&#39;sales&#39;]<br>X_train = train[cols]<br><br><br>test = df.loc[df.sales.isna()]<br>X_test = test[cols]</pre><pre>lgb_params = {&#39;num_leaves&#39;: 10,<br>              &#39;learning_rate&#39;: 0.02,<br>              &#39;feature_fraction&#39;: 0.8,<br>              &#39;max_depth&#39;: 5,<br>              &#39;verbose&#39;: 0,<br>              &#39;nthread&#39;: -1,<br>              &quot;num_boost_round&quot;: model.best_iteration}<br><br>lgbtrain_all = lgb.Dataset(data=X_train, label=Y_train, feature_name=cols)<br><br>final_model = lgb.train(lgb_params, lgbtrain_all, num_boost_round=model.best_iteration)<br><br><br>test_preds = final_model.predict(X_test, num_iteration=model.best_iteration)</pre><h3>Submission File</h3><p>Submissions are evaluated on <a href="https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error">SMAPE</a> between forecasts and actual values. We define SMAPE = 0 when the actual and predicted values are both 0.</p><pre>submission_df = test.loc[:, [&quot;id&quot;, &quot;sales&quot;]]<br>submission_df[&#39;sales&#39;] = np.expm1(test_preds)<br><br>submission_df[&#39;id&#39;] = submission_df.id.astype(int)<br><br>submission_df.to_csv(&quot;submission.csv&quot;, index=False)</pre><p>🔔 <strong><em>If you’d like to get in touch, you can find me on Linkedin, drop me an email or follow me</em></strong> 👇</p><ul><li><strong>Follow me:</strong> <a href="https://www.linkedin.com/in/eminebozkus/">LinkedIn</a> | <a href="https://www.kaggle.com/emineyetm">Kaggle</a> | <a href="https://github.com/bozkusemine">Github</a></li></ul><h3>References</h3><ol><li><a href="https://www.miuul.com/zaman-serileri">https://www.miuul.com/zaman-serileri</a></li><li><a href="https://github.com/AutoViML/AutoViz">https://github.com/AutoViML/AutoViz</a></li><li><a href="https://www.kaggle.com/code/emineyetm/using-machine-learning-for-time-series-forecasting">https://www.kaggle.com/code/emineyetm/using-machine-learning-for-time-series-forecasting</a></li></ol><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=db94e523d42a" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/using-machine-learning-for-time-series-forecasting-db94e523d42a">Using Machine Learning for Time Series Forecasting</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Time Series Forecasting with Statistical Models]]></title>
            <link>https://medium.datadriveninvestor.com/time-series-forecasting-with-statistical-models-b9a266669dbf?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/b9a266669dbf</guid>
            <category><![CDATA[time-series-forecasting]]></category>
            <category><![CDATA[statistical-analysis]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[time-series-analysis]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Tue, 07 Feb 2023 12:22:07 GMT</pubDate>
            <atom:updated>2023-02-10T02:20:24.927Z</atom:updated>
            <content:encoded><![CDATA[<p>Time series forecasting refers to the process of predicting future values of a time-dependent variable based on past observations. It is widely used in various industries, such as finance, economics, and weather forecasting, to make informed decisions and improve overall planning and strategy.</p><p>Statistical models are one of the most common approaches used in time series forecasting. These models are mathematical representations of the underlying relationships between the variables in a time series and are used to make predictions about future values. There are several types of statistical models that can be used for time series forecasting, including:</p><p><strong>1.Autoregressive (AR) Model:</strong> The autoregressive model is another common method for time series forecasting. It is based on the assumption that the future value of a time series is a linear combination of past values and a white noise error term. The number of past values used in the calculation is referred to as the “order” of the model. The larger the order, the more information is used in the prediction, but the more complicated the model becomes.</p><p><strong>2.Moving Average (MA) Model:</strong> The moving average model is a simple and straightforward method for forecasting time series data. It involves calculating the average of a set of past observations and using that average as the prediction for future values. The number of past observations used in the calculation is referred to as the “window size”. The larger the window size, the smoother the forecast, but the less responsive it will be to changes in the underlying trends.</p><p><strong>3.ARMA (Auto-Regressive Moving Average):</strong> The ARMA is one of the most commonly used methods to model univariate time series. ARMA(p,q) combines two components: AR(p), and MA(q).</p><p><strong>4.Autoregressive Integrated Moving Average (ARIMA) Model:</strong> The autoregressive integrated moving average (ARIMA) model combines the moving average and autoregressive models to produce a more sophisticated time series forecasting method. It can handle both linear and non-linear relationships between the variables in a time series, making it a powerful tool for time series analysis. The order of the autoregression and moving average components of the model, as well as the order of integration, are parameters that must be specified in order to fit the model to the data</p><pre># autoregressive: p<br># integrated: d<br># moving average: q<br># order: (p, d, q)  # p: AR, d: I, q: MA</pre><p><strong>5. Seasonal Autoregressive Integrated Moving Average (SARIMA) Model:</strong> The seasonal autoregressive integrated moving average (SARIMA) model is an extension of the ARIMA model that takes into account seasonality in the data. Seasonality refers to patterns in the data that repeat at regular intervals, such as daily, weekly, or yearly patterns. The SARIMA model adds an additional set of parameters that capture the seasonal patterns in the data, allowing for more accurate forecasting of time series with strong seasonality.</p><p>Let’s practice in python.</p><h3>Import Libraries &amp; Load Data</h3><pre>import numpy as np<br>import pandas as pd<br>import itertools<br>import matplotlib.pyplot as plt<br>import statsmodels.api as sm<br>from sklearn.metrics import mean_absolute_error<br><br>from statsmodels.tsa.api import SARIMAX             # SARIMA: Seasonal Autoregressive Integrated Moving Average<br>from statsmodels.tsa.arima.model import ARIMA       # ARIMA: Autoregressive Integrated Moving Average<br><br>import warnings          # warnings: to avoid seeing error messages<br>warnings.filterwarnings(&#39;ignore&#39;)</pre><ul><li>Atmospheric CO2 from Continuous Air Samples at Mauna Loa Observatory, Hawaii, U.S.A.</li><li><strong>Period of Record:</strong> March 1958 — December 2001</li></ul><pre>data = sm.datasets.co2.load_pandas()    # loads the CO2 dataset into a pandas DataFrame object, which is stored in the data variable.<br>y = data.data           # accesses the data in the loaded CO2 dataset<br>y = y[&#39;co2&#39;].resample(&#39;MS&#39;).mean()<br>y = y.fillna(y.bfill())<br>train = y[:&#39;1997-12-01&#39;]<br>test = y[&#39;1998-01-01&#39;:]</pre><ul><li>y = y[‘co2’].resample(‘MS’).mean() resamples the CO2 data to obtain the mean value for each month. The argument ‘MS’ stands for “month start”, and indicates that the data should be resampled to obtain the mean value for each month, starting at the beginning of the month.</li><li>y = y.fillna(y.bfill()) fills any missing values in the data with the values from the previous observation. The method bfill() stands for “backward fill”, which means that the missing values are filled with the values from the previous observation.</li><li>train = y[:’1997–12–01&#39;] and test = y[‘1998–01–01’:] split the resampled and cleaned CO2 data into two separate datasets: the training dataset and the test dataset. The training dataset consists of all the data up to and including December 1st, 1997, while the test dataset consists of all the data starting from January 1st, 1998. The training dataset is used to fit the time series model, while the test dataset is used to evaluate the performance of the model.</li></ul><pre>train.head()</pre><pre>1958-03-01    316.100000<br>1958-04-01    317.200000<br>1958-05-01    317.433333<br>1958-06-01    315.625000<br>1958-07-01    315.625000<br>Freq: MS, Name: co2, dtype: float64</pre><h3>ARIMA(Autoregressive Integrated Moving Average)</h3><p>The order of the ARIMA model is specified as (p, d, q), and the model is fit to the time series data to make predictions about future values based on the historical patterns in the data.</p><ul><li>autoregressive: p</li><li>integrated: d</li><li>moving average: q</li><li>order: (p, d, q) # p: AR, d: I, q: MA</li></ul><pre>arima_model = ARIMA(train, order=(1, 1, 1)).fit()<br>arima_model.summary()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/964/1*XifCEm1oaGBHd8_y7YI6Eg.png" /></figure><ul><li>Dep. Variable: The dependent variable that the model is trying to predict. In this case, it is &quot;co2&quot;.</li><li>No. Observations: The number of observations in the data used to fit the model.</li><li>Model: The type of ARIMA model fit, including the parameters used. In this case, the model is ARIMA(1, 1, 1), meaning it has 1 autoregressive term, 1 degree of differencing, and 1 moving average component.</li><li>Log Likelihood: The log-likelihood of the model, which is a measure of how well the model fits the data.</li><li>Date and Time: The date and time when the model was fit.</li><li>Sample: The range of the sample data used to fit the model.</li><li>AIC (Akaike Information Criteria): A measure of the relative quality of the model fit, taking into account both the goodness of fit and the number of parameters used. A lower AIC value indicates a better model fit.</li><li>BIC (Bayesian Information Criteria): Similar to AIC, but with a stronger penalty for the number of parameters used.</li><li>HQIC (Hannan-Quinn Information Criteria): Similar to AIC and BIC, but with a different weighting between goodness of fit and complexity.</li><li>Covariance Type: The type of covariance matrix used to estimate the parameters in the model. In this case, it is &quot;opg&quot;, which stands for &quot;outer product of the gradients&quot;.</li><li>coef: The coefficient of each term in the model.</li><li>std err: The standard error of the coefficient estimate.</li><li>z: The z-score for each coefficient, which measures the number of standard deviations the coefficient is from zero.</li><li>P&gt;|z|: The p-value for each coefficient, which measures the probability of observing a coefficient as extreme as the one estimated, given that the true coefficient is zero.</li><li>[0.025 0.975]: The 95% confidence interval for each coefficient, which provides an interval estimate of the true value of the coefficient.</li></ul><p>From these results, we can see that both the autoregressive term ar.L1 and the moving average term ma.L1 are significant, as indicated by the low p-values and the z-scores that are far from zero. The confidence intervals for these coefficients also do not contain zero, which further supports their significance. The sigma2 term is the variance of the residuals (the differences between the observed values and the values predicted by the model) and its low p-value and significant z-score also support the validity of the model fit.</p><ul><li>Ljung-Box (L1) (Q): The value of the Ljung-Box test for residual autocorrelation, with L1 indicating that the test is performed at lag 1. The test statistic measures whether the residuals are independently distributed, with a low value indicating that the residuals are independent.</li><li>Prob(Q): The p-value of the Ljung-Box test, which measures the probability of observing the test statistic as extreme as the one estimated, given that the residuals are independently distributed.</li><li>Jarque-Bera (JB): The value of the Jarque-Bera test, which tests the residuals for normality. A low value indicates that the residuals are close to normally distributed.</li><li>Prob(JB): The p-value of the Jarque-Bera test, which measures the probability of observing the test statistic as extreme as the one estimated, given that the residuals are normally distributed.</li><li>Heteroskedasticity (H): The value of the Breusch-Pagan test, which tests the residuals for heteroskedasticity (unequal variance). A low value indicates that the residuals have equal variance.</li><li>Prob(H) (two-sided): The p-value of the Breusch-Pagan test, which measures the probability of observing the test statistic as extreme as the one estimated, given that the residuals have equal variance.</li><li>Skew: The skewness of the residuals, which measures the degree of asymmetry in the residual distribution. A value close to zero indicates a symmetric distribution.</li><li>Kurtosis: The kurtosis of the residuals, which measures the &quot;peakedness&quot; of the residual distribution. A value close to 3 indicates a normal distribution.</li></ul><p>In summary, these results suggest that the ARIMA(1, 1, 1) model is a good fit for the “co2” time series data, with both the autoregressive and moving average terms having significant impact on the predictions.</p><pre>y_pred = arima_model.forecast(48)[0]       # 48: timeframe to estimate (size of test set) #0: predicted value 1.index<br>y_pred</pre><pre>365.5586389302753</pre><pre># visualization function expects input in form of pandas series or dataframe. For that we need to change it.<br>y_pred = pd.Series(y_pred, index=test.index)</pre><pre>def plot_co2(train, test, y_pred, title):<br>    mae = mean_absolute_error(test, y_pred)<br>    train[&quot;1985&quot;:].plot(legend=True, label=&quot;TRAIN&quot;, title=f&quot;{title}, MAE: {round(mae,2)}&quot;)<br>    test.plot(legend=True, label=&quot;TEST&quot;, figsize=(6, 4))<br>    y_pred.plot(legend=True, label=&quot;PREDICTION&quot;)<br>    plt.show()<br><br>plot_co2(train, test, y_pred, &quot;ARIMA&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*rLqk3t1KAcr9dpoe.png" /></figure><h3>SARIMA(Seasonal Autoregressive Integrated Moving-Average):</h3><p>SARIMA stands for Seasonal-ARIMA and it includes seasonality contribution to the forecast. The importance of seasonality is quite evident and ARIMA fails to encapsulate that information implicitly.</p><p>The Autoregressive (AR), Integrated (I), and Moving Average (MA) parts of the model remain as that of ARIMA. The addition of Seasonality adds robustness to the SARIMA model. It’s represented as:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/425/1*QBGZKLesH8h1s8Rnw8lgxQ.png" /></figure><ul><li>order = (p, d, q) They are trend components from ARIMA.</li><li>seasonal_order = (P, D, Q, m) They are seasonal components of SARIMA.</li></ul><pre>model = SARIMAX(train, order=(1, 0, 1), seasonal_order=(0, 0, 0, 12))<br><br>sarima_model = model.fit(disp=0)<br>sarima_model.summary()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/912/1*9TFZ3ZPnKOmIqQWmryl6UQ.png" /></figure><pre>y_pred_test = sarima_model.get_forecast(steps=48)   # get_forecast: timeframe to be estimated<br>y_pred_test.predicted_mean</pre><pre>y_pred = y_pred_test.predicted_mean<br>y_pred = pd.Series(y_pred, index=test.index)<br>plot_co2(train, test, y_pred, &quot;SARIMA&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*3vTrMGgmIeBLw_Pt.png" /></figure><h3>Hyperparameter Optimization (Determining Model Degrees)</h3><p>The function sarima_optimizer_mae takes in the training time series data (train), along with grid search parameters for SARIMA models, pdq and seasonal_pdq. The function iterates over all possible combinations of pdq and seasonal_pdq parameters to fit SARIMA models. For each model, it generates predictions using the get_forecast method and calculates the mean absolute error (MAE) between the predictions and the test set. The function keeps track of the SARIMA model with the lowest MAE and returns the corresponding parameters as the best SARIMA model. Finally, the best SARIMA model is fit on the training set and predictions are generated for the test set. The predictions and actual test set values are then plotted using the plot_co2 function.</p><pre>p = d = q = range(0, 2)<br>pdq = list(itertools.product(p, d, q))<br>seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]<br><br><br>def sarima_optimizer_aic(train, pdq, seasonal_pdq):<br>    best_aic, best_order, best_seasonal_order = float(&quot;inf&quot;), None, None<br>    for param in pdq:<br>        for param_seasonal in seasonal_pdq:<br>            try:<br>                sarimax_model = SARIMAX(train, order=param, seasonal_order=param_seasonal)<br>                results = sarimax_model.fit(disp=0)<br>                aic = results.aic<br>                if aic &lt; best_aic:<br>                    best_aic, best_order, best_seasonal_order = aic, param, param_seasonal<br>                print(&#39;SARIMA{}x{}12 - AIC:{}&#39;.format(param, param_seasonal, aic))<br>            except:<br>                continue<br>    print(&#39;SARIMA{}x{}12 - AIC:{}&#39;.format(best_order, best_seasonal_order, best_aic))<br>    return best_order, best_seasonal_order<br><br>best_order, best_seasonal_order = sarima_optimizer_aic(train, pdq, seasonal_pdq)</pre><pre>SARIMA(0, 0, 0)x(0, 0, 0, 12)12 - AIC:6922.606550808509<br>SARIMA(0, 0, 0)x(0, 0, 1, 12)12 - AIC:6318.305219679214<br>SARIMA(0, 0, 0)x(0, 1, 0, 12)12 - AIC:1643.9996657880379<br>SARIMA(0, 0, 0)x(0, 1, 1, 12)12 - AIC:1428.2938925348508<br>SARIMA(0, 0, 0)x(1, 0, 0, 12)12 - AIC:1820.7236583825966<br>SARIMA(0, 0, 0)x(1, 0, 1, 12)12 - AIC:1653.729484027914<br>SARIMA(0, 0, 0)x(1, 1, 0, 12)12 - AIC:1205.025400971046<br>SARIMA(0, 0, 0)x(1, 1, 1, 12)12 - AIC:973.207727675453<br>SARIMA(0, 0, 1)x(0, 0, 0, 12)12 - AIC:6269.190364756832<br>SARIMA(0, 0, 1)x(0, 0, 1, 12)12 - AIC:5663.567928540047<br>SARIMA(0, 0, 1)x(0, 1, 0, 12)12 - AIC:1229.8447516025176<br>SARIMA(0, 0, 1)x(0, 1, 1, 12)12 - AIC:1126.5843176793833<br>SARIMA(0, 0, 1)x(1, 0, 0, 12)12 - AIC:1473.0898881947135<br>SARIMA(0, 0, 1)x(1, 0, 1, 12)12 - AIC:1414.49020595465<br>SARIMA(0, 0, 1)x(1, 1, 0, 12)12 - AIC:1008.160268516428<br>SARIMA(0, 0, 1)x(1, 1, 1, 12)12 - AIC:767.6332844686492<br>SARIMA(0, 1, 0)x(0, 0, 0, 12)12 - AIC:1523.9134546907358<br>SARIMA(0, 1, 0)x(0, 0, 1, 12)12 - AIC:1154.743619904219<br>SARIMA(0, 1, 0)x(0, 1, 0, 12)12 - AIC:585.8949540598103<br>SARIMA(0, 1, 0)x(0, 1, 1, 12)12 - AIC:371.57825689147813<br>SARIMA(0, 1, 0)x(1, 0, 0, 12)12 - AIC:608.9685497853327<br>SARIMA(0, 1, 0)x(1, 0, 1, 12)12 - AIC:410.71468501006075<br>SARIMA(0, 1, 0)x(1, 1, 0, 12)12 - AIC:495.3771447981145<br>SARIMA(0, 1, 0)x(1, 1, 1, 12)12 - AIC:373.1539006474194<br>SARIMA(0, 1, 1)x(0, 0, 0, 12)12 - AIC:1254.7914169695318<br>SARIMA(0, 1, 1)x(0, 0, 1, 12)12 - AIC:1039.3952573257652<br>SARIMA(0, 1, 1)x(0, 1, 0, 12)12 - AIC:543.1399633696033<br>SARIMA(0, 1, 1)x(0, 1, 1, 12)12 - AIC:393.8943760680236<br>SARIMA(0, 1, 1)x(1, 0, 0, 12)12 - AIC:579.922934531628<br>SARIMA(0, 1, 1)x(1, 0, 1, 12)12 - AIC:383.09871119803915<br>SARIMA(0, 1, 1)x(1, 1, 0, 12)12 - AIC:452.11811365175356<br>SARIMA(0, 1, 1)x(1, 1, 1, 12)12 - AIC:339.1641111208867<br>SARIMA(1, 0, 0)x(0, 0, 0, 12)12 - AIC:1540.4140252670818<br>SARIMA(1, 0, 0)x(0, 0, 1, 12)12 - AIC:1171.2466461793142<br>SARIMA(1, 0, 0)x(0, 1, 0, 12)12 - AIC:579.208370937031<br>SARIMA(1, 0, 0)x(0, 1, 1, 12)12 - AIC:376.830651073989<br>SARIMA(1, 0, 0)x(1, 0, 0, 12)12 - AIC:625.4609723210033<br>SARIMA(1, 0, 0)x(1, 0, 1, 12)12 - AIC:426.6332821688898<br>SARIMA(1, 0, 0)x(1, 1, 0, 12)12 - AIC:495.7546159387019<br>SARIMA(1, 0, 0)x(1, 1, 1, 12)12 - AIC:378.4090442279553<br>SARIMA(1, 0, 1)x(0, 0, 0, 12)12 - AIC:1271.2934125926395<br>SARIMA(1, 0, 1)x(0, 0, 1, 12)12 - AIC:1055.8968573894322<br>SARIMA(1, 0, 1)x(0, 1, 0, 12)12 - AIC:544.036979839994<br>SARIMA(1, 0, 1)x(0, 1, 1, 12)12 - AIC:342.59441296560226<br>SARIMA(1, 0, 1)x(1, 0, 0, 12)12 - AIC:596.6333264561456<br>SARIMA(1, 0, 1)x(1, 0, 1, 12)12 - AIC:400.17578732713<br>SARIMA(1, 0, 1)x(1, 1, 0, 12)12 - AIC:455.6579852467138<br>SARIMA(1, 0, 1)x(1, 1, 1, 12)12 - AIC:344.40946539807214<br>SARIMA(1, 1, 0)x(0, 0, 0, 12)12 - AIC:1207.7849901797972<br>SARIMA(1, 1, 0)x(0, 0, 1, 12)12 - AIC:1004.4872257540137<br>SARIMA(1, 1, 0)x(0, 1, 0, 12)12 - AIC:556.2117153544921<br>SARIMA(1, 1, 0)x(0, 1, 1, 12)12 - AIC:347.6673054338916<br>SARIMA(1, 1, 0)x(1, 0, 0, 12)12 - AIC:588.1986879134922<br>SARIMA(1, 1, 0)x(1, 0, 1, 12)12 - AIC:390.8372874271904<br>SARIMA(1, 1, 0)x(1, 1, 0, 12)12 - AIC:463.3371366789647<br>SARIMA(1, 1, 0)x(1, 1, 1, 12)12 - AIC:349.441132479151<br>SARIMA(1, 1, 1)x(0, 0, 0, 12)12 - AIC:1157.5365027891548<br>SARIMA(1, 1, 1)x(0, 0, 1, 12)12 - AIC:999.6119471633762<br>SARIMA(1, 1, 1)x(0, 1, 0, 12)12 - AIC:531.0882141113823<br>SARIMA(1, 1, 1)x(0, 1, 1, 12)12 - AIC:323.3128816560523<br>SARIMA(1, 1, 1)x(1, 0, 0, 12)12 - AIC:560.3099483839314<br>SARIMA(1, 1, 1)x(1, 0, 1, 12)12 - AIC:367.09243865603963<br>SARIMA(1, 1, 1)x(1, 1, 0, 12)12 - AIC:442.4874503875827<br>SARIMA(1, 1, 1)x(1, 1, 1, 12)12 - AIC:324.9964687919045<br>SARIMA(1, 1, 1)x(0, 1, 1, 12)12 - AIC:323.3128816560523</pre><h3>Final Model</h3><pre>model = SARIMAX(train, order=best_order, seasonal_order=best_seasonal_order)<br>sarima_final_model = model.fit(disp=0)<br>y_pred_test = sarima_final_model.get_forecast(steps=48)</pre><pre>y_pred = y_pred_test.predicted_mean<br>y_pred = pd.Series(y_pred, index=test.index)<br>plot_co2(train, test, y_pred, &quot;SARIMA&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*K4EWctTmV9_9iPWg.png" /></figure><h3>SARIMA Optimization by MAE</h3><pre>p = d = q = range(0, 2)<br>pdq = list(itertools.product(p, d, q))<br>seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]<br><br><br>def sarima_optimizer_mae(train, pdq, seasonal_pdq):<br>    best_mae, best_order, best_seasonal_order = float(&quot;inf&quot;), None, None<br>    for param in pdq:<br>        for param_seasonal in seasonal_pdq:<br>            try:<br>                model = SARIMAX(train, order=param, seasonal_order=param_seasonal)<br>                sarima_model = model.fit(disp=0)<br>                y_pred_test = sarima_model.get_forecast(steps=48)<br>                y_pred = y_pred_test.predicted_mean<br>                mae = mean_absolute_error(test, y_pred)<br>                if mae &lt; best_mae:<br>                    best_mae, best_order, best_seasonal_order = mae, param, param_seasonal<br>                print(&#39;SARIMA{}x{}12 - MAE:{}&#39;.format(param, param_seasonal, mae))<br>            except:<br>                continue<br>    print(&#39;SARIMA{}x{}12 - MAE:{}&#39;.format(best_order, best_seasonal_order, best_mae))<br>    return best_order, best_seasonal_order<br><br>best_order, best_seasonal_order = sarima_optimizer_mae(train, pdq, seasonal_pdq)<br><br>model = SARIMAX(train, order=best_order, seasonal_order=best_seasonal_order)<br>sarima_final_model = model.fit(disp=0)<br><br>y_pred_test = sarima_final_model.get_forecast(steps=48)<br>y_pred = y_pred_test.predicted_mean<br>y_pred = pd.Series(y_pred, index=test.index)</pre><pre>plot_co2(train, test, y_pred, &quot;SARIMA&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*GRcgLs-zoCZ-NdnP.png" /></figure><pre>model = SARIMAX(train, order=best_order, seasonal_order=best_seasonal_order)<br>sarima_final_model = model.fit(disp=0)<br><br>y_pred_test = sarima_final_model.get_forecast(steps=48)<br><br># MAE<br>y_pred = y_pred_test.predicted_mean<br>y_pred = pd.Series(y_pred, index=test.index)<br><br>plot_co2(train, test, y_pred, &quot;SARIMA&quot;)<br>plt.style.use(&#39;ggplot&#39;)<br>sarima_final_model.plot_diagnostics(figsize=(15, 10))<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*HekwB4cwRlovJsZP.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/0*zvGn-qOTMsYLICZJ.png" /></figure><ul><li>Histogram plus estimated density plot: The red KDE line follows closely with the N(0,1) line. This is a good indication that the residuals are normally distributed.</li><li>The Q-Q-plot: Shows that the ordered distribution of residuals (blue dots) follows the linear trend of the samples taken from a standard normal distribution with N(0, 1). This is an indication that the residuals are normally distributed.</li><li>The standardize residual plot: The residuals over time don’t display any obvious seasonality and appear to be white noise.</li><li>The Correlogram plot: Shows that the time series residuals have low correlation with lagged versions of itself.</li></ul><h3>Conclusion</h3><p>In conclusion, time series forecasting with statistical models can be a powerful tool for making predictions about future events based on historical data. This notebook has shown how different statistical models such as ARIMA and SARIMA can be applied to time series data to make accurate forecasts. The results of the analysis demonstrate that while these models have their limitations, they can provide meaningful insights and predictions when used correctly. The appropriate choice of model will depend on the specific requirements of the problem, such as the nature of the underlying data, the size of the time series, and the desired level of accuracy. It is important to carefully consider these factors and experiment with different models to find the best solution for each specific use case.</p><p>🔔 <strong><em>If you’d like to get in touch, you can find me on Linkedin, drop me an email or follow me</em></strong> 👇</p><ul><li><strong>Follow me:</strong> <a href="https://www.linkedin.com/in/eminebozkus/">LinkedIn</a> | <a href="https://www.kaggle.com/emineyetm">Kaggle</a> | <a href="https://github.com/bozkusemine">Github</a></li></ul><h3>References</h3><ol><li><a href="https://www.kaggle.com/code/emineyetm/time-series-forecasting-with-statistical-models">https://www.kaggle.com/code/emineyetm/time-series-forecasting-with-statistical-models</a></li><li><a href="https://www.miuul.com/zaman-serileri">https://www.miuul.com/zaman-serileri</a></li></ol><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b9a266669dbf" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/time-series-forecasting-with-statistical-models-b9a266669dbf">Time Series Forecasting with Statistical Models</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Exponential Smoothing Techniques for Time Series Forecasting in Python: A Guide]]></title>
            <link>https://medium.datadriveninvestor.com/exponential-smoothing-techniques-for-time-series-forecasting-in-python-a-guide-bc38f216f6e4?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc38f216f6e4</guid>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[forecasting]]></category>
            <category><![CDATA[smoothing]]></category>
            <category><![CDATA[time-series-analysis]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Sun, 05 Feb 2023 08:42:36 GMT</pubDate>
            <atom:updated>2023-02-06T02:55:30.457Z</atom:updated>
            <content:encoded><![CDATA[<p>Time series forecasting is the process of using historical data to predict future values of a time-dependent variable. This type of forecasting is based on the idea that past behavior and trends in the data can be used to make educated guesses about future values.</p><p>Many disciplines, such as finance, public administration, energy, retail, and healthcare, are dominated by time-series data. Large areas of micro- and macroeconomics rely on applied statistics with an emphasis on time-series analyses and modeling. The following are examples of time-series data:</p><ul><li>Daily closing values of a stock index</li><li>Number of weekly infections of a disease</li><li>Weekly series of train accidents</li><li>Rainfall per day</li><li>Sensor data such as temperature measurements per hour</li><li>Population growth per year</li><li>Quarterly earnings of a company over a number of years</li></ul><h4>Import Libraries</h4><pre>import itertools    # for grid search<br>import matplotlib.pyplot as plt  # for plotting graphs<br>import numpy as np         # for mathematical calculations<br>import pandas as pd     # for data manipulation<br>import statsmodels.api as sm        # for statistical models<br>from sklearn.metrics import mean_absolute_error # for evaluating models<br>from statsmodels.tsa.holtwinters import ExponentialSmoothing        # for Holt-Winters Exponential Smoothing<br>from statsmodels.tsa.holtwinters import SimpleExpSmoothing      # for Simple Exponential Smoothing<br>from statsmodels.tsa.seasonal import seasonal_decompose     # for seasonal decomposition<br>import statsmodels.tsa.api as smt       # for statistical tests<br>import warnings     # for ignoring warnings<br>warnings.filterwarnings(&#39;ignore&#39;)</pre><pre>data = sm.datasets.co2.load_pandas()        # 1958-03-01 - 2001-12-01<br>y = data.data                         # 1958-03-01 - 2001-12-01<br>y = y[&#39;co2&#39;].resample(&#39;MS&#39;).mean()  # Monthly Mean</pre><p>This code loads the CO2 data from the statsmodels library, and then selects the &quot;co2&quot; column of the data, which represents the CO2 concentration measurements. The resample method is then used to resample the data to a monthly frequency, taking the mean value for each month. This results in a new time series with the average CO2 concentration for each month.</p><pre>y.isnull().sum()  #5<br>y = y.fillna(y.bfill())     # Backward Fill</pre><pre>y.describe()</pre><pre>count    526.000000<br>mean     339.624826<br>std       17.110954<br>min      313.400000<br>25%      324.025000<br>50%      337.912500<br>75%      354.537500<br>max      373.800000<br>Name: co2, dtype: float64</pre><pre>y.plot(figsize=(15, 6))<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/877/0*95hHQeOZ5qaMDhYg.png" /></figure><h4>Holdout</h4><p>“Holdout” is a commonly used method in machine learning for evaluating the performance of a model. It involves dividing the data into two parts: a training set and a testing set. The model is trained on the training set, and then the performance is evaluated on the testing set. The holdout method is used to estimate the performance of the model on unseen data, as the testing set is held out from the training process and used only for evaluation.</p><pre>train = y[:&#39;1997-12-01&#39;]        # 1958-03-01 - 1997-12-01<br>len(train)    #478</pre><pre>test = y[&#39;1998-01-01&#39;:]     # 1998-01-01 - 2001-12-01<br>len(test)    #48</pre><h3>Time Series Structural Analysis</h3><p><strong>Dickey-Fuller Test</strong></p><pre>def is_stationary(y):<br><br>    # &quot;HO: Non-stationary&quot;<br>    # &quot;H1: Stationary&quot;<br><br>    p_value = sm.tsa.stattools.adfuller(y)[1]<br>    if p_value &lt; 0.05:<br>        print(F&quot;Result: Stationary (H0: non-stationary, p-value: {round(p_value, 3)})&quot;)<br>    else:<br>        print(F&quot;Result: Non-Stationary (H0: non-stationary, p-value: {round(p_value, 3)})&quot;)<br><br>is_stationary(y)</pre><p>This code defines a function is_stationary which takes in a time series y as input. The function performs the Augmented Dickey-Fuller test to test the null hypothesis that the time series is non-stationary.</p><p>The p-value of the test is obtained using the adfuller function from the stattools module of statsmodels. If the p-value is less than 0.05, it suggests that the null hypothesis can be rejected, and the time series is stationary. In this case, the function prints &quot;Result: Stationary&quot;. If the p-value is greater than 0.05, it suggests that the null hypothesis cannot be rejected, and the time series is non-stationary. In this case, the function prints &quot;Result: Non-Stationary&quot;.</p><pre>Result: Non-Stationary (H0: non-stationary, p-value: 0.999)</pre><p><strong>Time Series Components and Stationarity Test</strong></p><pre>def ts_decompose(y, model=&quot;additive&quot;, stationary=False):<br>    result = seasonal_decompose(y, model=model)<br>    fig, axes = plt.subplots(4, 1, sharex=True, sharey=False)<br>    fig.set_figheight(10)<br>    fig.set_figwidth(15)<br><br>    axes[0].set_title(&quot;Decomposition for &quot; + model + &quot; model&quot;)<br>    axes[0].plot(y, &#39;k&#39;, label=&#39;Original &#39; + model)<br>    axes[0].legend(loc=&#39;upper left&#39;)<br><br>    axes[1].plot(result.trend, label=&#39;Trend&#39;)<br>    axes[1].legend(loc=&#39;upper left&#39;)<br><br>    axes[2].plot(result.seasonal, &#39;g&#39;, label=&#39;Seasonality &amp; Mean: &#39; + str(round(result.seasonal.mean(), 4)))<br>    axes[2].legend(loc=&#39;upper left&#39;)<br><br>    axes[3].plot(result.resid, &#39;r&#39;, label=&#39;Residuals &amp; Mean: &#39; + str(round(result.resid.mean(), 4)))<br>    axes[3].legend(loc=&#39;upper left&#39;)<br>    plt.show(block=True)<br><br>    if stationary:<br>        is_stationary(y)<br><br>ts_decompose(y, stationary=True)</pre><p>This code defines a function ts_decompose that takes in a time series y and optional parameters model and stationary. The function performs a time series decomposition on y using the seasonal_decompose function from the statsmodels library, with the specified decomposition model (either &quot;additive&quot; or &quot;multiplicative&quot;).</p><p>The function then creates a plot with 4 subplots to visualize the original time series, the trend, the seasonal component, and the residuals. The plot title and labels are set to reflect the specified decomposition model.</p><p>If the stationary parameter is True, the function calls the is_stationary function to test the stationarity of the original time series.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/877/0*2z-eAxwPCDl0eTD5.png" /></figure><pre>Result: Non-Stationary (H0: non-stationary, p-value: 0.999)</pre><h3>1. Single Exponential Smoothing</h3><pre>ses_model = SimpleExpSmoothing(train).fit(smoothing_level=0.5)<br><br>y_pred = ses_model.forecast(48)<br><br>mean_absolute_error(test, y_pred)</pre><p>This code fits a simple exponential smoothing (SES) model to the time series data in train. The SimpleExpSmoothing class from the statsmodels library is used to fit the model. The fit method is used to fit the model to the data, with a smoothing level of 0.5.</p><p>The model is then used to make 48-step ahead forecasts for the time series data in test. The forecasts are stored in the y_pred variable.</p><p>Finally, the function mean_absolute_error from the statsmodels library is used to calculate the mean absolute error (MAE) between the actual test data and the predicted values y_pred. The MAE is a measure of the average magnitude of the errors between the actual and predicted values. Lower values of MAE indicate better fit of the model to the data.</p><pre>5.706393369643809</pre><pre>train.plot(title=&quot;Single Exponential Smoothing&quot;)<br>test.plot()<br>y_pred.plot()<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*qTTKIuurw3MEJexV.png" /></figure><pre>train[&quot;1985&quot;:].plot(title=&quot;Single Exponential Smoothing&quot;)<br>test.plot()<br>y_pred.plot()<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*kCpCgXWJKTVyAPxX.png" /></figure><pre>def plot_co2(train, test, y_pred, title):<br>    mae = mean_absolute_error(test, y_pred)<br>    train[&quot;1985&quot;:].plot(legend=True, label=&quot;TRAIN&quot;, title=f&quot;{title}, MAE: {round(mae,2)}&quot;)<br>    test.plot(legend=True, label=&quot;TEST&quot;, figsize=(6, 4))<br>    y_pred.plot(legend=True, label=&quot;PREDICTION&quot;)<br>    plt.show()<br><br>plot_co2(train, test, y_pred, &quot;Single Exponential Smoothing&quot;)</pre><p>This code defines a function plot_co2 which plots the original time series data in train and test, and the predicted values in y_pred. The function also calculates the mean absolute error (MAE) between the actual test values and the predicted values y_pred, using the mean_absolute_error function from the statsmodels library. The MAE is then displayed in the plot title along with the title argument.</p><p>The function uses the plot method from the pandas library to plot the time series data. The legend parameter is set to True to display a legend in the plot, and the label parameter is used to specify the labels for each time series data. The figsize parameter is used to specify the size of the plot.</p><p>The function can be used to plot the results of any time series forecasting model, by passing in the relevant train, test, and y_pred arguments.</p><pre>ses_model.params</pre><pre>{&#39;smoothing_level&#39;: 0.5,<br> &#39;smoothing_trend&#39;: nan,<br> &#39;smoothing_seasonal&#39;: nan,<br> &#39;damping_trend&#39;: nan,<br> &#39;initial_level&#39;: 316.4419309772571,<br> &#39;initial_trend&#39;: nan,<br> &#39;initial_seasons&#39;: array([], dtype=float64),<br> &#39;use_boxcox&#39;: False,<br> &#39;lamda&#39;: None,<br> &#39;remove_bias&#39;: False}</pre><h3>2. Double Exponential Smoothing (DES)</h3><p>Double Exponential Smoothing, also known as Holt’s method, is a time series forecasting technique that extends simple exponential smoothing by adding a trend component to the forecast model. It is used to handle time series data with a trend, such as sales data with an upward or downward trend over time. The method models the data as a combination of a level and a trend component. The level component captures the average value of the data, and the trend component captures changes in the level over time.</p><p>The method uses a weighted average of the past values and the trend to make predictions for future time steps. The weighting factors are determined by two smoothing parameters, alpha and beta, which control the weight given to the past values and the trend, respectively. The method can be implemented in a variety of ways, including simple exponential smoothing with a trend, and Holt-Winters with a seasonal period of 1.</p><pre><br>ts_decompose(y)<br><br>des_model = ExponentialSmoothing(train, trend=&quot;add&quot;).fit(smoothing_level=0.5,<br>                                                         smoothing_trend=0.5)<br><br>y_pred = des_model.forecast(48)<br><br>plot_co2(train, test, y_pred, &quot;Double Exponential Smoothing&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/877/0*YQ-KgqwTRYiab13O.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*-GFhmC5GF_1_Hnfy.png" /></figure><pre>des_model.params</pre><pre>{&#39;smoothing_level&#39;: 0.5,<br> &#39;smoothing_trend&#39;: 0.5,<br> &#39;smoothing_seasonal&#39;: nan,<br> &#39;damping_trend&#39;: nan,<br> &#39;initial_level&#39;: 317.5299919184764,<br> &#39;initial_trend&#39;: -0.3037511835408627,<br> &#39;initial_seasons&#39;: array([], dtype=float64),<br> &#39;use_boxcox&#39;: False,<br> &#39;lamda&#39;: None,<br> &#39;remove_bias&#39;: False}</pre><h3>3. Triple Exponential Smoothing (Holt-Winters)</h3><p>Triple Exponential Smoothing, also known as the Holt-Winters method, is a time series forecasting technique that extends exponential smoothing by adding a seasonal component to the forecast model. It is used to handle time series data with a trend and seasonality, such as monthly sales data with a consistent upward trend and a repeating seasonal pattern from year to year.</p><p>The method models the data as a combination of a level, trend, and seasonality component. The level component captures the average value of the data, the trend component captures changes in the level over time, and the seasonality component captures repeating patterns in the data. The method uses a weighted average of the past values, level, and trend, to make predictions for future time steps.</p><pre>tes_model = ExponentialSmoothing(train,<br>                                 trend=&quot;add&quot;,<br>                                 seasonal=&quot;add&quot;,<br>                                 seasonal_periods=12).fit(smoothing_level=0.5,<br>                                                          smoothing_slope=0.5,<br>                                                          smoothing_seasonal=0.5)<br><br>y_pred = tes_model.forecast(48)<br>plot_co2(train, test, y_pred, &quot;Triple Exponential Smoothing&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/0*NGROzqtG3sVrBtdt.png" /></figure><h3>Model Comparison</h3><pre>model_names = [&quot;SES&quot;, &quot;DES&quot;, &quot;TES&quot;]<br>model_mse = [round(np.mean((ses_model.resid)**2), 4),             <br>             round(np.mean((des_model.resid)**2), 4),             <br>             round(np.mean((tes_model.resid)**2), 4)]<br><br>plt.figure(figsize=(7, 5))<br>plt.bar(model_names, model_mse)<br>plt.xlabel(&#39;Models&#39;)<br>plt.ylabel(&#39;Mean Squared Error (MSE)&#39;)<br>plt.title(&#39;MSE of Different Time Series Models&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/432/0*6StxJdNSBfol61rB.png" /></figure><h3>Conclusion</h3><p>Time series forecasting is a powerful tool for organizations in a variety of industries. By using historical data to make predictions about future trends, organizations can make informed decisions and allocate resources effectively. There are many different types of time series forecasting models, ranging from simple methods to more complex models, and the choice of method will depend on the characteristics of the data and the goals of the problem. With the right tools and techniques, time series forecasting can provide valuable insights into future trends and help organizations plan for the future.</p><p>There are many resources available for learning about time series forecasting and how to perform it using Python. Here are a few recommended references:</p><ul><li>Time Series Forecasting in Python-by Marco Peixeiro</li><li>Time Series Analysis with Python Cookbook: Practical Recipes for Exploratory Data Analysis, Data Preparation, Forecasting, and Model Evaluation-by Tarek A. Atwan</li><li>Python for Time Series Data Analysis by Travis Mahoney</li><li>Time Series Analysis and Forecasting with Python by Dr. PKS Prakash</li><li>Hands-On Time Series Analysis with R by Vishwanathan N</li><li>Time Series Analysis and Its Applications: With R Examples by Robert H. Shumway, David S. Stoffer</li></ul><p><em>You can find the detailed part of the project on my </em><a href="https://www.kaggle.com/code/emineyetm/time-series-forecasting-with-python"><em>Kaggle notebook</em></a><em>.</em></p><h3>References</h3><ol><li><a href="https://www.miuul.com/zaman-serileri">https://www.miuul.com/zaman-serileri</a></li></ol><p>🔔 If you’d like to get in touch, you can find me on Linkedin, drop me an email or follow me 👇</p><ul><li><strong>Follow me:</strong> <a href="https://www.linkedin.com/in/eminebozkus/">LinkedIn</a> | <a href="https://www.kaggle.com/emineyetm">Kaggle</a> | <a href="https://github.com/bozkusemine">Github</a></li></ul><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bc38f216f6e4" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/exponential-smoothing-techniques-for-time-series-forecasting-in-python-a-guide-bc38f216f6e4">Exponential Smoothing Techniques for Time Series Forecasting in Python: A Guide</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modeling for Unbalanced Datasets: Tips and Strategies]]></title>
            <link>https://medium.datadriveninvestor.com/modeling-for-unbalanced-datasets-tips-and-strategies-dfd3a0b9eb70?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/dfd3a0b9eb70</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[modelling]]></category>
            <category><![CDATA[imbalanced-data]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Sat, 28 Jan 2023 02:55:10 GMT</pubDate>
            <atom:updated>2023-01-28T13:34:31.958Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>When dealing with unbalanced datasets in machine learning, it’s important to approach the problem carefully. Unbalanced datasets can occur when one class or group of data points dominates the other classes. This can cause issues when training machine learning models, because the model may be overly biased towards the dominant class.</blockquote><h3>Introduction</h3><p>Unbalanced datasets refer to instances where the number of examples in one class is significantly different from the number of examples in another class. For example, in a binary classification problem where one class represents a small percentage of the total examples, this is known as an imbalanced dataset. In such scenarios, the class imbalance can lead to several issues while building a machine learning model.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*kPPaSALyYGkyh2gk.png" /><figcaption>Figure 1. <a href="https://medium.com/analytics-vidhya/how-to-deal-with-an-imbalanced-dataset-47c8ce98c459">How to deal with an imbalanced dataset</a></figcaption></figure><p>One of the major issues with unbalanced datasets is that the model may be biased towards the majority class, leading to poor performance in predicting the minority class. This is because the model is trained to minimize the error rate, and when the majority class is over-represented, the model tends to predict the majority class more often. This leads to a higher accuracy score, but a poor recall and precision score for the minority class.</p><p>Another issue is that the model may not generalize well when exposed to new, unseen data. This is because the model is trained on a skewed dataset and may not be able to handle the imbalance in the test data.</p><p>In this article, we will discuss various tips and strategies to handle unbalanced datasets and improve the performance of machine learning models. Some of the techniques that will be covered include resampling techniques, cost-sensitive learning, using appropriate performance metrics, ensemble methods, and other strategies. By following these guidelines, we can build effective models for unbalanced datasets.</p><h3>Tips for handling unbalanced datasets</h3><p>Resampling techniques are one of the most popular ways to handle unbalanced datasets. These techniques involve either reducing the number of examples in the majority class or increasing the number of examples in the minority class.</p><p>Undersampling is a technique where we randomly remove examples from the majority class to reduce its size and balance the dataset. This technique is simple and easy to implement, but it can lead to information loss as it discards some of the majority class examples.</p><p>Oversampling is the opposite of undersampling, where we randomly replicate examples from the minority class to increase its size. This technique can lead to overfitting as the model is trained on repeated examples of the minority class.</p><p>SMOTE (Synthetic Minority Over-sampling Technique) is a more advanced technique that creates synthetic examples of the minority class rather than replicating existing examples. This technique helps to balance the dataset without introducing duplicates.</p><p>Cost-sensitive learning is another technique that can be used to handle unbalanced datasets. In this approach, different misclassification costs are assigned to different classes. This means that the model is penalized more heavily for misclassifying examples from the minority class than for misclassifying examples from the majority class.</p><p>Using appropriate performance metrics is also important when working with unbalanced datasets. Accuracy is not always the best metric as it can be misleading when dealing with unbalanced datasets. Instead, using a metric such as AUC-ROC (Area Under the Receiver Operating Characteristic Curve) can provide a better indication of model performance.</p><p>Ensemble methods, such as bagging and boosting, can also be effective for modeling unbalanced datasets. These methods combine the predictions of multiple models to improve the overall performance. Bagging involves training multiple models independently and averaging their predictions, while boosting involves training multiple models sequentially, where each model attempts to correct the errors of the previous model.</p><p>In summary, resampling techniques, cost-sensitive learning, using appropriate performance metrics, and ensemble methods are some of the tips and strategies that can help to handle unbalanced datasets and improve the performance of machine learning models.</p><h3>Strategies for improving model performance on unbalanced datasets</h3><p>Collecting more data is one of the most straightforward strategies for improving model performance on unbalanced datasets. By increasing the number of examples in the minority class, the model will have more information to learn from and will be less likely to be biased towards the majority class. This strategy is especially useful when the number of examples in the minority class is very small.</p><p>Generating synthetic samples is another strategy that can be used to improve model performance. Synthetic samples are artificially created examples that are similar to the real examples in the minority class. These samples can be generated using techniques such as SMOTE (Synthetic Minority Over-sampling Technique), which creates synthetic examples by interpolating between existing examples. Generating synthetic samples can help to balance the dataset and provide more examples for the model to learn from.</p><p>Using domain knowledge to focus on important samples is a strategy that can be used to improve model performance by identifying the most informative examples in the dataset. For example, if we are working on a medical dataset, we may know that certain symptoms or lab results are more indicative of a certain disease. By focusing on these examples, we can improve the model’s ability to accurately predict the minority class.</p><p>Finally, advanced techniques such as anomaly detection can be used to identify and focus on the minority class examples. These techniques can be used to identify examples that are different from the majority class and are likely to be minority class examples. This can help to improve model performance by identifying the most informative examples in the dataset.</p><p>In summary, collecting more data, generating synthetic samples, using domain knowledge to focus on important samples and using advanced techniques such as anomaly detection are some of the strategies that can be used to improve model performance on unbalanced datasets. These strategies can help to balance the dataset, provide more examples for the model to learn from, and identify the most informative examples in the dataset.</p><h4>Let’s practise in python.</h4><h4>Import Libraries</h4><pre>import pandas as pd<br>import numpy as np<br>from sklearn.preprocessing import RobustScaler<br>from sklearn.linear_model import LogisticRegression<br>from sklearn.model_selection import train_test_split<br>from sklearn.metrics import accuracy_score<br>from sklearn.metrics import confusion_matrix, classification_report,f1_score,recall_score,roc_auc_score, roc_curve<br>import matplotlib.pyplot as plt<br>import seaborn as sns<br>from matplotlib import rc,rcParams<br>import itertools<br><br>import warnings<br>warnings.filterwarnings(&quot;ignore&quot;, category=DeprecationWarning) <br>warnings.filterwarnings(&quot;ignore&quot;, category=FutureWarning) <br>warnings.filterwarnings(&quot;ignore&quot;, category=UserWarning)</pre><h4>Read data</h4><pre># Reading the dataset<br>df = pd.read_csv(&quot;creditcard.csv&quot;)<br>df.head()</pre><pre># Number of variables and observations in the data set<br>print(&quot;Number of observations : &quot; ,len(df))<br>print(&quot;Number of variables : &quot;, len(df.columns))</pre><pre>Number of observations :  284807<br>Number of variables :  31</pre><pre># We want to observe the types of variables in the dataset and whether they contain nulls<br>df.info()</pre><pre>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;<br>RangeIndex: 284807 entries, 0 to 284806<br>Data columns (total 31 columns):<br> #   Column  Non-Null Count   Dtype  <br>---  ------  --------------   -----  <br> 0   Time    284807 non-null  float64<br> 1   V1      284807 non-null  float64<br> 2   V2      284807 non-null  float64<br> 3   V3      284807 non-null  float64<br> 4   V4      284807 non-null  float64<br> 5   V5      284807 non-null  float64<br> 6   V6      284807 non-null  float64<br> 7   V7      284807 non-null  float64<br> 8   V8      284807 non-null  float64<br> 9   V9      284807 non-null  float64<br> 10  V10     284807 non-null  float64<br> 11  V11     284807 non-null  float64<br> 12  V12     284807 non-null  float64<br> 13  V13     284807 non-null  float64<br> 14  V14     284807 non-null  float64<br> 15  V15     284807 non-null  float64<br> 16  V16     284807 non-null  float64<br> 17  V17     284807 non-null  float64<br> 18  V18     284807 non-null  float64<br> 19  V19     284807 non-null  float64<br> 20  V20     284807 non-null  float64<br> 21  V21     284807 non-null  float64<br> 22  V22     284807 non-null  float64<br> 23  V23     284807 non-null  float64<br> 24  V24     284807 non-null  float64<br> 25  V25     284807 non-null  float64<br> 26  V26     284807 non-null  float64<br> 27  V27     284807 non-null  float64<br> 28  V28     284807 non-null  float64<br> 29  Amount  284807 non-null  float64<br> 30  Class   284807 non-null  int64  <br>dtypes: float64(30), int64(1)<br>memory usage: 67.4 MB</pre><pre># The rate of presence of class 1 in the data set is 0.2%, and class 0 is 99.8%.<br><br>f,ax=plt.subplots(1,2,figsize=(18,8))<br>df[&#39;Class&#39;].value_counts().plot.pie(explode=[0,0.1],autopct=&#39;%1.1f%%&#39;,ax=ax[0],shadow=True)<br>ax[0].set_title(&#39;dağılım&#39;)<br>ax[0].set_ylabel(&#39;&#39;)<br>sns.countplot(&#39;Class&#39;,data=df,ax=ax[1])<br>ax[1].set_title(&#39;Class&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*U61OWvPxS4V1Qqqw.png" /></figure><pre># Standardizing Time and Amount variables<br>rob_scaler = RobustScaler()<br>df[&#39;Amount&#39;] = rob_scaler.fit_transform(df[&#39;Amount&#39;].values.reshape(-1,1))<br>df[&#39;Time&#39;] = rob_scaler.fit_transform(df[&#39;Time&#39;].values.reshape(-1,1))<br>df.head()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Gq376yC5L4SGlsWF.png" /></figure><pre>X = df.drop(&quot;Class&quot;, axis=1)<br>y = df[&quot;Class&quot;]<br>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=123456)</pre><pre>model = LogisticRegression(random_state=123456)<br>model.fit(X_train, y_train)<br>y_pred = model.predict(X_test)<br>accuracy = accuracy_score(y_test, y_pred)<br>print(&quot;Accuracy: %.3f&quot;%(accuracy))</pre><p>Accuracy is the ratio of correct predictions to all predictions in the system. The accuracy score of the model we created is 0.999. We can say that our model works perfectly, right?</p><p><strong><em>Let’s take a look at the Confusion Matrix to examine its performance.</em></strong></p><h3>Confusion Matrix</h3><p>The Confusion Matrix is a table used to describe the performance of a classification model’s true values on test data. It contains 4 different combinations of estimated and actual values.</p><p><strong>Terminology and derivations from a confusion matrix</strong></p><ul><li>condition positive (P): the number of real positive cases in the data</li><li>condition negative (N): the number of real negative cases in the data</li><li>true positive (TP): A test result that correctly indicates the presence of a condition or characteristic</li><li>true negative (TN): A test result that correctly indicates the absence of a condition or characteristic</li><li>false positive (FP): A test result which wrongly indicates that a particular condition or attribute is present</li><li>false negative (FN): A test result which wrongly indicates that a particular condition or attribute is absent</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/862/0*QsIq3b-BPqEp8Wbf.png" /></figure><pre>def plot_confusion_matrix(cm, classes,<br>                          title=&#39;Confusion matrix&#39;,<br>                          cmap=plt.cm.Blues):<br><br>    plt.rcParams.update({&#39;font.size&#39;: 19})<br>    plt.imshow(cm, interpolation=&#39;nearest&#39;, cmap=cmap)<br>    plt.title(title,fontdict={&#39;size&#39;:&#39;16&#39;})<br>    plt.colorbar()<br>    tick_marks = np.arange(len(classes))<br>    plt.xticks(tick_marks, classes, rotation=45,fontsize=12,color=&quot;blue&quot;)<br>    plt.yticks(tick_marks, classes,fontsize=12,color=&quot;blue&quot;)<br>    rc(&#39;font&#39;, weight=&#39;bold&#39;)<br>    fmt = &#39;.1f&#39;<br>    thresh = cm.max()<br>    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):<br>        plt.text(j, i, format(cm[i, j], fmt),<br>                 horizontalalignment=&quot;center&quot;,<br>                 color=&quot;red&quot;)<br><br>    plt.ylabel(&#39;True label&#39;,fontdict={&#39;size&#39;:&#39;16&#39;})<br>    plt.xlabel(&#39;Predicted label&#39;,fontdict={&#39;size&#39;:&#39;16&#39;})<br>    plt.tight_layout()<br><br>plot_confusion_matrix(confusion_matrix(y_test, y_pred=y_pred), classes=[&#39;Non Fraud&#39;,&#39;Fraud&#39;],<br>                      title=&#39;Confusion matrix&#39;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/342/0*4yYXqFaHKdQ1lqcq.png" /></figure><p>• A total of 56875 predictions were made for the Non Fraud class, with 56870 (TP) correct and 5 (FP) incorrect.</p><p>• A total of 87 predictions were made for the Fraud class, with 31 (FN) incorrect and 56 (TN) correct.</p><p>The model tells us that it can predict the Fraud state with 0.99 accuracies. But when we examine the confusion Matrix, the rate of false predictions in the Fraud class is quite high. While it is good at predicting the majority class, it is not good at predicting the minority class. In other words, the model correctly predicts the non-fraud class with a rate of 0.99. The fact that the number of observations belonging to the Non-Fraud class is higher than the number of observations of the fraud class causes the model to be successful in estimating the Non-Fraud class. With this observation we have made, we can say that the accuracy score is not a good performance measure for classification models, especially if it contains imbalances like the data set we have. We’ve looked at the dataset, we can look at how we can deal with the imbalance and build a model, what methods can be applied, and with what metrics we can measure its performance.</p><h3>Choosing the Right Metric</h3><p>When dealing with imbalanced datasets, it is important to choose the right metric to evaluate the performance of the model. Traditional metrics, such as accuracy, precision, and recall, may not be appropriate for imbalanced datasets because they do not take into account the distribution of the classes in the data.</p><p>One metric that is often used for imbalanced datasets is the F1 score. The F1 score is the harmonic mean of precision and recall, and it provides a balance between the two metrics. It is calculated as follows:</p><p>F1 = 2 * (precision * recall) / (precision + recall)</p><p>Another metric that is often used for imbalanced datasets is the area under the receiver operating characteristic curve (AUC-ROC). The AUC-ROC is a measure of the model’s ability to distinguish between positive and negative classes. It is calculated by plotting the true positive rate (TPR) against the false positive rate (FPR) at different classification thresholds. AUC-ROC values range from 0.5 (random guessing) to 1.0 (perfect classification).</p><pre>print(classification_report(y_test, y_pred))</pre><pre>                precision   recall   f1-score   support<br><br>           0       1.00      1.00      1.00     56875<br>           1       0.92      0.64      0.76        87<br><br>    accuracy                           1.00     56962<br>   macro avg       0.96      0.82      0.88     56962<br>weighted avg       1.00      1.00      1.00     56962</pre><p><strong>Let’s examine the Precision measure for each class.</strong></p><p>Returns how many of the predictions made for the 0 (non-fraud) class are correct. Looking at the confusion matrix, 56870 + 31 = 56901 non-fraud class predictions were made and 56870 of them were estimated correctly. The precision value for class 0 is 1 (56870 / 56901)</p><p>Returns how many of the predictions for the 1 (fraud) class are correct. Looking at the confusion matrix, 5 + 56 = 61 fraud class predictions were made and 56 of them were correctly estimated. The precision for class 0 is 0.92 (56 / 61)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*jKa1BcQaXp6U7D87.png" /></figure><p><strong>Let’s examine the Recall measure for each class.</strong></p><p>It shows how many of the values we need to predict for the 0(non-fraud) class are correctly predicted. We have 56870 + 5 = 56875 observations belonging to the non-fraud class and 56870 of them have been estimated correctly. The recall value for class 0 is 56870 / 56875 = 1.</p><p>It shows how many of the values we need to predict for the 1(fraud) class correctly. 31 + 56 = We have observations of 87 fraud classes and 56 of them are correctly estimated. The recall value for class 1 is 56 / 87 = 0.64.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*MVTMWcGgfnk9xncW.png" /></figure><p>When we look at the Recall values, we can easily see the failure of estimating 1 class. <strong>F1-score</strong> also expresses the harmonic mean of the recall and precision values.</p><p><strong>Support</strong> refers to the number of actual values of the classes. We can show the structural weaknesses of the measurements, that is, we can say that the imbalance in the number of observations between the classes affects the measurements.</p><h3>ROC curve</h3><p>A receiver operating characteristic (ROC) curve is a graphical plot that shows the performance of a binary classification model at all classification thresholds. The ROC curve is created by plotting the true positive rate (TPR) against the false positive rate (FPR) at different classification thresholds. The true positive rate is the proportion of positive samples that are correctly classified as positive. It is calculated as the number of true positives divided by the number of actual positives. The false positive rate is the proportion of negative samples that are incorrectly classified as positive. It is calculated as the number of false positives divided by the number of actual negatives.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/336/0*H242FdwZedCTf92B.png" /></figure><h3>AUC (Area under the ROC curve)</h3><p>AUC stands for “Area under the ROC Curve.” That is, AUC measures the entire two-dimensional area underneath the entire ROC curve (think integral calculus) from (0,0) to (1,1).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/627/0*yxkP4u6tV_-IfjgC.png" /></figure><pre># Auc Roc Curve<br>def generate_auc_roc_curve(clf, X_test):<br>    y_pred_proba = clf.predict_proba(X_test)[:, 1]<br>    fpr, tpr, thresholds = roc_curve(y_test,  y_pred_proba)<br>    auc = roc_auc_score(y_test, y_pred_proba)<br>    plt.plot(fpr,tpr)<br>    plt.show()<br>    pass<br><br>generate_auc_roc_curve(model, X_test)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/415/0*dSAuKJI9P1BSOknz.png" /></figure><pre>y_pred_proba = model.predict_proba(X_test)[:, 1]<br>auc = roc_auc_score(y_test, y_pred_proba)<br>print(&quot;AUC ROC Curve with Area Under the curve = %.3f&quot;%auc)</pre><pre>AUC ROC Curve with Area Under the curve = 0.985</pre><h3>Resampling</h3><h4>Oversampling</h4><p>Stabilizes the dataset by duplicating minority-class samples.</p><p><strong>Random Oversampling:</strong></p><p>It is the balancing of the data set by adding randomly selected samples from the minority class. This technique can be used if your dataset is small. It may cause overfitting. The RandomOverSampler method takes the sampling_strategy argument, and when sampling_stratefy=’minority’ is called, it increments the number of the minority class to equal the number of the majority class.</p><p>We can enter a float value in this argument. For example, let the number of our minority class be 1000 and the number of the majority class be 100. If we say sampling_stratefy = 0.5, the minority class will be added to be 500.</p><pre># Number of classes in the training set before random oversampling<br>y_train.value_counts()</pre><pre>0    227440<br>1       405<br>Name: Class, dtype: int64</pre><pre> # Implementing RandomOver Sampling (Applying to the training set)<br>from imblearn.over_sampling import RandomOverSampler<br>oversample = RandomOverSampler(sampling_strategy=&#39;minority&#39;)<br>X_randomover, y_randomover = oversample.fit_resample(X_train, y_train)</pre><pre># Number of classes of the training set after random oversampling<br>y_randomover.value_counts()</pre><pre>#training the model and its success rate<br>model.fit(X_randomover, y_randomover)<br>y_pred = model.predict(X_test)<br><br>accuracy = accuracy_score(y_test, y_pred)<br>print(&quot;Accuracy: %.3f%%&quot; % (accuracy))</pre><pre>plot_confusion_matrix(confusion_matrix(y_test, y_pred=y_pred), classes=[&#39;Non Fraud&#39;,&#39;Fraud&#39;],<br>                      title=&#39;Confusion matrix&#39;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/349/0*l1DtiDIKcdEOjQkz.png" /></figure><pre>#classification report<br>print(classification_report(y_test, y_pred))</pre><pre>                 precision    recall  f1-score   support<br><br>           0       1.00      0.98      0.99     56875<br>           1       0.05      0.86      0.10        87<br><br>    accuracy                           0.98     56962<br>   macro avg       0.53      0.92      0.55     56962<br>weighted avg       1.00      0.98      0.99     56962</pre><p>After applying Random Oversampling, the accuracy value of the trained model is 0.97, a decrease is observed. Looking at the Confusion Matrix and Classification report, the predicted fraud classes seem to have a high false rate, which lowered the precision of 1 class. But there is also an increase in the recall value of the 1 class, the rate of correctly estimating the fraud class of the model has increased. According to the first model, the prediction success of the Non fraud class has decreased, but the increase in the correct estimation of the fraud class is a big factor in our preference for the model created after randomoversampling.</p><h3>SMOTE Oversampling:</h3><p>Generating minority class synthetic samples to prevent overfitting.</p><p>First, a random sample from the minority class is selected. Then, k nearest neighbors are found for this sample. One of the k nearest neighbors is randomly selected and the synthetic sample is formed by combining it with the randomly selected sample from the minority class and forming a line segment in the feature space.</p><pre>y_train.value_counts()</pre><pre>0    227440<br>1       405<br>Name: Class, dtype: int64</pre><pre># Smote<br>from imblearn.over_sampling import SMOTE<br>oversample = SMOTE()<br>X_smote, y_smote = oversample.fit_resample(X_train, y_train)</pre><pre># class number of training set after smote<br>y_smote.value_counts()</pre><pre>1    227440<br>0    227440<br>Name: Class, dtype: int64</pre><pre>model.fit(X_smote, y_smote)<br>y_pred = model.predict(X_test)<br><br>accuracy = accuracy_score(y_test, y_pred)<br>print(&quot;Accuracy: %.3f%%&quot; % (accuracy))</pre><pre>Accuracy: 0.975%</pre><pre>plot_confusion_matrix(confusion_matrix(y_test, y_pred=y_pred), classes=[&#39;Non Fraud&#39;,&#39;Fraud&#39;],<br>                      title=&#39;Confusion matrix&#39;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/349/0*VbNauN-m17FTC5Wm.png" /></figure><pre>#classification report<br>print(classification_report(y_test, y_pred))</pre><pre>precision    recall  f1-score   support<br><br>           0       1.00      0.98      0.99     56875<br>           1       0.05      0.86      0.10        87<br><br>    accuracy                           0.98     56962<br>   macro avg       0.53      0.92      0.54     56962<br>weighted avg       1.00      0.98      0.99     56962</pre><h3>Undersampling</h3><p>It is a technique of balancing the data set by removing samples belonging to the majority class. It can be used when you have a large data set. Since the data set we have is not large, efficient results will not be obtained. But I will explain the methods and show how some of them can be applied.</p><p>Random Undersampling:</p><ul><li>Extracted samples are randomly selected.</li><li>You can use this technique if you have a large data set.</li><li>Information may be lost due to random selection.</li></ul><pre># random undersampling<br>y_train.value_counts()</pre><pre>0    227440<br>1       405<br>Name: Class, dtype: int64</pre><pre>from imblearn.under_sampling import RandomUnderSampler<br># transform the dataset<br>ranUnSample = RandomUnderSampler()<br>X_ranUnSample, y_ranUnSample = ranUnSample.fit_resample(X_train, y_train)</pre><pre># After Random undersampling <br>y_ranUnSample.value_counts()</pre><h3>Change the algorithm</h3><pre>from sklearn.ensemble import RandomForestClassifier<br># train model<br>rfc = RandomForestClassifier(n_estimators=10).fit(X_train, y_train)<br># predict on test set<br>rfc_pred = rfc.predict(X_test)<br>accuracy_score(y_test, rfc_pred)</pre><p>0.9996313331694814</p><pre># f1 score<br>f1_score(y_test, rfc_pred)</pre><p>0.8645161290322582</p><pre># confusion matrix<br>pd.DataFrame(confusion_matrix(y_test, rfc_pred))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/312/0*6-TcxpehZ6FYfny_.png" /></figure><pre># recall score<br>recall_score(y_test, rfc_pred)</pre><p>0.7976190476190477</p><h3>Conclusion</h3><p>In this article, we discussed various tips and strategies for handling unbalanced datasets and improving the performance of machine learning models. Unbalanced datasets can be a common problem in machine learning and can lead to poor performance in predicting the minority class.</p><p>We discussed various resampling techniques such as undersampling, oversampling, and SMOTE that can be used to balance the dataset. We also discussed cost-sensitive learning and using appropriate performance metrics such as AUC-ROC, which can provide a better indication of model performance. Additionally, we discussed ensemble methods such as bagging and boosting that can also be effective for modeling unbalanced datasets.</p><p>We also discussed strategies for improving model performance on unbalanced datasets, such as collecting more data, generating synthetic samples, using domain knowledge to focus on important samples, and using advanced techniques such as anomaly detection.</p><p>In summary, unbalanced datasets can be challenging to work with, but by following the tips and strategies discussed in this article, we can build effective models that can accurately predict the minority class. It’s important to remember that the best approach will depend on the specific dataset and problem, and that a combination of techniques may be necessary to achieve the best results. Therefore, it’s important to experiment with different techniques and evaluate their performance using appropriate metrics.</p><h3>References</h3><ol><li><a href="https://imbalanced-learn.org/stable/introduction.html">https://imbalanced-learn.org/stable/introduction.html</a></li><li><a href="https://courses.miuul.com/p/machine-learning">https://courses.miuul.com/p/machine-learning</a></li><li><a href="https://imbalanced-learn.org/dev/references/over_sampling.html">https://imbalanced-learn.org/dev/references/over_sampling.html</a></li></ol><p>🔔 If you’d like to get in touch, you can find me on Linkedin, drop me an email or follow me 👇</p><ul><li><strong>Follow me:</strong> <a href="https://www.linkedin.com/in/eminebozkus/">LinkedIn</a> | <a href="https://www.kaggle.com/emineyetm">Kaggle</a> | <a href="https://github.com/bozkusemine">Github</a></li></ul><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dfd3a0b9eb70" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/modeling-for-unbalanced-datasets-tips-and-strategies-dfd3a0b9eb70">Modeling for Unbalanced Datasets: Tips and Strategies</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Beginner’s Guide to Time Series Analysis]]></title>
            <link>https://eminebozkus.medium.com/a-beginners-guide-to-time-series-analysis-f16c545e414e?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/f16c545e414e</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[guides-and-tutorials]]></category>
            <category><![CDATA[time-series-forecasting]]></category>
            <category><![CDATA[time-series-analysis]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Fri, 27 Jan 2023 10:43:07 GMT</pubDate>
            <atom:updated>2023-01-27T10:43:07.994Z</atom:updated>
            <content:encoded><![CDATA[<h4>Forecasting the Future with Time Series Analysis</h4><blockquote>Many disciplines, such as finance, public administration, energy, retail, and healthcare, are dominated by time-series data. Large areas of micro- and macroeconomics rely on applied statistics with an emphasis on time-series analyses and modeling.</blockquote><h3>Introduction</h3><p>Time series data refers to a set of observations collected over a period of time. It is widely used in various fields such as finance, economics, meteorology, and more.</p><p><strong><em>The following are examples of time-series data:</em></strong><em><br>• Daily closing values of a stock index<br>• Number of weekly infections of a disease<br>• Weekly series of train accidents<br>• Rainfall per day<br>• Sensor data such as temperature measurements per hour<br>• Population growth per year<br>• Quarterly earnings of a company over a number of years</em></p><p>Time series data can be either continuous or discrete, and it can be univariate (one variable) or multivariate (multiple variables)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/918/1*uHalT7JrYb2MPV8w3chJLA.png" /><figcaption>Figure: The time-series machine learning flywheel</figcaption></figure><h4>Characteristics:</h4><ul><li>Time-dependent: the observations are collected at specific time intervals and the order of observations matters.</li><li>Stationarity: the statistical properties of a time series do not change over time.</li><li>Seasonality: a repeating pattern within a year or another fixed period of time.</li><li>Trend: a long-term increase or decrease in the data.</li><li>Noise: random fluctuations in the data.</li></ul><p>Understanding these characteristics is important for selecting the appropriate time series modeling technique and for interpreting the results of the analysis.</p><h4>Types of Time Series Data:</h4><ol><li>Additive time series: the individual components (trend, seasonality, and noise) can be separated and added together to obtain the total value.</li><li>Multiplicative time series: the individual components are multiplied together to obtain the total value.</li></ol><p>Applications:</p><ol><li>Financial data: stock prices, exchange rates, interest rates, etc.</li><li>Economic data: GDP, inflation, unemployment, etc.</li><li>Meteorological data: temperature, precipitation, wind speed, etc.</li><li>Healthcare data: hospital visits, prescription drug sales, etc.</li><li>Industrial data: production levels, energy consumption, etc.</li><li>Social media data: number of likes, shares, comments, etc.</li><li>Transportation data: traffic volume, fuel consumption, etc.</li></ol><p>These are some examples of the types of data that can be analyzed using time series methods, and the specific type of data will affect the choice of model used in the analysis.</p><h4>Time series modeling techniques including trend analysis, decomposition, and forecasting methods</h4><p>Time series modeling techniques:</p><ol><li>Trend analysis: identifies and models the long-term trend in the data. Techniques include moving averages, linear regression, and polynomial regression.</li><li>Decomposition: separates the time series into its individual components (trend, seasonality, and noise). Techniques include additive and multiplicative decomposition, and the classical decomposition of X-11.</li><li>Forecasting methods: use historical data to make predictions about future values. Techniques include simple exponential smoothing, Holt’s linear trend method, and ARIMA (Auto-Regressive Integrated Moving Average) model.</li></ol><p>It’s important to note that many time series datasets are non-stationary and may require a technique like differencing to make it stationary before applying any of the above methods.</p><h4>Importance of data preprocessing and cleaning in time series analysis</h4><p>Data preprocessing and cleaning is an essential step in time series analysis as it helps to ensure the quality and reliability of the data. This is particularly important when working with real-world data, as it may contain missing values, outliers, and other errors.</p><p>Here are a few key aspects of data preprocessing and cleaning for time series analysis:</p><ol><li>Missing values: Time series data often contains missing values, which can affect the accuracy of the analysis. These missing values must be handled appropriately, either by interpolation or by deletion.</li><li>Outliers: Outliers can have a significant impact on the results of time series analysis. They should be identified and handled by replacing them with a more appropriate value or by deletion.</li><li>Data transformation: Data may need to be transformed, such as taking the logarithm of the data, to stabilize the variance and make the data more suitable for analysis.</li><li>Data normalization: normalizing the data to a common scale is important for comparing different time series or for using some methods like ARIMA.</li><li>Data validation: it’s important to validate the data before analyzing it to ensure that it meets the assumptions of the chosen model.</li></ol><p>By performing these steps, you can ensure that the data is of high quality, which will lead to more accurate and reliable results in the analysis.</p><h4>Commonly used tools and software for time series analysis</h4><p>There are several tools and software available for time series analysis, depending on the specific needs of the project and the level of complexity of the analysis. Some of the most commonly used tools and software include:</p><ol><li>R: A programming language and software environment for statistical computing and graphics. It has a wide variety of packages for time series analysis, including “forecast”, “tseries”, “astsa”, “prophet” and more.</li><li>Python: A popular programming language that also has a wide variety of libraries for time series analysis such as “pandas”, “statsmodels”, “prophet”, “sklearn”, “numpy” and more.</li><li>Excel: a spreadsheet software that is widely used for simple time series analysis. It has built-in functions for handling time series data, such as moving averages, trendlines, and forecasting.</li><li>Tableau: a business intelligence and data visualization software, it can be used to create interactive dashboards and visualizations for time series data.</li><li>SAS: A widely used software for statistical analysis and data visualization, it has many capabilities for time series analysis like ARIMA, ETS, and more.</li><li>MATLAB: A multi-paradigm numerical computing environment and programming language, it has a wide range of toolboxes for time series analysis, signal processing, and control systems.</li></ol><p>It’s also worth noting that some of these tools and software have online platforms such as RStudio, Jupyter, and Colab that can be used to perform time series analysis.</p><h4>Real-world examples of time series analysis in various industries</h4><p>Time series analysis is widely used in various industries to gain insights from historical data and make predictions about future events. Here are a few examples of how time series analysis is used in different industries:</p><ol><li>Finance: Time series analysis is used to analyze stock prices, exchange rates, and interest rates. Financial institutions use it to identify trends and make predictions about future market conditions.</li><li>Economics: Time series analysis is used to analyze economic data such as GDP, inflation, and unemployment. This helps policymakers to understand the current state of the economy and make informed decisions.</li><li>Meteorology: Time series analysis is used to analyze weather data such as temperature, precipitation, and wind speed. This helps meteorologists to make weather predictions and issue alerts for severe weather conditions.</li><li>Healthcare: Time series analysis is used to analyze healthcare data such as hospital visits and prescription drug sales. This helps healthcare providers to understand patient needs and allocate resources more effectively.</li><li>Manufacturing: Time series analysis is used to analyze production levels, energy consumption, and other operational data. This helps manufacturers to optimize their production processes and reduce costs.</li><li>Retail: Retail companies use time series analysis on historical sales data to understand patterns in customer behavior, predict future sales and optimize inventory management.</li><li>Energy: Time series analysis is used to analyze energy consumption data, it helps energy companies to predict energy demand and optimize the operation of power plants, reduce costs and plan for the future.</li></ol><p>These are just a few examples of how time series analysis is used in various industries, but the possibilities are endless. With the help of time series analysis, organizations can make data-driven decisions, optimize processes and improve their overall performance.</p><h3>Conclusion</h3><p>Time series analysis is a powerful tool for understanding historical data and making predictions about future events. By understanding the characteristics of time series data, selecting the appropriate modeling techniques, and properly preprocessing and cleaning the data, it is possible to gain valuable insights and make data-driven decisions.</p><p>🔔 If you’d like to get in touch, you can find me on Linkedin, drop me an email or follow me 👇</p><ul><li><strong>Follow me:</strong> <a href="https://www.linkedin.com/in/eminebozkus/">LinkedIn</a> | <a href="https://www.kaggle.com/emineyetm">Kaggle</a> | <a href="https://github.com/bozkusemine">Github</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f16c545e414e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Autoviz: The Key to Effortless Data Visualization]]></title>
            <link>https://medium.datadriveninvestor.com/autoviz-the-key-to-effortless-data-visualization-4b930b0c5ad9?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/4b930b0c5ad9</guid>
            <category><![CDATA[data-visualization]]></category>
            <category><![CDATA[autoviz]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[exploratory-data-analysis]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Tue, 17 Jan 2023 16:20:09 GMT</pubDate>
            <atom:updated>2023-01-18T02:50:11.199Z</atom:updated>
            <content:encoded><![CDATA[<h4>Automatically visualize any dataset, any size with a single line of code.</h4><blockquote>Data visualization is a crucial step in the data analysis process, as it allows us to quickly identify patterns and relationships within the data. However, creating visualizations can be a time-consuming and tedious task, especially when dealing with large and complex datasets. This is where Autoviz comes in. Autoviz is a powerful tool that allows users to easily visualize any dataset without the need for manual data manipulation or coding.</blockquote><p>One of the key features of Autoviz is its ability to handle large and complex datasets. It can quickly identify patterns and relationships within the data, making it an ideal tool for data exploration and discovery. Additionally, Autoviz is highly customizable, allowing users to specify the types of visualizations they want to generate, as well as the color schemes and layouts of the charts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HlPnTg3FsmmRYC0iQdgaRg.png" /><figcaption><strong>Figure 1. </strong>The Key to Effortless Data Visualization (Created by the author)</figcaption></figure><p>The process of using Autoviz is simple and straightforward. Users can import their data into the tool using a variety of file formats, including CSV, Excel, and JSON. Once the data is imported, Autoviz will automatically generate a variety of visualizations, which can be further customized and refined by the user.</p><p>Another benefit of Autoviz is its user-friendliness. It is built with a graphical user interface that makes it easy for users of all skill levels to navigate and understand. Users can also create and share visualizations with others by exporting them to various file formats, such as PDF, PNG, and JPEG.</p><h4>Import Libraries</h4><pre>import numpy as np # linear algebra<br>import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)<br><br>import warnings<br>warnings.filterwarnings(&#39;ignore&#39;)</pre><p>The process of using Autoviz is simple and straightforward. First, you need to <strong><em>install Autoviz</em></strong> by running the following command in your terminal:</p><pre>pip install autoviz</pre><p>Once Autoviz is installed, you can import your data into the tool using a variety of file formats, including CSV, Excel, and JSON. For example, if your data is in a CSV file called “data.csv”, you can import it using the following code:</p><pre>data = pd.read_csv(&#39;Iris.csv&#39;)<br>data.head()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VB8nFczFXN5TtgSiayKXjw.png" /></figure><h4>Generate visualizations</h4><p>Now that your data is imported, you can use Autoviz to generate visualizations. Autoviz have a function called “AutoViz_Class” that takes in a pandas DataFrame and generates visualizations. Here is an example of how to use it:</p><pre>from autoviz.AutoViz_Class import AutoViz_Class<br>AV = AutoViz_Class()<br><br>%matplotlib inline # AutoViz no displays plots automatically. You must perform %matplotlib inline just before you run AutoViz on your data.<br><br># Generate visualizations<br>AV.AutoViz(&quot;/kaggle/input/iris/Iris.csv&quot;)</pre><p>This will generate a variety of visualizations, including bar charts, line graphs, and scatter plots. These visualizations will be saved in the current working directory as HTML files that can be opened in a web browser for viewing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dhulGVi8vhZqqdabqLZXjw.png" /></figure><pre>6 Predictors classified...<br>        1 variables removed since they were ID or low-information variables<br>        List of variables removed: [&#39;Id&#39;]<br>Number of All Scatter Plots = 10</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*VX1VEJ8HHj--AI9O.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/996/0*AtcRAflNaNV-kywQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/695/0*H2oNuGXyZ4wzgoUo.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wF0XmyYC5OApP6pv.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/982/0*Xx3qPUO96_lHN47Z.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cUr8Pn5KcKpMVAyg.png" /></figure><pre>All Plots done<br>Time to run AutoViz = 6 seconds <br><br> ###################### AUTO VISUALIZATION Completed ########################</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MbWwn7HtTPMO0ppKjy1elw.png" /></figure><p><strong><em>Note:</em></strong><em> Autoviz only works for continuous and categorical variables. You can use dep_var to define continuous variables in your dataset.</em></p><p>This will generate a variety of visualizations, including bar charts, line graphs, and scatter plots. These visualizations will be saved in the current working directory as HTML files that can be opened in a web browser for viewing. In addition to generating visualizations, Autoviz also allows users to customize and refine their visualizations. For example, you can specify the types of visualizations you want to generate, as well as the color schemes and layouts of the charts.</p><h4>Parameters</h4><ul><li>filename: The name of the file containing the dataset.</li><li>sep: The delimiter used in the file.</li><li>depVar: The name of the target variable.</li><li>dfte: The dataframe containing the dataset.</li><li>header: The row number of the header in the file.</li><li>verbose: The level of verbosity. If it is 0 or 1, it only shows the plots on the notebook. If we give 2, it also saves the plots.</li><li>lowess: A boolean indicating whether to use the LOWESS smoother for scatter plots.</li><li>chart_format: The format of the generated charts. In this case, it is &#39;png&#39;.</li><li>max_rows_analyzed: The maximum number of rows to be analyzed from the dataset.</li><li>max_cols_analyzed: The maximum number of columns to be analyzed from the dataset.</li></ul><h4>Setting a Target Variable</h4><p>While visualizing the data, we can give a parameter called depVar. In this way, we can determine a target variable and create plots accordingly. You can also specify the columns of the dataframe to be plotted and excluded in the visualization.</p><p><em>Here is an example of how to do this:</em></p><pre>AV = AutoViz_Class()<br>dftc = AV.AutoViz(<br>    filename=&#39;&#39;, <br>    sep=&#39;&#39; , <br>    depVar=&#39;Species&#39;, <br>    dfte=data, <br>    header=0, <br>    verbose=1, <br>    lowess=False, <br>    chart_format=&#39;png&#39;, <br>    max_rows_analyzed=300000, <br>    max_cols_analyzed=30<br>)</pre><pre>Shape of your Data Set loaded: (150, 6)<br>#######################################################################################<br>######################## C L A S S I F Y I N G  V A R I A B L E S  ####################<br>#######################################################################################<br>Classifying variables in data set...<br>Data cleaning improvement suggestions. Complete them before proceeding to ML modeling.</pre><pre>Multi_Classification problem</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xBJX2R7HSq8ZRnsw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*bBPsav5gF_BQNuAr.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GFLEZmayr7QNypFD.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*RUzWYIvZd2pPi3_B.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/0*entmeidNUguNBJIp.png" /></figure><h4>AutoViz provides data cleaning suggestions</h4><p>AutoViz automatically analyzes your dataset and provides suggestions for how to clean your data set. It detects missing values, identifies rare categories, finds infinite values, detects mixed data types, and so much more. This will help you tremendously speed up your data cleaning activities.</p><pre>from autoviz import data_cleaning_suggestions<br>data_cleaning_suggestions(data)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aGCkDKw2Z-DueOPl74jn9g.png" /></figure><p>Besides these AutoViz can create Wordclouds automatically for your NLP variables in data. It detects NLP variables automatically and creates wordclouds for them. And AutoViz runs on Docker containers as part of MLOps pipelines. Check out <a href="https://pypi.org/project/autoviz/orchest.io/">Orchest.io</a></p><h4>Conclusion</h4><p>In conclusion, Autoviz is a powerful and user-friendly tool that makes data visualization easy and effortless. Its ability to handle large and complex datasets, highly customizable and ability to specify columns to be plotted makes it an ideal tool for data exploration and discovery. By using Autoviz, data scientists and analysts can save time and effort when creating visualizations, allowing them to focus on interpreting the data and uncovering insights.</p><p><em>Thanks for reading this article. You can access the detailed codes of the project and other projects on </em><a href="https://github.com/bozkusemine"><em>my Github account</em></a><em> or </em><a href="https://www.kaggle.com/emineyetm"><em>Kaggle account</em></a><em>. Happy coding!</em></p><p><em>Please feel free to </em><a href="https://www.linkedin.com/in/eminebozkus/"><em>contact me</em></a><em> if you need any further information.</em></p><h4>References</h4><ol><li><a href="https://pypi.org/project/autoviz/">https://pypi.org/project/autoviz/</a></li><li><a href="https://github.com/AutoViML/AutoViz">https://github.com/AutoViML/AutoViz</a></li><li><a href="https://github.com/rsesha/autoviz_pipeline">https://github.com/rsesha/autoviz_pipeline</a></li></ol><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4b930b0c5ad9" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/autoviz-the-key-to-effortless-data-visualization-4b930b0c5ad9">Autoviz: The Key to Effortless Data Visualization</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Insights from the World Happiness Report: A Data-Driven Perspective]]></title>
            <link>https://medium.datadriveninvestor.com/insights-from-the-world-happiness-report-a-data-driven-perspective-c736858d90f?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/c736858d90f</guid>
            <category><![CDATA[world-happiness-report]]></category>
            <category><![CDATA[kaggle]]></category>
            <category><![CDATA[world]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Thu, 12 Jan 2023 14:45:42 GMT</pubDate>
            <atom:updated>2023-01-13T07:54:20.677Z</atom:updated>
            <content:encoded><![CDATA[<h4>This post aims to teach you how to analysis and predict World Happiness use python.</h4><blockquote>Hello everyone!</blockquote><blockquote>In this post, we will explore the use of Python to analyze and predict World Happiness. The World Happiness Report, which is published by the United Nations Sustainable Development Solutions Network, ranks 156 countries by their overall happiness levels.</blockquote><p>We will begin by importing the necessary libraries, including pandas for data manipulation and matplotlib for visualization. Next, we will load in the World Happiness Report dataset and take a look at the data to understand the different factors that contribute to a country’s overall happiness score.</p><p>Using statistical analysis techniques, such as correlation and regression analysis, we will then identify the strongest predictors of happiness. We can use machine learning algorithms like linear regression, Random Forest and Decision Tree.</p><p>Finally, we will use our findings to create a predictive model that can estimate a country’s happiness score based on its other characteristics.</p><p>This post will serve as a comprehensive guide for those looking to learn about data analysis and prediction using Python in the context of World Happiness. By the end of this post, readers will have a better understanding of the factors that contribute to a country’s overall happiness, and will be able to create their own predictive models using Python.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*I5sIf94agP76AJ3G.jpg" /><figcaption>Figure 1. <a href="https://www.visualcapitalist.com/relationship-between-wealth-and-happiness-by-country/">Charting the Relationship Between Wealth and Happiness, by Country</a></figcaption></figure><p>The World Happiness Report is a survey that ranks countries by their happiness levels, using data from the Gallup World Poll. The report uses the Cantril ladder question, which asks respondents to rate their current lives on a scale of 0 to 10, with 10 being the best possible life. The report also includes estimates of how six factors — economic production, social support, life expectancy, freedom, absence of corruption, and generosity — contribute to making life evaluations higher in each country. The report also includes a hypothetical country called Dystopia, which has the lowest national averages for each of the six factors, and serves as a benchmark against which all countries can be compared.</p><h4>Variables</h4><ul><li>Overall rank: Rank of countries based on the Happiness Score</li><li>Score: A metric measured in 2019 by asking the sampled people the question: “How would you rate your happiness on a scale of 0 to 10 where 10 is the happiest.”</li><li>GDP per capita: The extent to which GDP contributes to the calculation of the Happiness Score.</li><li>Social support: The extent to which Social support contributes to the calculation of the Happiness Score</li><li>Healthy life expectancy: The extent to which Life expectancy contributed to the calculation of the Happiness Score</li><li>Freedom to make life choices: The extent to which Freedom contributed to the calculation of the Happiness Score</li><li>Generosity: The extent to which Generosity contributed to the calculation of the Happiness Score</li><li>Perceptions of corruption: The extent to which Perception of Corruption contributes to Happiness Score.</li></ul><h4>Import libraries</h4><pre>import pandas as pd<br>import numpy as np<br>import matplotlib.pyplot as plt<br>import seaborn as sns<br>from sklearn.preprocessing import StandardScaler<br>import warnings<br>warnings.filterwarnings(&#39;ignore&#39;)</pre><h4>Read data</h4><pre>df = pd.read_csv(&#39;/kaggle/input/world-happiness/2019.csv&#39;)<br>df.head()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YPmVfQbxusWURkyILtUsKw.png" /></figure><h4>Summary Statistics</h4><p>To get a summary of the numerical columns in the data, you can use the some function.</p><p>This code defines a function called check_df that takes a DataFrame as input and prints various information about the DataFrame, including its shape, data types, head, tail, missing values, and quantiles.</p><p>The function has two parameters: dataframe, which is the DataFrame to be analyzed, and head, which is the number of rows to print for the head and tail of the DataFrame. The default value for head is 5.</p><pre>def check_df(dataframe, head=5):<br>    print(&quot;##################### Shape #####################&quot;)<br>    print(dataframe.shape)<br>    print(&quot;##################### Types #####################&quot;)<br>    print(dataframe.dtypes)<br>    print(&quot;##################### Head #####################&quot;)<br>    print(dataframe.head(head))<br>    print(&quot;##################### Tail #####################&quot;)<br>    print(dataframe.tail(head))<br>    print(&quot;##################### NA #####################&quot;)<br>    print(dataframe.isnull().sum())<br>    print(&quot;##################### Quantiles #####################&quot;)<br>    print(dataframe.quantile([0, 0.05, 0.50, 0.95, 0.99, 1]).T)<br><br>check_df(df)</pre><pre>##################### Shape #####################<br>(156, 9)<br>##################### Types #####################<br>Overall rank                      int64<br>Country or region                object<br>Score                           float64<br>GDP per capita                  float64<br>Social support                  float64<br>Healthy life expectancy         float64<br>Freedom to make life choices    float64<br>Generosity                      float64<br>Perceptions of corruption       float64<br>dtype: object<br>##################### Head #####################<br>   Overall rank Country or region  Score  GDP per capita  Social support  \<br>0             1           Finland  7.769           1.340           1.587   <br>1             2           Denmark  7.600           1.383           1.573   <br>2             3            Norway  7.554           1.488           1.582   <br>3             4           Iceland  7.494           1.380           1.624   <br>4             5       Netherlands  7.488           1.396           1.522   <br><br>   Healthy life expectancy  Freedom to make life choices  Generosity  \<br>0                    0.986                         0.596       0.153   <br>1                    0.996                         0.592       0.252   <br>2                    1.028                         0.603       0.271   <br>3                    1.026                         0.591       0.354   <br>4                    0.999                         0.557       0.322   <br><br>   Perceptions of corruption  <br>0                      0.393  <br>1                      0.410  <br>2                      0.341  <br>3                      0.118  <br>4                      0.298  <br>##################### Tail #####################<br>     Overall rank         Country or region  Score  GDP per capita  \<br>151           152                    Rwanda  3.334           0.359   <br>152           153                  Tanzania  3.231           0.476   <br>153           154               Afghanistan  3.203           0.350   <br>154           155  Central African Republic  3.083           0.026   <br>155           156               South Sudan  2.853           0.306   <br><br>     Social support  Healthy life expectancy  Freedom to make life choices  \<br>151           0.711                    0.614                         0.555   <br>152           0.885                    0.499                         0.417   <br>153           0.517                    0.361                         0.000   <br>154           0.000                    0.105                         0.225   <br>155           0.575                    0.295                         0.010   <br><br>     Generosity  Perceptions of corruption  <br>151       0.217                      0.411  <br>152       0.276                      0.147  <br>153       0.158                      0.025  <br>154       0.235                      0.035  <br>155       0.202                      0.091  <br>##################### NA #####################<br>Overall rank                    0<br>Country or region               0<br>Score                           0<br>GDP per capita                  0<br>Social support                  0<br>Healthy life expectancy         0<br>Freedom to make life choices    0<br>Generosity                      0<br>Perceptions of corruption       0<br>dtype: int64<br>##################### Quantiles #####################<br>                               0.00     0.05     0.50       0.95       0.99  \<br>Overall rank                  1.000  8.75000  78.5000  148.25000  154.45000   <br>Score                         2.853  3.48150   5.3795    7.28525    7.57470   <br>GDP per capita                0.000  0.25200   0.9600    1.44150    1.58865   <br>Social support                0.000  0.64325   1.2715    1.53800    1.58425   <br>Healthy life expectancy       0.000  0.28825   0.7890    1.03975    1.10330   <br>Freedom to make life choices  0.000  0.14275   0.4170    0.58425    0.60570   <br>Generosity                    0.000  0.04675   0.1775    0.34950    0.45455   <br>Perceptions of corruption     0.000  0.01900   0.0855    0.32225    0.41045   <br><br>                                 1.00  <br>Overall rank                  156.000  <br>Score                           7.769  <br>GDP per capita                  1.684  <br>Social support                  1.624  <br>Healthy life expectancy         1.141  <br>Freedom to make life choices    0.631  <br>Generosity                      0.566  <br>Perceptions of corruption       0.453</pre><p>The describe method is a function of the Pandas DataFrame class that generates descriptive statistics of a DataFrame.</p><p>When you call the describe method on a DataFrame, it returns a new DataFrame that contains various statistical summary measures of the data in the original DataFrame. These summary measures include the count, mean, standard deviation, minimum, maximum, 25th percentile, 50th percentile (also known as the median), and 75th percentile of the data.</p><pre># Generate statistics<br>df.describe()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AGBRPFAsJr-y7QJFbvr4uA.png" /></figure><h4>Remove outliers</h4><p>This code defines a function called remove_outliers that takes a DataFrame and a column name as input and returns a new DataFrame with the outliers in the specified column removed.</p><p>The function works by first sorting the DataFrame by the specified column. It then calculates the first quartile (Q1) and third quartile (Q3) of the column, as well as the interquartile range (IQR) which is the difference between Q3 and Q1. The function then calculates the lower and upper range of the column data by adding and subtracting 1.5 * IQR from Q1 and Q3, respectively.</p><p>Finally, the function filters the original DataFrame to include only rows where the value in the specified column is within the lower and upper range, and returns the resulting DataFrame.</p><pre>def remove_outliers(df, column):<br>    sorted(df)<br>    Q1, Q3 = np.percentile(df[column], [25, 75])<br>    IQR = Q3 - Q1<br>    lower_range = Q1 - (1.5 * IQR)<br>    upper_range = Q3 + (1.5 * IQR)<br>    df = df[(df[column] &gt; lower_range) &amp; (df[column] &lt; upper_range)]<br>    return df<br><br>df = remove_outliers(df, &#39;GDP per capita&#39;)<br>df = remove_outliers(df, &#39;Social support&#39;)<br>df = remove_outliers(df, &#39;Healthy life expectancy&#39;)<br>df = remove_outliers(df, &#39;Freedom to make life choices&#39;)<br>df = remove_outliers(df, &#39;Generosity&#39;)<br>df = remove_outliers(df, &#39;Perceptions of corruption&#39;)<br><br># Check if there is any outliers<br><br>df.boxplot(figsize=(20, 8))<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M8-vI6x6r-etvWmWI9iBew.png" /></figure><pre># Correlation matrix<br><br>corr_matrix = df.corr()<br>sns.heatmap(corr_matrix, annot=True, cmap=&#39;coolwarm&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/493/0*9DmUHXKKmbmRRbmN.png" /></figure><pre># Scatter plot<br><br>sns.scatterplot(x = &#39;GDP per capita&#39;, y = &#39;Happiness Score&#39;, data = df)<br>plt.show()<br><br>sns.scatterplot(x = &#39;Social support&#39;, y = &#39;Happiness Score&#39;, data = df)<br>plt.show()<br><br>sns.scatterplot(x = &#39;Healthy life expectancy&#39;, y = &#39;Happiness Score&#39;, data = df)<br>plt.show()<br><br>sns.scatterplot(x = &#39;Freedom to make life choices&#39;, y = &#39;Happiness Score&#39;, data = df)<br>plt.show()<br><br>sns.scatterplot(x = &#39;Generosity&#39;, y = &#39;Happiness Score&#39;, data = df)<br>plt.show()<br><br>sns.scatterplot(x = &#39;Perceptions of corruption&#39;, y = &#39;Happiness Score&#39;, data = df)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/384/0*9N80JrkzdtfgHEwZ.png" /></figure><pre># Histogram<br><br>sns.distplot(df[&#39;Happiness Score&#39;])<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/392/0*Al4dAFpPdFOIoAF6.png" /></figure><h4>Barplot</h4><p>This code uses the Matplotlib and Seaborn libraries to create a bar plot that visualizes the relationship between the Country and Happiness Score columns in the DataFrame df.</p><p>The figure function from Matplotlib is used to set the size of the plot, and the barplot function from Seaborn is used to create the bar plot. The x and y parameters specify the variables to use for the x-axis and y-axis, respectively, and the data parameter specifies the DataFrame to use for the plot.</p><p>The xticks function from Matplotlib is used to rotate the labels on the x-axis, and the show function is used to display the plot.</p><pre>plt.figure(figsize=(25, 10))<br>sns.barplot(x=&#39;Country&#39;, y=&#39;Happiness Score&#39;, data=df)<br>plt.xticks(rotation=90)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*s2CK_HPM6a77mnNK.png" /></figure><pre># Top 10 countries with the highest happiness score<br><br>top10 = df.sort_values(by = &#39;Happiness Score&#39;, ascending = False).head(10)<br>plt.figure(figsize=(20, 10))<br>sns.barplot(x = &#39;Country&#39;, y = &#39;Happiness Score&#39;, data = top10)<br>plt.xticks(rotation = 90)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*5b1tbbkH2_K_yTYM.png" /></figure><pre># Top 10 countries with the highest GDP per capita<br><br>top10_gdp = df.sort_values(by = &#39;GDP per capita&#39;, ascending = False).head(10)<br>plt.figure(figsize=(25, 10))<br>sns.barplot(x = &#39;Country&#39;, y = &#39;GDP per capita&#39;, data = top10_gdp)<br>plt.xticks(rotation = 90)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*F952kLJrFNvXtheS.png" /></figure><pre># Top 10 countries with the highest social support<br><br>top10_social = df.sort_values(by = &#39;Social support&#39;, ascending = False).head(10)<br>plt.figure(figsize=(25, 10))<br>sns.barplot(x = &#39;Country&#39;, y = &#39;Social support&#39;, data = top10_social)<br>plt.xticks(rotation = 90)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*SJr1zq8nszruEsFJ.png" /></figure><pre># Top 10 countries with the highest healthy life expectancy<br><br>top10_health = df.sort_values(by = &#39;Healthy life expectancy&#39;, ascending = False).head(10)<br>plt.figure(figsize=(25, 10))<br>sns.barplot(x = &#39;Country&#39;, y = &#39;Healthy life expectancy&#39;, data = top10_health)<br>plt.xticks(rotation = 90)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hVHj0S1zDoERpyIb.png" /></figure><pre>from sklearn.model_selection import train_test_split<br><br># Splitting the data into features and target<br>X = df.drop([&#39;Country&#39;, &#39;Happiness Score&#39;], axis=1)<br>y = df[&#39;Happiness Score&#39;]<br><br># Splitting the dataset into the Training set and Test set<br>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)<br><br># Feature Scaling<br>sc = StandardScaler()<br>X_train = sc.fit_transform(X_train)<br>X_test = sc.transform(X_test)</pre><p>This code uses the train_test_split function from the sklearn.model_selection module to split a dataset into a training set and a test set. The X variable contains the features of the dataset, and the y variable contains the target values. The train_test_split function takes the features and target values as input, along with the test size (in this case, 20% of the data is used for the test set) and a random seed (to ensure reproducibility).</p><p>The StandardScaler class from the sklearn.preprocessing module is then used to perform feature scaling on the training and test sets. Feature scaling is a technique used to standardize the range of independent variables or features of data. It is important to scale the features in a machine learning model to ensure that no single feature dominates the others and to avoid any bias in the model.</p><p>To use the StandardScaler, an instance of the class is first created and then fit to the training set using the fit_transform method. The resulting transformed data is stored in X_train. The transform method is then used to apply the same transformation to the test set, and the resulting transformed data is stored in X_test.</p><h4>Model Building</h4><p>This code imports several classes from the xgboost, sklearn.linear_model, sklearn.tree, sklearn.ensemble, and sklearn.ensemble modules, which are commonly used for building regression models in Python.</p><ul><li>The XGBRegressor class from the xgboost library is a gradient boosting model that uses decision trees as its base learners. It is a popular choice for building regression models because of its good performance and ability to handle large datasets efficiently.</li><li>The LinearRegression class from the sklearn.linear_model module is a simple linear regression model that fits a linear equation to the data. It is a good choice for modeling linear relationships between variables.</li><li>The DecisionTreeRegressor class from the sklearn.tree module is a decision tree model that splits the data into groups based on the value of a feature. It is a good choice for modeling non-linear relationships between variables.</li><li>The RandomForestRegressor class from the sklearn.ensemble module is an ensemble model that combines multiple decision trees and averages their predictions. It is a good choice for improving the performance of a decision tree model and reducing overfitting.</li><li>The GradientBoostingRegressor class from the sklearn.ensemble module is another gradient boosting model that uses decision trees as its base learners. It is similar to the XGBRegressor class, but has more options for model tuning and is slower to train.</li><li>The AdaBoostRegressor class from the sklearn.ensemble module is an ensemble model that combines multiple weak models and weights their predictions to make a final prediction. It is a good choice for improving the performance of a simple model.</li></ul><pre>from xgboost import XGBRegressor<br>from sklearn.linear_model import LinearRegression<br>from sklearn.tree import DecisionTreeRegressor<br>from sklearn.ensemble import RandomForestRegressor<br>from sklearn.ensemble import GradientBoostingRegressor<br>from sklearn.ensemble import AdaBoostRegressor<br>from sklearn.neighbors import KNeighborsRegressor</pre><pre># Linear Regression<br>lr = LinearRegression()<br>lr.fit(X_train, y_train)<br>lr_pred = lr.predict(X_test)<br>lr_score = lr.score(X_test, y_test)<br>print(&#39;Linear Regression Score: &#39;, lr_score)<br><br># Decision Tree<br>dt = DecisionTreeRegressor()<br>dt.fit(X_train, y_train)<br>dt_pred = dt.predict(X_test)<br>dt_score = dt.score(X_test, y_test)<br>print(&#39;Decision Tree Score: &#39;, dt_score)<br><br># Random Forest<br>rf = RandomForestRegressor()<br>rf.fit(X_train, y_train)<br>rf_pred = rf.predict(X_test)<br>rf_score = rf.score(X_test, y_test)<br>print(&#39;Random Forest Score: &#39;, rf_score)<br><br># XGBoost<br>xgb = XGBRegressor()<br>xgb.fit(X_train, y_train)<br>xgb_pred = xgb.predict(X_test)<br>xgb_score = xgb.score(X_test, y_test)<br>print(&#39;XGBoost Score: &#39;, xgb_score)<br><br># RandomForestRegressor<br>rf = RandomForestRegressor()<br>rf.fit(X_train, y_train)<br>rf_pred = rf.predict(X_test)<br>rf_score = rf.score(X_test, y_test)<br>print(&#39;RandomForestRegressor Score: &#39;, rf_score)<br><br># GradientBoostingRegressor<br>gb = GradientBoostingRegressor()<br>gb.fit(X_train, y_train)<br>gb_pred = gb.predict(X_test)<br>gb_score = gb.score(X_test, y_test)<br>print(&#39;GradientBoostingRegressor Score: &#39;, gb_score)<br><br># AdaBoostRegressor<br>ada = AdaBoostRegressor()<br>ada.fit(X_train, y_train)<br>ada_pred = ada.predict(X_test)<br>ada_score = ada.score(X_test, y_test)<br>print(&#39;AdaBoostRegressor Score: &#39;, ada_score)<br><br># KNeighborsRegressor<br>knn = KNeighborsRegressor()<br>knn.fit(X_train, y_train)<br>knn_pred = knn.predict(X_test)<br>knn_score = knn.score(X_test, y_test)<br>print(&#39;KNeighborsRegressor Score: &#39;, knn_score)</pre><pre>Linear Regression Score:  0.6841216592604057<br>Decision Tree Score:  0.28616030271278814<br>Random Forest Score:  0.69443250417991<br>XGBoost Score:  0.5981049248655365<br>RandomForestRegressor Score:  0.7092322318852047<br>GradientBoostingRegressor Score:  0.6715963944352763<br>AdaBoostRegressor Score:  0.6841751067060653<br>KNeighborsRegressor Score:  0.6816380800543443</pre><h4>Model Evaluation</h4><p>Evaluating a model’s performance is an important step in any data analysis or machine learning project. There are many different ways to evaluate a model’s performance, depending on the specific problem you are trying to solve and the type of model you are using.</p><p>For example, if you are working on a classification problem (e.g. predicting whether someone is happy or not), you might use evaluation metrics such as accuracy, precision, recall, and F1 score to measure how well your model is performing.</p><p>On the other hand, if you are working on a regression problem (e.g. predicting happiness on a continuous scale), you might use evaluation metrics such as mean absolute error (MAE), mean squared error (MSE), and root mean squared error (RMSE) to measure the model’s performance.</p><p>To evaluate a model’s performance, you will typically split your data into a training set and a test set. You will train your model on the training set and then use the test set to evaluate the model’s performance. This helps ensure that the model is not overfitting to the training data and can generalize well to new data.</p><p>It is also important to consider the context of your analysis and the goals of your model. For example, if you are trying to predict happiness around the world, you might want to consider factors such as cultural differences and the impact of specific events on happiness levels. You might also want to consider using multiple evaluation metrics to get a more comprehensive view of the model’s performance.</p><pre>from sklearn.metrics import mean_squared_error<br>from sklearn.metrics import r2_score<br>from sklearn.metrics import mean_absolute_error</pre><p>The code you provided will evaluate the performance of a linear regression model using four different evaluation metrics: mean squared error (MSE), root mean squared error (RMSE), mean absolute error (MAE), and R2 score.</p><p><strong><em>Here is a brief explanation of each metric:</em></strong></p><ul><li>Mean squared error (MSE) is a measure of the average squared difference between the predicted values and the true values. It is calculated by taking the sum of the squared differences and dividing by the number of samples. Lower values of MSE indicate a better fit.</li><li>Root mean squared error (RMSE) is the square root of the MSE. It is a measure of the average magnitude of the error. Lower values of RMSE indicate a better fit.</li><li>Mean absolute error (MAE) is a measure of the average magnitude of the error. It is calculated by taking the absolute value of the difference between the predicted values and the true values and averaging over all samples. Lower values of MAE indicate a better fit.</li><li>R2 score (also known as the coefficient of determination) is a measure of the proportion of the variance in the dependent variable that is explained by the independent variables. It ranges from 0 to 1, with higher values indicating a better fit. An R2 score of 1 indicates that the model perfectly explains the variance in the dependent variable.</li></ul><pre># Linear Regression<br>print(&#39;Linear Regression&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, lr_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, lr_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, lr_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, lr_pred))<br><br>print(&#39;*************************&#39;)<br><br># Decision Tree<br>print(&#39;Decision Tree&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, dt_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, dt_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, dt_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, dt_pred))<br><br>print(&#39;*************************&#39;)<br><br># Random Forest<br>print(&#39;Random Forest&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, rf_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, rf_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, rf_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, rf_pred))<br><br>print(&#39;*************************&#39;)<br><br># XGBoost<br>print(&#39;XGBoost&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, xgb_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, xgb_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, xgb_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, xgb_pred))<br><br>print(&#39;*************************&#39;)  # Add a newline between the output for the two models<br><br># RandomForestRegressor<br>print(&#39;RandomForestRegressor&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, rf_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, rf_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, rf_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, rf_pred))<br><br>print(&#39;*************************&#39;)<br><br># GradientBoostingRegressor<br>print(&#39;GradientBoostingRegressor&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, gb_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, gb_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, gb_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, gb_pred))<br><br>print(&#39;*************************&#39;)<br><br># AdaBoostRegressor<br>print(&#39;AdaBoostRegressor&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, ada_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, ada_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, ada_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, ada_pred))<br><br>print(&#39;*************************&#39;)<br><br># KNeighborsRegressor<br>print(&#39;KNeighborsRegressor&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, knn_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, knn_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, knn_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, knn_pred))</pre><pre>Linear Regression<br>Mean Squared Error: 0.3029439735952702<br>Root Mean Squared Error: 0.5504034643743353<br>Mean Absolute Error: 0.42688322026284425<br>R2 Score: 0.6841216592604057<br>*************************<br>Decision Tree<br>Mean Squared Error: 0.5624305769230769<br>Root Mean Squared Error: 0.7499537165206109<br>Mean Absolute Error: 0.5437307692307694<br>R2 Score: 0.41355612619967286<br>*************************<br>Random Forest<br>Mean Squared Error: 0.2824164245730768<br>Root Mean Squared Error: 0.5314286636728177<br>Mean Absolute Error: 0.38225346153846146<br>R2 Score: 0.7055256437913671<br>*************************<br>XGBoost<br>Mean Squared Error: 0.38543855442742897<br>Root Mean Squared Error: 0.6208369789465097<br>Mean Absolute Error: 0.5258417670910175<br>R2 Score: 0.5981049248655365<br>*************************<br>RandomForestRegressor<br>Mean Squared Error: 0.2824164245730768<br>Root Mean Squared Error: 0.5314286636728177<br>Mean Absolute Error: 0.38225346153846146<br>R2 Score: 0.7055256437913671<br>*************************<br>GradientBoostingRegressor<br>Mean Squared Error: 0.31603251429639845<br>Root Mean Squared Error: 0.562167692327119<br>Mean Absolute Error: 0.44836291139259415<br>R2 Score: 0.67047429578818<br>*************************<br>AdaBoostRegressor<br>Mean Squared Error: 0.28672776810554257<br>Root Mean Squared Error: 0.535469670574854<br>Mean Absolute Error: 0.40385947538218353<br>R2 Score: 0.701030224967776<br>*************************<br>KNeighborsRegressor<br>Mean Squared Error: 0.30532585692307673<br>Root Mean Squared Error: 0.5525629890999547<br>Mean Absolute Error: 0.3932692307692307<br>R2 Score: 0.6816380800543443</pre><h3>Model Tuning</h3><p>Model tuning, also known as hyperparameter optimization or hyperparameter tuning, refers to the process of finding the best values for the hyperparameters of a machine learning model. Hyperparameters are parameters that are set before the model is trained and are not learned from the data during training. They control the model’s behavior and can significantly impact its performance.</p><pre>from sklearn.model_selection import GridSearchCV</pre><pre># Random Forest<br>rf_params = {&quot;max_depth&quot;: [3, 5, 8, None],<br>                &quot;max_features&quot;: [3, 5, 10],<br>                &quot;min_samples_split&quot;: [2, 5, 10],<br>                &quot;min_samples_leaf&quot;: [1, 3, 5, 10],<br>                &quot;bootstrap&quot;: [True, False],<br>                &quot;n_estimators&quot;: [100, 500, 1000],<br>                &quot;random_state&quot;: [42]}<br>rf_cv_model = GridSearchCV(rf, rf_params, cv=5, n_jobs=-1, verbose=2)<br>rf_cv_model.fit(X_train, y_train)<br>print(&quot;Best Parameters: &quot; + str(rf_cv_model.best_params_))<br><br># GradientBoostingRegressor<br>gb_params = {&quot;learning_rate&quot;: [0.01, 0.1, 0.05],<br>                &quot;max_depth&quot;: [3, 5, 8],<br>                &quot;max_features&quot;: [3, 5, 10],<br>                &quot;min_samples_split&quot;: [2, 5, 10],<br>                &quot;min_samples_leaf&quot;: [1, 3, 5, 10],<br>                &quot;n_estimators&quot;: [100, 500, 1000],<br>                &quot;subsample&quot;: [1, 0.5, 0.75],<br>                &quot;random_state&quot;: [42]}<br>gb_cv_model = GridSearchCV(gb, gb_params, cv=5, n_jobs=-1, verbose=2)<br>gb_cv_model.fit(X_train, y_train)<br>print(&quot;Best Parameters: &quot; + str(gb_cv_model.best_params_))<br><br># AdaBoostRegressor<br>ada_params = {&quot;learning_rate&quot;: [0.01, 0.1, 0.05],<br>                &quot;n_estimators&quot;: [100, 500, 1000],<br>                &quot;random_state&quot;: [42]}<br>ada_cv_model = GridSearchCV(ada, ada_params, cv=5, n_jobs=-1, verbose=2)<br>ada_cv_model.fit(X_train, y_train)<br>print(&quot;Best Parameters: &quot; + str(ada_cv_model.best_params_))<br><br># KNeighborsRegressor<br>knn_params = {&quot;n_neighbors&quot;: np.arange(1, 50)}<br>knn_cv_model = GridSearchCV(knn, knn_params, cv=5, n_jobs=-1, verbose=2)<br>knn_cv_model.fit(X_train, y_train)<br>print(&quot;Best Parameters: &quot; + str(knn_cv_model.best_params_))</pre><pre>Fitting 5 folds for each of 9 candidates, totalling 45 fits<br>Best Parameters: {&#39;learning_rate&#39;: 0.05, &#39;n_estimators&#39;: 100, &#39;random_state&#39;: 42}<br>Fitting 5 folds for each of 49 candidates, totalling 245 fits<br>Best Parameters: {&#39;n_neighbors&#39;: 3}</pre><h4>Model Comparison</h4><pre>models = [<br>    RandomForestRegressor(),<br>    GradientBoostingRegressor(),<br>    AdaBoostRegressor(),<br>    KNeighborsRegressor()<br>]<br><br>for model in models:<br>    model.fit(X_train, y_train)<br>    y_pred = model.predict(X_test)<br>    print(model)<br>    print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, y_pred))<br>    print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, y_pred)))<br>    print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, y_pred))<br>    print(&#39;R2 Score:&#39;, r2_score(y_test, y_pred))<br>    print(&#39;---------------------------------------------------&#39;)</pre><pre>RandomForestRegressor()<br>Mean Squared Error: 0.2892094872846152<br>Root Mean Squared Error: 0.5377820072153914<br>Mean Absolute Error: 0.39066615384615405<br>R2 Score: 0.6984425473613733<br>---------------------------------------------------<br>GradientBoostingRegressor()<br>Mean Squared Error: 0.31686866643486644<br>Root Mean Squared Error: 0.5629108867617204<br>Mean Absolute Error: 0.44874855982340944<br>R2 Score: 0.6696024436533756<br>---------------------------------------------------<br>AdaBoostRegressor()<br>Mean Squared Error: 0.29817323290920117<br>Root Mean Squared Error: 0.5460524085737569<br>Mean Absolute Error: 0.3969715415454<br>R2 Score: 0.6890960894632248<br>---------------------------------------------------<br>KNeighborsRegressor()<br>Mean Squared Error: 0.30532585692307673<br>Root Mean Squared Error: 0.5525629890999547<br>Mean Absolute Error: 0.3932692307692307<br>R2 Score: 0.6816380800543443<br>---------------------------------------------------</pre><pre># Random Forest<br>rf_tuned = RandomForestRegressor(bootstrap=False, max_depth=8, max_features=5, min_samples_leaf=1, min_samples_split=2, n_estimators=1000, random_state=42)<br>rf_tuned.fit(X_train, y_train)<br>rf_tuned_pred = rf_tuned.predict(X_test)<br>print(&#39;Random Forest Tuned&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, rf_tuned_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, rf_tuned_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, rf_tuned_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, rf_tuned_pred))<br><br># GradientBoostingRegressor<br>gb_tuned = GradientBoostingRegressor(learning_rate=0.01, max_depth=3, max_features=5, min_samples_leaf=1, min_samples_split=2, n_estimators=1000, random_state=42, subsample=1)<br>gb_tuned.fit(X_train, y_train)<br>gb_tuned_pred = gb_tuned.predict(X_test)<br>print(&#39;GradientBoostingRegressor Tuned&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, gb_tuned_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, gb_tuned_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, gb_tuned_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, gb_tuned_pred))<br><br># AdaBoostRegressor<br>ada_tuned = AdaBoostRegressor(learning_rate=0.01, n_estimators=1000, random_state=42)<br>ada_tuned.fit(X_train, y_train)<br>ada_tuned_pred = ada_tuned.predict(X_test)<br>print(&#39;AdaBoostRegressor Tuned&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, ada_tuned_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, ada_tuned_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, ada_tuned_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, ada_tuned_pred))<br><br># KNeighborsRegressor<br>knn_tuned = KNeighborsRegressor(n_neighbors=3)<br>knn_tuned.fit(X_train, y_train)<br>knn_tuned_pred = knn_tuned.predict(X_test)<br>print(&#39;KNeighborsRegressor Tuned&#39;)<br>print(&#39;Mean Squared Error:&#39;, mean_squared_error(y_test, knn_tuned_pred))<br>print(&#39;Root Mean Squared Error:&#39;, np.sqrt(mean_squared_error(y_test, knn_tuned_pred)))<br>print(&#39;Mean Absolute Error:&#39;, mean_absolute_error(y_test, knn_tuned_pred))<br>print(&#39;R2 Score:&#39;, r2_score(y_test, knn_tuned_pred))</pre><pre>Random Forest Tuned<br>Mean Squared Error: 0.45508467626236465<br>Root Mean Squared Error: 0.6745996414632642<br>Mean Absolute Error: 0.4930034936591129<br>R2 Score: 0.5254852218125935<br>GradientBoostingRegressor Tuned<br>Mean Squared Error: 0.29546406657813795<br>Root Mean Squared Error: 0.5435660645939351<br>Mean Absolute Error: 0.4266534944405497<br>R2 Score: 0.6919209252085536<br>AdaBoostRegressor Tuned<br>Mean Squared Error: 0.284297692788161<br>Root Mean Squared Error: 0.5331957359058314<br>Mean Absolute Error: 0.385970685031292<br>R2 Score: 0.7035640537481176<br>KNeighborsRegressor Tuned<br>Mean Squared Error: 0.4097848888888888<br>Root Mean Squared Error: 0.6401444281479679<br>Mean Absolute Error: 0.4633589743589744<br>R2 Score: 0.5727191096551916</pre><h4>Model Saving</h4><p>The pickle.dump() function is used to serialize an object hierarchy and write it to a file. The first argument to pickle.dump() is the object you want to serialize, and the second argument is a file-like object, such as a file opened in write mode using the open() function. In your code, you are creating new files with the names ‘rf_tuned.pkl’, ‘gb_tuned.pkl’, ‘ada_tuned.pkl’, and ‘knn_tuned.pkl’ and opening them in write mode (‘wb’) before passing them to pickle.dump().</p><p>By serializing the models and saving them to files, you can later load them using the pickle.load() function and use them to make predictions or perform other operations. This can be useful if you want to use the models in a different script or after your Python interpreter has been closed.</p><pre>import pickle<br><br>pickle.dump(rf_tuned, open(&#39;rf_tuned.pkl&#39;, &#39;wb&#39;))<br>pickle.dump(gb_tuned, open(&#39;gb_tuned.pkl&#39;, &#39;wb&#39;))<br>pickle.dump(ada_tuned, open(&#39;ada_tuned.pkl&#39;, &#39;wb&#39;))<br>pickle.dump(knn_tuned, open(&#39;knn_tuned.pkl&#39;, &#39;wb&#39;))</pre><h4>Model Loading</h4><p>The pickle module is a part of the Python Standard Library and provides a way to serialize and deserialize Python objects. The pickle.load() function is used to deserialize a pickled object hierarchy stored in a file, which you can then use to make predictions or perform other operations with the model.</p><pre>import pickle<br><br>rf_tuned = pickle.load(open(&#39;rf_tuned.pkl&#39;, &#39;rb&#39;))<br>gb_tuned = pickle.load(open(&#39;gb_tuned.pkl&#39;, &#39;rb&#39;))<br>ada_tuned = pickle.load(open(&#39;ada_tuned.pkl&#39;, &#39;rb&#39;))<br>knn_tuned = pickle.load(open(&#39;knn_tuned.pkl&#39;, &#39;rb&#39;))</pre><h4>Model Visualization</h4><pre># Random Forest<br>rf_tuned_pred = rf_tuned.predict(X_test)<br>plt.figure(figsize=(10, 5))<br>plt.scatter(y_test, rf_tuned_pred, color=&#39;red&#39;)<br>plt.plot(y_test, y_test, color=&#39;blue&#39;)<br>plt.xlabel(&#39;Actual&#39;)<br>plt.ylabel(&#39;Predicted&#39;)<br>plt.title(&#39;Random Forest Tuned&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/609/0*K9O1V8Eqccccq5b-.png" /></figure><h3>Conclusion</h3><p>We have the results of some final model evaluations for four different models: a random forest model (rf_tuned), a gradient boosting regressor model (gb_tuned), an AdaBoost regressor model (ada_tuned), and a K-nearest neighbors regressor model (knn_tuned).</p><p>For each model, the results include several evaluation metrics: mean squared error (MSE), root mean squared error (RMSE), mean absolute error (MAE), and R2 score.</p><p>The MSE is a measure of the average squared difference between the predicted values and the true values. A lower MSE indicates that the model is making more accurate predictions. The RMSE is the square root of the MSE, which gives the error in the same units as the target variable. The MAE is the average absolute difference between the predicted values and the true values. A lower MAE indicates that the model is making more accurate predictions.</p><p>The R2 score, also known as the coefficient of determination, is a measure of how well the model explains the variance in the target variable. It ranges from 0 to 1, with a higher score indicating a better fit.</p><p>Looking at the results, it appears that the gradient boosting regressor model (gb_tuned) and the AdaBoost regressor model (ada_tuned) have the lowest MSE and RMSE, indicating that they are making more accurate predictions on average. The gradient boosting regressor model also has the highest R2 score, indicating that it is the best at explaining the variance in the target variable.</p><p><em>Thanks for reading this article. You can access the detailed codes of the project and other projects on </em><a href="https://github.com/bozkusemine"><em>my Github account</em></a><em> or </em><a href="https://www.kaggle.com/emineyetm"><em>Kaggle account</em></a><em>. Happy coding!</em></p><p><em>Please feel free to </em><a href="https://www.linkedin.com/in/eminebozkus/"><em>contact me</em></a><em> if you need any further information.</em></p><h3>References</h3><ol><li><a href="https://www.kaggle.com/datasets/unsdsn/world-happiness">https://www.kaggle.com/datasets/unsdsn/world-happiness</a></li><li><a href="https://www.kaggle.com/code/emineyetm/happiness-around-the-world-a-comparative-analysis/notebook">https://www.kaggle.com/code/emineyetm/happiness-around-the-world-a-comparative-analysis/notebook</a></li><li><a href="https://worldhappiness.report/">https://worldhappiness.report/</a></li></ol><p>Subscribe to DDIntel <a href="https://ddintel.datadriveninvestor.com/">Here</a>.</p><p>Visit our website here: <a href="https://www.datadriveninvestor.com/">https://www.datadriveninvestor.com</a></p><p>Join our network here: <a href="https://datadriveninvestor.com/collaborate">https://datadriveninvestor.com/collaborate</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c736858d90f" width="1" height="1" alt=""><hr><p><a href="https://medium.datadriveninvestor.com/insights-from-the-world-happiness-report-a-data-driven-perspective-c736858d90f">Insights from the World Happiness Report: A Data-Driven Perspective</a> was originally published in <a href="https://medium.datadriveninvestor.com/">DataDrivenInvestor</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Top Data Cleaning and Feature Engineering Books Every Data Scientist Should Own]]></title>
            <link>https://eminebozkus.medium.com/the-top-data-cleaning-and-feature-engineering-books-every-data-scientist-should-own-3f6d4200edcd?source=rss-151d1cbb89fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/3f6d4200edcd</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[feature-engineering]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[data-wrangling]]></category>
            <category><![CDATA[data-cleaning]]></category>
            <dc:creator><![CDATA[Emine Bozkus, PhD]]></dc:creator>
            <pubDate>Tue, 27 Dec 2022 13:09:06 GMT</pubDate>
            <atom:updated>2022-12-27T13:09:06.193Z</atom:updated>
            <content:encoded><![CDATA[<p>There are many books available on data cleaning and feature engineering that can be helpful for data scientists. Here are a few that I recommend:</p><h4>1. Data Wrangling with Python: Tips and Tools to Make Your Life Easier- <strong>by Jacqueline Kazil and David Beazley</strong></h4><p>This book covers a wide range of data cleaning and preprocessing techniques, including handling missing values, working with strings and dates, and dealing with messy data. It also covers how to use Python’s pandas library for data manipulation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/0*EqHnByRQrDV6_qm-" /></figure><p>The book begins with an introduction to Python and the fundamental concepts of data wrangling, including how to read and write data, how to explore and summarize data, and how to visualize data using Python libraries such as Pandas, NumPy, and Matplotlib.</p><p>As the book progresses, it covers more advanced topics such as how to work with large datasets, how to perform statistical analysis, and how to use machine learning algorithms to analyze data. It also includes practical examples and exercises to help readers apply what they have learned.</p><p>Overall, “Data Wrangling with Python” is a comprehensive guide to working with data in Python, and is suitable for people who are new to both programming and data analysis. It is a useful resource for anyone who wants to learn how to manipulate, analyze, and visualize data using Python</p><h4><strong>2. Bad Data Handbook: Cleaning Up The Data So You Can Get Back To Work-by </strong>Q. Ethan McCallum</h4><p>The “Bad Data Handbook” is a book that provides guidance on how to identify and fix problems with data. Data quality is an important aspect of any project that involves analysis or decision-making based on data. Poor quality data can lead to incorrect conclusions and ineffective decisions, which can have serious consequences for organizations.</p><p>The book covers a variety of topics related to data quality, including how to identify bad data, how to clean and transform data, and how to maintain data quality over time. It also includes practical tips and best practices for working with data, as well as case studies and real-world examples to illustrate the concepts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/274/0*nraK5BuwsQjqxkmJ" /></figure><p>Some of the key topics covered in the “Bad Data Handbook” include:</p><ul><li>Identifying common problems with data, such as missing values, incorrect data types, and incorrect formatting</li><li>Techniques for cleaning and transforming data, including using functions and scripts, using data quality tools, and working with data in a spreadsheet or database</li><li>Strategies for maintaining data quality, including implementing data governance policies and processes, and using data quality tools and techniques to monitor and improve data quality</li><li>Case studies and examples of how to apply these concepts in real-world situations</li></ul><p>Overall, the “Bad Data Handbook” is a useful resource for anyone who works with data and wants to ensure that they are using high-quality data for their analysis and decision-making.</p><h4>3. Feature Engineering and Selection: A Practical Approach for Predictive Models- by Kjell Johnson and Max Kuhn</h4><p>“Feature Engineering and Selection: A Practical Approach for Predictive Models” is a book that teaches readers how to create and select features for use in predictive modeling. Feature engineering and selection are important aspects of the data science process, as they can significantly affect the accuracy and performance of a predictive model.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/349/0*p2nlZNnCWVlyI-wD.jpg" /></figure><p>The book covers a wide range of topics related to feature engineering and selection, including how to create new features from existing data, how to select the most relevant features for a particular problem, and how to evaluate the effectiveness of different features. It also includes practical examples and case studies to illustrate the concepts and show how they can be applied in real-world situations.</p><p>Some of the key topics covered in “Feature Engineering and Selection” include:</p><ul><li>The role of feature engineering and selection in the data science process</li><li>Techniques for creating and transforming features, including feature extraction, feature selection, and feature construction</li><li>Strategies for evaluating and comparing the effectiveness of different features</li><li>Case studies and examples of how to apply these concepts in real-world situations</li></ul><p>Overall, “Feature Engineering and Selection” is a useful resource for anyone who is interested in predictive modeling and wants to learn more about how to create and select effective features for their models.</p><h4><strong>4. Feature Engineering for Machine Learning: Principles and Techniques for Data Scientists- by Alice Zheng and Amanda Casari</strong></h4><p>“Feature Engineering for Machine Learning” by Alice Zheng and Amanda Casari is a comprehensive guide to the principles and techniques of feature engineering for machine learning.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/381/0*Ky_gT92Ol4LnsQPl.jpg" /></figure><p>The book covers a wide range of topics, including:</p><ul><li>The role of feature engineering in the machine learning process</li><li>Techniques for preprocessing and cleaning data</li><li>Encoding and transforming features</li><li>Feature selection and dimensionality reduction</li><li>Creating new features through feature construction and feature transformation</li><li>Working with different types of data, including numerical, categorical, and text data</li></ul><p>The book also includes practical examples and case studies to illustrate the concepts and techniques discussed. It is suitable for both beginner and experienced data scientists who want to learn more about feature engineering and how to effectively preprocess and transform data for machine learning.</p><h4>5. Python Feature Engineering Cookbook: Over 70 Recipes for Creating, Engineering, and Transforming Features to Build Machine Learning Models- by Soledad Galli</h4><p>Feature engineering is an important step in the machine learning process, as it involves creating and transforming features to make them more suitable for building effective models. The “Python Feature Engineering Cookbook” by Soledad Galli offers a collection of over 70 recipes for creating, engineering, and transforming features in Python.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/405/0*KwWqjo9lCKwj8sGl.jpg" /></figure><p>Some of the topics covered in the book include:</p><ul><li>Working with numerical and categorical features</li><li>Handling missing values</li><li>Encoding categorical features</li><li>Extracting features from text</li><li>Feature selection and dimensionality reduction</li><li>Creating new features through feature transformation and feature construction</li></ul><p>By following the recipes in the book, you can learn how to effectively preprocess and transform your data to improve the performance of your machine learning models. The book also includes practical tips and best practices for feature engineering, making it a useful resource for both beginner and experienced data scientists.</p><h4>6. Best Practices in Data Cleaning: A Complete Guide to Everything You Need to Do Before and After Collecting Your Data- by Jason W. Osborne</h4><p>“Best Practices in Data Cleaning: A Complete Guide to Everything You Need to Do Before and After Collecting Your Data” by Jason W. Osborne is a comprehensive guide to the process of data cleaning, which is an important step in the data preparation process for machine learning and data analysis.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/333/0*SwY3uo8iBU3g4Mr-.jpg" /></figure><p>The book covers a wide range of topics, including:</p><ul><li>The importance of data cleaning and the impact of dirty data on the accuracy of machine learning models</li><li>Techniques for identifying and correcting errors and inconsistencies in data</li><li>Strategies for handling missing values and outliers</li><li>Best practices for data cleaning, including planning, documentation, and testing</li><li>Tips for working with different types of data, including numerical, categorical, and text data</li></ul><p>By following the best practices and techniques outlined in the book, you can ensure that your data is clean and ready for analysis or machine learning. The book is suitable for both beginner and experienced data scientists who want to learn more about data cleaning and how to effectively prepare data for analysis and machine learning.</p><p>🌸<em>Thanks for reading this article. You can access my projects on </em><a href="https://github.com/bozkusemine"><em>my Github account</em></a><em> or </em><a href="https://www.kaggle.com/emineyetm"><em>Kaggle account</em></a><em>. Happy coding!</em></p><p><em>Please feel free to </em><a href="https://www.linkedin.com/in/eminebozkus/"><em>contact me</em></a><em> if you need any further information.</em>🌸</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3f6d4200edcd" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>