blob: c70f7c53b960075592583e094ed586568a498f00 [file] [log] [blame]
{
"cells": [
{
"cell_type": "markdown",
"id": "83034970",
"metadata": {},
"source": [
"# Distill Example"
]
},
{
"cell_type": "markdown",
"id": "0809cd43",
"metadata": {},
"source": []
},
{
"cell_type": "markdown",
"id": "49900c00",
"metadata": {},
"source": [
"### License"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a54331ad",
"metadata": {},
"outputs": [],
"source": [
"#\n",
"# Copyright 2022 The Applied Research Laboratory for Intelligence and Security (ARLIS)\n",
"#\n",
"# Licensed to the Apache Software Foundation (ASF) under one or more\n",
"# contributor license agreements. See the NOTICE file distributed with\n",
"# this work for additional information regarding copyright ownership.\n",
"# The ASF licenses this file to You under the Apache License, Version 2.0\n",
"# (the \"License\"); you may not use this file except in compliance with\n",
"# the License. You may obtain a copy of the License at\n",
"#\n",
"# http://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"id": "42d170c5",
"metadata": {},
"source": [
"### Imports Used in this Example"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "9d2e506b",
"metadata": {},
"outputs": [],
"source": [
"from elasticsearch import Elasticsearch\n",
"from elasticsearch_dsl import connections\n",
"from elasticsearch_dsl import Search\n",
"from elasticsearch_dsl import Q\n",
"from elasticsearch_dsl.query import MultiMatch, Match\n",
"from collections import Counter, deque\n",
"from itertools import count\n",
"from uuid import uuid4\n",
"\n",
"import sys\n",
"sys.path.append('../')\n",
"\n",
"import distill\n",
"import numpy as np\n",
"import pandas as pd\n",
"from pandas.io.json import json_normalize\n",
"import json\n",
"import itertools\n",
"import networkx as nx\n",
"import hashlib, base64\n",
"import plotly.graph_objects as go"
]
},
{
"cell_type": "markdown",
"id": "b55f549a",
"metadata": {},
"source": [
"## Define Search into Logging Database"
]
},
{
"cell_type": "markdown",
"id": "e5359a48",
"metadata": {},
"source": [
"Using Elasticsearch as a backend, we can create new connection to a test instance and define a search object based on that instance and a specific index to search."
]
},
{
"cell_type": "code",
"execution_count": 109,
"id": "f8eed107",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Elasticsearch([{'host': 'localhost', 'port': 9200}])>\n"
]
}
],
"source": [
"flagonClient = connections.create_connection('flagonTest', hosts=['localhost:9200'], timeout=60)\n",
"\n",
"#TODO describeabs connections\n",
"\n",
"#hello world test\n",
"print(flagonClient)"
]
},
{
"cell_type": "code",
"execution_count": 110,
"id": "6caa6227",
"metadata": {},
"outputs": [],
"source": [
"AleS = Search(using='flagonTest', index=\"userale\")"
]
},
{
"cell_type": "markdown",
"id": "63f4b599",
"metadata": {},
"source": [
"## Define Queries against Log Data"
]
},
{
"cell_type": "markdown",
"id": "88c2b4ea",
"metadata": {},
"source": [
"### Simple Queries"
]
},
{
"cell_type": "code",
"execution_count": 111,
"id": "85cbdaf0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Bool(should=[Match(logType='raw'), Match(logType='custom')])\n"
]
}
],
"source": [
"qLogType = Q(\"match\", logType=\"raw\") | Q(\"match\", logType=\"custom\")\n",
"print(qLogType)"
]
},
{
"cell_type": "code",
"execution_count": 112,
"id": "f3db4b61",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Match(userId='superset-user')\n"
]
}
],
"source": [
"qUserId = Q(\"match\", userId=\"superset-user\")\n",
"print(qUserId)"
]
},
{
"cell_type": "code",
"execution_count": 113,
"id": "a9fa6510",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Bool(must=[Match(sessionID=''), Match(sessionID='')])\n"
]
}
],
"source": [
"qExcludeSession = Q(\"match\", sessionID=\"\") & Q(\"match\", sessionID=\"\")\n",
"print(qExcludeSession)"
]
},
{
"cell_type": "markdown",
"id": "d8f18d58",
"metadata": {},
"source": [
"### Not-As-Simple Queries"
]
},
{
"cell_type": "code",
"execution_count": 114,
"id": "39f94c13",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wildcard(pageUrl={'value': '*/superset/dashboard*'})\n"
]
}
],
"source": [
"qUrl = Q({\"wildcard\": {\n",
" \"pageUrl\": {\n",
" \"value\": \"*/superset/dashboard*\"\n",
" }\n",
"}})\n",
"print(qUrl)"
]
},
{
"cell_type": "markdown",
"id": "e3806738",
"metadata": {},
"source": [
"### Define Filters"
]
},
{
"cell_type": "code",
"execution_count": 115,
"id": "1ae3df5f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Bool(filter=[Bool(must_not=[Terms(type=['keydown', 'mousedown', 'mouseup'])])])\n"
]
}
],
"source": [
"filterEvents = Q('bool', filter=[~Q('terms', type=['keydown', 'mousedown', 'mouseup'])])\n",
"print(filterEvents)"
]
},
{
"cell_type": "markdown",
"id": "218dcf93",
"metadata": {},
"source": [
"## Chained Searches"
]
},
{
"cell_type": "markdown",
"id": "94521da8",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": 116,
"id": "0afab6a0",
"metadata": {},
"outputs": [],
"source": [
"elk_search = AleS \\\n",
" .query(qUrl) \\\n",
" .query(qLogType) \\\n",
" .query(qUserId) \\\n",
" .query(filterEvents) \\\n",
" .extra(track_total_hits=True) #breaks return limit of 10000 hits"
]
},
{
"cell_type": "markdown",
"id": "cfe9411a",
"metadata": {},
"source": [
"NOTE: `.execute()` will only retreive the first 10 hits with additional terms embedded in queries. Use `.scan()` instead if you want to retreive all the hits. We use `.execute()` below for brevity."
]
},
{
"cell_type": "code",
"execution_count": 163,
"id": "7401817d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"12341\n"
]
}
],
"source": [
"ale_dict = {}\n",
"elk_response = elk_search.scan()\n",
"for hit in elk_response:\n",
" logEntry = (hit.to_dict())\n",
" logEntry['uid'] = distill.getUUID(logEntry)\n",
" logEntry['clientTime'] = distill.epoch_to_datetime(logEntry['clientTime'])\n",
" ctr = len(ale_dict)\n",
" ctr += 1\n",
" ale_dict[ctr] = logEntry\n",
"\n",
"print(len(ale_dict))\n",
"#print(ale_dict)"
]
},
{
"cell_type": "markdown",
"id": "b761d6ca",
"metadata": {},
"source": [
"## Data Forensics\n",
"Data Forensics refers to ascertaining what is in our data. We may decide that we filtered to much or too little, and want to re-run our scan through ELK. Or, we may decide just how to apply filters as we go and \"carve\" out new dictionaries with less data, but more of the data we want. The following examples illustrate how to work with UserALE data in a dictionary format to perform data forensics."
]
},
{
"cell_type": "markdown",
"id": "82cd296d",
"metadata": {},
"source": [
"### Sorting\n",
"Getting User logs into a logical sequence can aid in a number of operations down the line."
]
},
{
"cell_type": "markdown",
"id": "74ba205d",
"metadata": {},
"source": [
"A simple lambda function helps in sorting our user log dict by `clientTime` (when logs were written by the client)."
]
},
{
"cell_type": "code",
"execution_count": 118,
"id": "be808aef",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"12305"
]
},
"execution_count": 118,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sorted_data = dict(sorted(ale_dict.items(), key = lambda kv: kv[1]['clientTime']))\n",
"len(sorted_data)"
]
},
{
"cell_type": "markdown",
"id": "8d381225",
"metadata": {},
"source": [
"### Searching\n",
"Before we can filter out what we don't want in our data, we have to be able to be able to describe what we do and don't want. Dictionaries are a fast and efficient way to search through data and Distill provides some supporting libraries for finding the information you want from your user logs."
]
},
{
"cell_type": "markdown",
"id": "89e91341",
"metadata": {},
"source": [
"Distill's `find_meta_values` function uses list comprehensions to quickly provide all the unique values for specific key (e.g., `sessionID`, `userId`)."
]
},
{
"cell_type": "code",
"execution_count": 119,
"id": "bae89caf",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['session_1642013755036',\n",
" 'session_1642561069785',\n",
" 'session_1642012917325',\n",
" 'session_1641584276813',\n",
" 'session_1640200820004',\n",
" 'session_1642626473013',\n",
" 'session_1641502434428',\n",
" 'session_1640029398947',\n",
" 'session_1642562635205',\n",
" 'session_1640118177195',\n",
" 'session_1641844965430',\n",
" 'session_1642004982781']"
]
},
"execution_count": 119,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sessions = distill.find_meta_values('sessionID', sorted_data)\n",
"sessions"
]
},
{
"cell_type": "code",
"execution_count": 120,
"id": "ed519ff9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['superset-user']"
]
},
"execution_count": 120,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"users = distill.find_meta_values('userId', sorted_data)\n",
"users "
]
},
{
"cell_type": "markdown",
"id": "cc3840bf",
"metadata": {},
"source": [
"Relying on the dictionary format, we can quickly create new dictionaries with certain characteristics using simple dictionary comprehensions (e.g., a dictionary with all logs that contain the key: `path`; a dictionarey with all logs where `type`== `click`)."
]
},
{
"cell_type": "code",
"execution_count": 121,
"id": "76139d82",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"12302"
]
},
"execution_count": 121,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"values = ['path']\n",
"sorted_data_paths = {k:v for k, v in sorted_data.items() if any(item in values for item in v.keys())}\n",
"len(sorted_data_paths)"
]
},
{
"cell_type": "code",
"execution_count": 122,
"id": "6bf84749",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"392"
]
},
"execution_count": 122,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"values = ['click']\n",
"sorted_data_paths_clicks = {k:v for k, v in sorted_data_paths.items() if any(item in values for item in v.values())}\n",
"len(sorted_data_paths_clicks)"
]
},
{
"cell_type": "markdown",
"id": "53a86d61",
"metadata": {},
"source": [
"Using the same methods, we can find all logs that refer to a specific DOM element in the field `path`. "
]
},
{
"cell_type": "code",
"execution_count": 123,
"id": "6cbaf33e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1889"
]
},
"execution_count": 123,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ele = ['div.superset-legacy-chart-world-map']\n",
"sorted_data_pathele = {k:v for k, v in sorted_data_paths.items() if any(item in ele for item in v['path'])}\n",
"len(sorted_data_pathele.keys())"
]
},
{
"cell_type": "code",
"execution_count": 124,
"id": "b2b4deff",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 124,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"toggleEle = ['button.ant-btn superset-button css-1mljg09', 'div#chart-id-515.filter_box']\n",
"sorted_data_pathele = {k:v for k, v in sorted_data_paths_clicks.items() if all(item in v['path'] for item in toggleEle)}\n",
"len(sorted_data_pathele.keys()) "
]
},
{
"cell_type": "markdown",
"id": "ecac79e3",
"metadata": {},
"source": [
"## Segmentation\n",
"User data is always nested in time--the things they do, explore, and select are bound to time. Segmentation is the practice of slicing a series of data into a set of epochs (time-bound bins of logs) defined by some characteristic. They can be very general (e.g., 30 second, non-overlapping intervals starting from the beginning of a user session), or they can be very specific (e.g., an epoch when users were interacting with a specific UI element with filters set). Segmentation is generally very challenging and in the realm of 'advanced user analytics'. Distill makes segmentation much easier by supporting data scientists in creating and curating segments as mutable object. See the examples below: "
]
},
{
"cell_type": "markdown",
"id": "8f867369",
"metadata": {},
"source": [
"We want to to be able to create and curate segments without having to rewrite new datasets every time. We're going to start by creating a Master Dictionary for all our interesting segments:"
]
},
{
"cell_type": "code",
"execution_count": 125,
"id": "10e34203",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{}"
]
},
"execution_count": 125,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"superSegments = {}\n",
"superSegments"
]
},
{
"cell_type": "markdown",
"id": "0d991926",
"metadata": {},
"source": [
"### Finding Deadspace\n",
"In one case we might want to readily identify epochs within user sessions wherein users aren't doing anything. We call this \"deadspace\"--a user might have started doing something else AFK, but we have no user behavior to indicate they've switch tasks (e.g., `blur` event). Deadspace can be useful to identify; we can omit it from other segments if we need to. Distill's `detect_deadspace` function is helpful for finding deadspace:"
]
},
{
"cell_type": "code",
"execution_count": 126,
"id": "47553657",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deadSpace1 Segment_Type.DEADSPACE (1640029869288, 1640030063271) 193.983 4 [350, 301, 346, 347]\n",
"deadSpace2 Segment_Type.DEADSPACE (1640030219069, 1640098958897) 68739.828 2 [840, 924]\n",
"deadSpace3 Segment_Type.DEADSPACE (1640098969598, 1640099715182) 745.584 2 [991, 990]\n",
"deadSpace4 Segment_Type.DEADSPACE (1640099716927, 1640118186776) 18469.849 3 [1007, 674, 1126]\n",
"deadSpace5 Segment_Type.DEADSPACE (1640118296632, 1640182567282) 64270.65 6 [782, 981, 1121, 1222, 1227, 1241]\n",
"deadSpace6 Segment_Type.DEADSPACE (1640182573419, 1640201030250) 18456.831 3 [1231, 1426, 1589]\n",
"deadSpace7 Segment_Type.DEADSPACE (1640201075969, 1640201157009) 81.04 2 [1651, 1819]\n",
"deadSpace8 Segment_Type.DEADSPACE (1640201172007, 1640201332691) 160.684 2 [1812, 1869]\n",
"deadSpace9 Segment_Type.DEADSPACE (1640201346787, 1640201425011) 78.224 4 [1974, 2102, 2118, 2127]\n",
"deadSpace10 Segment_Type.DEADSPACE (1640201494535, 1640201568436) 73.901 4 [2183, 2184, 2185, 2186]\n",
"deadSpace11 Segment_Type.DEADSPACE (1640201578551, 1640201708691) 130.14 6 [2081, 2083, 2176, 2045, 2046, 2047]\n",
"deadSpace12 Segment_Type.DEADSPACE (1640201899707, 1640201968335) 68.628 3 [2859, 2876, 2877]\n",
"deadSpace13 Segment_Type.DEADSPACE (1640202073587, 1641502449931) 1300376.344 3 [3040, 3049, 3061]\n",
"deadSpace14 Segment_Type.DEADSPACE (1641502510070, 1641584293776) 81783.706 3 [3018, 4019, 4020]\n",
"deadSpace15 Segment_Type.DEADSPACE (1641584454611, 1641584584359) 129.748 2 [3969, 3519]\n",
"deadSpace16 Segment_Type.DEADSPACE (1641584657254, 1641584742169) 84.915 2 [4055, 4072]\n",
"deadSpace17 Segment_Type.DEADSPACE (1641584821749, 1641585078332) 256.583 2 [3315, 3316]\n",
"deadSpace18 Segment_Type.DEADSPACE (1641585114110, 1641585228031) 113.921 2 [3739, 3745]\n",
"deadSpace19 Segment_Type.DEADSPACE (1641585237896, 1641585458459) 220.563 2 [3580, 3408]\n",
"deadSpace20 Segment_Type.DEADSPACE (1641585467013, 1641846627837) 261160.824 3 [3582, 7240, 7242]\n",
"deadSpace21 Segment_Type.DEADSPACE (1641846637675, 1641849234850) 2597.175 2 [5053, 5054]\n",
"deadSpace22 Segment_Type.DEADSPACE (1641849676536, 1641910810485) 61133.949 2 [7238, 7263]\n",
"deadSpace23 Segment_Type.DEADSPACE (1641910811783, 1641961009794) 50198.011 2 [7262, 7282]\n",
"deadSpace24 Segment_Type.DEADSPACE (1641961062271, 1641963232792) 2170.521 4 [7281, 7284, 7285, 7286]\n",
"deadSpace25 Segment_Type.DEADSPACE (1641963235873, 1642004991756) 41755.883 4 [7279, 7287, 7906, 7907]\n",
"deadSpace26 Segment_Type.DEADSPACE (1642005017893, 1642005128878) 110.985 2 [7680, 7709]\n",
"deadSpace27 Segment_Type.DEADSPACE (1642005129089, 1642005196721) 67.632 2 [7708, 7691]\n",
"deadSpace28 Segment_Type.DEADSPACE (1642005199678, 1642013738275) 8538.597 3 [7747, 7912, 7913]\n",
"deadSpace29 Segment_Type.DEADSPACE (1642013783536, 1642013854497) 70.961 2 [7335, 7336]\n",
"deadSpace30 Segment_Type.DEADSPACE (1642013961974, 1642014461416) 499.442 2 [8147, 8432]\n",
"deadSpace31 Segment_Type.DEADSPACE (1642014578838, 1642014670475) 91.637 2 [8738, 8379]\n",
"deadSpace32 Segment_Type.DEADSPACE (1642014723082, 1642015133292) 410.21 2 [8794, 8731]\n",
"deadSpace33 Segment_Type.DEADSPACE (1642015161819, 1642015236013) 74.194 2 [8577, 8618]\n",
"deadSpace34 Segment_Type.DEADSPACE (1642015271091, 1642015659247) 388.156 2 [8682, 8678]\n",
"deadSpace35 Segment_Type.DEADSPACE (1642015701502, 1642015925856) 224.354 2 [8690, 8712]\n",
"deadSpace36 Segment_Type.DEADSPACE (1642015928230, 1642016248803) 320.573 2 [8730, 8802]\n",
"deadSpace37 Segment_Type.DEADSPACE (1642016278737, 1642018691736) 2412.999 2 [8956, 8909]\n",
"deadSpace38 Segment_Type.DEADSPACE (1642018770931, 1642561099479) 542328.548 2 [8938, 9020]\n",
"deadSpace39 Segment_Type.DEADSPACE (1642561100398, 1642561241813) 141.415 2 [9072, 9108]\n",
"deadSpace40 Segment_Type.DEADSPACE (1642561252257, 1642561320627) 68.37 2 [9070, 9124]\n",
"deadSpace41 Segment_Type.DEADSPACE (1642561588507, 1642561806420) 217.913 2 [9469, 9470]\n",
"deadSpace42 Segment_Type.DEADSPACE (1642561840009, 1642561903885) 63.876 2 [9691, 9755]\n",
"deadSpace43 Segment_Type.DEADSPACE (1642561989927, 1642562053670) 63.743 2 [10005, 10016]\n",
"deadSpace44 Segment_Type.DEADSPACE (1642562185295, 1642562247581) 62.286 2 [10172, 10272]\n",
"deadSpace45 Segment_Type.DEADSPACE (1642562253855, 1642562316596) 62.741 2 [10229, 10230]\n",
"deadSpace46 Segment_Type.DEADSPACE (1642562433438, 1642562501117) 67.679 2 [10435, 10444]\n",
"deadSpace47 Segment_Type.DEADSPACE (1642562644232, 1642563245456) 601.224 2 [10647, 10660]\n",
"deadSpace48 Segment_Type.DEADSPACE (1642563558577, 1642568294888) 4736.311 4 [11876, 11839, 11840, 11841]\n",
"deadSpace49 Segment_Type.DEADSPACE (1642568310491, 1642626477474) 58166.983 3 [11783, 11637, 11638]\n",
"deadSpace50 Segment_Type.DEADSPACE (1642626559946, 1642642862736) 16302.79 2 [11838, 12288]\n",
"deadSpace51 Segment_Type.DEADSPACE (1642642866908, 1642646440472) 3573.564 2 [12294, 12295]\n",
"deadSpace52 Segment_Type.DEADSPACE (1642646442067, 1642648050144) 1608.077 2 [12292, 12293]\n",
"deadSpace53 Segment_Type.DEADSPACE (1642648052957, 1642654564752) 6511.795 2 [12302, 12299]\n"
]
}
],
"source": [
"deadSpaceSegments = distill.detect_deadspace(sorted_data_paths, 60, 0, 0)\n",
"for counter, d in enumerate(deadSpaceSegments.values(), start=1):\n",
" d.segment_name = str(\"deadSpace\" + str(counter)) #renaming segment names on the fly\n",
" d.segment_length_sec = (d.start_end_val[1] - d.start_end_val[0])/1000 #adding custom segment-object attributes\n",
" print(d.segment_name, d.segment_type, d.start_end_val, d.segment_length_sec, d.num_logs, d.uids)"
]
},
{
"cell_type": "markdown",
"id": "c946342d",
"metadata": {},
"source": [
"Distill is designed to supplement forensic workflows. We might learn that segmenting one way doesn't work. We can easily modify parameters with review and modify quickly. In this case we may need to assume that 1 minute of 'deadspace' is normal use, we can revise our timing parameters and return a more reasonable solution:"
]
},
{
"cell_type": "code",
"execution_count": 191,
"id": "dc130a1f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deadSpace1 Segment_Type.DEADSPACE (1640030219069, 1640098958897) 68739.828 2 [840, 924]\n",
"deadSpace2 Segment_Type.DEADSPACE (1640098969598, 1640099715182) 745.584 2 [991, 990]\n",
"deadSpace3 Segment_Type.DEADSPACE (1640099716927, 1640118186776) 18469.849 3 [1007, 674, 1126]\n",
"deadSpace4 Segment_Type.DEADSPACE (1640118296632, 1640182567282) 64270.65 6 [782, 981, 1121, 1222, 1227, 1241]\n",
"deadSpace5 Segment_Type.DEADSPACE (1640182573419, 1640201030250) 18456.831 3 [1231, 1426, 1589]\n",
"deadSpace6 Segment_Type.DEADSPACE (1640202073587, 1641502449931) 1300376.344 3 [3040, 3049, 3061]\n",
"deadSpace7 Segment_Type.DEADSPACE (1641502510070, 1641584293776) 81783.706 3 [3018, 4019, 4020]\n",
"deadSpace8 Segment_Type.DEADSPACE (1641585467013, 1641846627837) 261160.824 3 [3582, 7240, 7242]\n",
"deadSpace9 Segment_Type.DEADSPACE (1641846637675, 1641849234850) 2597.175 2 [5053, 5054]\n",
"deadSpace10 Segment_Type.DEADSPACE (1641849676536, 1641910810485) 61133.949 2 [7238, 7263]\n",
"deadSpace11 Segment_Type.DEADSPACE (1641910811783, 1641961009794) 50198.011 2 [7262, 7282]\n",
"deadSpace12 Segment_Type.DEADSPACE (1641961062271, 1641963232792) 2170.521 4 [7281, 7284, 7285, 7286]\n",
"deadSpace13 Segment_Type.DEADSPACE (1641963235873, 1642004991756) 41755.883 4 [7279, 7287, 7906, 7907]\n",
"deadSpace14 Segment_Type.DEADSPACE (1642005199678, 1642013738275) 8538.597 3 [7747, 7912, 7913]\n",
"deadSpace15 Segment_Type.DEADSPACE (1642013961974, 1642014461416) 499.442 2 [8147, 8432]\n",
"deadSpace16 Segment_Type.DEADSPACE (1642014723082, 1642015133292) 410.21 2 [8794, 8731]\n",
"deadSpace17 Segment_Type.DEADSPACE (1642015271091, 1642015659247) 388.156 2 [8682, 8678]\n",
"deadSpace18 Segment_Type.DEADSPACE (1642016278737, 1642018691736) 2412.999 2 [8956, 8909]\n",
"deadSpace19 Segment_Type.DEADSPACE (1642018770931, 1642561099479) 542328.548 2 [8938, 9020]\n",
"deadSpace20 Segment_Type.DEADSPACE (1642562644232, 1642563245456) 601.224 2 [10647, 10660]\n",
"deadSpace21 Segment_Type.DEADSPACE (1642563558577, 1642568294888) 4736.311 4 [11876, 11839, 11840, 11841]\n",
"deadSpace22 Segment_Type.DEADSPACE (1642568310491, 1642626477474) 58166.983 3 [11783, 11637, 11638]\n",
"deadSpace23 Segment_Type.DEADSPACE (1642626559946, 1642642862736) 16302.79 2 [11838, 12288]\n",
"deadSpace24 Segment_Type.DEADSPACE (1642642866908, 1642646440472) 3573.564 2 [12294, 12295]\n",
"deadSpace25 Segment_Type.DEADSPACE (1642646442067, 1642648050144) 1608.077 2 [12292, 12293]\n",
"deadSpace26 Segment_Type.DEADSPACE (1642648052957, 1642654564752) 6511.795 2 [12302, 12299]\n"
]
}
],
"source": [
"deadSpaceSegments = distill.detect_deadspace(sorted_data_paths, 360, 0, 0)\n",
"for counter, d in enumerate(deadSpaceSegments.values(), start=1):\n",
" d.segment_name = str(\"deadSpace\" + str(counter)) #renaming segment names on the fly\n",
" d.segment_length_sec = (d.start_end_val[1] - d.start_end_val[0])/1000 #adding custom segment-object attributes\n",
" print(d.segment_name, d.segment_type, d.start_end_val, d.segment_length_sec, d.num_logs, d.uids)"
]
},
{
"cell_type": "code",
"execution_count": 189,
"id": "2efcd5ed",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys([840, 991, 1007, 1121, 1231, 3040, 3018, 3582, 5053, 7238, 7262, 7281, 7287, 7747, 8147, 8794, 8682, 8956, 8938, 10647, 11876, 11783, 11838, 12294, 12292, 12302])"
]
},
"execution_count": 189,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"deadSpaceSegments.keys()"
]
},
{
"cell_type": "markdown",
"id": "f593d800",
"metadata": {},
"source": [
"Add the revised deadspace segments to the Master Dictionary of segments:"
]
},
{
"cell_type": "code",
"execution_count": 128,
"id": "9cd5dffc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deadSpace1 Segment_Type.DEADSPACE\n",
"deadSpace2 Segment_Type.DEADSPACE\n",
"deadSpace3 Segment_Type.DEADSPACE\n",
"deadSpace4 Segment_Type.DEADSPACE\n",
"deadSpace5 Segment_Type.DEADSPACE\n",
"deadSpace6 Segment_Type.DEADSPACE\n",
"deadSpace7 Segment_Type.DEADSPACE\n",
"deadSpace8 Segment_Type.DEADSPACE\n",
"deadSpace9 Segment_Type.DEADSPACE\n",
"deadSpace10 Segment_Type.DEADSPACE\n",
"deadSpace11 Segment_Type.DEADSPACE\n",
"deadSpace12 Segment_Type.DEADSPACE\n",
"deadSpace13 Segment_Type.DEADSPACE\n",
"deadSpace14 Segment_Type.DEADSPACE\n",
"deadSpace15 Segment_Type.DEADSPACE\n",
"deadSpace16 Segment_Type.DEADSPACE\n",
"deadSpace17 Segment_Type.DEADSPACE\n",
"deadSpace18 Segment_Type.DEADSPACE\n",
"deadSpace19 Segment_Type.DEADSPACE\n",
"deadSpace20 Segment_Type.DEADSPACE\n",
"deadSpace21 Segment_Type.DEADSPACE\n",
"deadSpace22 Segment_Type.DEADSPACE\n",
"deadSpace23 Segment_Type.DEADSPACE\n",
"deadSpace24 Segment_Type.DEADSPACE\n",
"deadSpace25 Segment_Type.DEADSPACE\n",
"deadSpace26 Segment_Type.DEADSPACE\n"
]
}
],
"source": [
"superSegments.update(deadSpaceSegments)\n",
"for d in superSegments.values():\n",
" print(d.segment_name, d.segment_type)"
]
},
{
"cell_type": "code",
"execution_count": 165,
"id": "3114cf69",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys([840, 991, 1007, 1121, 1231, 3040, 3018, 3582, 5053, 7238, 7262, 7281, 7287, 7747, 8147, 8794, 8682, 8956, 8938, 10647, 11876, 11783, 11838, 12294, 12292, 12302, 'toggle1', 'toggle2', 'toggle3', 'toggle4', 'toggle1_2', 75, 206, 312, 415, 1277, 1312, 925, 1002, 762, 1068, 653, 1235, 1665, 1711, 1833, 1872, 2108, 2157, 2002, 2048, 2332, 2663, 2795, 2888, 2943, 2981, 2991, 3082, 3628, 3925, 3499, 3519, 3710, 4072, 3315, 3326, 4004, 3745, 3848, 5060, 6676, 4541, 5076, 4624, 6835, 5864, 5966, 6000, 5553, 7269, 7277, 7774, 7692, 8044, 8055, 7427, 7574, 8143, 8346, 8464, 8373, 8221, 8627, 8598, 8713, 8817, 8911, 8941, 9085, 9094, 9185, 9304, 9329, 9418, 9432, 9466, 9627, 9757, 10140, 10530, 10633, 10663, 10766, 11225, 11461, 11639, 12303])"
]
},
"execution_count": 165,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"superSegments.keys()"
]
},
{
"cell_type": "code",
"execution_count": 183,
"id": "9e002514",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<distill.segmentation.segment.Segment at 0x21d0f1d09a0>"
]
},
"execution_count": 183,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"superSegments['toggle4']"
]
},
{
"cell_type": "markdown",
"id": "1bf72eb2",
"metadata": {},
"source": [
"### Simple Segments - Toggles\n",
"In another case, we might know exactly which events bound segment, e.g., a toggle feature or the application of a filter. If the corresponding element(s) are known we can search our dictionary for these events and create new segments readily with Distill's `create_segment` function. "
]
},
{
"cell_type": "markdown",
"id": "8b389422",
"metadata": {},
"source": [
"First, find all logs that contain the key with corresponding values that relate to those elements. Using UserALE.js data, we're looking for the \"path\" key, and within that set, only logs that correspond to 'click' events:"
]
},
{
"cell_type": "code",
"execution_count": 129,
"id": "c1aeb62c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"12302"
]
},
"execution_count": 129,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"values = ['path']\n",
"sorted_data_paths = {k:v for k, v in sorted_data.items() if any(item in values for item in v.keys())}\n",
"len(sorted_data_paths)"
]
},
{
"cell_type": "code",
"execution_count": 130,
"id": "ab609416",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"392"
]
},
"execution_count": 130,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"values = ['click']\n",
"sorted_data_paths_clicks = {k:v for k, v in sorted_data_paths.items() if any(item in values for item in v.values())}\n",
"len(sorted_data_paths_clicks)"
]
},
{
"cell_type": "markdown",
"id": "4e1bdae5",
"metadata": {},
"source": [
"Next, find all logs where \"path\" contains the elements that correspond to the exact 'toggle' element and extrac the times that indicate each time it was 'clicked'."
]
},
{
"cell_type": "code",
"execution_count": 131,
"id": "6c32d7e2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1642561335946, 1642561421205),\n",
" (1642561421205, 1642561581309),\n",
" (1642561581309, 1642563313727),\n",
" (1642563313727, 1642563487560)]"
]
},
"execution_count": 131,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"toggleEle = ['button.ant-btn superset-button css-1mljg09', 'div#chart-id-515.filter_box']\n",
"toggle_times = distill.pairwiseSeq([log['clientTime'] for log in sorted_data_paths_clicks.values() if all(item in log['path'] for item in toggleEle)])\n",
"toggle_times"
]
},
{
"cell_type": "markdown",
"id": "0e9247ce",
"metadata": {},
"source": [
"Now, we can submit these times to Distill's `create_segment` function:"
]
},
{
"cell_type": "code",
"execution_count": 132,
"id": "d94c4010",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"toggle1 Segment_Type.CREATE (1642561335946, 1642561421205) 85.259 4\n",
"toggle2 Segment_Type.CREATE (1642561421205, 1642561581309) 160.104 14\n",
"toggle3 Segment_Type.CREATE (1642561581309, 1642563313727) 1732.418 127\n",
"toggle4 Segment_Type.CREATE (1642563313727, 1642563487560) 173.833 32\n"
]
}
],
"source": [
"segment_names = []\n",
"for i in range(0,len(toggle_times),1):\n",
" segment_names.append(str(\"toggle\" + str(i+1)))\n",
"toggleSegments = distill.create_segment(sorted_data_paths_clicks, segment_names, toggle_times)\n",
"for d in toggleSegments.values():\n",
" d.segment_length_sec = (d.start_end_val[1] - d.start_end_val[0])/1000 #adding custom segment-object attributes\n",
" print(d.segment_name, d.segment_type, d.start_end_val, d.segment_length_sec, d.num_logs)"
]
},
{
"cell_type": "markdown",
"id": "86a1e3be",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": 149,
"id": "2c5ab730",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"toggle1 Segment_Type.CREATE (1642561335946, 1642561421205) 85.259 4\n",
"toggle2 Segment_Type.CREATE (1642561421205, 1642561581309) 160.104 14\n",
"toggle3 Segment_Type.CREATE (1642561581309, 1642563313727) 1732.418 127\n",
"toggle4 Segment_Type.CREATE (1642563313727, 1642563487560) 173.833 32\n",
"toggle1_2 Segment_Type.UNION (1642561335946, 1642561581309) 245.363 17\n"
]
}
],
"source": [
"toggleSegments['toggle1_2'] = distill.union('toggle1_2', toggleSegments['toggle2'], toggleSegments['toggle1'])\n",
"for d in toggleSegments.values():\n",
" d.segment_length_sec = (d.start_end_val[1] - d.start_end_val[0])/1000 #adding custom segment-object attributes\n",
" print(d.segment_name, d.segment_type, d.start_end_val, d.segment_length_sec, d.num_logs)"
]
},
{
"cell_type": "markdown",
"id": "55dc664e",
"metadata": {},
"source": [
"Finally, add revised deadspace segments to the Master Dictionary of segments:"
]
},
{
"cell_type": "code",
"execution_count": 150,
"id": "2471c232",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deadSpace1 Segment_Type.DEADSPACE\n",
"deadSpace2 Segment_Type.DEADSPACE\n",
"deadSpace3 Segment_Type.DEADSPACE\n",
"deadSpace4 Segment_Type.DEADSPACE\n",
"deadSpace5 Segment_Type.DEADSPACE\n",
"deadSpace6 Segment_Type.DEADSPACE\n",
"deadSpace7 Segment_Type.DEADSPACE\n",
"deadSpace8 Segment_Type.DEADSPACE\n",
"deadSpace9 Segment_Type.DEADSPACE\n",
"deadSpace10 Segment_Type.DEADSPACE\n",
"deadSpace11 Segment_Type.DEADSPACE\n",
"deadSpace12 Segment_Type.DEADSPACE\n",
"deadSpace13 Segment_Type.DEADSPACE\n",
"deadSpace14 Segment_Type.DEADSPACE\n",
"deadSpace15 Segment_Type.DEADSPACE\n",
"deadSpace16 Segment_Type.DEADSPACE\n",
"deadSpace17 Segment_Type.DEADSPACE\n",
"deadSpace18 Segment_Type.DEADSPACE\n",
"deadSpace19 Segment_Type.DEADSPACE\n",
"deadSpace20 Segment_Type.DEADSPACE\n",
"deadSpace21 Segment_Type.DEADSPACE\n",
"deadSpace22 Segment_Type.DEADSPACE\n",
"deadSpace23 Segment_Type.DEADSPACE\n",
"deadSpace24 Segment_Type.DEADSPACE\n",
"deadSpace25 Segment_Type.DEADSPACE\n",
"deadSpace26 Segment_Type.DEADSPACE\n",
"toggle1 Segment_Type.CREATE\n",
"toggle2 Segment_Type.CREATE\n",
"toggle3 Segment_Type.CREATE\n",
"toggle4 Segment_Type.CREATE\n",
"toggle1_2 Segment_Type.UNION\n"
]
}
],
"source": [
"superSegments.update(toggleSegments)\n",
"for d in superSegments.values():\n",
" print(d.segment_name, d.segment_type)"
]
},
{
"cell_type": "markdown",
"id": "05eccefd",
"metadata": {},
"source": [
"### Ambiguous Segments"
]
},
{
"cell_type": "code",
"execution_count": 151,
"id": "42f0102e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"map_1 (1640029804278, 1640029834278) 30.0 183\n",
"map_2 (1640029840106, 1640029870106) 30.0 67\n",
"map_3 (1640030065505, 1640030095505) 30.0 140\n",
"map_4 (1640030113456, 1640030143456) 30.0 84\n",
"map_5 (1640030159682, 1640030189682) 30.0 19\n",
"map_6 (1640030215637, 1640030245637) 30.0 7\n",
"map_7 (1640098960393, 1640098990393) 30.0 96\n",
"map_8 (1640099715638, 1640099745638) 30.0 14\n",
"map_9 (1640118193428, 1640118223428) 30.0 185\n",
"map_10 (1640118242304, 1640118272304) 30.0 135\n",
"map_11 (1640118276485, 1640118306485) 30.0 145\n",
"map_12 (1640182568142, 1640182598142) 30.0 5\n",
"map_13 (1640201041753, 1640201071753) 30.0 183\n",
"map_14 (1640201071761, 1640201101761) 30.0 55\n",
"map_15 (1640201157250, 1640201187250) 30.0 146\n",
"map_16 (1640201333004, 1640201363004) 30.0 116\n",
"map_17 (1640201425485, 1640201455485) 30.0 54\n",
"map_18 (1640201493781, 1640201523781) 30.0 8\n",
"map_19 (1640201571360, 1640201601360) 30.0 92\n",
"map_20 (1640201709131, 1640201739131) 30.0 107\n",
"map_21 (1640201770496, 1640201800496) 30.0 113\n",
"map_22 (1640201846176, 1640201876176) 30.0 107\n",
"map_23 (1640201879303, 1640201909303) 30.0 98\n",
"map_24 (1640201971359, 1640202001359) 30.0 37\n",
"map_25 (1640202031447, 1640202061447) 30.0 64\n",
"map_26 (1641502458602, 1641502488602) 30.0 16\n",
"map_27 (1641502506921, 1641502536921) 30.0 45\n",
"map_28 (1641584316907, 1641584346907) 30.0 170\n",
"map_29 (1641584351264, 1641584381264) 30.0 109\n",
"map_30 (1641584412220, 1641584442220) 30.0 78\n",
"map_31 (1641584443149, 1641584473149) 30.0 133\n",
"map_32 (1641584584359, 1641584614359) 30.0 42\n",
"map_33 (1641584656995, 1641584686995) 30.0 2\n",
"map_34 (1641584742169, 1641584772169) 30.0 43\n",
"map_35 (1641584821749, 1641584851749) 30.0 1\n",
"map_36 (1641585078613, 1641585108613) 30.0 280\n",
"map_37 (1641585110991, 1641585140991) 30.0 55\n",
"map_38 (1641585228031, 1641585258031) 30.0 28\n",
"map_39 (1641585458977, 1641585488977) 30.0 14\n",
"map_40 (1641849235130, 1641849265130) 30.0 128\n",
"map_41 (1641849271492, 1641849301492) 30.0 284\n",
"map_42 (1641849306285, 1641849336285) 30.0 180\n",
"map_43 (1641849336995, 1641849366995) 30.0 216\n",
"map_44 (1641849367149, 1641849397149) 30.0 168\n",
"map_45 (1641849436992, 1641849466992) 30.0 191\n",
"map_46 (1641849467312, 1641849497312) 30.0 258\n",
"map_47 (1641849526231, 1641849556231) 30.0 105\n",
"map_48 (1641849560480, 1641849590480) 30.0 121\n",
"map_49 (1641849671655, 1641849701655) 30.0 32\n",
"map_50 (1641910810650, 1641910840650) 30.0 9\n",
"map_51 (1641963233861, 1641963263861) 30.0 10\n",
"map_52 (1642004997774, 1642005027774) 30.0 56\n",
"map_53 (1642005196917, 1642005226917) 30.0 35\n",
"map_54 (1642013742966, 1642013772966) 30.0 27\n",
"map_55 (1642013773427, 1642013803427) 30.0 52\n",
"map_56 (1642013854863, 1642013884863) 30.0 219\n",
"map_57 (1642013911632, 1642013941632) 30.0 167\n",
"map_58 (1642013961109, 1642013991109) 30.0 3\n",
"map_59 (1642014463528, 1642014493528) 30.0 31\n",
"map_60 (1642014516874, 1642014546874) 30.0 28\n",
"map_61 (1642014670794, 1642014700794) 30.0 291\n",
"map_62 (1642014716890, 1642014746890) 30.0 11\n",
"map_63 (1642015133602, 1642015163602) 30.0 104\n",
"map_64 (1642015237595, 1642015267595) 30.0 34\n",
"map_65 (1642015925873, 1642015955873) 30.0 39\n",
"map_66 (1642016249603, 1642016279603) 30.0 145\n",
"map_67 (1642018692112, 1642018722112) 30.0 38\n",
"map_68 (1642018769090, 1642018799090) 30.0 14\n",
"map_69 (1642561250405, 1642561280405) 30.0 7\n",
"map_70 (1642561321319, 1642561351319) 30.0 51\n",
"map_71 (1642561381832, 1642561411832) 30.0 77\n",
"map_72 (1642561418573, 1642561448573) 30.0 26\n",
"map_73 (1642561489022, 1642561519022) 30.0 129\n",
"map_74 (1642561525426, 1642561555426) 30.0 13\n",
"map_75 (1642561582104, 1642561612104) 30.0 11\n",
"map_76 (1642561806544, 1642561836544) 30.0 107\n",
"map_77 (1642561836797, 1642561866797) 30.0 35\n",
"map_78 (1642561904243, 1642561934243) 30.0 49\n",
"map_79 (1642562156535, 1642562186535) 30.0 110\n",
"map_80 (1642562613217, 1642562643217) 30.0 34\n",
"map_81 (1642562643454, 1642562673454) 30.0 10\n",
"map_82 (1642563261459, 1642563291459) 30.0 102\n",
"map_83 (1642563311454, 1642563341454) 30.0 183\n",
"map_84 (1642563425528, 1642563455528) 30.0 86\n",
"map_85 (1642563483058, 1642563513058) 30.0 91\n",
"map_86 (1642626481298, 1642626511298) 30.0 362\n",
"map_87 (1642654564769, 1642654594769) 30.0 3\n"
]
}
],
"source": [
"mapSegments = distill.generate_segments(sorted_data_paths,'path',['div.superset-legacy-chart-world-map','window'],0,30)\n",
"for counter, d in enumerate(mapSegments.values(), start=1): \n",
" d.segment_name = str(\"map_\" + str(counter))\n",
" d.segment_length_sec = (d.start_end_val[1] - d.start_end_val[0])/1000 #adding custom segment-object attributes\n",
" print(d.segment_name, d.start_end_val, d.segment_length_sec, d.num_logs)"
]
},
{
"cell_type": "code",
"execution_count": 164,
"id": "6e5a5738",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deadSpace1 Segment_Type.DEADSPACE\n",
"deadSpace2 Segment_Type.DEADSPACE\n",
"deadSpace3 Segment_Type.DEADSPACE\n",
"deadSpace4 Segment_Type.DEADSPACE\n",
"deadSpace5 Segment_Type.DEADSPACE\n",
"deadSpace6 Segment_Type.DEADSPACE\n",
"deadSpace7 Segment_Type.DEADSPACE\n",
"deadSpace8 Segment_Type.DEADSPACE\n",
"deadSpace9 Segment_Type.DEADSPACE\n",
"deadSpace10 Segment_Type.DEADSPACE\n",
"deadSpace11 Segment_Type.DEADSPACE\n",
"deadSpace12 Segment_Type.DEADSPACE\n",
"deadSpace13 Segment_Type.DEADSPACE\n",
"deadSpace14 Segment_Type.DEADSPACE\n",
"deadSpace15 Segment_Type.DEADSPACE\n",
"deadSpace16 Segment_Type.DEADSPACE\n",
"deadSpace17 Segment_Type.DEADSPACE\n",
"deadSpace18 Segment_Type.DEADSPACE\n",
"deadSpace19 Segment_Type.DEADSPACE\n",
"deadSpace20 Segment_Type.DEADSPACE\n",
"deadSpace21 Segment_Type.DEADSPACE\n",
"deadSpace22 Segment_Type.DEADSPACE\n",
"deadSpace23 Segment_Type.DEADSPACE\n",
"deadSpace24 Segment_Type.DEADSPACE\n",
"deadSpace25 Segment_Type.DEADSPACE\n",
"deadSpace26 Segment_Type.DEADSPACE\n",
"toggle1 Segment_Type.CREATE\n",
"toggle2 Segment_Type.CREATE\n",
"toggle3 Segment_Type.CREATE\n",
"toggle4 Segment_Type.CREATE\n",
"toggle1_2 Segment_Type.UNION\n",
"map_1 Segment_Type.GENERATE\n",
"map_2 Segment_Type.GENERATE\n",
"map_3 Segment_Type.GENERATE\n",
"map_4 Segment_Type.GENERATE\n",
"map_5 Segment_Type.GENERATE\n",
"map_6 Segment_Type.GENERATE\n",
"map_7 Segment_Type.GENERATE\n",
"map_8 Segment_Type.GENERATE\n",
"map_9 Segment_Type.GENERATE\n",
"map_10 Segment_Type.GENERATE\n",
"map_11 Segment_Type.GENERATE\n",
"map_12 Segment_Type.GENERATE\n",
"map_13 Segment_Type.GENERATE\n",
"map_14 Segment_Type.GENERATE\n",
"map_15 Segment_Type.GENERATE\n",
"map_16 Segment_Type.GENERATE\n",
"map_17 Segment_Type.GENERATE\n",
"map_18 Segment_Type.GENERATE\n",
"map_19 Segment_Type.GENERATE\n",
"map_20 Segment_Type.GENERATE\n",
"map_21 Segment_Type.GENERATE\n",
"map_22 Segment_Type.GENERATE\n",
"map_23 Segment_Type.GENERATE\n",
"map_24 Segment_Type.GENERATE\n",
"map_25 Segment_Type.GENERATE\n",
"map_26 Segment_Type.GENERATE\n",
"map_27 Segment_Type.GENERATE\n",
"map_28 Segment_Type.GENERATE\n",
"map_29 Segment_Type.GENERATE\n",
"map_30 Segment_Type.GENERATE\n",
"map_31 Segment_Type.GENERATE\n",
"map_32 Segment_Type.GENERATE\n",
"map_33 Segment_Type.GENERATE\n",
"map_34 Segment_Type.GENERATE\n",
"map_35 Segment_Type.GENERATE\n",
"map_36 Segment_Type.GENERATE\n",
"map_37 Segment_Type.GENERATE\n",
"map_38 Segment_Type.GENERATE\n",
"map_39 Segment_Type.GENERATE\n",
"map_40 Segment_Type.GENERATE\n",
"map_41 Segment_Type.GENERATE\n",
"map_42 Segment_Type.GENERATE\n",
"map_43 Segment_Type.GENERATE\n",
"map_44 Segment_Type.GENERATE\n",
"map_45 Segment_Type.GENERATE\n",
"map_46 Segment_Type.GENERATE\n",
"map_47 Segment_Type.GENERATE\n",
"map_48 Segment_Type.GENERATE\n",
"map_49 Segment_Type.GENERATE\n",
"map_50 Segment_Type.GENERATE\n",
"map_51 Segment_Type.GENERATE\n",
"map_52 Segment_Type.GENERATE\n",
"map_53 Segment_Type.GENERATE\n",
"map_54 Segment_Type.GENERATE\n",
"map_55 Segment_Type.GENERATE\n",
"map_56 Segment_Type.GENERATE\n",
"map_57 Segment_Type.GENERATE\n",
"map_58 Segment_Type.GENERATE\n",
"map_59 Segment_Type.GENERATE\n",
"map_60 Segment_Type.GENERATE\n",
"map_61 Segment_Type.GENERATE\n",
"map_62 Segment_Type.GENERATE\n",
"map_63 Segment_Type.GENERATE\n",
"map_64 Segment_Type.GENERATE\n",
"map_65 Segment_Type.GENERATE\n",
"map_66 Segment_Type.GENERATE\n",
"map_67 Segment_Type.GENERATE\n",
"map_68 Segment_Type.GENERATE\n",
"map_69 Segment_Type.GENERATE\n",
"map_70 Segment_Type.GENERATE\n",
"map_71 Segment_Type.GENERATE\n",
"map_72 Segment_Type.GENERATE\n",
"map_73 Segment_Type.GENERATE\n",
"map_74 Segment_Type.GENERATE\n",
"map_75 Segment_Type.GENERATE\n",
"map_76 Segment_Type.GENERATE\n",
"map_77 Segment_Type.GENERATE\n",
"map_78 Segment_Type.GENERATE\n",
"map_79 Segment_Type.GENERATE\n",
"map_80 Segment_Type.GENERATE\n",
"map_81 Segment_Type.GENERATE\n",
"map_82 Segment_Type.GENERATE\n",
"map_83 Segment_Type.GENERATE\n",
"map_84 Segment_Type.GENERATE\n",
"map_85 Segment_Type.GENERATE\n",
"map_86 Segment_Type.GENERATE\n",
"map_87 Segment_Type.GENERATE\n"
]
}
],
"source": [
"superSegments.update(mapSegments)\n",
"for d in superSegments.values():\n",
" print(d.segment_name, d.segment_type)"
]
},
{
"cell_type": "code",
"execution_count": 153,
"id": "20ab036f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"51"
]
},
"execution_count": 153,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mapSegments_list = []\n",
"mapSegment_times = []\n",
"for d in mapSegments.values():\n",
" if d.num_logs > 50:\n",
" mapSegments_list.append(d.segment_name)\n",
" mapSegment_times.append(d.start_end_val)\n",
"len(mapSegment_times)"
]
},
{
"cell_type": "markdown",
"id": "322fb822",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": 154,
"id": "3ad9c6af",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"map_1 183\n",
"map_9 185\n",
"map_13 183\n",
"map_28 170\n",
"map_36 280\n",
"map_41 284\n",
"map_42 180\n",
"map_43 216\n",
"map_44 168\n",
"map_45 191\n",
"map_46 258\n",
"map_56 219\n",
"map_57 167\n",
"map_61 291\n",
"map_83 183\n",
"map_86 362\n"
]
}
],
"source": [
"mapSegments_data = distill.write_segment(sorted_data_paths, mapSegments_list, mapSegment_times)\n",
"for d in mapSegments_data.keys():\n",
" if len(mapSegments_data[d]) > 150:\n",
" print(d, len(mapSegments_data[d]))"
]
},
{
"cell_type": "markdown",
"id": "26915660",
"metadata": {},
"source": [
"## Graphs and Stats"
]
},
{
"cell_type": "code",
"execution_count": 155,
"id": "17476fd9",
"metadata": {},
"outputs": [],
"source": [
"edges_map_1 = distill.pairwiseSeq(['|'.join(log['path']) for log in mapSegments_data['map_1'].values()])\n",
"edges_list_map_1 = list(edges_map_1)\n",
"edges_map_2 = distill.pairwiseSeq(['|'.join(log['path']) for log in mapSegments_data['map_9'].values()])\n",
"edges_list_map_2 = list(edges_map_2)"
]
},
{
"cell_type": "code",
"execution_count": 156,
"id": "bb75016c",
"metadata": {},
"outputs": [],
"source": [
"nodes_map_1 = set(['|'.join(log['path']) for log in mapSegments_data['map_1'].values()])\n",
"nodes_list_map_1 = list(nodes_map_1)\n",
"nodes_map_2 = set(['|'.join(log['path']) for log in mapSegments_data['map_9'].values()])\n",
"nodes_list_map_2 = list(nodes_map_2)"
]
},
{
"cell_type": "code",
"execution_count": 157,
"id": "a1140db2",
"metadata": {},
"outputs": [],
"source": [
"G_map1 = distill.createDiGraph(nodes_list_map_1, edges_list_map_1, drop_recursions = False)\n",
"G_map2 = distill.createDiGraph(nodes_list_map_2, edges_list_map_2, drop_recursions = False)"
]
},
{
"cell_type": "code",
"execution_count": 158,
"id": "e7b2ecbf",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"nx.draw(G_map1, with_labels=False)"
]
},
{
"cell_type": "code",
"execution_count": 159,
"id": "a81165c5",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"nx.draw(G_map2, with_labels=False)"
]
},
{
"cell_type": "code",
"execution_count": 160,
"id": "839167fc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9979518689196109"
]
},
"execution_count": 160,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nx.average_node_connectivity(G_map2)"
]
},
{
"cell_type": "markdown",
"id": "db537c67",
"metadata": {},
"source": [
"## Exploratory Visualization"
]
},
{
"cell_type": "code",
"execution_count": 195,
"id": "a7231ba0",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"link": {
"source": [
0,
1,
2,
0,
3,
4,
5,
6,
7,
8,
7,
5,
4,
7,
0,
2,
3,
9,
10,
2,
11,
12,
13,
14,
15,
14,
16,
13,
13,
11,
16,
12,
2,
1,
2,
9,
17,
18,
19,
20,
21,
18,
17,
9,
2,
12,
8,
22,
23,
8,
0,
24,
23,
9,
12,
24,
2,
23,
25,
8,
0,
26,
9,
27,
7,
9
],
"target": [
1,
2,
0,
3,
4,
5,
6,
7,
8,
7,
5,
4,
7,
2,
2,
3,
9,
10,
2,
11,
12,
13,
14,
15,
14,
16,
13,
16,
11,
16,
12,
0,
1,
0,
9,
17,
18,
19,
20,
21,
18,
17,
9,
2,
12,
8,
22,
23,
8,
12,
24,
23,
9,
12,
24,
2,
23,
25,
23,
9,
26,
1,
27,
7,
4,
7
],
"value": [
8,
5,
16,
1,
1,
1,
1,
1,
2,
2,
1,
1,
3,
2,
16,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
1,
1,
1,
1,
2,
4,
8,
4,
1,
1,
1,
1,
1,
1,
1,
1,
2,
1,
1,
1,
1,
2,
1,
1,
1,
1,
2,
2,
2,
1,
1,
1,
1,
1,
1,
1,
1,
3,
1
]
},
"node": {
"label": [
"path.[object SVGAnimatedString]",
"circle.[object SVGAnimatedString]",
"svg.[object SVGAnimatedString]",
"div.superset-legacy-chart-world-map",
"td. ",
"th. ",
"div.header-title",
"div.dashboard-component dashboard-component-chart-holder fade-out",
"div.dashboard-content css-wp1ax2",
"div.dashboard-component dashboard-component-chart-holder fade-out",
"div.grid-column background--transparent",
"#document",
"div.header-title",
"svg.[object SVGAnimatedString]",
"rect.[object SVGAnimatedString]",
"path.[object SVGAnimatedString]",
"text.[object SVGAnimatedString]",
"div.grid-row background--transparent",
"div.dashboard-component dashboard-component-chart-holder fade-out",
"div.header-controls",
"div.chart-slice",
"div.text-container",
"div.dashboard-component-header header-large",
"div.dashboard-header css-1qf0uii",
"div.chart-slice",
"ul.ant-menu ant-menu-light main-nav css-188dvs4 ant-menu-root ant-menu-horizontal",
"div.hoverinfo",
"div.grid-row background--transparent"
]
},
"type": "sankey"
}
],
"layout": {
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"autotypenumbers": "strict",
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
}
}
},
"text/html": [
"<div> <div id=\"3c045324-ae46-488c-bea6-b7dea93ac970\" class=\"plotly-graph-div\" style=\"height:525px; width:100%;\"></div> <script type=\"text/javascript\"> require([\"plotly\"], function(Plotly) { window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById(\"3c045324-ae46-488c-bea6-b7dea93ac970\")) { Plotly.newPlot( \"3c045324-ae46-488c-bea6-b7dea93ac970\", [{\"link\":{\"source\":[0,1,2,0,3,4,5,6,7,8,7,5,4,7,0,2,3,9,10,2,11,12,13,14,15,14,16,13,13,11,16,12,2,1,2,9,17,18,19,20,21,18,17,9,2,12,8,22,23,8,0,24,23,9,12,24,2,23,25,8,0,26,9,27,7,9],\"target\":[1,2,0,3,4,5,6,7,8,7,5,4,7,2,2,3,9,10,2,11,12,13,14,15,14,16,13,16,11,16,12,0,1,0,9,17,18,19,20,21,18,17,9,2,12,8,22,23,8,12,24,23,9,12,24,2,23,25,23,9,26,1,27,7,4,7],\"value\":[8,5,16,1,1,1,1,1,2,2,1,1,3,2,16,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,2,4,8,4,1,1,1,1,1,1,1,1,2,1,1,1,1,2,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,3,1]},\"node\":{\"label\":[\"path.[object SVGAnimatedString]\",\"circle.[object SVGAnimatedString]\",\"svg.[object SVGAnimatedString]\",\"div.superset-legacy-chart-world-map\",\"td. \",\"th. \",\"div.header-title\",\"div.dashboard-component dashboard-component-chart-holder fade-out\",\"div.dashboard-content css-wp1ax2\",\"div.dashboard-component dashboard-component-chart-holder fade-out\",\"div.grid-column background--transparent\",\"#document\",\"div.header-title\",\"svg.[object SVGAnimatedString]\",\"rect.[object SVGAnimatedString]\",\"path.[object SVGAnimatedString]\",\"text.[object SVGAnimatedString]\",\"div.grid-row background--transparent\",\"div.dashboard-component dashboard-component-chart-holder fade-out\",\"div.header-controls\",\"div.chart-slice\",\"div.text-container\",\"div.dashboard-component-header header-large\",\"div.dashboard-header css-1qf0uii\",\"div.chart-slice\",\"ul.ant-menu ant-menu-light main-nav css-188dvs4 ant-menu-root ant-menu-horizontal\",\"div.hoverinfo\",\"div.grid-row background--transparent\"]},\"type\":\"sankey\"}], {\"template\":{\"data\":{\"bar\":[{\"error_x\":{\"color\":\"#2a3f5f\"},\"error_y\":{\"color\":\"#2a3f5f\"},\"marker\":{\"line\":{\"color\":\"#E5ECF6\",\"width\":0.5},\"pattern\":{\"fillmode\":\"overlay\",\"size\":10,\"solidity\":0.2}},\"type\":\"bar\"}],\"barpolar\":[{\"marker\":{\"line\":{\"color\":\"#E5ECF6\",\"width\":0.5},\"pattern\":{\"fillmode\":\"overlay\",\"size\":10,\"solidity\":0.2}},\"type\":\"barpolar\"}],\"carpet\":[{\"aaxis\":{\"endlinecolor\":\"#2a3f5f\",\"gridcolor\":\"white\",\"linecolor\":\"white\",\"minorgridcolor\":\"white\",\"startlinecolor\":\"#2a3f5f\"},\"baxis\":{\"endlinecolor\":\"#2a3f5f\",\"gridcolor\":\"white\",\"linecolor\":\"white\",\"minorgridcolor\":\"white\",\"startlinecolor\":\"#2a3f5f\"},\"type\":\"carpet\"}],\"choropleth\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"type\":\"choropleth\"}],\"contour\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"contour\"}],\"contourcarpet\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"type\":\"contourcarpet\"}],\"heatmap\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"heatmap\"}],\"heatmapgl\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"heatmapgl\"}],\"histogram\":[{\"marker\":{\"pattern\":{\"fillmode\":\"overlay\",\"size\":10,\"solidity\":0.2}},\"type\":\"histogram\"}],\"histogram2d\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"histogram2d\"}],\"histogram2dcontour\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"histogram2dcontour\"}],\"mesh3d\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"type\":\"mesh3d\"}],\"parcoords\":[{\"line\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"parcoords\"}],\"pie\":[{\"automargin\":true,\"type\":\"pie\"}],\"scatter\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatter\"}],\"scatter3d\":[{\"line\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatter3d\"}],\"scattercarpet\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattercarpet\"}],\"scattergeo\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattergeo\"}],\"scattergl\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattergl\"}],\"scattermapbox\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattermapbox\"}],\"scatterpolar\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatterpolar\"}],\"scatterpolargl\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatterpolargl\"}],\"scatterternary\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatterternary\"}],\"surface\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"surface\"}],\"table\":[{\"cells\":{\"fill\":{\"color\":\"#EBF0F8\"},\"line\":{\"color\":\"white\"}},\"header\":{\"fill\":{\"color\":\"#C8D4E3\"},\"line\":{\"color\":\"white\"}},\"type\":\"table\"}]},\"layout\":{\"annotationdefaults\":{\"arrowcolor\":\"#2a3f5f\",\"arrowhead\":0,\"arrowwidth\":1},\"autotypenumbers\":\"strict\",\"coloraxis\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"colorscale\":{\"diverging\":[[0,\"#8e0152\"],[0.1,\"#c51b7d\"],[0.2,\"#de77ae\"],[0.3,\"#f1b6da\"],[0.4,\"#fde0ef\"],[0.5,\"#f7f7f7\"],[0.6,\"#e6f5d0\"],[0.7,\"#b8e186\"],[0.8,\"#7fbc41\"],[0.9,\"#4d9221\"],[1,\"#276419\"]],\"sequential\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"sequentialminus\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]]},\"colorway\":[\"#636efa\",\"#EF553B\",\"#00cc96\",\"#ab63fa\",\"#FFA15A\",\"#19d3f3\",\"#FF6692\",\"#B6E880\",\"#FF97FF\",\"#FECB52\"],\"font\":{\"color\":\"#2a3f5f\"},\"geo\":{\"bgcolor\":\"white\",\"lakecolor\":\"white\",\"landcolor\":\"#E5ECF6\",\"showlakes\":true,\"showland\":true,\"subunitcolor\":\"white\"},\"hoverlabel\":{\"align\":\"left\"},\"hovermode\":\"closest\",\"mapbox\":{\"style\":\"light\"},\"paper_bgcolor\":\"white\",\"plot_bgcolor\":\"#E5ECF6\",\"polar\":{\"angularaxis\":{\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\"},\"bgcolor\":\"#E5ECF6\",\"radialaxis\":{\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\"}},\"scene\":{\"xaxis\":{\"backgroundcolor\":\"#E5ECF6\",\"gridcolor\":\"white\",\"gridwidth\":2,\"linecolor\":\"white\",\"showbackground\":true,\"ticks\":\"\",\"zerolinecolor\":\"white\"},\"yaxis\":{\"backgroundcolor\":\"#E5ECF6\",\"gridcolor\":\"white\",\"gridwidth\":2,\"linecolor\":\"white\",\"showbackground\":true,\"ticks\":\"\",\"zerolinecolor\":\"white\"},\"zaxis\":{\"backgroundcolor\":\"#E5ECF6\",\"gridcolor\":\"white\",\"gridwidth\":2,\"linecolor\":\"white\",\"showbackground\":true,\"ticks\":\"\",\"zerolinecolor\":\"white\"}},\"shapedefaults\":{\"line\":{\"color\":\"#2a3f5f\"}},\"ternary\":{\"aaxis\":{\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\"},\"baxis\":{\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\"},\"bgcolor\":\"#E5ECF6\",\"caxis\":{\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\"}},\"title\":{\"x\":0.05},\"xaxis\":{\"automargin\":true,\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\",\"title\":{\"standoff\":15},\"zerolinecolor\":\"white\",\"zerolinewidth\":2},\"yaxis\":{\"automargin\":true,\"gridcolor\":\"white\",\"linecolor\":\"white\",\"ticks\":\"\",\"title\":{\"standoff\":15},\"zerolinecolor\":\"white\",\"zerolinewidth\":2}}}}, {\"responsive\": true} ).then(function(){\n",
" \n",
"var gd = document.getElementById('3c045324-ae46-488c-bea6-b7dea93ac970');\n",
"var x = new MutationObserver(function (mutations, observer) {{\n",
" var display = window.getComputedStyle(gd).display;\n",
" if (!display || display === 'none') {{\n",
" console.log([gd, 'removed!']);\n",
" Plotly.purge(gd);\n",
" observer.disconnect();\n",
" }}\n",
"}});\n",
"\n",
"// Listen for the removal of the full notebook cells\n",
"var notebookContainer = gd.closest('#notebook-container');\n",
"if (notebookContainer) {{\n",
" x.observe(notebookContainer, {childList: true});\n",
"}}\n",
"\n",
"// Listen for the clearing of the current output cell\n",
"var outputEl = gd.closest('.output');\n",
"if (outputEl) {{\n",
" x.observe(outputEl, {childList: true});\n",
"}}\n",
"\n",
" }) }; }); </script> </div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"distill.sankey(edges_map_1,[nodes_list_map_2[item].split(\"|\")[0] for item in range(len(nodes_list_map_2))])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3fb3d8d8",
"metadata": {},
"outputs": [],
"source": [
"distill.funnel"
]
},
{
"cell_type": "markdown",
"id": "11b105f5",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "e12b4d7d",
"metadata": {},
"outputs": [],
"source": [
"#clickRate"
]
},
{
"cell_type": "markdown",
"id": "a06bf50a",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "90badd8d",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "348e3a5b",
"metadata": {},
"outputs": [],
"source": [
"edge_list_temp = []\n",
"for row in edges_segmentN:\n",
" if row[0] != row[1]: \n",
" edge_list_temp.append(row)\n",
"edge_list = edge_list_temp\n",
"\n",
"edge_list_counter = Counter(edge_list)\n",
"\n",
"source_list = [i[0] for i in edge_list_counter.keys()]\n",
"target_list = [i[1] for i in edge_list_counter.keys()]\n",
"value_list = [i for i in edge_list_counter.values()]\n",
"\n",
"nodes = []\n",
"for row in edge_list:\n",
" for col in row:\n",
" if col not in nodes:\n",
" nodes.append(col) \n",
" \n",
"sources = []\n",
"for i in source_list:\n",
" sources.append(nodes.index(i))\n",
"targets = []\n",
"for i in target_list:\n",
" targets.append(nodes.index(i))\n",
"values = value_list\n",
"\n",
"fig = go.Figure(data=[go.Sankey(\n",
" node = dict(\n",
" label = [nodes[item].split(\"|\")[0] for item in range(len(nodes))],\n",
" ),\n",
" link = dict(\n",
" source = sources,\n",
" target = targets,\n",
" value = values\n",
" ))])\n",
"\n",
"fig.show()"
]
},
{
"cell_type": "markdown",
"id": "9bd03731",
"metadata": {},
"source": [
"# WIP"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dc8b6cdd",
"metadata": {},
"outputs": [],
"source": [
"x = [hashlib.md5('_'.join(log['path']).encode('utf-8')).digest() for log in finalSegments['...'].values()]\n",
"y = [hashlib.md5('_'.join(log['path']).encode('utf-8')).digest() for log in finalSegments['...'].values()]\n",
"set(x) & set (y)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8fbf9bbb",
"metadata": {},
"outputs": [],
"source": [
"x = ['_'.join(log['path']) for log in finalSegments['...'].values()]\n",
"y = ['_'.join(log['path']) for log in finalSegments['...'].values()]\n",
"set(x) & set(y)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb1e095c",
"metadata": {},
"outputs": [],
"source": [
"nx.graph_edit_distance(G_segmentN, G_segmentN)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3f79c272",
"metadata": {},
"outputs": [],
"source": [
"for v in nx.optimize_graph_edit_distance(G_segmentN, G_segmentN):\n",
" minv = v\n",
"minv"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a01f8ef7",
"metadata": {},
"outputs": [],
"source": [
"dictionary[new_key] = dictionary.pop(old_key)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "20cf3107",
"metadata": {},
"outputs": [],
"source": [
"superSegments"
]
}
],
"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.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}