Skip to content

Instantly share code, notes, and snippets.

@twisstosin
Created March 3, 2019 20:22
Show Gist options
  • Save twisstosin/c6af43f6e9eed39a2f25270b9de88886 to your computer and use it in GitHub Desktop.
Save twisstosin/c6af43f6e9eed39a2f25270b9de88886 to your computer and use it in GitHub Desktop.
tf_kmeans.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "tf_kmeans.ipynb",
"version": "0.3.2",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true,
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/twisstosin/c6af43f6e9eed39a2f25270b9de88886/tf_kmeans.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"metadata": {
"id": "Xle0dXxNiGGw",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Using TensorFlow Kmeans estimator to segment mall customers\n",
"\n",
"####By Tosin Omotoyinbo\n",
"Companies will not survive if their marketing strategy is dependent upon targeting an entire market. The importance of market segmentation is that it allows a business to precisely reach a consumer with specific needs, wants, and capacity. In the long run, this benefits the company because they are able to use their corporate resources more effectively and make better strategic marketing decisions.\n",
"\n",
"\n",
"This guide trains a mall customers model to segment them based on how much they earn and how much they spend at the mall using kmeans. It's okay if you don't understand all the details; this is a fast-paced overview of a complete TensorFlow program, and we will explain the details as we go.\n",
"\n",
"This guide uses [tf.contrib.factorization.KMeansClustering](https://www.tensorflow.org/api_docs/python/tf/contrib/factorization/KMeansClustering)."
]
},
{
"metadata": {
"id": "zXYxjVKqDmbU",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"# Tensorflow, pandas, pylab and pandas\n",
"import tensorflow as tf\n",
"import pylab as pl\n",
"import pandas as pd\n",
"\n",
"\n",
"# Download our dataset and read into a pandas frame \n",
"url=\"https://raw.githubusercontent.com/DraghiciStefan1984/Kmeans-Clustering-MallCustomers/master/Mall_Customers.csv\"\n",
"dataset = pd.read_csv(url)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "XK6yxwHbR6Cu",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"We will use the [Mall Customers](https://raw.githubusercontent.com/DraghiciStefan1984/Kmeans-Clustering-MallCustomers/master/Mall_Customers.csv) data set which contains customer information for 200 mall customers. This data set is relatively small, but useful in demonstrating clustering, and we will use it to verify that the algorithm works as expected. It's a good starting point for testing and debugging your code, and you can build off of this starting point with your own data or larger datasets. \n",
"\n",
"We will use this 200 customers to train the model, group the customers, and explore ways we can apply this model.\n",
"\n",
"\n",
"### About the dataset\n",
"#### Context\n",
"This data set was created for the purpose of learning customer segmentation concepts, also known as [market basket analysis](https://www.albionresearch.com/data_mining/market_basket.php). We will demonstrate this by using an unsupervised ML technique (KMeans Clustering) in the simplest form.\n",
"\n",
"#### Content\n",
"You own a supermarket mall and, through membership cards, you have some basic data about your customers like Customer ID, age, gender, annual income, and spending score. Spending Score is something you assign to the customer based on defined parameters like customer behavior and purchasing data. (Note that you might even use a separate machine learning model to assign this score, but how the score gets assigned will not be covered here.)\n",
"\n",
"#### Problem Statement \n",
"You want to better understand your customers and what they are like. Instead of trying to give generic experiences, you want to understand them what would be benefitial to each of them so that the sense can be given to marketing team to plan the strategy accordingly."
]
},
{
"metadata": {
"id": "aWDMSfNbntbl",
"colab_type": "code",
"outputId": "5c7ef0d8-601d-4e8b-8765-03b63b946bee",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 359
}
},
"cell_type": "code",
"source": [
"# Check the first 10 rows to have an idea of the structure of the dataset\n",
"dataset.head(10)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>CustomerID</th>\n",
" <th>Genre</th>\n",
" <th>Age</th>\n",
" <th>Annual Income (k$)</th>\n",
" <th>Spending Score (1-100)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Male</td>\n",
" <td>19</td>\n",
" <td>15</td>\n",
" <td>39</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>Male</td>\n",
" <td>21</td>\n",
" <td>15</td>\n",
" <td>81</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>Female</td>\n",
" <td>20</td>\n",
" <td>16</td>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>Female</td>\n",
" <td>23</td>\n",
" <td>16</td>\n",
" <td>77</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>Female</td>\n",
" <td>31</td>\n",
" <td>17</td>\n",
" <td>40</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6</td>\n",
" <td>Female</td>\n",
" <td>22</td>\n",
" <td>17</td>\n",
" <td>76</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>7</td>\n",
" <td>Female</td>\n",
" <td>35</td>\n",
" <td>18</td>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>8</td>\n",
" <td>Female</td>\n",
" <td>23</td>\n",
" <td>18</td>\n",
" <td>94</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>9</td>\n",
" <td>Male</td>\n",
" <td>64</td>\n",
" <td>19</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>10</td>\n",
" <td>Female</td>\n",
" <td>30</td>\n",
" <td>19</td>\n",
" <td>72</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" CustomerID Genre Age Annual Income (k$) Spending Score (1-100)\n",
"0 1 Male 19 15 39\n",
"1 2 Male 21 15 81\n",
"2 3 Female 20 16 6\n",
"3 4 Female 23 16 77\n",
"4 5 Female 31 17 40\n",
"5 6 Female 22 17 76\n",
"6 7 Female 35 18 6\n",
"7 8 Female 23 18 94\n",
"8 9 Male 64 19 3\n",
"9 10 Female 30 19 72"
]
},
"metadata": {
"tags": []
},
"execution_count": 2
}
]
},
{
"metadata": {
"id": "MCj3mL24V4rI",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Explore the data\n",
"\n",
"Let's explore the format of the dataset before training the model. The result shows there are 5 columns - `CustomerID`, `Genre`, `Age`, `Annua Income`, `Spending Score` then we'll check for datatype of each column :"
]
},
{
"metadata": {
"id": "f3wp8xx7n7b1",
"colab_type": "code",
"outputId": "103cc56b-df41-4c26-c528-1840d320fca0",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
}
},
"cell_type": "code",
"source": [
"#checking the total number of rows and columns (to be able to know if there are missing values later)\n",
"dataset.shape"
],
"execution_count": 0,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"(200, 5)"
]
},
"metadata": {
"tags": []
},
"execution_count": 3
}
]
},
{
"metadata": {
"id": "GQwRScwbpD7l",
"colab_type": "code",
"outputId": "847f8375-181c-484a-ae8f-9a9cb1fc4057",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 197
}
},
"cell_type": "code",
"source": [
"dataset.info() # there are no missing values as all the columns has 200 entries properly"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 200 entries, 0 to 199\n",
"Data columns (total 5 columns):\n",
"CustomerID 200 non-null int64\n",
"Genre 200 non-null object\n",
"Age 200 non-null int64\n",
"Annual Income (k$) 200 non-null int64\n",
"Spending Score (1-100) 200 non-null int64\n",
"dtypes: int64(4), object(1)\n",
"memory usage: 7.9+ KB\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "34N0bKPGXfuX",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Preprocess the data\n",
"\n",
"The data must be preprocessed before training. We'll check for null values to so we don't run into null errors"
]
},
{
"metadata": {
"id": "7Hr8hSAppNzy",
"colab_type": "code",
"outputId": "3a11f960-45aa-4dca-de78-958708fa54d1",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 119
}
},
"cell_type": "code",
"source": [
"# Missing values computation\n",
"dataset.isnull().sum()"
],
"execution_count": 0,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"CustomerID 0\n",
"Genre 0\n",
"Age 0\n",
"Annual Income (k$) 0\n",
"Spending Score (1-100) 0\n",
"dtype: int64"
]
},
"metadata": {
"tags": []
},
"execution_count": 5
}
]
},
{
"metadata": {
"id": "fJiQiw8MVGCe",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Selecting features for the model\n",
"Even though we could choose all the available data, we've decided to choose `Annual income` and `Spending Score` as the only 2 features considered to make this tutorial easier to visualize."
]
},
{
"metadata": {
"id": "LTh9aB1RDpna",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"# Seleecting chosen features for the model from dataset\n",
"points = dataset.iloc[:, [3,4]].values\n",
"\n",
"\n",
"# Saving the number of rows in a variable\n",
"num_rows = len(points)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "7m1BKEuIYVUq",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Visualizing the dataset and creating a tensorflow model \n",
"\n",
"Before the model is ready for training, it needs a few more settings. These are added during the model's *initialization* step:"
]
},
{
"metadata": {
"id": "K-tXQTM1Du8a",
"colab_type": "code",
"outputId": "8cc07f92-840c-4b1a-cc6f-d8d29394b37c",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 347
}
},
"cell_type": "code",
"source": [
"# Define function to convert points in our selection to tensors\n",
"def input_fn():\n",
" return tf.train.limit_epochs(tf.convert_to_tensor(points, dtype=tf.float32), num_epochs=1)\n",
"\n",
"# Plot each point in the dataset so we can visualize\n",
"for i in range(num_rows):\n",
"\t\tpl.scatter(points[i][0], points[i][1], c='black')\n",
"pl.show()"
],
"execution_count": 0,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\nNPYPUCz2A0IAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5e23100240>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"metadata": {
"id": "njWmMoqcpPxL",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Understanding how Kmeans works in 6 steps\n",
"\n",
"\n",
"\n",
"1. Select `k` cluster centers (number of groups you want to have or number that would be best). \n",
"\n",
"2. Calculate the distance between each data point and cluster centers.\n",
"\n",
"3. Assign the data point to the cluster center whose distance from the cluster center is minimum of all the cluster centers also called the [within-cluster sum of squares (WCSS)](https://en.wikipedia.org/wiki/K-means_clustering#Description).\n",
"\n",
"4. Recalculate the new cluster center.\n",
"\n",
"5. Recalculate the distance between each data point and new obtained cluster centers.\n",
"\n",
"6. If no data point was reassigned then stop, otherwise repeat from step 3\n",
"\n",
"\n",
"So kmeans in essence helps us with our problem by allowing us to find similarities amongst the data points and sort them into groups (known as clusters).\n",
"\n"
]
},
{
"metadata": {
"id": "uhhhy7Djf1pZ",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Implementing this in Python with TensorFlow :\n",
"We'll be using a method called 'the elblow method' to get the optimal value of k (the best number of clusters to have based on our dataset)."
]
},
{
"metadata": {
"id": "TGt7lrSRgIIF",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Finding the optimal value of k\n",
"\n",
"We will run a few cycles with different values of k, and then use the data we collect below to pick the best k.\n",
"\n",
"#### The Elbow Method\n",
"One method to validate the number of clusters is the [elbow method](https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set#The_elbow_method). The idea of the elbow method is to run k-means clustering on the dataset for a range of values of k (say, k from 1 to 10), and for each value of k calculate the within-cluster sum of squares (WCSS).\n",
"\n",
"Then, plot a line chart of the WCSS for each value of k. If the line chart looks like an arm, then the \"elbow\" on the arm is the value of k that is the best. The idea is that we want a small WCSS, but that the WCSS tends to decrease toward 0 as we increase k (the WCSS is 0 when k is equal to the number of data points in the dataset, because then each data point is its own cluster, and there is no error between it and the center of its cluster). So our goal is to choose a small value of k that still has a low WCSS, and the elbow usually represents where we start to have diminishing returns by increasing k."
]
},
{
"metadata": {
"id": "jAuc3cQNf3zB",
"colab_type": "code",
"outputId": "713dbcd1-fcef-4418-ea07-1fb439740a12",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 4967
}
},
"cell_type": "code",
"source": [
"# Within-cluster sum of squares (WCSS) (i.e. variance)\n",
"wcss=[]\n",
"\n",
"# Create multiple models using different values as k to find optimal value (1-10)\n",
"for i in range(1,11):\n",
" kmeans_checker_model = tf.contrib.factorization.KMeansClustering(\n",
" num_clusters=i, use_mini_batch=False)\n",
" kmeans_checker_model.train(input_fn)\n",
" wcss.append(kmeans_checker_model.score(input_fn))"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpyknkuaem\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpyknkuaem', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e2745c240>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpyknkuaem/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpyknkuaem/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:53\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpyknkuaem/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:53\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 710476.0, score = 710476.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmpyknkuaem/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp4gf9wz8i\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp4gf9wz8i', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e1e2bfcc0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp4gf9wz8i/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmp4gf9wz8i/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:54\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmp4gf9wz8i/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:54\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 246236.0, score = 246236.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmp4gf9wz8i/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpdev1r8kf\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpdev1r8kf', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e23207748>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpdev1r8kf/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpdev1r8kf/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:55\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpdev1r8kf/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:55\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 220035.0, score = 220035.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmpdev1r8kf/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpz6mbb001\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpz6mbb001', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e23bfb2e8>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpz6mbb001/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpz6mbb001/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:56\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpz6mbb001/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:56\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 151836.0, score = 151836.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmpz6mbb001/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp26uedrnu\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp26uedrnu', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e20be3128>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp26uedrnu/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmp26uedrnu/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:57\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmp26uedrnu/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:57\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 124138.0, score = 124138.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmp26uedrnu/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp5_mjjb4q\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp5_mjjb4q', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e1e981b70>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp5_mjjb4q/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmp5_mjjb4q/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:58\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmp5_mjjb4q/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:58\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 123523.0, score = 123523.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmp5_mjjb4q/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp9chj85yu\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp9chj85yu', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e231d9c88>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp9chj85yu/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmp9chj85yu/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:29:59\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmp9chj85yu/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:29:59\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 114909.0, score = 114909.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmp9chj85yu/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp91otp6ad\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp91otp6ad', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e1e9e1710>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp91otp6ad/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmp91otp6ad/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:30:00\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmp91otp6ad/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:30:00\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 112837.0, score = 112837.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmp91otp6ad/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpi9_3d86a\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpi9_3d86a', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e23a7aef0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpi9_3d86a/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpi9_3d86a/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:30:01\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpi9_3d86a/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:30:01\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 111529.0, score = 111529.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmpi9_3d86a/model.ckpt-1\n",
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp1bn1doch\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp1bn1doch', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e215c4860>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp1bn1doch/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmp1bn1doch/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:30:02\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmp1bn1doch/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:30:02\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 110398.0, score = 110398.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmp1bn1doch/model.ckpt-1\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "fvua8kcmZ8LH",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Plotting the elbow graph to know the optimal value of k\n",
"\n",
"Before we train our main model, we should know the best number of clusters to have for our dataset using the elbow method by observing the number at which start having negligible changes in wcss."
]
},
{
"metadata": {
"id": "n8eOXmnVAnqk",
"colab_type": "code",
"outputId": "f3cf1318-6634-4634-ec8f-54942b597d38",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 393
}
},
"cell_type": "code",
"source": [
"# Visualizing the ELBOW method to get the optimal value of K \n",
"print(wcss)\n",
"pl.plot(range(1,11), wcss)\n",
"pl.title('The Elbow Method')\n",
"pl.xlabel('Number of clusters')\n",
"pl.ylabel('wcss')\n",
"pl.show()"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"[710476.0, 246236.0, 220035.0, 151836.0, 124138.0, 123523.0, 114909.0, 112837.0, 111529.0, 110398.0]\n"
],
"name": "stdout"
},
{
"output_type": "display_data",
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAFnCAYAAAA7VkqGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3Xl8VNX9//HXnZkMIWGGZEIChCUQ\n0KAsAaQEAhERcUHbLxWDkG+wtthfrdjali9Io2IoUnChVZSvUNHKFxuhUrQUkaCUoJYQhSiLioKy\nhABZICFkI8vM74/AQGQJaGYmybyfjwcluXPvuecebPKee87cj+FyuVyIiIiI3zL5ugMiIiLiWwoD\nIiIifk5hQERExM8pDIiIiPg5hQERERE/pzAgIiLi5xQGRJqJxx9/nFtvvZVbb72V3r17M3LkSPf3\npaWlTJo0iX/+85/f6xw33nhjvXbP/Hn33Xc5dOgQ1157LQDPP/88jzzySGNc1iXFxMTw61//+rzt\njzzyCDExMQ0eX1hYyIYNGwDq9f/7GD16NFlZWd+7HZGmxOLrDojI5Zk1a5b76xtvvJGnnnqKQYMG\nNfp5nn766Qu2e+jQoUY/1+X48ssvKS0tpU2bNgBUVVWxc+fOyzo2KyuLzZs3M2rUKE92UaTZ050B\nkRbk0KFDTJo0iYSEBH73u9/hdDoB2LZtG+PGjWP06NGMHz+enJyc732usrIyfvGLX3DjjTcyadIk\nCgsLATh8+DCTJ0/mlltu4Y477uCtt94CYMSIERw4cACAtWvX0qdPHyoqKgD461//yhNPPHHB88TF\nxfHuu++6v//www/p27dvvX3ee+89fvjDHzJq1Ch+9rOfcfz4cT777DP+8Ic/kJ6ezm9/+1v3vitX\nruSHP/whI0aMYM2aNQA4nU7+/Oc/u++EzJgxg/LycgB27drF7bffzi233MIf//jH7z1uIk2RwoBI\nC/LRRx/x0ksvsW7dOrKyssjOzqa0tJRf/vKX/O53v+Pdd9/lnnvu4aGHHvre53r//fd59NFH+fe/\n/0379u35y1/+AsBjjz3G4MGDSU9PZ/HixTzxxBMcOnSIuLg4PvnkEwA+/vhjevfuzY4dOwDYunUr\nQ4YMueB5brvtNvcvbYC3336bW2+91f19Tk4O06dPZ/78+WzYsIG4uDhSU1Pp3bs3ycnJ3HLLLfz5\nz38G6n7pV1dX869//Yvf//73PPvsswC88847vP/++6xatYq3336bkpISXn31VQBSU1O55557SE9P\nZ8CAAT67QyLiSQoDIi3IzTffTGBgIMHBwURFRXH06FG2bdtG+/btGTZsGAB33HEHBw8e5PDhwxds\nY9q0aeetGaiqqjpvv+uuu44uXboAcOutt/Lpp59SXV3N5s2bSUpKAqBTp07ExcWxZcsW4uLi+PTT\nTwHYvn07d911F9nZ2e7v4+LiLtifwYMHs2fPHo4dO0ZFRQWffPIJQ4cOdb/+/vvvM3jwYK6++moA\nJkyYwL///W9qa2vPa8vlcjF27FgArr32Wo4ePQpARkYGY8eOJSgoCLPZzJ133sl//vMfTp06xc6d\nOxkzZoz7Olu3bn2pfwKRZklrBkRakDPz6gBms5na2lpKSkrIycmp927aarVy/PhxIiMjz2vjYmsG\nvs3hcLi/ttlsnDhxguLiYlwuFzabzf2a3W7n+PHjjBkzhmXLlnHixAkCAgIYMmQIf/jDH/j666/p\n2LFjvWPOZTabufnmm3nnnXdwOBwMHz4ci+Xsj66TJ0+ydevWetfXpk0biouLL9jWmV/mJpPJPY1y\n/Phx2rZt696vbdu2HDt2zN3GmXE1DAO73d7g2Ig0NwoDIi1cREQE0dHRrFq1qlHbPXHihPvrkpIS\nQkJCCA0NxWQyceLECfcv1+LiYsLCwujcuTPl5eV88MEH9O/fny5dunDo0CG2bdtW753+hYwZM4Y/\n//nPhIaGuu86nHt98fHxLFiw4DtfS7t27eqFh+LiYtq1a+e+htLSUmw2G06ns951i7QUmiYQaeFi\nY2MpKChg+/btQN0c+7Rp0/i+BUu3bdvmnmpYt24d1113HRaLheHDh7NixQoADh48yNatW4mPjwfq\nphb+7//+j4EDBwIQHR3NP/7xjwbDwIABA8jPz2fPnj0MHjy43mvDhw9n69at7kWRO3bscC9GtFgs\nnDx5ssFrueGGG1i9ejUVFRXU1NSwcuVKRowYQWBgIL169XIvYHz77bc5derU5Q6RSLOhOwMiLVxg\nYCALFixg9uzZlJWVERAQwEMPPYRhGBfcf9q0abRq1arettGjR3P33XfX23bjjTcye/ZsvvrqKzp3\n7ux+7sCsWbN49NFHWbVqFQEBATzxxBN07NgRqPtkwKpVqxgwYABQ90v+ueeec4eDizEMg9GjR1NR\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5e23b5c198>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"metadata": {
"id": "Elf_k4jZangK",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Creating and training the model\n",
"\n",
"From the graph we can see that the line forms an elbow between (k= 2 and k=5) and since we're trying to segment our mall customers based on how much they earn and how much they spend at the mall, It would make more sense to select 5 as our optimal k so we have more groups to analyze.\n",
"\n",
"In the previous loop, we trained for the first 10 steps of k so as to get the optimal value, but now that we know the optimal value of k is 5 (from the elbow method), we can now create and train our model using `5` as `k`."
]
},
{
"metadata": {
"id": "bgS0SXmpDxUX",
"colab_type": "code",
"outputId": "c6648b5c-1395-409a-838b-63b87b5a0dd9",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 4151
}
},
"cell_type": "code",
"source": [
"# Create a model from known optimal number of clusters\n",
"\n",
"num_clusters = 5\n",
"kmeans = tf.contrib.factorization.KMeansClustering(\n",
" num_clusters=num_clusters, use_mini_batch=False)\n",
"\n",
"# Train\n",
"num_iterations = 10\n",
"previous_centers = None\n",
"list_of_deltas = []\n",
"for _ in range(num_iterations):\n",
" kmeans.train(input_fn)\n",
" cluster_centers = kmeans.cluster_centers()\n",
" if previous_centers is not None:\n",
" list_of_deltas.append(cluster_centers - previous_centers)\n",
" #print ('delta:', cluster_centers - previous_centers)\n",
" previous_centers = cluster_centers\n",
" print ('score:', kmeans.score(input_fn))\n",
"print ('cluster centers:', cluster_centers)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"INFO:tensorflow:Using default config.\n",
"WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpkh4z03rk\n",
"INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpkh4z03rk', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true\n",
"graph_options {\n",
" rewrite_options {\n",
" meta_optimizer_iterations: ONE\n",
" }\n",
"}\n",
", '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f5e215c4668>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: None.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:04\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:05\n",
"INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 124138.0, score = 124138.0\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1: /tmp/tmpkh4z03rk/model.ckpt-1\n",
"score: 124138.0\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-1\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 124138.0, step = 2\n",
"INFO:tensorflow:Saving checkpoints for 3 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 124138.0.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:05\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-3\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:05\n",
"INFO:tensorflow:Saving dict for global step 3: global_step = 3, loss = 75643.586, score = 75643.586\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 3: /tmp/tmpkh4z03rk/model.ckpt-3\n",
"score: 75643.586\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-3\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 3 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 75643.586, step = 4\n",
"INFO:tensorflow:Saving checkpoints for 5 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 75643.586.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:06\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-5\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:06\n",
"INFO:tensorflow:Saving dict for global step 5: global_step = 5, loss = 55477.582, score = 55477.582\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 5: /tmp/tmpkh4z03rk/model.ckpt-5\n",
"score: 55477.582\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-5\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 5 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 55477.582, step = 6\n",
"INFO:tensorflow:Saving checkpoints for 7 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 55477.582.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:07\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-7\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:07\n",
"INFO:tensorflow:Saving dict for global step 7: global_step = 7, loss = 44470.4, score = 44470.4\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 7: /tmp/tmpkh4z03rk/model.ckpt-7\n",
"score: 44470.4\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-7\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 7 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 44470.4, step = 8\n",
"INFO:tensorflow:Saving checkpoints for 9 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 44470.4.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:08\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-9\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:08\n",
"INFO:tensorflow:Saving dict for global step 9: global_step = 9, loss = 44448.43, score = 44448.43\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 9: /tmp/tmpkh4z03rk/model.ckpt-9\n",
"score: 44448.43\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-9\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 9 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 44448.43, step = 10\n",
"INFO:tensorflow:Saving checkpoints for 11 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 44448.43.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:09\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-11\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:09\n",
"INFO:tensorflow:Saving dict for global step 11: global_step = 11, loss = 44448.43, score = 44448.43\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 11: /tmp/tmpkh4z03rk/model.ckpt-11\n",
"score: 44448.43\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-11\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 11 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 44448.43, step = 12\n",
"INFO:tensorflow:Saving checkpoints for 13 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 44448.43.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:10\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-13\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:10\n",
"INFO:tensorflow:Saving dict for global step 13: global_step = 13, loss = 44448.43, score = 44448.43\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 13: /tmp/tmpkh4z03rk/model.ckpt-13\n",
"score: 44448.43\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-13\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 13 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 44448.43, step = 14\n",
"INFO:tensorflow:Saving checkpoints for 15 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 44448.43.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:11\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-15\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:11\n",
"INFO:tensorflow:Saving dict for global step 15: global_step = 15, loss = 44448.43, score = 44448.43\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 15: /tmp/tmpkh4z03rk/model.ckpt-15\n",
"score: 44448.43\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-15\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 15 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 44448.43, step = 16\n",
"INFO:tensorflow:Saving checkpoints for 17 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 44448.43.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:12\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-17\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:12\n",
"INFO:tensorflow:Saving dict for global step 17: global_step = 17, loss = 44448.43, score = 44448.43\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 17: /tmp/tmpkh4z03rk/model.ckpt-17\n",
"score: 44448.43\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Create CheckpointSaverHook.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-17\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Saving checkpoints for 17 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:loss = 44448.43, step = 18\n",
"INFO:tensorflow:Saving checkpoints for 19 into /tmp/tmpkh4z03rk/model.ckpt.\n",
"INFO:tensorflow:Loss for final step: 44448.43.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Starting evaluation at 2018-10-22-17:31:12\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-19\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n",
"INFO:tensorflow:Evaluation [1/1]\n",
"INFO:tensorflow:Finished evaluation at 2018-10-22-17:31:13\n",
"INFO:tensorflow:Saving dict for global step 19: global_step = 19, loss = 44448.43, score = 44448.43\n",
"INFO:tensorflow:Saving 'checkpoint_path' summary for global step 19: /tmp/tmpkh4z03rk/model.ckpt-19\n",
"score: 44448.43\n",
"cluster centers: [[25.72727 79.36363 ]\n",
" [55.296295 49.51852 ]\n",
" [26.304346 20.913042]\n",
" [86.53846 82.128204]\n",
" [88.2 17.114286]]\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "0i6m62E7o_AU",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Visualising and analysing the model\n",
"\n",
"Now that we've trained our model, let's take a look at it using the pylab library to visualize what we've learned.\n",
"\n"
]
},
{
"metadata": {
"id": "rstlaenEDz8r",
"colab_type": "code",
"outputId": "9b33ab23-2bcb-41b6-b14b-bc39da381858",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 585
}
},
"cell_type": "code",
"source": [
"# Map input points to their clusters\n",
"cluster_indices = list(kmeans.predict_cluster_index(input_fn))\n",
"\n",
"colors = ['orange', 'red', 'blue', 'cyan', 'yellow']\n",
"label_indexes = []\n",
"cluster_counter = 0\n",
"index = 0\n",
"\n",
"for i, point in enumerate(points):\n",
" cluster_index = cluster_indices[i]\n",
" center = cluster_centers[cluster_index]\n",
" if cluster_index not in label_indexes :\n",
" cluster_counter= cluster_counter+1\n",
" label = 'Cluster '+ str(cluster_counter)\n",
" label_indexes.append(cluster_index)\n",
" else :\n",
" label = ''\n",
" \n",
" pl.scatter(points[index][0], points[index][1], c=colors[cluster_index], label = label )\n",
" index = index + 1\n",
"pl.scatter(cluster_centers[:, 0], cluster_centers[:, 1], c='black', s=200, alpha=0.5, label = 'Centroids')\n",
"\n",
"pl.xlabel('Annual Income (k$)')\n",
"pl.ylabel('Spending Score (1-100)')\n",
"pl.legend()\n",
"pl.show()\n",
"print (kmeans.cluster_centers())"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"WARNING:tensorflow:Input graph does not use tf.data.Dataset or contain a QueueRunner. That means predict yields forever. This is probably a mistake.\n",
"INFO:tensorflow:Calling model_fn.\n",
"INFO:tensorflow:Done calling model_fn.\n",
"INFO:tensorflow:Graph was finalized.\n",
"INFO:tensorflow:Restoring parameters from /tmp/tmpkh4z03rk/model.ckpt-19\n",
"INFO:tensorflow:Running local_init_op.\n",
"INFO:tensorflow:Done running local_init_op.\n"
],
"name": "stdout"
},
{
"output_type": "display_data",
"data": {
"image/png": "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\nQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5e23a72080>"
]
},
"metadata": {
"tags": []
}
},
{
"output_type": "stream",
"text": [
"[[25.72727 79.36363 ]\n",
" [55.296295 49.51852 ]\n",
" [26.304346 20.913042]\n",
" [86.53846 82.128204]\n",
" [88.2 17.114286]]\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "p7yjvxQ09rpD",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Interpreting the model \n",
"Here I'm going to give a possible interpretation of this model, although this isn't necessarily the only way it could be interpreted, it's an interpretation that that is valid for our objective.\n",
"\n",
"-\n",
"* *Cluster 1 (Blue Color) -> Customers earning little and spending little* \n",
"* *Cluster 2 (Orange Color) -> Customers earning little but spending a lot* \n",
"* *Cluster 3 (Red Color) -> Customers that spend averagely with respect to thier earnings * \n",
"* *Cluster 4 (Cyan Color) -> Customers earning a lot and also spending a lot * \n",
"* *Cluster 5 (Yellow Color) -> Customers earning a lot but spending little * "
]
},
{
"metadata": {
"id": "q2l47pvS4x_S",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Exploring possible applications\n",
"\n",
"Now that we've gotten an interpretation, we could go on and design business strategies as a result. For example, we could decide to apply this model by sending customers who \"earn more and spend more\" notifications of more premium offers at the mall daily, and we could send those who spend less notifications of sale items.\n",
"\n",
"You can explore other ways to apply this with different datasets.\n",
"\n",
"# Thank You"
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment