Skip to content

Instantly share code, notes, and snippets.

@stevengonsalvez
Last active March 17, 2024 12:04
Show Gist options
  • Save stevengonsalvez/48b7bf8ba6f98d2895899e2d7d95a255 to your computer and use it in GitHub Desktop.
Save stevengonsalvez/48b7bf8ba6f98d2895899e2d7d95a255 to your computer and use it in GitHub Desktop.
customer_browser_analysis
Display the source blob
Display the rendered blob
Raw
{"cells":[{"cell_type":"markdown","metadata":{},"source":["<a href=\"https://colab.research.google.com/gist/stevengonsalvez/48b7bf8ba6f98d2895899e2d7d95a255/ecommerce_analysis_notebook.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["!pip install dask[complete]\n","!pip install \"dask[complete]\"\n","!pip install bokeh==2.4.2\n","!pip install numpy\n","!pip install sklearn\n","!pip install scikit-learn\n","!pip install scipy\n","!pip install pandas matplotlib seaborn\n"]},{"cell_type":"code","execution_count":17,"metadata":{},"outputs":[{"data":{"text/html":["\n"," <div class=\"bk-root\">\n"," <a href=\"https://bokeh.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n"," <span id=\"1424\">Loading BokehJS ...</span>\n"," </div>"]},"metadata":{},"output_type":"display_data"},{"data":{"application/javascript":"\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n const JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"<div style='background-color: #fdd'>\\n\"+\n \"<p>\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"</p>\\n\"+\n \"<ul>\\n\"+\n \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n \"<li>use INLINE resources instead, as so:</li>\\n\"+\n \"</ul>\\n\"+\n \"<code>\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"</code>\\n\"+\n \"</div>\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1424\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js\"];\n const css_urls = [];\n \n\n const inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1424\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));","application/vnd.bokehjs_load.v0+json":""},"metadata":{},"output_type":"display_data"}],"source":["import dask.dataframe as dd\n","from dask.diagnostics import ProgressBar\n","from bokeh.plotting import figure, show, output_notebook\n","from bokeh.models import ColumnDataSource\n","\n","from bokeh.layouts import gridplot\n","from bokeh.palettes import Viridis256\n","import dask.dataframe as dd\n","from dask.diagnostics import ProgressBar\n","from bokeh.plotting import figure, show, output_notebook\n","from bokeh.models import ColumnDataSource\n","from sklearn.preprocessing import StandardScaler\n","from sklearn.cluster import KMeans\n","from scipy.stats import gaussian_kde\n","import numpy as np\n","\n","# Initialize output for notebook\n","output_notebook()"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":[]},{"cell_type":"code","execution_count":3,"metadata":{},"outputs":[],"source":["def load_and_prepare_data(filename):\n"," \"\"\"\n"," Load the dataset and perform basic preparation and cleaning.\n"," \"\"\"\n"," ddf = dd.read_csv(filename, parse_dates=['timestamp'])\n"," # Print columns for debugging\n"," print(\"Columns in the dataset:\", ddf.columns)\n"," # Ensure 'event_type' column exists\n"," assert 'event_type' in ddf.columns, \"'event_type' column not found in the dataset.\"\n"," ddf = ddf.dropna()\n"," ddf['hour'] = ddf['timestamp'].dt.hour\n"," return ddf"]},{"cell_type":"code","execution_count":4,"metadata":{},"outputs":[],"source":["def user_behavior_analysis(ddf):\n"," activity_by_hour = ddf.groupby('hour').size().compute()\n"," \n"," source = ColumnDataSource(data=dict(hour=activity_by_hour.index, counts=activity_by_hour.values))\n"," \n"," p = figure(x_range=(0, 23), height=250, title=\"User Activity by Hour\",\n"," toolbar_location=None, tools=\"\")\n"," \n"," p.vbar(x='hour', top='counts', width=0.9, source=source)\n"," \n"," p.xgrid.grid_line_color = None\n"," p.y_range.start = 0\n"," \n"," show(p)"]},{"cell_type":"code","execution_count":5,"metadata":{},"outputs":[],"source":["def product_category_performance(ddf):\n"," top_categories = ddf[ddf['event_type'] == 'view']['category_string'].value_counts().nlargest(5).compute()\n"," print(top_categories)"]},{"cell_type":"code","execution_count":7,"metadata":{},"outputs":[],"source":["def pricing_strategy_insights(ddf):\n"," average_price_by_category = ddf.groupby('category_string')['price'].mean().compute()\n"," average_price_by_category = average_price_by_category.sort_values(ascending=False)[:10]\n","\n"," source = ColumnDataSource(data=dict(categories=average_price_by_category.index, avg_price=average_price_by_category.values))\n"," \n"," p = figure(x_range=average_price_by_category.index.tolist(), height=250, title=\"Average Price by Category\",\n"," toolbar_location=None, tools=\"\")\n","\n"," p.vbar(x='categories', top='avg_price', width=0.9, source=source)\n","\n"," p.xgrid.grid_line_color = None\n"," p.xaxis.major_label_orientation = \"vertical\"\n"," p.y_range.start = 0\n","\n"," show(p)"]},{"cell_type":"code","execution_count":8,"metadata":{},"outputs":[],"source":["def brand_analysis(ddf):\n"," brand_popularity = ddf[ddf['event_type'] == 'view']['brand'].value_counts().nlargest(10).compute()\n","\n"," source = ColumnDataSource(data=dict(brands=brand_popularity.index, views=brand_popularity.values))\n"," \n"," p = figure(x_range=brand_popularity.index.tolist(), height=250, title=\"Brand Popularity (Views)\",\n"," toolbar_location=None, tools=\"\")\n","\n"," p.vbar(x='brands', top='views', width=0.9, source=source)\n","\n"," p.xgrid.grid_line_color = None\n"," p.xaxis.major_label_orientation = \"vertical\"\n"," p.y_range.start = 0\n","\n"," show(p)"]},{"cell_type":"code","execution_count":15,"metadata":{},"outputs":[],"source":["# %%\n","def segment_users_and_visualize_kde(ddf, feature_to_visualize='price', n_clusters=3):\n"," \"\"\"\n"," Segment users based on interaction patterns and visualize the distribution of a selected feature across segments\n"," using Kernel Density Estimation.\n"," \n"," :param ddf: Dask DataFrame with the ecommerce interactions\n"," :param feature_to_visualize: String name of the feature to visualize with KDE\n"," :param n_clusters: Number of clusters to use for segmentation\n"," \"\"\"\n"," # Ensure the feature exists in the dataframe\n"," assert feature_to_visualize in ddf.columns, f\"'{feature_to_visualize}' not found in the dataset.\"\n"," \n"," # Convert Dask DataFrame to Pandas DataFrame for clustering\n"," pdf = ddf.compute()\n"," \n"," # Assuming clustering based on the selected feature for simplicity\n"," X = pdf[[feature_to_visualize]].dropna().values\n"," X_scaled = StandardScaler().fit_transform(X)\n"," \n"," # Clustering\n"," kmeans = KMeans(n_clusters=n_clusters, random_state=42)\n"," clusters = kmeans.fit_predict(X_scaled)\n"," pdf['cluster'] = clusters\n"," \n"," # Prepare the KDE plot\n"," p = figure(title=f'KDE of {feature_to_visualize} Across Clusters', tools=\"\", background_fill_color=\"#fafafa\")\n"," \n"," # Color palette for clusters\n"," palette = Viridis256[0:len(Viridis256):int(len(Viridis256)/n_clusters)]\n"," \n"," for i, color in zip(range(n_clusters), palette):\n"," subset = pdf[pdf['cluster'] == i][feature_to_visualize].values\n"," if len(subset) > 1: # KDE requires more than one data point\n"," # Calculate the KDE\n"," kde = gaussian_kde(subset)\n"," x_range = np.linspace(subset.min(), subset.max(), 1000)\n"," y = kde(x_range)\n"," p.line(x_range, y, legend_label=f'Cluster {i}', line_width=2, color=color)\n"," \n"," p.legend.location = \"top_right\"\n"," p.legend.title = 'Clusters'\n"," p.xaxis.axis_label = feature_to_visualize\n"," p.yaxis.axis_label = 'Density'\n"," \n"," show(p)\n"]},{"cell_type":"markdown","metadata":{},"source":["# Main execution\n","Replace 'dataset.csv' with the path to your actual dataset file."]},{"cell_type":"code","execution_count":18,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Columns in the dataset: Index(['timestamp', 'event_type', 'product_id', 'category_id',\n"," 'category_string', 'brand', 'price', 'user_id', 'user_session_id'],\n"," dtype='object')\n","Total number of records: 26560620.0\n"]}],"source":["# Example: Count total records (executes computation)\n","ddf = load_and_prepare_data('dataset.csv')\n","\n","total_records = ddf.shape[0].compute()\n","print(f\"Total number of records: {total_records}\")"]},{"cell_type":"code","execution_count":10,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Columns in the dataset: Index(['timestamp', 'event_type', 'product_id', 'category_id',\n"," 'category_string', 'brand', 'price', 'user_id', 'user_session_id'],\n"," dtype='object')\n","[########################################] | 100% Completed | 98.37 s\n"]},{"data":{"text/html":["\n","\n","\n","\n","\n","\n"," <div class=\"bk-root\" id=\"0ab08981-757b-4c08-b36d-a9230385cc80\" data-root-id=\"1005\"></div>\n"]},"metadata":{},"output_type":"display_data"},{"data":{"application/javascript":"(function(root) {\n function embed_document(root) {\n \n const docs_json = {\"f2c93ab9-802a-4fa1-8bb5-6a719a78148c\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1016\"}],\"center\":[{\"id\":\"1019\"},{\"id\":\"1023\"}],\"height\":250,\"left\":[{\"id\":\"1020\"}],\"renderers\":[{\"id\":\"1029\"}],\"title\":{\"id\":\"1006\"},\"toolbar\":{\"id\":\"1024\"},\"toolbar_location\":null,\"x_range\":{\"id\":\"1008\"},\"x_scale\":{\"id\":\"1012\"},\"y_range\":{\"id\":\"1010\"},\"y_scale\":{\"id\":\"1014\"}},\"id\":\"1005\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1012\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1033\"},\"group\":null,\"major_label_policy\":{\"id\":\"1034\"},\"ticker\":{\"id\":\"1021\"}},\"id\":\"1020\",\"type\":\"LinearAxis\"},{\"attributes\":{\"end\":23},\"id\":\"1008\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"1034\",\"type\":\"AllLabels\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"top\":{\"field\":\"counts\"},\"width\":{\"value\":0.9},\"x\":{\"field\":\"hour\"}},\"id\":\"1027\",\"type\":\"VBar\"},{\"attributes\":{},\"id\":\"1036\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1004\"},\"glyph\":{\"id\":\"1026\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1028\"},\"nonselection_glyph\":{\"id\":\"1027\"},\"view\":{\"id\":\"1030\"}},\"id\":\"1029\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#1f77b4\"},\"line_color\":{\"value\":\"#1f77b4\"},\"top\":{\"field\":\"counts\"},\"width\":{\"value\":0.9},\"x\":{\"field\":\"hour\"}},\"id\":\"1026\",\"type\":\"VBar\"},{\"attributes\":{},\"id\":\"1021\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1037\",\"type\":\"AllLabels\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"top\":{\"field\":\"counts\"},\"width\":{\"value\":0.9},\"x\":{\"field\":\"hour\"}},\"id\":\"1028\",\"type\":\"VBar\"},{\"attributes\":{\"start\":0},\"id\":\"1010\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1017\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1014\",\"type\":\"LinearScale\"},{\"attributes\":{\"axis\":{\"id\":\"1020\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1023\",\"type\":\"Grid\"},{\"attributes\":{\"data\":{\"counts\":[178052,327935,639179,954463,1203459,1346691,1440298,1484440,1514572,1493203,1457418,1395629,1365198,1496143,1687597,1863832,1886350,1675688,1288687,821616,461629,274218,171027,133296],\"hour\":{\"__ndarray__\":\"AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAA\",\"dtype\":\"int32\",\"order\":\"little\",\"shape\":[24]}},\"selected\":{\"id\":\"1039\"},\"selection_policy\":{\"id\":\"1038\"}},\"id\":\"1004\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"1004\"}},\"id\":\"1030\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1039\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1038\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"User Activity by Hour\"},\"id\":\"1006\",\"type\":\"Title\"},{\"attributes\":{\"axis\":{\"id\":\"1016\"},\"coordinates\":null,\"grid_line_color\":null,\"group\":null,\"ticker\":null},\"id\":\"1019\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1036\"},\"group\":null,\"major_label_policy\":{\"id\":\"1037\"},\"ticker\":{\"id\":\"1017\"}},\"id\":\"1016\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1033\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1024\",\"type\":\"Toolbar\"}],\"root_ids\":[\"1005\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.2\"}};\n const render_items = [{\"docid\":\"f2c93ab9-802a-4fa1-8bb5-6a719a78148c\",\"root_ids\":[\"1005\"],\"roots\":{\"1005\":\"0ab08981-757b-4c08-b36d-a9230385cc80\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);","application/vnd.bokehjs_exec.v0+json":""},"metadata":{"application/vnd.bokehjs_exec.v0+json":{"id":"1005"}},"output_type":"display_data"}],"source":["with ProgressBar():\n"," user_behavior_analysis(ddf)\n"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["with ProgressBar(): \n"," product_category_performance(ddf)\n"," "]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["with ProgressBar():\n"," pricing_strategy_insights(ddf)\n"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["with ProgressBar():\n"," brand_analysis(ddf)"]},{"cell_type":"code","execution_count":16,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["[########################################] | 100% Completed | 98.19 s\n"]},{"data":{"text/html":["\n","\n","\n","\n","\n","\n"," <div class=\"bk-root\" id=\"24dd5bec-ddc9-4816-b4f0-bcb591b6bd62\" data-root-id=\"1249\"></div>\n"]},"metadata":{},"output_type":"display_data"},{"data":{"application/javascript":"(function(root) {\n function embed_document(root) {\n \n const docs_json = {\"09a9943b-1fea-4b7f-b904-9e769c119adb\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"background_fill_color\":\"#fafafa\",\"below\":[{\"id\":\"1260\"}],\"center\":[{\"id\":\"1263\"},{\"id\":\"1267\"},{\"id\":\"1284\"}],\"left\":[{\"id\":\"1264\"}],\"renderers\":[{\"id\":\"1273\"},{\"id\":\"1290\"},{\"id\":\"1308\"}],\"title\":{\"id\":\"1250\"},\"toolbar\":{\"id\":\"1268\"},\"x_range\":{\"id\":\"1252\"},\"x_scale\":{\"id\":\"1256\"},\"y_range\":{\"id\":\"1254\"},\"y_scale\":{\"id\":\"1258\"}},\"id\":\"1249\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"axis\":{\"id\":\"1264\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1267\",\"type\":\"Grid\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1306\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1258\",\"type\":\"LinearScale\"},{\"attributes\":{\"axis_label\":\"price\",\"coordinates\":null,\"formatter\":{\"id\":\"1280\"},\"group\":null,\"major_label_policy\":{\"id\":\"1281\"},\"ticker\":{\"id\":\"1261\"}},\"id\":\"1260\",\"type\":\"LinearAxis\"},{\"attributes\":{\"label\":{\"value\":\"Cluster 1\"},\"renderers\":[{\"id\":\"1290\"}]},\"id\":\"1303\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1282\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1281\",\"type\":\"AllLabels\"},{\"attributes\":{\"label\":{\"value\":\"Cluster 0\"},\"renderers\":[{\"id\":\"1273\"}]},\"id\":\"1285\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1283\",\"type\":\"Selection\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1271\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1278\",\"type\":\"AllLabels\"},{\"attributes\":{\"axis_label\":\"Density\",\"coordinates\":null,\"formatter\":{\"id\":\"1277\"},\"group\":null,\"major_label_policy\":{\"id\":\"1278\"},\"ticker\":{\"id\":\"1265\"}},\"id\":\"1264\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1270\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1256\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"KDE of price Across Clusters\"},\"id\":\"1250\",\"type\":\"Title\"},{\"attributes\":{\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1305\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1288\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1269\"}},\"id\":\"1274\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1307\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1277\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"items\":[{\"id\":\"1285\"},{\"id\":\"1303\"},{\"id\":\"1323\"}],\"title\":\"Clusters\"},\"id\":\"1284\",\"type\":\"Legend\"},{\"attributes\":{},\"id\":\"1254\",\"type\":\"DataRange1d\"},{\"attributes\":{\"axis\":{\"id\":\"1260\"},\"coordinates\":null,\"group\":null,\"ticker\":null},\"id\":\"1263\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1269\"},\"glyph\":{\"id\":\"1270\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1272\"},\"nonselection_glyph\":{\"id\":\"1271\"},\"view\":{\"id\":\"1274\"}},\"id\":\"1273\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1287\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1268\",\"type\":\"Toolbar\"},{\"attributes\":{\"label\":{\"value\":\"Cluster 2\"},\"renderers\":[{\"id\":\"1308\"}]},\"id\":\"1323\",\"type\":\"LegendItem\"},{\"attributes\":{\"data\":{\"x\":{\"__ndarray__\":\"mpmZmZnkkUD6rUqKVR6SQFvC+3oRWJJAu9asa82RkkAc611cicuSQHz/Dk1FBZNA3BPAPQE/k0A9KHEuvXiTQJ08Ih95spNA/lDTDzXsk0BeZYQA8SWUQL55NfGsX5RAH47m4WiZlEB/opfSJNOUQOC2SMPgDJVAQMv5s5xGlUCg36qkWICVQAH0W5UUupVAYQgNhtDzlUDCHL52jC2WQCIxb2dIZ5ZAgkUgWAShlkDjWdFIwNqWQENugjl8FJdApIIzKjhOl0AEl+Qa9IeXQGSrlQuwwZdAxb9G/Gv7l0Am1PfsJzWYQIboqN3jbphA5vxZzp+omEBGEQu/W+KYQKclvK8XHJlACDptoNNVmUBoTh6Rj4+ZQMhiz4FLyZlAKHeAcgcDmkCJizFjwzyaQOqf4lN/dppASrSTRDuwmkCqyEQ19+maQArd9SWzI5tAa/GmFm9dm0DMBVgHK5ebQCwaCfjm0JtAjC666KIKnEDsQmvZXkScQE1XHMoafpxArmvNuta3nEAOgH6rkvGcQG6UL5xOK51AzqjgjAplnUAvvZF9xp6dQJDRQm6C2J1A8OXzXj4SnkBQ+qRP+kueQLEOVkC2hZ5AESMHMXK/nkByN7ghLvmeQNJLaRLqMp9AMmAaA6Zsn0CTdMvzYaafQPOIfOQd4J9Aqs6W6uwMoEDaWO/iyimgQArjR9uoRqBAOm2g04ZjoEBq9/jLZICgQJuBUcRCnaBAywuqvCC6oED7lQK1/tagQCwgW63c86BAXKqzpboQoUCMNAyemC2hQLy+ZJZ2SqFA7Ei9jlRnoUAc0xWHMoShQExdbn8QoaFAfefGd+69oUCtcR9wzNqhQN37d2iq96FADobQYIgUokA+EClZZjGiQG6agVFETqJAniTaSSJrokDOrjJCAIiiQP44izrepKJALsPjMrzBokBfTTwrmt6iQI/XlCN4+6JAwGHtG1YYo0Dw60UUNDWjQCB2ngwSUqNAUAD3BPBuo0CAik/9zYujQLAUqPWrqKNA4J4A7onFo0AQKVnmZ+KjQEGzsd5F/6NAcT0K1yMcpEA=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[100]},\"y\":{\"__ndarray__\":\"P51sfu+eUT/TlaO52i9YP8BLUuo+e1o/GdItV73iWT9C+NlYhJVXP5n3ORv14VM/MDEg5GVcUD/G1oB6V2pNPzTwNcjNjk0/VjuMMdqZTj91bCQ2Q/9MP4sTV/VlrEg/39TsFQGGRz9rvb+1BShNPyUd/ByKq1I/pMr9CMORVT9vRboJ/oRaPwHJmZK8LWQ/Z3Nicfi7bT+RJ3yuuXxwP31WAVQtg2k/xpyvVGYmXT9LobjTqmVPP30mJsAsZkU/ORHcxm+aQj/rQQBiIz1FP2vnWJnlvE0/F2CiBHUqUz9K4gpRaBVTPwTJIHPkYU0/Q1i6LyoURT+yA7P2uwVDP7QYvd6k1EU/fzHtx9GCSD93zxo5TAxIPygsFKvIfUc/BMef80MXSj/24ochnfdMP25aOY67H04/DmYnKQOmUT9IJ67sD+dYP+4yZJhxI2A/DplZG5oFXz/Sqe2Bl1pVP4SJTNzvIkg/6iXlhI2SPT+qbux1Y680P6mIgTzi9is/JkXipSo4JD/hMlhFHgEkP7pTwXleYyk/FaNvpsquMD/kWhb8yLQzP+Wwsc+bCjQ/NJ1PXqMTMj8MiCkCJ2EuPwMJdgzanic/D2aBt4MnID/gyj25LxUWP4evZkDH8hc/joBUKPhaJD8wCK/fCJUyP4NKK4YyCD8/ahLxSqEWRT/pPpWQZaBFP3pCaUziL0E/5LFwMl18OD9fe/m8rv8xP/DyURmXYSs/ioxdR2mFJz/F1rchuX4oP/F4gQeqByk/tSXpQOC6JT8dI3jGaAUgP5iKkU7PvRU/yV/yL12qET/zc0vtqPITP+XZC6e5GRc/b6PtsTsdFz9C7GlxygEWP/ahD9xTeRY/jzNdCkWrFz+viY+w3E0XP3hGHYWtKBQ/qbuqD8s1ED/cSICpOkEPP2fjuI4SIRM/U+UFs4f0Fj8zmzoJDJ4YP4jXh2d7Fhk/xp+BL7UEGT/zEz4RZ2AaP2iEsMkWbSE/Q7m+T5ISKT+xp2tX7kQvPzK5cX8J1zA/uN1a2me1MT/1AJue5q40PzUfNhgUYTk/vZ7VryKFOT8=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[100]}},\"selected\":{\"id\":\"1322\"},\"selection_policy\":{\"id\":\"1321\"}},\"id\":\"1304\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1280\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1252\",\"type\":\"DataRange1d\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1286\"},\"glyph\":{\"id\":\"1287\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1289\"},\"nonselection_glyph\":{\"id\":\"1288\"},\"view\":{\"id\":\"1291\"}},\"id\":\"1290\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data\":{\"x\":{\"__ndarray__\":\"7FG4HoX/e0DtP8L+I3B8QO0tzN7C4HxA7hvWvmFRfUDuCeCeAMJ9QO/36X6fMn5A8OXzXj6jfkDw0/0+3RN/QPHBBx98hH9A8q8R/xr1f0D5zo3v3DKAQPnFkl8sa4BA+ryXz3ujgED6s5w/y9uAQPqqoa8aFIFA+6GmH2pMgUD7mKuPuYSBQPuPsP8IvYFA/Ia1b1j1gUD8fbrfpy2CQPx0v0/3ZYJA/GvEv0aegkD9YskvltaCQP1Zzp/lDoNA/VDTDzVHg0D+R9h/hH+DQP4+3e/Tt4NA/jXiXyPwg0D+LOfPciiEQP8j7D/CYIRA/xrxrxGZhEAAEvYfYdGEQAAJ+4+wCYVAAAAAAABChUAA9wRwT3qFQAHuCeCesoVAAeUOUO7qhUAC3BPAPSOGQALTGDCNW4ZAAsodoNyThkACwSIQLMyGQAK4J4B7BIdAA68s8Mo8h0ADpjFgGnWHQASdNtBprYdABJQ7QLnlh0AEi0CwCB6IQASCRSBYVohABHlKkKeOiEAFcE8A98aIQAVnVHBG/4hABl5Z4JU3iUAGVV5Q5W+JQAZMY8A0qIlABkNoMITgiUAHOm2g0xiKQAcxchAjUYpACCh3gHKJikAIH3zwwcGKQAgWgWAR+opACA2G0GAyi0AIBItAsGqLQAn7j7D/ootACfKUIE/bi0AK6ZmQnhOMQArgngDuS4xACtejcD2EjEAKzqjgjLyMQArFrVDc9IxAC7yywCstjUAMs7cwe2WNQAyqvKDKnY1ADKHBEBrWjUAMmMaAaQ6OQA2Py/C4Ro5ADYbQYAh/jkANfdXQV7eOQA102kCn745ADmvfsPYnj0AOYuQgRmCPQA5Z6ZCVmI9AD1DuAOXQj0CIo3k4mgSQQAgffPDBIJBAiJp+qOk8kEAIFoFgEVmQQIiRgxg5dZBACA2G0GCRkECIiIiIiK2QQAgEi0CwyZBAiH+N+NflkEAJ+4+w/wGRQIl2kmgnHpFACfKUIE86kUCKbZfYdlaRQArpmZCecpFAimScSMaOkUAK4J4A7qqRQIpbobgVx5FACtejcD3jkUA=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[100]},\"y\":{\"__ndarray__\":\"MAy9Nzs/XD9Fq4w+baNsP4jfQxr7ZXI/7+TY2gQKcD8KSpGVEgJoPwi/d11OsmQ/zIwtZYQ+Yz9hKFh9telgP32h4qo0EWA/WllmK3DiYD8EjB+o6p1gP5Dhi/wr918/yhTkdHo2YD/lipm+cD5fP1zxu3CNa1w/uqpA2K8gWz+8Ve5UZJ5bP1iW+vpQpl0/D+NlVJhxYT9NtpZWhmlkP/Q3Gq+GNGQ/57+LXn80YD94QaI+2Z1XP3ae4BNxelM/mM5A4kzhUj+nWuQ19oNTP1MdL+3Nr1U/gEc+IsvWVz/+jgLJVVZVP5DpOItYV00/81VXEpfLRD9i0SMTnsREP779ex92pUY/wNOwzL5ySz/KZ060FYdUP3YeHzgy1Vo/eQjM3ZbkWT9D4sdK1yBYP/QJfotD9V4/R4bLwYBpZT8KdjQj+KtoP3xzIRWDhGc/wFXgPrUxZD8aiykEb8ZgP4qvCUqtcF4/x8DNrJcEYD+o0dLbfWdfPyVvAA4ZZFg/c3PMXhHjUT/3fcUVBitRP5QHYMomHVI/nQWHbGfhUD+CfmYn5lZNP/BxeVxIwkg/e98g0YMDQz/pAjNtkew9Pz0KKg5ZH0A/JmVqcUO0Qz+5LgAOoZREP8uABfaOPkM/oql65nVqQj+WN2u7oDFBP52C7CdJZUA/0xTzTS+iQz9gKK++rN9HP+i1tesCREY/mulO/YJ2Qj8tvGozh5dEP1RjQVx4aUs/60VVGAPIUD8tbjHBjlpUP3ju8Uyxclg/giO+V28sWT8agBDYndNYPwGBywkHXFw/DDgS4kI0Xj+CM7BiCr9aP7eQPTtt+Vw/72ZRIRooZT+twh5KFW5pP/HhZRC60mQ/B+8uYG3QWj9aYxa7kEtTP1eyoe3J304/Pfy0GTrVRj9Jc0hvGw1EP8A0nmO5YUU/Y74q+6PjQz/kumliQ31AP8kl86xDKEE/R1DGJzdbSD/TZ19ViKxOPwpZuPS0xko/AhZkHTf6QD/Al0ebYng0P5v5QiSPcjA/2AcJSxUJMz/+iYbFDxY4P1MGL/AwbDg/YjV42NiMMD8=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[100]}},\"selected\":{\"id\":\"1302\"},\"selection_policy\":{\"id\":\"1301\"}},\"id\":\"1286\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"1304\"}},\"id\":\"1309\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1286\"}},\"id\":\"1291\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1301\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1322\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1261\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1289\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1321\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1265\",\"type\":\"BasicTicker\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1304\"},\"glyph\":{\"id\":\"1305\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1307\"},\"nonselection_glyph\":{\"id\":\"1306\"},\"view\":{\"id\":\"1309\"}},\"id\":\"1308\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1302\",\"type\":\"Selection\"},{\"attributes\":{\"data\":{\"x\":{\"__ndarray__\":\"KVyPwvUo7D9AvKxudpUVQH7GgxLn0iNA2y6x7RLbLECcS29kn/EyQMv/BVK1dTdA+bOcP8v5O0AUtJmW8D5AQCwOZY37gEJAQ2gwhAbDREBbwvt6EQVHQHIcx3EcR0lAiXaSaCeJS0Ch0F1fMstNQFyVFKueBlBAZ0J6JqQnUUBz79+hqUhSQH+cRR2vaVNAikmrmLSKVECW9hAUuqtVQKKjdo+/zFZArVDcCsXtV0C5/UGGyg5ZQMWqpwHQL1pA0FcNfdVQW0DcBHP42nFcQOix2HPgkl1A9F4+7+WzXkD/C6Rq69RfQIXcBHP4emBAC7O3MHsLYUCRiWru/ZthQBdgHayALGJAnTbQaQO9YkAjDYMnhk1jQKnjNeUI3mNALrroootuZEC0kJtgDv9kQDpnTh6Rj2VAwD0B3BMgZkBGFLSZlrBmQMzqZlcZQWdAUcEZFZzRZ0DXl8zSHmJoQF1uf5Ch8mhA40QyTiSDaUBpG+ULpxNqQO/xl8kppGpAdMhKh6w0a0D6nv1EL8VrQIB1sAKyVWxABkxjwDTmbECMIhZ+t3ZtQBL5yDs6B25AmM97+byXbkAdpi63PyhvQKN84XTCuG9AlSlKmaIkcEDXlCP442xwQBoA/VYltXBAXWvWtWb9cECg1q8UqEVxQONBiXPpjXFAJq1i0irWcUBpGDwxbB5yQKyDFZCtZnJA7+7u7u6uckAyWshNMPdyQHXFoaxxP3NAuDB7C7OHc0D7m1Rq9M9zQD0HLsk1GHRAgHIHKHdgdEDD3eCGuKh0QAZJuuX58HRASbSTRDs5dUCMH22jfIF1QM+KRgK+yXVAEvYfYf8RdkBVYfm/QFp2QJjM0h6ConZA2zesfcPqdkAeo4XcBDN3QGEOXztGe3dAo3k4mofDd0Dm5BH5yAt4QClQ61cKVHhAbLvEtkuceECvJp4VjeR4QPKRd3TOLHlANf1Q0w91eUB4aCoyUb15QLvTA5GSBXpA/j7d79NNekBBqrZOFZZ6QIQVkK1W3npAxoBpDJgme0AJ7EJr2W57QExXHMoat3tAj8L1KFz/e0A=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[100]},\"y\":{\"__ndarray__\":\"WIbaPpnpOj/cHPScXK5UP3gHDvF30GA/O1Ony7e/Yz/jHEeVcylnP0G50FAmBmw/rF0gM0B6bD8dmSnDhVptP0+Zs/T6uW0/Z+PyrN8qbT83dfVHwjJvP7txU/8tOnA/3+ab+jBpbD89IuoaPChqPyVS3QMzLGs/QKIM+OPwaz+2Vh+jxDhrPwsgka6172Y/DUAKtN1gZD81HidzadFpP/yu8DMpgW0/anGxsaJ3bD8NXTgZ01BsP7yfi9iAV2k/f6xSBFeIZz9HeDX2oolnPyTgALz6wWU/9bWsWTFHaD/0nNEiFgh0Pzvmf8TiBXg/fEh+vh/VcD9xDBA3hI9qPzdyotjOmWc/NPTXH/K9aT/MPyhTqDNsP6vQliaU0mg/nXJ4Rz68Zz/xHw1nyUZsP9oSqI7Qkm8/7rf+vJJFbD+iGDID1A1nP/fgN30lNGU/V5mYFUV/az/eNmifWxZqP+xizFfcx2I/IaMUa4loWz/PSwNd3UxWPz5cZW5IiFY/t9roTCfBXT87HRxuuRFjP95Woz4Bi2g/NbPdqxm5aT+2qSSRkJxfP6mwBYLz31s/eG1TscqmZT/6adQeT/htPysVVM/y+28/laT1Aa/hZz/2sofI8KxWP5x4if7TIVE/2DJ9ZDcjVT8zWNYO7dRVP2kRQYYkrl4/DqkNJeMxYj9Tqrw6x0VfP1LgaNMYMVs/lUzKjEqHVD+zb9K6kn1QPxbEesoBh1Q/Zt1NMPqPUD9eHnl1KEFPP4R3v/M4ClM/fv5L5cYMTz9JXzTWpPRUP00cfbErcFc/pJz8W+YJTT8vPZxN2r9MP4CM4AYHo04/JDkjpr9tUD9wzgNyrbdbPy5DZSlz11o/wJkV437wWD+9b+FhAIVcP1JGunbRmFc/LLiTweVCVz++VM0doAxaPw8n/qpdyFI/AQT9bAf3RD+MPvORMe9BPw3wkZ427j0/2xaPAmErRD9VUNxRZw1JP0y8TqA82kM/OgnYBhbaRT/F8ORu6KBFP2YhELupzkc/sTmjT9sdUT8Z0s4eaSVKP3xmxs+R1TM/oL6WOpkQID8=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[100]}},\"selected\":{\"id\":\"1283\"},\"selection_policy\":{\"id\":\"1282\"}},\"id\":\"1269\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1272\",\"type\":\"Line\"}],\"root_ids\":[\"1249\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.2\"}};\n const render_items = [{\"docid\":\"09a9943b-1fea-4b7f-b904-9e769c119adb\",\"root_ids\":[\"1249\"],\"roots\":{\"1249\":\"24dd5bec-ddc9-4816-b4f0-bcb591b6bd62\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);","application/vnd.bokehjs_exec.v0+json":""},"metadata":{"application/vnd.bokehjs_exec.v0+json":{"id":"1249"}},"output_type":"display_data"}],"source":["with ProgressBar():\n"," segment_users_and_visualize(ddf, feature_to_visualize='price', n_clusters=3)"]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.11.3"}},"nbformat":4,"nbformat_minor":2}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment