<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>EDA | Kishan Mistri</title><link>https://deploy-preview-6--kishan-mistri.netlify.app/tag/eda/</link><atom:link href="https://deploy-preview-6--kishan-mistri.netlify.app/tag/eda/index.xml" rel="self" type="application/rss+xml"/><description>EDA</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Wed, 14 Sep 2022 09:37:32 +0000</lastBuildDate><image><url>https://deploy-preview-6--kishan-mistri.netlify.app/media/icon_huc7c9dc13e82656c337473117c97a25ad_25328_512x512_fill_lanczos_center_3.png</url><title>EDA</title><link>https://deploy-preview-6--kishan-mistri.netlify.app/tag/eda/</link></image><item><title>Customer Segmentation Report</title><link>https://deploy-preview-6--kishan-mistri.netlify.app/post/customer-segmentation-report/</link><pubDate>Wed, 14 Sep 2022 09:37:32 +0000</pubDate><guid>https://deploy-preview-6--kishan-mistri.netlify.app/post/customer-segmentation-report/</guid><description>&lt;p>Customer segmentation is a way to identify groups of similar customers. Customers can be segmented on a wide variety of characteristics, such as demographic information, purchase behaviour, and attitudes. This template provides an end-to-end report for processing and segmenting customer purchase data using a K-means clustering algorithm. It also includes a snake plot and heatmap to visualize the resulting clusters and feature importance.&lt;/p>
&lt;ul>
&lt;li>Multiple numerical variables that you can use for clustering.&lt;/li>
&lt;li>No NaN/NA values. You can use &lt;a href="https://app.datacamp.com/workspace/templates/recipe-python-impute-missing-data" target="_blank" rel="noopener">this to impute missing values&lt;/a> if needed.&lt;/li>
&lt;/ul>
&lt;p>The dataset consists of customer data, including purchase recency, frequency, and monetary value. Each row represents a different customer with a distinct customer ID.&lt;/p>
&lt;h2 id="1-loading-packages-and-inspecting-the-data">1. Loading packages and Inspecting the Data&lt;/h2>
&lt;p>The code below imports the packages necessary for data manipulation, visualization, pre-processing, and clustering. It also sets up the visualization style and loads in the data.&lt;/p>
&lt;p>Finally, it inspects the data types and missing values with the &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.info.html" target="_blank" rel="noopener">&lt;code>.info()&lt;/code>&lt;/a> method from &lt;code>pandas&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Load packages&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">matplotlib.pyplot&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">plt&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">seaborn&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">sns&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">sklearn.preprocessing&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">StandardScaler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">sklearn.cluster&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">KMeans&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set visualization style&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">set_style&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;darkgrid&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Load the data and replace with your CSV file path&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">read_csv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;data/customer_data.csv&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Preview the data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div>
&lt;style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
&lt;pre>&lt;code>.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
&lt;/code>&lt;/pre>
&lt;p>&lt;/style>&lt;/p>
&lt;table border="1" class="dataframe">
&lt;thead>
&lt;tr style="text-align: right;">
&lt;th>&lt;/th>
&lt;th>CustomerID&lt;/th>
&lt;th>Recency&lt;/th>
&lt;th>Frequency&lt;/th>
&lt;th>MonetaryValue&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;th>0&lt;/th>
&lt;td>12747&lt;/td>
&lt;td>3&lt;/td>
&lt;td>25&lt;/td>
&lt;td>948.70&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>1&lt;/th>
&lt;td>12748&lt;/td>
&lt;td>1&lt;/td>
&lt;td>888&lt;/td>
&lt;td>7046.16&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>2&lt;/th>
&lt;td>12749&lt;/td>
&lt;td>4&lt;/td>
&lt;td>37&lt;/td>
&lt;td>813.45&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3&lt;/th>
&lt;td>12820&lt;/td>
&lt;td>4&lt;/td>
&lt;td>17&lt;/td>
&lt;td>268.02&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>4&lt;/th>
&lt;td>12822&lt;/td>
&lt;td>71&lt;/td>
&lt;td>9&lt;/td>
&lt;td>146.15&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>...&lt;/th>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3638&lt;/th>
&lt;td>18280&lt;/td>
&lt;td>278&lt;/td>
&lt;td>2&lt;/td>
&lt;td>38.70&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3639&lt;/th>
&lt;td>18281&lt;/td>
&lt;td>181&lt;/td>
&lt;td>2&lt;/td>
&lt;td>31.80&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3640&lt;/th>
&lt;td>18282&lt;/td>
&lt;td>8&lt;/td>
&lt;td>2&lt;/td>
&lt;td>30.70&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3641&lt;/th>
&lt;td>18283&lt;/td>
&lt;td>4&lt;/td>
&lt;td>152&lt;/td>
&lt;td>432.93&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3642&lt;/th>
&lt;td>18287&lt;/td>
&lt;td>43&lt;/td>
&lt;td>15&lt;/td>
&lt;td>395.76&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>3643 rows × 4 columns&lt;/p>
&lt;/div>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check columns for data types and missing values&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">info&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>&amp;lt;class 'pandas.core.frame.DataFrame'&amp;gt;
RangeIndex: 3643 entries, 0 to 3642
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 CustomerID 3643 non-null int64
1 Recency 3643 non-null int64
2 Frequency 3643 non-null int64
3 MonetaryValue 3643 non-null float64
dtypes: float64(1), int64(3)
memory usage: 114.0 KB
&lt;/code>&lt;/pre>
&lt;h2 id="2-exploring-the-data">2. Exploring the Data&lt;/h2>
&lt;p>Based on the evaluation above, you can select columns you wish to inspect further. In this template, three columns are selected from the four columns. CustomerID is omitted because it is an identifier and not useful for clustering.&lt;/p>
&lt;p>The code below reduces the DataFrame to the columns you wish to cluster on and then prints descriptive statistics using the &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.describe.html" target="_blank" rel="noopener">&lt;code>describe()&lt;/code>&lt;/a> method from &lt;code>pandas&lt;/code>.&lt;/p>
&lt;p>Printing descriptive statistics is helpful because K-means clustering has several key assumptions that can be revealed via this exploration:&lt;/p>
&lt;ol>
&lt;li>There is no skewness to the data.&lt;/li>
&lt;li>The variables have the same average values.&lt;/li>
&lt;li>The variables have the same variance.&lt;/li>
&lt;/ol>
&lt;p>If you&amp;rsquo;d like to learn more about pre-processing data for K-means clustering, you can refer to this &lt;a href="https://campus.datacamp.com/courses/customer-segmentation-in-python/data-pre-processing-for-clustering?ex=1" target="_blank" rel="noopener">video&lt;/a> from the course Customer Segmentation in Python.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Select columns for clustering&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">columns_for_clustering&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Recency&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Frequency&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;MonetaryValue&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create new DataFrame with clustering variables&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_features&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">columns_for_clustering&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Print a summary of descriptive statistics&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_features&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">describe&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div>
&lt;style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
&lt;pre>&lt;code>.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
&lt;/code>&lt;/pre>
&lt;p>&lt;/style>&lt;/p>
&lt;table border="1" class="dataframe">
&lt;thead>
&lt;tr style="text-align: right;">
&lt;th>&lt;/th>
&lt;th>Recency&lt;/th>
&lt;th>Frequency&lt;/th>
&lt;th>MonetaryValue&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;th>count&lt;/th>
&lt;td>3643.00000&lt;/td>
&lt;td>3643.000000&lt;/td>
&lt;td>3643.000000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>mean&lt;/th>
&lt;td>90.43563&lt;/td>
&lt;td>18.714247&lt;/td>
&lt;td>370.694387&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>std&lt;/th>
&lt;td>94.44651&lt;/td>
&lt;td>43.754468&lt;/td>
&lt;td>1347.443451&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>min&lt;/th>
&lt;td>1.00000&lt;/td>
&lt;td>1.000000&lt;/td>
&lt;td>0.650000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>25%&lt;/th>
&lt;td>19.00000&lt;/td>
&lt;td>4.000000&lt;/td>
&lt;td>58.705000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>50%&lt;/th>
&lt;td>51.00000&lt;/td>
&lt;td>9.000000&lt;/td>
&lt;td>136.370000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>75%&lt;/th>
&lt;td>139.00000&lt;/td>
&lt;td>21.000000&lt;/td>
&lt;td>334.350000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>max&lt;/th>
&lt;td>365.00000&lt;/td>
&lt;td>1497.000000&lt;/td>
&lt;td>48060.350000&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;p>The &lt;a href="https://seaborn.pydata.org/generated/seaborn.FacetGrid.html" target="_blank" rel="noopener">&lt;code>facetgrid()&lt;/code>&lt;/a> function from &lt;code>seaborn&lt;/code> creates a grid of histograms of the data to be clustered. It serves as a further exploration of the data to determine its skew and whether it needs transformation.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Plot the distributions of the selected variables&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">FacetGrid&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df_features&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">melt&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="c1"># Reformat the DataFrame for plotting purposes&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">col&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;variable&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Split on the &amp;#39;variable&amp;#39; column created by reformating&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sharey&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Turn off shared y-axis&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sharex&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Turn off shared x-axis&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Apply a histogram to the facet grid&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">histplot&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;value&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Adjust the top of the plots to make room for the title&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fig&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">subplots_adjust&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">top&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.8&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create a title&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fig&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">suptitle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Unprocessed Variable Distributions&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fontsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">show&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://user-images.githubusercontent.com/20341930/208640481-c85d002b-1d81-49f2-b8ce-9cd7e2acfc2f.png" alt="png" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Before proceeding, it is crucial to ensure that all columns selected for clustering are numeric. The following code iterates through the reduced DataFrame and checks whether each column is numeric. If it returns &lt;code>True&lt;/code>, then you can proceed with the pre-processing.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">all&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">api&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">types&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">is_numeric_dtype&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_features&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">col&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">col&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">columns_for_clustering&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>True
&lt;/code>&lt;/pre>
&lt;h2 id="3-pre-processing-the-data">3. Pre-processing the Data&lt;/h2>
&lt;p>Based on the grids above, if there is a skew, you will have to complete this step which removes the skew and center the variables. This is the case for the placeholder dataset used in this template and will likely be the case for your data.&lt;/p>
&lt;ul>
&lt;li>First, a log transformation is applied to the data using the &lt;code>numpy&lt;/code> &lt;a href="https://numpy.org/doc/stable/reference/generated/numpy.log.html" target="_blank" rel="noopener">&lt;code>log()&lt;/code>&lt;/a> function. A log transformation unskews the data in preparation for clustering.&lt;/li>
&lt;li>Next, the &lt;code>StandardScaler()&lt;/code> from &lt;a href="https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html" target="_blank" rel="noopener">&lt;code>sklearn.preprocessing&lt;/code>&lt;/a> fits and transforms the log-transformed data. This centers and scales the data in further preparation for clustering.&lt;/li>
&lt;li>Finally, a new DataFrame is created and visualized again to confirm the results.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Perform a log transformation of the data to unskew the data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_log&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_features&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Initialize a standard scaler and fit it&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">scaler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">StandardScaler&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">scaler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_log&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Scale and center the data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_normalized&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">scaler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">transform&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_log&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create a pandas DataFrame of the processed data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_processed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">df_normalized&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">index&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">df_features&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">index&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">df_features&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">columns&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Plot the distributions of the selected variables&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">FacetGrid&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_processed&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">melt&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">col&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;variable&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">histplot&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;value&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fig&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">subplots_adjust&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">top&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.8&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">g&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fig&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">suptitle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Preprocessed Variable Distributions&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fontsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">show&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://user-images.githubusercontent.com/20341930/208640501-9809e47f-9925-4860-998f-2d25d2db0cc0.png" alt="png" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="4-choosing-the-number-of-clusters">4. Choosing the Number of Clusters&lt;/h2>
&lt;p>The next step is to fit a variable number of clusters and plot each cluster&amp;rsquo;s sum-of-squared errors (SSE). The SSE reflects the sum of squared distances from every data point to the cluster center. The aim is to reduce the SSE while still maintaining a reasonable number of clusters.&lt;/p>
&lt;p>By plotting the SSE for each number of clusters, you can identify at what point there are diminishing returns by adding new clusters. This type of plot is called an elbow plot.&lt;/p>
&lt;p>In the code below, you can set the maximum number of clusters you want to plot, and then a loop is used to generate the SSE for each number of clusters. Finally, the &lt;code>seaborn&lt;/code> function &lt;a href="https://seaborn.pydata.org/generated/seaborn.pointplot.html" target="_blank" rel="noopener">&lt;code>pointplot()&lt;/code>&lt;/a> plots a curve with each cluster number and SSE. This allows you to identify the &amp;rsquo;elbow&amp;rsquo; or point where there are only marginal reductions for each additional cluster.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set the maximum number of clusters to plot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">max_clusters&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">10&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Initialize empty dictionary to store sum of squared errors&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">sse&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Fit KMeans and calculate SSE for each k&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">max_clusters&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Initialize KMeans with k clusters&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">kmeans&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">KMeans&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_clusters&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">random_state&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Fit KMeans on the normalized dataset&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">kmeans&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_processed&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Assign sum of squared distances to k element of dictionary&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sse&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">kmeans&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">inertia_&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Initialize a figure of set size&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">figure&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">figsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create an elbow plot of SSE values for each key in the dictionary&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pointplot&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sse&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">keys&lt;/span>&lt;span class="p">()),&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sse&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">values&lt;/span>&lt;span class="p">()))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add labels to the plot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">title&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Elbow Method Plot&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fontsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># Add a title to the plot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">xlabel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Number of Clusters&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># Add x-axis label&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ylabel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;SSE&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># Add y-axis label&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Show the plot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">show&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://user-images.githubusercontent.com/20341930/208640509-b6265b2f-7232-4eee-98b4-3e76c6b76e93.png" alt="png" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="5-clustering-the-data">5. Clustering the Data&lt;/h2>
&lt;p>You can now select an optimal number of clusters based on the elbow plot above by setting &lt;code>k&lt;/code>. In this example, &lt;code>k&lt;/code> is set to 3.&lt;/p>
&lt;p>&lt;a href="https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html" target="_blank" rel="noopener">&lt;code>KMeans()&lt;/code>&lt;/a> from &lt;code>sklearn.cluster&lt;/code> with &lt;code>k&lt;/code> clusters is then fit to the processed data, and the cluster labels are extracted and assigned back to the original data. This allows you to inspect raw data by cluster in later steps.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Choose number of clusters&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">k&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">3&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Initialize KMeans&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kmeans&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">KMeans&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_clusters&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">random_state&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Fit k-means clustering on the normalized data set&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kmeans&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df_processed&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Extract cluster labels&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cluster_labels&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">kmeans&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">labels_&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create a new DataFrame by adding a new cluster column to the original data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_clustered&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">assign&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Cluster&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">cluster_labels&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Preview the clustered DataFrame&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_clustered&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div>
&lt;style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
&lt;pre>&lt;code>.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
&lt;/code>&lt;/pre>
&lt;p>&lt;/style>&lt;/p>
&lt;table border="1" class="dataframe">
&lt;thead>
&lt;tr style="text-align: right;">
&lt;th>&lt;/th>
&lt;th>CustomerID&lt;/th>
&lt;th>Recency&lt;/th>
&lt;th>Frequency&lt;/th>
&lt;th>MonetaryValue&lt;/th>
&lt;th>Cluster&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;th>0&lt;/th>
&lt;td>12747&lt;/td>
&lt;td>3&lt;/td>
&lt;td>25&lt;/td>
&lt;td>948.70&lt;/td>
&lt;td>0&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>1&lt;/th>
&lt;td>12748&lt;/td>
&lt;td>1&lt;/td>
&lt;td>888&lt;/td>
&lt;td>7046.16&lt;/td>
&lt;td>0&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>2&lt;/th>
&lt;td>12749&lt;/td>
&lt;td>4&lt;/td>
&lt;td>37&lt;/td>
&lt;td>813.45&lt;/td>
&lt;td>0&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3&lt;/th>
&lt;td>12820&lt;/td>
&lt;td>4&lt;/td>
&lt;td>17&lt;/td>
&lt;td>268.02&lt;/td>
&lt;td>0&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>4&lt;/th>
&lt;td>12822&lt;/td>
&lt;td>71&lt;/td>
&lt;td>9&lt;/td>
&lt;td>146.15&lt;/td>
&lt;td>2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>...&lt;/th>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;td>...&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3638&lt;/th>
&lt;td>18280&lt;/td>
&lt;td>278&lt;/td>
&lt;td>2&lt;/td>
&lt;td>38.70&lt;/td>
&lt;td>1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3639&lt;/th>
&lt;td>18281&lt;/td>
&lt;td>181&lt;/td>
&lt;td>2&lt;/td>
&lt;td>31.80&lt;/td>
&lt;td>1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3640&lt;/th>
&lt;td>18282&lt;/td>
&lt;td>8&lt;/td>
&lt;td>2&lt;/td>
&lt;td>30.70&lt;/td>
&lt;td>1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3641&lt;/th>
&lt;td>18283&lt;/td>
&lt;td>4&lt;/td>
&lt;td>152&lt;/td>
&lt;td>432.93&lt;/td>
&lt;td>0&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>3642&lt;/th>
&lt;td>18287&lt;/td>
&lt;td>43&lt;/td>
&lt;td>15&lt;/td>
&lt;td>395.76&lt;/td>
&lt;td>2&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>3643 rows × 5 columns&lt;/p>
&lt;/div>
&lt;h2 id="6-inspecting-the-clusters">6. Inspecting the Clusters&lt;/h2>
&lt;h3 id="6a-visualizing-the-raw-values-by-cluster">6a. Visualizing the Raw Values by Cluster&lt;/h3>
&lt;p>The next step is to analyze the unprocessed data by cluster. The &lt;code>pandas&lt;/code> method &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html" target="_blank" rel="noopener">&lt;code>DataFrame.groupby()&lt;/code>&lt;/a>, combined with the &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.core.groupby.GroupBy.size.html" target="_blank" rel="noopener">&lt;code>.size()&lt;/code>&lt;/a> method, returns the total number of rows per &lt;code>Cluster&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Group the data by cluster and calculate the total number of rows per group&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_sizes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df_clustered&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">groupby&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="s2">&amp;#34;Cluster&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">as_index&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Inspect the row counts&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_sizes&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div>
&lt;style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
&lt;pre>&lt;code>.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
&lt;/code>&lt;/pre>
&lt;p>&lt;/style>&lt;/p>
&lt;table border="1" class="dataframe">
&lt;thead>
&lt;tr style="text-align: right;">
&lt;th>&lt;/th>
&lt;th>Cluster&lt;/th>
&lt;th>size&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;th>0&lt;/th>
&lt;td>0&lt;/td>
&lt;td>901&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>1&lt;/th>
&lt;td>1&lt;/td>
&lt;td>1156&lt;/td>
&lt;/tr>
&lt;tr>
&lt;th>2&lt;/th>
&lt;td>2&lt;/td>
&lt;td>1586&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;p>Next, the mean values per cluster are visualized. The data is grouped again, and this time, the &lt;code>pandas&lt;/code> method &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.core.groupby.GroupBy.mean.html" target="_blank" rel="noopener">&lt;code>.mean()&lt;/code>&lt;/a> is used to aggregate the data by cluster and calculate the mean for each variable. Alternatively, the &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.agg.html" target="_blank" rel="noopener">&lt;code>.agg()&lt;/code>&lt;/a> method can also be used to specify specific aggregations for different columns if necessary. Consult the &lt;a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.agg.html" target="_blank" rel="noopener">documentation&lt;/a> for further information on the types of aggregations possible.&lt;/p>
&lt;p>The &lt;code>seaborn&lt;/code> &lt;a href="https://seaborn.pydata.org/generated/seaborn.catplot.html#seaborn.catplot" target="_blank" rel="noopener">&lt;code>catplot()&lt;/code>&lt;/a> function visualizes the means per cluster.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Calculate the mean of feature columns by cluster&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_means&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df_clustered&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">groupby&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="s2">&amp;#34;Cluster&amp;#34;&lt;/span>&lt;span class="p">])[&lt;/span>&lt;span class="n">df_features&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">columns&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">reset_index&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Plot the distributions of the selected variables&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">catplot&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">df_means&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">melt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">id_vars&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Cluster&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="c1"># Transform the data to enable plotting&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">col&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;variable&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Cluster&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">y&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;value&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;bar&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add a title&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">suptitle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Average Values by Cluster&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">1.04&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fontsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Show the plot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">show&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://user-images.githubusercontent.com/20341930/208640524-c4526195-435a-4e6a-b126-9e3758b213a1.png" alt="png" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h3 id="6b-create-a-snake-plot-of-the-clusters">6b. Create a Snake Plot of the Clusters&lt;/h3>
&lt;p>The next step takes the processed data and visualizes the differences between the clusters using a snake plot. This can be helpful in spotting trends or key differences that would not be visible with the raw data.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Assign cluster labels to processed DataFrame&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_processed_clustered&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df_processed&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">assign&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Cluster&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">cluster_labels&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Melt the normalized DataFrame and reset the index&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df_processed_melt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">melt&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df_processed_clustered&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">reset_index&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Assign the cluster labels as the ID&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">id_vars&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;Cluster&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Assign clustering variables as values&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">value_vars&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">df_features&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">columns&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Name the variable and value&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">var_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Metric&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">value_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Value&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Change the figure size&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">figure&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">figsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">6&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add label and titles to the plot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">title&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Snake Plot of Normalized Variables&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fontsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">xlabel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Metric&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ylabel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Average Normalized Value&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Plot a line for each value of the cluster variable&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">lineplot&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">df_processed_melt&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;Metric&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;Value&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">hue&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;Cluster&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">show&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://user-images.githubusercontent.com/20341930/208640535-4c8c2e3a-9862-4335-8dd7-1e60c8bbc5c0.png" alt="png" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h3 id="6c-create-a-heatmap-of-relative-importance">6c. Create a Heatmap of Relative Importance&lt;/h3>
&lt;p>Another technique to help visualize how each segment is distinct is to plot the relative importance. The code below achieves this by doing the following:&lt;/p>
&lt;ul>
&lt;li>First, it calculates the average values for each cluster.&lt;/li>
&lt;li>Next, it calculates the average values for the total population.&lt;/li>
&lt;li>It then divides the cluster averages by the population averages and subtracts one.&lt;/li>
&lt;/ul>
&lt;p>This provides a relative importance score for each of the different features used for clustering. The &lt;code>seaborn&lt;/code> &lt;a href="https://seaborn.pydata.org/generated/seaborn.heatmap.html" target="_blank" rel="noopener">&lt;code>heatmap()&lt;/code>&lt;/a> function plots these relative importances on a red-to-blue colour scale to help visualize the relative importance of each attribute to the segments.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Calculate average RFM values for each cluster&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cluster_avg&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df_clustered&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">groupby&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="s2">&amp;#34;Cluster&amp;#34;&lt;/span>&lt;span class="p">])[&lt;/span>&lt;span class="n">columns_for_clustering&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Calculate average RFM values for the total customer population&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">population_avg&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">columns_for_clustering&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Calculate relative importance of cluster&amp;#39;s attribute value compared to the population&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">relative_imp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">cluster_avg&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">population_avg&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Change the figure size&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">figure&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">figsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add the plot title&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">title&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Relative importance of attributes&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fontsize&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Plot the heatmap&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">heatmap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">relative_imp&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">annot&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">fmt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;.2f&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cmap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">sns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">diverging_palette&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">20&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">220&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">as_cmap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">plt&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">show&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://user-images.githubusercontent.com/20341930/208640551-382662b5-ee68-4881-97c7-f534e0092e79.png" alt="png" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>This concludes the report! Hope you find it enjoyable &amp;amp; insightful.&lt;/p></description></item></channel></rss>