{ "cells": [ { "cell_type": "markdown", "id": "96ec678e-b20c-4213-8616-542010f46342", "metadata": {}, "source": [ "\n", "# Dirty ER\n", "\n", "In this notebook we present the pyJedAI approach in the well-known Cora dataset. Dirty ER, is the process of dedeplication of one set." ] }, { "cell_type": "markdown", "id": "5274855c-ba95-49b1-ba68-4f50ca2bbd89", "metadata": {}, "source": [ "# How to install?\n", "\n", "pyJedAI is an open-source library that can be installed from PyPI.\n", "\n", "For more: [pypi.org/project/pyjedai/](https://pypi.org/project/pyjedai/)" ] }, { "cell_type": "code", "execution_count": null, "id": "4697d149-c1a4-4767-9ed1-14444485e409", "metadata": {}, "outputs": [], "source": [ "%python --version" ] }, { "cell_type": "code", "execution_count": null, "id": "776843a2-570d-4d87-bb1d-b5b61f07b1da", "metadata": {}, "outputs": [], "source": [ "%pip install pyjedai -U" ] }, { "cell_type": "code", "execution_count": null, "id": "6d2e5cf7-ff2e-4271-9242-fe3d638263e9", "metadata": {}, "outputs": [], "source": [ "%pip show pyjedai" ] }, { "cell_type": "markdown", "id": "15d28272-269a-4e87-bb03-0a45a5492a06", "metadata": {}, "source": [ "Imports" ] }, { "cell_type": "code", "execution_count": 1, "id": "a0890ce6-3a10-4e66-913f-78095bd786a1", "metadata": {}, "outputs": [], "source": [ "import os\n", "import sys\n", "import pandas as pd\n", "import networkx\n", "from networkx import draw, Graph\n", "\n", "from pyjedai.utils import print_clusters, print_blocks, print_candidate_pairs\n", "from pyjedai.evaluation import Evaluation" ] }, { "cell_type": "markdown", "id": "af77914f-5e76-4da8-a0ad-1c53e0111a0f", "metadata": { "tags": [] }, "source": [ "## Reading the dataset\n", "\n", "pyJedAI in order to perfrom needs only the tranformation of the initial data into a pandas DataFrame. Hence, pyJedAI can function in every structured or semi-structured data. In this case Abt-Buy dataset is provided as .csv files. \n", "\n", "
\n", " \n", "
\n", "\n", "\n", "### pyjedai module\n", "\n", "Data module offers a numpber of options\n", "- Selecting the parameters (columns) of the dataframe, in D1 (and in D2)\n", "- Prints a detailed text analysis\n", "- Stores a hidden mapping of the ids, and creates it if not exists." ] }, { "cell_type": "code", "execution_count": 2, "id": "3d3feb89-1406-4c90-a1aa-dc2cf4707739", "metadata": {}, "outputs": [], "source": [ "from pyjedai.datamodel import Data\n", "\n", "d1 = pd.read_csv(\"./../data/der/cora/cora.csv\", sep='|')\n", "gt = pd.read_csv(\"./../data/der/cora/cora_gt.csv\", sep='|', header=None)\n", "attr = ['author', 'title']" ] }, { "cell_type": "markdown", "id": "fda32323-c74d-4374-b322-5c11a175c3ea", "metadata": {}, "source": [ "Data is the connecting module of all steps of the workflow" ] }, { "cell_type": "code", "execution_count": 3, "id": "e257597d-ea77-4090-ba34-e1038d8f9a0d", "metadata": {}, "outputs": [], "source": [ "data = Data(\n", " dataset_1=d1,\n", " id_column_name_1='Entity Id',\n", " ground_truth=gt,\n", " attributes_1=attr,\n", " dataset_name_1=\"CORA\"\n", ")" ] }, { "cell_type": "markdown", "id": "93464edd-b88a-40d9-aa4d-7fe1523db662", "metadata": {}, "source": [ "## Workflow with Block Cleaning Methods\n", "\n", "In this notebook we created the bellow architecture:\n", "\n", "![workflow1-cora.png](https://github.com/AI-team-UoA/pyJedAI/blob/main/docs/img/workflow1-cora.png?raw=true)\n", "\n" ] }, { "cell_type": "markdown", "id": "9c068252-4a69-405a-a320-c2875ec08ea5", "metadata": {}, "source": [ "## Block Building\n", "\n", "It clusters entities into overlapping blocks in a lazy manner that relies on unsupervised blocking keys: every token in an attribute value forms a key. Blocks are then extracted, possibly using a transformation, based on its equality or on its similarity with other keys.\n", "\n", "The following methods are currently supported:\n", "\n", "- Standard/Token Blocking\n", "- Sorted Neighborhood\n", "- Extended Sorted Neighborhood\n", "- Q-Grams Blocking\n", "- Extended Q-Grams Blocking\n", "- Suffix Arrays Blocking\n", "- Extended Suffix Arrays Blocking" ] }, { "cell_type": "code", "execution_count": 4, "id": "9c1b6213-a218-40cf-bc72-801b77d28da9", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/conda/miniconda3/envs/pypi_dependencies/lib/python3.9/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "from pyjedai.block_building import (\n", " StandardBlocking,\n", " QGramsBlocking,\n", " SuffixArraysBlocking,\n", " ExtendedSuffixArraysBlocking,\n", " ExtendedQGramsBlocking\n", ")" ] }, { "cell_type": "code", "execution_count": 5, "id": "7ee34038-1352-440e-8c34-98c5cf036523", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Suffix Arrays Blocking: 100%|██████████| 1295/1295 [00:00<00:00, 7419.94it/s]\n" ] } ], "source": [ "bb = SuffixArraysBlocking(suffix_length=2)\n", "blocks = bb.build_blocks(data)" ] }, { "cell_type": "code", "execution_count": 6, "id": "b0ac846d-0f13-4b90-b4c8-688054ed7ffe", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Suffix Arrays Blocking\n", "***************************************************************************************************************************\n", "Method name: Suffix Arrays Blocking\n", "Parameters: \n", "\tSuffix length: 2\n", "\tMaximum Block Size: 53\n", "Runtime: 0.1759 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 4.40% \n", "\tRecall: 75.75%\n", "\tF1-score: 8.31%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "_ = bb.evaluate(blocks)" ] }, { "cell_type": "markdown", "id": "9fd79ed0-4073-4789-9f9c-09e61da1f4ef", "metadata": {}, "source": [ "## Block Purging\n", "\n", "__Optional step__\n", "\n", "Discards the blocks exceeding a certain number of comparisons. \n" ] }, { "cell_type": "code", "execution_count": 7, "id": "ca78a044-589d-48c1-b508-72d5d3205a1c", "metadata": {}, "outputs": [], "source": [ "from pyjedai.block_cleaning import BlockPurging" ] }, { "cell_type": "code", "execution_count": 8, "id": "56f77f40-1c76-4f03-b0dd-5bb592f586e0", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Block Purging: 100%|██████████| 2842/2842 [00:00<00:00, 127747.12it/s]\n" ] } ], "source": [ "bp = BlockPurging()\n", "cleaned_blocks = bp.process(blocks, data, tqdm_disable=False)" ] }, { "cell_type": "code", "execution_count": 9, "id": "9ad1950f-9c89-484e-926e-54892dcd93d6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Method name: Block Purging\n", "Method info: Discards the blocks exceeding a certain number of comparisons.\n", "Parameters: \n", "\tSmoothing factor: 1.025\n", "\tMax Comparisons per Block: 1378.0\n", "Runtime: 0.0283 seconds\n" ] } ], "source": [ "bp.report()" ] }, { "cell_type": "code", "execution_count": 10, "id": "e3a7cbdf-7ed5-499d-b8da-aa7da3167660", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Block Purging\n", "***************************************************************************************************************************\n", "Method name: Block Purging\n", "Parameters: \n", "\tSmoothing factor: 1.025\n", "\tMax Comparisons per Block: 1378.0\n", "Runtime: 0.0283 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 4.40% \n", "\tRecall: 75.75%\n", "\tF1-score: 8.31%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "_ = bp.evaluate(cleaned_blocks)" ] }, { "cell_type": "markdown", "id": "62b067d8-fbc4-4689-ba72-7ab5baf88a70", "metadata": { "tags": [] }, "source": [ "## Block Cleaning\n", "\n", "___Optional step___\n", "\n", "Its goal is to clean a set of overlapping blocks from unnecessary comparisons, which can be either redundant (i.e., repeated comparisons that have already been executed in a previously examined block) or superfluous (i.e., comparisons that involve non-matching entities). Its methods operate on the coarse level of individual blocks or entities." ] }, { "cell_type": "code", "execution_count": 11, "id": "9c2c0e42-485a-444e-9161-975f30d21a02", "metadata": {}, "outputs": [], "source": [ "from pyjedai.block_cleaning import BlockFiltering" ] }, { "cell_type": "code", "execution_count": 12, "id": "bf5c20ac-b16a-484d-82b0-61ecb9e7f3ea", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Block Filtering: 100%|██████████| 3/3 [00:00<00:00, 51.87it/s]\n" ] } ], "source": [ "bc = BlockFiltering(ratio=0.9)\n", "blocks = bc.process(blocks, data)" ] }, { "cell_type": "code", "execution_count": 13, "id": "25fd0be0-91c3-4d0b-b596-c66dccba3c79", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Block Filtering\n", "***************************************************************************************************************************\n", "Method name: Block Filtering\n", "Parameters: \n", "\tRatio: 0.9\n", "Runtime: 0.0615 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 5.21% \n", "\tRecall: 74.08%\n", "\tF1-score: 9.73%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "_ = bc.evaluate(blocks)" ] }, { "cell_type": "markdown", "id": "9cd12048-bd0c-4571-ba70-488d46afcdd6", "metadata": {}, "source": [ "## Comparison Cleaning - Meta Blocking\n", "\n", "___Optional step___\n", "\n", "Similar to Block Cleaning, this step aims to clean a set of blocks from both redundant and superfluous comparisons. Unlike Block Cleaning, its methods operate on the finer granularity of individual comparisons.\n", "\n", "The following methods are currently supported:\n", "\n", "- Comparison Propagation\n", "- Cardinality Edge Pruning (CEP)\n", "- Cardinality Node Pruning (CNP)\n", "- Weighed Edge Pruning (WEP)\n", "- Weighed Node Pruning (WNP)\n", "- Reciprocal Cardinality Node Pruning (ReCNP)\n", "- Reciprocal Weighed Node Pruning (ReWNP)\n", "- BLAST\n", "\n", "Most of these methods are Meta-blocking techniques. All methods are optional, but competive, in the sense that only one of them can part of an ER workflow. For more details on the functionality of these methods, see here. They can be combined with one of the following weighting schemes:\n", "\n", "- Aggregate Reciprocal Comparisons Scheme (ARCS)\n", "- Common Blocks Scheme (CBS)\n", "- Enhanced Common Blocks Scheme (ECBS)\n", "- Jaccard Scheme (JS)\n", "- Enhanced Jaccard Scheme (EJS)" ] }, { "cell_type": "code", "execution_count": 14, "id": "1f7d75f3-6bed-482d-a572-c3b4927236a5", "metadata": {}, "outputs": [], "source": [ "from pyjedai.comparison_cleaning import (\n", " WeightedEdgePruning,\n", " WeightedNodePruning,\n", " CardinalityEdgePruning,\n", " CardinalityNodePruning,\n", " BLAST,\n", " ReciprocalCardinalityNodePruning,\n", " ComparisonPropagation\n", ")" ] }, { "cell_type": "code", "execution_count": 15, "id": "c92e0ca3-5591-4620-b3f4-012a23637416", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Weighted Edge Pruning: 0%| | 0/1295 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw(pairs_graph)" ] }, { "cell_type": "code", "execution_count": 20, "id": "00bc2e82-9bc1-4119-b8cb-4a1c18afee19", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Entity Matching\n", "***************************************************************************************************************************\n", "Method name: Entity Matching\n", "Parameters: \n", "\tMetric: jaccard\n", "\tAttributes: None\n", "\tSimilarity threshold: 0.0\n", "\tTokenizer: white_space_tokenizer\n", "\tVectorizer: None\n", "\tQgrams: 1\n", "Runtime: 1.8509 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 77.91% \n", "\tRecall: 43.85%\n", "\tF1-score: 56.12%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "_ = em.evaluate(pairs_graph)" ] }, { "cell_type": "markdown", "id": "30a4c55c", "metadata": {}, "source": [ "### Experimenting with the attributes selected in Matching step" ] }, { "cell_type": "markdown", "id": "316ec67f", "metadata": {}, "source": [ "Giving a `list` of attributes (subset of initial), the user can experiment with the attributes that are selected in the matching step. The user can select the attributes that are used in the matching step, and the attributes that are used in the blocking step." ] }, { "cell_type": "code", "execution_count": 21, "id": "3c49107c", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Entity Matching (jaccard, white_space_tokenizer): 100%|██████████| 727/727 [00:00<00:00, 864.19it/s] \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Entity Matching\n", "***************************************************************************************************************************\n", "Method name: Entity Matching\n", "Parameters: \n", "\tMetric: jaccard\n", "\tAttributes: ['author']\n", "\tSimilarity threshold: 0.0\n", "\tTokenizer: white_space_tokenizer\n", "\tVectorizer: None\n", "\tQgrams: 1\n", "Runtime: 0.8427 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 77.53% \n", "\tRecall: 41.53%\n", "\tF1-score: 54.09%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "em = EntityMatching(\n", " metric='jaccard',\n", " similarity_threshold=0.0,\n", " attributes=['author']\n", ")\n", "\n", "authors_pairs_graph = em.predict(blocks, data)\n", "_ = em.evaluate(authors_pairs_graph)" ] }, { "cell_type": "markdown", "id": "4f016ac7", "metadata": {}, "source": [ "Giving weights as `dict`. Adding a weight factor to each attribute. " ] }, { "cell_type": "code", "execution_count": 22, "id": "da9845bb", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Entity Matching (jaccard, white_space_tokenizer): 11%|█ | 80/727 [00:00<00:00, 786.33it/s]" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Entity Matching (jaccard, white_space_tokenizer): 100%|██████████| 727/727 [00:01<00:00, 477.20it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Entity Matching\n", "***************************************************************************************************************************\n", "Method name: Entity Matching\n", "Parameters: \n", "\tMetric: jaccard\n", "\tAttributes: {'author': 0.2, 'title': 0.8}\n", "\tSimilarity threshold: 0.0\n", "\tTokenizer: white_space_tokenizer\n", "\tVectorizer: None\n", "\tQgrams: 1\n", "Runtime: 1.5248 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 77.91% \n", "\tRecall: 43.85%\n", "\tF1-score: 56.12%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "weights = {\n", " 'author': 0.2,\n", " 'title': 0.8\n", "}\n", "\n", "em = EntityMatching(\n", " metric='jaccard',\n", " similarity_threshold=0.0,\n", " attributes=weights\n", ")\n", "\n", "weights_pairs_graph = em.predict(blocks, data)\n", "_ = em.evaluate(weights_pairs_graph)" ] }, { "cell_type": "markdown", "id": "607ee1fb-bed4-4751-9fa8-429874457f72", "metadata": {}, "source": [ "### How to set a valid similarity threshold?\n", "\n", "Configure similariy threshold with a Grid-Search or with an Optuna search. Also pyJedAI provides some visualizations on the distributions of the scores.\n", "\n", "For example with a classic histogram:\n" ] }, { "cell_type": "code", "execution_count": 23, "id": "c04c0482-a0d2-4ebf-b9c8-f6cff1863e5d", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1IAAAH5CAYAAACLYg8DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABN/ElEQVR4nO3de1wWZf7/8TeiICg3aMrJUFHzgHm2DEulRMFYN1trtTyWh9XFvqtmqbulppu4ZnY03coivz9N3VatxEN4AFMpzSRNjdI06ivItil4o3Kc3x8us915yAs5iL6ej8f9eDAz11zzGRza+73XzDVulmVZAgAAAABcsWqVXQAAAAAAVDUEKQAAAAAwRJACAAAAAEMEKQAAAAAwRJACAAAAAEMEKQAAAAAwRJACAAAAAEPVK7uA8lJcXKzjx4/Lx8dHbm5ulV0OAAAAgEpiWZZOnz6t4OBgVatWNmNJ122QOn78uEJCQiq7DAAAAADXiO+//14333xzmfR13QYpHx8fSed/WQ6Ho5KrAQAAuHHk5krBwed/Pn5cqlWrcuuBmdzcXAX/5x/w+PHjqnUN/gPm5ucq+Pn/1Pj4cdXyuHyNOTk5CgkJsTNCWbhug1TJ7XwOh4MgBQAAUIHc3f/7s8NBkKpq3H/2D+hwOK7JIOWe7y7VPP+zw+H41SBVoiwf+WGyCQAAAAAwRJACAAAAAEMEKQAAAAAwdN0+I3WlioqKVFBQUNllAJWqRo0aLvdDAwAA4PJu2CBlWZYyMzN16tSpyi4FuCb4+fkpMDCQ964BAABcgRs2SJWEKH9/f3l7e/PlETcsy7J05swZZWVlSZKCgoIquSIAAIBr3w0ZpIqKiuwQddNNN1V2OUCl8/LykiRlZWXJ39+f2/wAAAB+xQ052UTJM1He3t6VXAlw7Sj5e+CZQQAAgF93QwapEtzOB/wXfw8AAABX7oYOUgAAAABQGgQp3FCSkpLk5uZmNFvjjBkz1L59+3KrCQAAAFUPQaoKSklJkbu7u2JiYiq7lCqna9euysjIkK+vb5n2GxERofHjx5dpnwAAALh2EaSqoMWLF+uxxx7Ttm3bdPz48XI9lmVZKiwsLNdjVCQPDw/elQQAAICrRpCqYpxOp1asWKGxY8cqJiZG8fHx9raHH35YAwYMcGlfUFCgevXqacmSJZKk4uJixcXFKTQ0VF5eXmrXrp3ee+89u33JrW/r169Xp06d5Onpqe3bt+vIkSO67777FBAQoNq1a+u2227Tpk2bXI6VkZGhmJgYeXl5KTQ0VMuWLVPjxo314osv2m1OnTqlkSNHqn79+nI4HLrnnnv0xRdfXPJ8H3jgAY0bN85eHj9+vNzc3PTVV19JkvLz81WrVi27lis9v5/f2vfGG28oJCRE3t7euv/++zV//nz5+fldUMv//u//qnHjxvL19dXAgQN1+vRpSdLw4cOVnJysl156SW5ubnJzc9OxY8cueU4AAACo+ghSkixLys2tnI9lmdW6cuVKtWzZUi1atNDgwYP11ltvyfpPJ4MGDdKHH34op9Npt9+4caPOnDmj+++/X5IUFxenJUuWaNGiRTpw4IAmTJigwYMHKzk52eU4U6ZM0Zw5c3To0CG1bdtWTqdT9957rzZv3qy9e/cqOjpaffv2VXp6ur3P0KFDdfz4cSUlJemf//ynXn/9dfslryUefPBBZWVlaf369dqzZ486duyonj176qeffrro+fbo0UNJSUn2cnJysurVq2ev2717twoKCtS1a1ej8yuxY8cOjRkzRn/605+UmpqqXr166dlnn72g3ZEjR7RmzRqtXbtWa9euVXJysubMmSNJeumllxQeHq5Ro0YpIyNDGRkZCgkJuejxAAAAcJ2wrlPZ2dmWJCs7O/uCbWfPnrUOHjxonT171rIsy3I6Let8pKn4j9Npdl5du3a1XnzxRcuyLKugoMCqV6+etXXrVpflJUuW2O0feugha8CAAZZlWda5c+csb29va+fOnS59jhgxwnrooYcsy7KsrVu3WpKsNWvW/GotrVu3tl555RXLsizr0KFDliRr9+7d9vZvvvnGkmS98MILlmVZ1scff2w5HA7r3LlzLv00bdrU+vvf/37RY+zbt89yc3OzsrKyrJ9++sny8PCwZs2aZZ/TX//6V6tr167G53fy5EnLsixrwIABVkxMjEv7QYMGWb6+vvby9OnTLW9vbysnJ8de98QTT1hdunSxl3v06GH96U9/utyv65r3y78LAABK6+ffrUy/66DyOZ1OS5IlyXJeo/+AzjynpRmyNEOWM+/Xa7xcNiit6pUX4WAqLS1Nu3bt0urVqyVJ1atX14ABA7R48WJFRESoevXq+v3vf6+lS5dqyJAhys3N1fvvv6/ly5dLkg4fPqwzZ86o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u3dvl239+vXTu+++qzFjxqhr164KCQnRihUrtH79ej344IP2l+ywsDB5enoqPT3d5Ta+K7Fjxw4NHz7cftbK6XTq2LFj9vYWLVqosLBQe/fuVadOnSSdHwE7efKk3aZjx47KzMxU9erVLxlMLqZRo0b2z9Wrn79kS545Ko06deooKChIubm5l2139uxZvf766+revbvq169/yXY9evTQ1q1btWvXLj377LOqW7euWrVqpWeffVZBQUFq3ry5JKlDhw4qKipSVlaWunXrdkW1tmjRQrt379bQoUPtdbt3776ifX/uYrMUAgAAoPQIUlXE2rVrdfLkSY0YMUK+vr4u2/r376/FixdrzJgxks7P3rdo0SJ9/fXX2rp1q93Ox8dHkyZN0oQJE1RcXKy77rpL2dnZ2rFjhxwOh4YNG3bJ499yyy1atWqV+vbtKzc3Nz399NMuIx4tW7ZUZGSkRo8erYULF6pGjRp6/PHH5eXlZd8WFxkZqfDwcPXr109z585V8+bNdfz4cSUkJOj++++/4HbCsvD3v/9dqampuv/++9W0aVOdO3dOS5Ys0YEDB/TKK6+4tM3KytK5c+d0+vRp7dmzR3PnztWPP/6oVatWXfYYEREReuWVV1S/fn37maqIiAi9+uqrevDBB+12zZs316BBgzR06FA9//zz6tChg/71r39p8+bNatu27UXfC/bYY49p1KhR6ty5s7p27aoVK1Zo3759atKkidHvoXHjxtq2bZsGDhwoT09P1atXz2h/AAAAuOIZqSpi8eLFioyMvCBESeeD1GeffaZ9+/ZJOj9738GDB9WgQQPdeeedLm1nzZqlp59+WnFxcWrVqpWio6OVkJCg0NDQyx5//vz5qlOnjrp27aq+ffsqKirK5XkoSVqyZIkCAgLUvXt33X///Ro1apR8fHxUs2ZNSedH/tatW6fu3bvrkUcesacZ/+677xQQEHA1v55Luv322+V0OjVmzBi1bt1aPXr00CeffKI1a9ZcMCrXokULBQcHq1OnTpozZ44iIyP15ZdfKiws7LLH6Natm4qLi136i4iIUFFRkf18VIm3335bQ4cO1eOPP64WLVqoX79+2r17txo2bHjRvgcNGqSpU6dq0qRJ6tixo44eParhw4fbv9MrNXPmTB07dkxNmza97OgaAAAAroybZTr/dhWRk5MjX19fZWdnXzA7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1NRUpaamSpKOHj2q1NRUpaeny+l06oknntAnn3yiY8eOafPmzbrvvvvUrFkzRUVFSZJatWql6OhojRo1Srt27dKOHTs0btw4DRw4UMHBwZKkhx9+WB4eHhoxYoQOHDigFStW6KWXXnK5dQ8AAAAAKotxkPrss8/UoUMHdejQQZI0ceJEdejQQdOmTZO7u7v27dun3/72t2revLlGjBihTp066eOPP5anp6fdx9KlS9WyZUv17NlT9957r+666y6Xd0T5+vrqo48+0tGjR9WpUyc9/vjjmjZtGlOfAwAAALgmGE82ERERIcuyLrl948aNv9pH3bp1tWzZssu2adu2rT7++GPT8gAAAACg3JX7M1IAAAAAcL0hSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAIYIUAAAAABgiSAEAAACAoeqVXQAAAMCNovGUhMouoUIU57tLipYktXp6g6p5FFVuQUA5MB6R2rZtm/r27avg4GC5ublpzZo1Ltsty9K0adMUFBQkLy8vRUZG6ptvvnFp89NPP2nQoEFyOBzy8/PTiBEj5HQ6Xdrs27dP3bp1U82aNRUSEqK5c+eanx0AAAAAlAPjIJWbm6t27dppwYIFF90+d+5cvfzyy1q0aJE+/fRT1apVS1FRUTp37pzdZtCgQTpw4IASExO1du1abdu2TaNHj7a35+TkqHfv3mrUqJH27Nmj5557TjNmzNDrr79eilMEAAAAgLJlfGtfnz591KdPn4tusyxLL774op56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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "em.plot_distribution_of_all_weights()" ] }, { "cell_type": "markdown", "id": "75b6218c-3983-413e-a904-53bba33ea381", "metadata": {}, "source": [ "Or with a range 0.1 from 0.0 to 1.0 grouping:" ] }, { "cell_type": "code", "execution_count": 24, "id": "3e624fb5-cb48-4081-b90f-0e59adf88d26", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Distribution-% of predicted scores: [0.175783269568814, 1.199462309998966, 1.5303484644814394, 3.732809430255403, 3.898252507496639, 6.545341743356427, 8.168751938786063, 8.334195016027298, 34.8361079516079, 17.79547099576052]\n" ] }, { "data": { "image/png": "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lCghT09PBQUF6dlnn9WFCxes9pW6jQMHDqh9+/by9/dX3rx59eKLLyohISHdfPZ+96UOdzIMQ5988onltbp9XkxMjJ5//nkVKFBAhQsXtqz76aefWr5jQkJC1L9//zSnZ6f2965du1S/fn15e3urVKlSls9YTEyMatWqJS8vL5UpU0arVq2y6XVITEzUm2++qVKlSlk+R6+88kqa96otvxNGjRqll19+WZIUGhqa5nv99t9rM2bMULt27SRJjz/+uGXZdevWqXv37sqXL59u3LiRJu8TTzyhMmXK3PU53W9f/fXXX3r++edVpkwZeXl5KW/evGrXrp3V76e75U91r++wVPf6DKU3pjv1e+3vv/9Wy5Yt5evrq/z582vo0KFKTk62Wv/ChQvq2rWr/P39FRgYqO7du2vnzp2ME0e2xZFu4CHTtWtXvfbaa/r555/Vp0+fdJfZu3evnnrqKVWuXFljxoyRh4eHjhw5oo0bN0qSypUrpzFjxuiNN95Q3759Va9ePUlSeHi4ZRsXLlzQk08+qY4dO+qZZ55RwYIF75pr7NixMplMGjZsmGJjYzVp0iRFRUVpx44dliPytrAl2+0Mw1CLFi20du1a9erVS1WrVtWKFSv08ssv6++//9bEiROtlt+wYYMWLlyo559/Xn5+fvroo4/Upk0bnThxQnnz5s0w1/Xr1xUZGakjR45owIABCg0N1fz589WjRw9dvnxZL774osqVK6dZs2Zp0KBBKly4sIYMGSJJyp8/f7rbvNfrJN36Z8ZTTz2l1atXq2PHjnrxxRd19epVrVy5Unv27FHJkiXt7oM1a9Zo3rx5GjBggPLly6fixYvr3Llzeuyxxyx/hObPn1/Lli1Tr169dOXKFcvF4D7//HO98MILatu2reWP+127dmnLli3q3Llzus/TZDKpTp06Wr9+vaVt165diouLk4uLizZu3KhmzZpJulV0VqtWTb6+vulua9asWerdu7ceffRR9e3bV5JUsmRJq2Xat2+v0NBQRUdH648//tAXX3yhAgUK6N13383o5c3Qhx9+qBYtWqhLly5KSkrSt99+q3bt2mnJkiWWzJI0evRojRo1SuHh4RozZozc3d21ZcsWrVmzRk888YSkW3/QPvvss6pQoYKGDx+uwMBAbd++XcuXL7f03fz583Xt2jU999xzyps3r3777TdNnjxZp06d0vz5862y3bx5U40bN1bdunX1/vvvy9vbW5LUu3dvff311+rcubPCw8O1Zs0aq6y2iI6OlpeXl1599VUdOXJEkydPlpubm1xcXHTp0iWNGjVKmzdv1owZMxQaGqo33njDsu7YsWM1cuRItW/fXr1799Y///yjyZMnKyIiQtu3b1dgYKBGjBihuLg4nTp1yvL+vPM1f+utt+Tu7q6hQ4cqMTExw7NsVq5cqaeeekrBwcF68cUXFRQUpP3792vJkiV68cUX7XreknTp0iU1adJErVu3Vvv27fXdd99p2LBhqlSpkp588sm7rtujRw/NmzdPXbt21WOPPaaYmJi79n27du0UFhamcePGWf5BtnLlSv3555/q2bOngoKCtHfvXn322Wfau3evNm/enOYfrO3bt1fx4sUVHR2tzZs366OPPtKlS5c0c+ZMq+Uy890XERFhuS5Fo0aN1K1btzTLPP/888qfP7/eeOMNxcfHS7pVqI4ePVpRUVF67rnndPDgQU2ZMkVbt27Vxo0brc4quXTpkp566il17NhR7dq105QpU9SxY0fNnj1bL730kvr166fOnTvrvffeU9u2bXXy5En5+fll2KcpKSlq0aKFNmzYoL59+6pcuXLavXu3Jk6cqEOHDqW5HsS9+qV169Y6dOiQvvnmG02cOFH58uWTlP73ekREhF544QV99NFHeu2111SuXDlJt36vde3aVTNnztSKFSv01FNPWdY5e/as1qxZozfffDPD5+SIvtq6dat+/fVXdezYUYULF9bx48c1ZcoURUZGat++ffL29r5rfsm277DUnJn9DCUnJ6tx48aqVauW3n//fa1atUoffPCBSpYsqeeee87yGjdv3ly//fabnnvuOZUtW1bff/+9unfvfs8+BB5aWXhqO/CvlDqme+vWrRkuExAQYFSrVs0ynTqWNdXEiRPvObb1buOm69evb0gypk6dmu68+vXrW6ZTx3QXKlTIuHLliqV93rx5hiTjww8/tLQVK1Ys3bG4d27zbtm6d+9uNQ508eLFhiTj7bfftlqubdu2hslkMo4cOWJpk2S4u7tbte3cudOQZEyePDnNvm43adIkQ5Lx9ddfW9qSkpKM2rVrG76+vlbPvVixYkazZs3uuj3DsO11+vLLLw1JxoQJE9LMS0lJMQzD/j5wcXEx9u7da7Vsr169jODgYOP8+fNW7R07djQCAgKMa9euGYZhGE8//bRN4/Xu9N577xmurq6Wfvroo4+MYsWKGY8++qgxbNgwwzBujbENDAw0Bg0aZFnvzve2Ydx7TPezzz5r1d6qVSsjb96898x453vLMAzL806VlJRkVKxY0WjQoIGl7fDhw4aLi4vRqlWrNOODU1+jy5cvG35+fkatWrXSjFFPXSa9/RmGYURHRxsmk8n466+/rLJKMl599VWrZXfs2GFIMp5//nmr9s6dO9s0pjv181yxYkWrcaqdOnUyTCaT8eSTT1otX7t2bas+O378uOHq6mqMHTvWarndu3cbuXLlsmrPaEx3aoYSJUqk6Y/UeanjTW/evGmEhoYaxYoVMy5dumS17O39erfnevvY1dTvvpkzZ1raEhMTjaCgIKNNmzZ33d62bdsMScZLL71k1d6jR480fZ/6Xu3UqVOa7aT3Hvjmm28MScb69evTbKNFixZWyz7//POGJKtrf9zPd1/q+neOCU/9XVW3bl2rcbmxsbGGu7u78cQTT1h9Hj7++GNDkvHll19a2lL7e86cOZa2AwcOWL6nNm/ebGlfsWKFTdchmTVrluHi4mL88ssvVu1Tp041JBkbN260el629MvdxnTf+XstozHRycnJRuHChY0OHTpYtU+YMMEwmUzGn3/+edfndb99ld77atOmTWne7xnlt/U7zNbP0LFjx9JkTP1eGzNmjNX2q1WrZtSoUcMyvWDBAkOSMWnSJEtbcnKy0aBBg0xdqwZ4GHB6OfAQ8vX1vetVzFPH3n3//fdKSUnJ1D48PDzUs2dPm5fv1q2b1dGHtm3bKjg4WD/99FOm9m+rn376Sa6urnrhhRes2ocMGSLDMLRs2TKr9qioKKsjo5UrV5a/v7/+/PPPe+4nKChInTp1srS5ubnphRdekNlsVkxMjN3ZbXmdFixYoHz58mngwIFp5qUe8bK3D+rXr2815twwDC1YsEDNmzeXYRg6f/685dG4cWPFxcXpjz/+sGQ+deqUtm7datdzrVevnpKTk/Xrr79KunVEu169eqpXr55++eUXSdKePXt0+fJly9kNmdWvX780+75w4YKuXLli97ZuP0vj0qVLiouLU7169Sz9Id06ZTclJUVvvPGGXFysf22mvkYrV67U1atX9eqrr6YZx3j7kcvb9xcfH6/z588rPDxchmFo+/btafKl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ejnwEFmzZo3eeusthYaGWm4PlJ6LFy+maUstBlJvmZJ6L9X0iuDMmDlzptU4te+++05nzpyxulJpyZIltXnzZiUlJVnalixZkubWYvZka9q0qZKTk/Xxxx9btU+cOFEmk+meV0q1VdOmTXX27FnNnTvX0nbz5k1NnjxZvr6+llOA7WHL69SmTRudP38+zfOT/v+owf32gaurq9q0aaMFCxZoz549aeb/888/lp/vvG2Ru7u7ypcvL8Mw0r0Vzu3q1aunxMRETZo0SXXr1rX8cVevXj3NmjVLp0+ftmk8t4+Pj8Pet3fj6uoqk8lkdaua48ePp7n6ccuWLeXi4qIxY8akOWKU+ho98cQT8vPzU3R0dJrbOaUuk3qE5/ajQYZh3PPWV7dLfa0/+ugjq/ZJkybZvI370bp1a7m6umr06NFpjmoZhmH1/vHx8bHptNa7qV69ukJDQzVp0qQ074kHffZK6j9CP/30U6v2yZMn27yN9N4D0t1fv08++STd/Tnqu89eUVFRcnd310cffWT1PKZNm6a4uDi7r6Rvr/bt2+vvv//W559/nmbe9evXLVdYt4c9v5PutWynTp1kMpn04osv6s8//7Qa++xMrq6uad5XkydPTnMrrozy2/Id9qA0btxYN27csHqNU1JS0nwWgOyEI91AFlm2bJkOHDigmzdv6ty5c1qzZo1WrlypYsWK6YcffrjrEcUxY8Zo/fr1atasmYoVK6bY2Fh9+umnKly4sGW8bMmSJRUYGKipU6fKz89PPj4+qlWrlk3jKNOTJ08e1a1bVz179tS5c+c0adIklSpVyupCJ71799Z3332nJk2aqH379jp69Ki+/vrrNONP7cnWvHlzPf744xoxYoSOHz+uKlWq6Oeff9b333+vl156Kc22M6tv377673//qx49emjbtm0qXry4vvvuO23cuFGTJk266xj7jNjyOnXr1k0zZ87U4MGD9dtvv6levXqKj4/XqlWr9Pzzz+vpp592SB+88847Wrt2rWrVqqU+ffqofPnyunjxov744w+tWrXK8g+CJ554QkFBQapTp44KFiyo/fv36+OPP1azZs3u2Qe1a9dWrly5dPDgQcvtvqRbt9mZMmWKJNlUdNeoUUOrVq3ShAkTFBISotDQUKuLCDlKs2bNNGHCBDVp0kSdO3dWbGysPvnkE5UqVUq7du2yLFeq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68SJE5Z1unXrptOnT2vdunVasGCBPvvsM8XGxlptt127doqNjdWyZcu0bds2Va9eXQ0bNtTFixfTfb7169fXunXrLNMxMTHKly+fpW3r1q26ceOGwsPD7Xp+qTZu3Kh+/frpxRdf1I4dO9SoUSONHTs2zXJHjx7V4sWLtWTJEi1ZskQxMTF65513JEkffvihateurT59+ujMmTM6c+aMihQpku7+AAAAAPxLGFno008/NSpVqmT4+fkZfn5+xmOPPWb89NNPlvn169c3JFk9/vOf/9i1j7i4OEOSERcXl2be9evXjX379hnXr183DMMwzGbDuFX+PviH2Wxf34WHhxuTJk0yDMMwbty4YeTLl89Yu3at1fTMmTMty3fq1Mno0KGDYRiGkZCQYHh7exu//vqr1TZ79epldOrUyTAMw1i7dq0hyVi8ePE9s1SoUMGYPHmyYRiGsX//fkOSsXXrVsv8w4cPG5KMiRMnGoZhGL/88ovh7+9vJCQkWG2nZMmSxn//+99097Fr1y7DZDIZsbGxxsWLFw13d3fjrbfesjynt99+2wgPD7f7+V26dMkwDMPo0KGD0axZM6vlu3TpYgQEBFim33zzTcPb29u4cuWKpe3ll182atWqZZmuX7++8eKLL96tux56d34uAABAznb738D2/k2Kh5/ZbLbUUuZs8AKbE82GRsnQKBnmxIc7791qzdvlyppS/5bChQvrnXfeUVhYmAzD0FdffaWnn35a27dvV4UKFSRJffr00ZgxYyzreHt7Z1Xch8bBgwf122+/adGiRZKkXLlyqUOHDpo2bZoiIyOVK1cutW/fXrNnz1bXrl0VHx+v77//Xt9++60k6ciRI7p27ZoaNWpktd2kpCRVq1bNqu2RRx6xmjabzRo1apSWLl2qM2fO6ObNm7p+/brlSPfBgweVK1cuVa9e3bJOqVKllDt3bsv0zp07ZTablTdvXqttX79+XUePHk33OVesWFF58uRRTEyM3N3dVa1aNT311FP65JNPJN068h0ZGWn387u9T1PPAkj16KOPasmSJVZtxYsXl5+fn2U6ODg4zVF8AAAAAEiVpUV38+bNrabHjh2rKVOmaPPmzZai29vbW0FBQQ8kj7e3dNsZ2Q+UPf9LmDZtmm7evKmQkBBLm2EY8vDw0Mcff6yAgAB16dJF9evXV2xsrFauXCkvLy81adJEkiynnS9dulSFChWy2raHh4fVtI+Pj9X00KFDtXLlSr3//vsqVaqUvLy81LZtWyUlJdmc32w2Kzg42Op08VTpjaGWJJPJpIiICK1bt04eHh6KjIxU5cqVlZiYqD179ujXX3/V0KFD7X5+9nJzc0uTKyUl5b62CQAAACDnytKi+3bJycmaP3++4uPjVbt2bUv77Nmz9fXXXysoKEjNmzfXyJEj73q0OzExUYmJiZbpK1eu2JzBZJLuqDEfOjdv3tTMmTP1wQcf6IknnrCa17JlS33zzTfq16+fwsPDVaRIEc2dO1fLli1Tu3btLAVj+fLl5eHhoRMnTqh+/fp27X/jxo3q0aOH5aiw2Wy2ulhYmTJldPPmTW3fvl01atSQdOvI86VLlyzLVK9eXWfPnlWuXLlUvHhxm/ddv359ff755/Lw8NDYsWPl4uKiiIgIvffee0pMTFSdOnUy/fzKlCmjrVu3WrXdOW0Ld3d3JScn270eAAAAgJwpy4vu3bt3q3bt2kpISJCvr68WLVqk8uXLS7p1Fe5ixYopJCREu3bt0rBhw3Tw4EEtXLgww+1FR0dr9OjRDyr+A7dkyRJdunRJvXr1SnOP6TZt2mjatGnq16+fpFv9N3XqVB06dEhr1661LOfn56ehQ4dq0KBBSklJUd26dRUXF6eNGzfK399f3bt3z3D/YWFhWrhwoZo3by6TyaSRI0daHektW7asoqKi1LdvX02ZMkVubm4aMmSIvLy8LLfnioqKUu3atdWyZUuNHz9epUuX1unTp7V06VK1atUqzSntqSIjIzVo0CC5u7urbt26lrahQ4eqZs2alqPymXl+AwcOVEREhCZMmKDmzZtrzZo1WrZsmd23FCtevLi2bNmi48ePy9fXV3ny5JGLC9crBAAAAP6tsrwaKFOmjHbs2KEtW7boueeeU/fu3bVv3z5JUt++fdW4cWNVqlRJXbp00cyZM7Vo0aIMx/1K0vDhwxUXF2d5nDx58kE9lQdi2rRpioqKSlNwS7eK7t9//127du2SdOsq5vv27VOhQoUsR4FTvfXWWxo5cqSio6NVrlw5NWnSREuXLlVoaOhd9z9hwgTlzp1b4eHhat68uRo3bmw1fluSZs6cqYIFCyoiIkKtWrVSnz595OfnJ09PT0m3Tsn+6aefFBERoZ49e6p06dLq2LGj/vrrLxUsWDDDfVeqVEmBgYGqWrWqfH19Jd0qupOTky3juTP7/OrUqaOpU6dqwoQJqlKlipYvX65BgwZZMttq6NChcnV1Vfny5ZU/f36rq7oDAAAA+PcxGYa9N6tyrqioKJUsWVL//e9/08yLj4+Xr6+vli9frsaNG9u0vStXriggIEBxcXHy9/e3mpeQkKBjx44pNDTU7uIKtjt16pSKFCmiVatWqWHDhlkdx2Z9+vTRgQMH9Msvv2R1lAeKzwUAADmIDWftxctbvoqXJJnlIx9dc3Yqaw9XOZLjpNZQ0q2hoXdes+lhE58UL9/o/+UdbpaP+8Ob92615u2y/PTyO6WkpFiNyb7djh07JN26YjQeXmvWrJHZbFalSpV05swZvfLKKypevLgiIiKyOtpdvf/++2rUqJF8fHy0bNkyffXVV/r000+zOhYAAACAbCxLi+7hw4frySefVNGiRXX16lXNmTNH69at04oVK3T06FHNmTNHTZs2Vd68ebVr1y4NGjRIERERqly5clbGxj3cuHFDr732mv7880/5+fkpPDxcs2fPTnPl74fNb7/9pvHjx+vq1asqUaKEPvroI/Xu3TurYwEAAADIxrK06I6NjVW3bt105swZBQQEqHLlylqxYoUaNWqkkydPatWqVZo0aZLi4+NVpEgRtWnTRq+//npWRoYNGjdubPPp/w+TefPmZXUEAAAAADlMlhbd06ZNy3BekSJFFBMT8wDTAAAAAADgWFl+9XIAAAAAAHIqim4AAAAAAJyEohsAAAAAACeh6AYAAAAAwEkougEAAAAAcBKKbqRr3bp1MplMunz5siRpxowZCgwMzNJMmVG8eHFNmjTJ5uWPHz8uk8mkHTt2OC0TAAAAgH8Piu5sqEePHjKZTOrXr1+aef3795fJZFKPHj0cus8OHTro0KFDDt3mg7B161b17dvXodvMrv+AAAAAAPDgUXRnU0WKFNG3336r69evW9oSEhI0Z84cFS1a1OH78/LyUoECBRy+XWfLnz+/vL29szoGAAAAgH8piu5sqnr16ipSpIgWLlxoaVu4cKGKFi2qatWqWS2bkpKi6OhohYaGysvLS1WqVNF3331ntcxPP/2k0qVLy8vLS48//riOHz9uNf/Oo7tHjx7V008/rYIFC8rX11c1a9bUqlWrrNYpXry4xo0bp2effVZ+fn4qWrSoPvvsswyf05IlSxQYGKjk5GRJ0o4dO2QymfTqq69alundu7eeeeYZy/SGDRtUr149eXl5qUiRInrhhRcUHx9vleH208sPHDigunXrytPTU+XLl9eqVatkMpm0ePFiqyx//vmnHn/8cXl7e6tKlSratGmTpFun3ffs2VNxcXEymUwymUwaNWpUhs8JAAAAwL8bRfdtDMNQfHx8ljwMw7A777PPPqvp06dbpr/88kv17NkzzXLR0dGaOXOmpk6dqr1792rQoEF65plnFBMTI0k6efKkWrdurebNm2vHjh3q3bu3VaGbHrPZrKZNm2r16tXavn27mjRpoubNm+vEiRNWy33wwQd65JFHtH37dj3//PN67rnndPDgwXS3Wa9ePV29elXbt2+XJMXExChfvnxat26dZZmYmBhFRkZKulX4N2nSRG3atNGuXbs0d+5cbdiwQQMGDEh3+8nJyWrZsqW8vb21ZcsWffbZZxoxYkS6y44YMUJDhw7Vjh07VLp0aXXq1Ek3b95UeHi4Jk2aJH9/f505c0ZnzpzR0KFD79pXAAAAAP7FjBwuLi7OkGTExcWlmXf9+nVj3759xvXr1w3DMAyz2WxIypKH2Wy2+Tl1797dePrpp43Y2FjDw8PDOH78uHH8+HHD09PT+Oeff4ynn37a6N69u2EYhpGQkGB4e3sbv/76q9U2evXqZXTq1MkwDMMYPny4Ub58eav5w4YNMyQZly5dMgzDMKZPn24EBATcNVeFChWMyZMnW6aLFStmPPPMM5bplJQUo0CBAsaUKVMy3Eb16tWN9957zzAMw2jZsqUxduxYw93d3bh69apx6tQpQ5Jx6NAhy3Po27ev1fq//PKL4eLiYnlNixUrZkycONEwDMNYtmyZkStXLuPMmTOW5VeuXGlIMhYtWmQYhmEcO3bMkGR88cUXlmX27t1rSDL2799vc19kZ3d+LgAAQDYm3fNhlrdl0ixvm9Zx6ANOdXuNY0/NkVXMiWZDo2RolAxz4sOd92615u1yObGeh5Plz59fzZo104wZM2QYhpo1a6Z8+fJZLXPkyBFdu3ZNjRo1smpPSkqynIa+f/9+1apVy2p+7dq177pvs9msUaNGaenSpTpz5oxu3ryp69evpznSXblyZcvPJpNJQUFBio2NzXC79evX17p16zRkyBD98ssvio6O1rx587RhwwZdvHhRISEhCgsLkyTt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Xl5q0qSJJFmOji5dulSFChWy2nbqkedUPj7WR9+HDh2qlStX6v3331epUqXk5eWltm3bWq4Abguz2azg4GCrMcyp7nabrJ9++skyPvnvv/9WZGSkduzYYZl/59js9BQqVEhdu3ZV165d9dZbb6l06dKaOnWqRo8efdf19u/fL+nW1b/TExgYqCpVqmjdunXatGmTGjVqpIiICMtVyA8fPmw50m02m+Xq6qpt27ZZFcjSrX8i3A83NzeraZPJpJSUlPvaJgAAAIDMo+i+jclksusU76xw8+ZNzZw5Ux988IGeeOIJq3ktW7bUN998o379+ik8PFxFihTR3LlztWzZMrVr185SkJUvX14eHh46ceKE1anktti4caN69OhhGRtuNpt1/Phxy/wyZcro5s2b2r59u2rUqCHp1pH1S5cuWZapXr26zp49q1y5cmVYxKanWLFilp9z5br11k0dI50ZuXPnVnBwsOLj4++63PXr1/XZZ58pIiJC+fPnz3C5+vXra+3atfrtt980duxY5cmTR+XKldPYsWMVHBys0qVLS5KqVaum5ORkxcbGql69ejZlLVOmjLZu3apu3bpZ2rZu3WrTurdL72rtAAAAAJyHojubWbJkiS5duqRevXopICDAal6bNm00bdo09evXT9Ktq5hPnTpVhw4d0tq1ay3L+fn5aejQoRo0aJBSUlJUt25dxcXFaePGjfL391f37t0z3H9YWJgWLlyo5s2by2QyaeTIkVZHUsuWLauoqCj17dtXU6ZMkZubm4YMGSIvLy/LqdlRUVGqXbu2WrZsqfHjx6t06dI6ffq0li5dqlatWqU5pd0R/vvf/2rHjh1q1aqVSpYsqYSEBM2cOVN79+7V5MmTrZaNjY1VQkKCrl69qm3btmn8+PE6f/68Fi5ceNd9REZGavLkycqfP79lDHhkZKQ+/vhjtWvXzrJc6dKl1aVLF3Xr1k0ffPCBqlWrpn/++UerV69W5cqV073v+sCBA9WnTx898sgjCg8P19y5c7Vr1y6VKFHCrn4oXry41q9fr44dO8rDw0P58uWza30AAAAA9mFMdzYzbdo0RUVFpSm4pVtF9++//65du3ZJunUV83379qlQoUKqU6eO1bJvvfWWRo4cqejoaJUrV05NmjTR0qVLFRoaetf9T5gwQblz51Z4eLiaN2+uxo0bW43flqSZM2eq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urpKksqUKaPHHnvMOSkBAAAAAMiGbC66jx49qlq1aum///2vqlWrpkaNGqlZs2Zq2bKlbty4oVmzZqlx48bOzAoAAAAAQLZic9H98ccfa/PmzXr22Wf1+OOPKzo6Wl9//bVWrlyp5ORktWvXTgMGDHBmVgAAAAAAshWbi25Jeuyxx7R161a9++67ql27tt577z0tWLDAWdkAAAAAAMjW7L6QWq5cuTRixAj9+OOPmjRpktq2bauzZ886IxsAAAAAANmazUX3zp07VbNmTfn5+alOnTpKSUnR6tWr1axZM4WHh2vKlCnOzAkAAAAAQLZjc9H97LPPql69etq6davatWunfv36SZJ69uypLVu2aOPGjapdu7bTggIAAAAAkN3YPKb70KFDmjt3rkqVKqWwsDBNmjTJMi9//vz6+uuv9fPPPzsjIwAAAAAA2ZLNRXdkZKT69u2rjh07as2aNapTp06aZZ544gmHhgMAAAAAIDuz+fTymTNnqnr16vr+++9VokQJxnADAAAAAHAPNh/pzp07t95//31nZgEAAAAAIEex6Uj3iRMn7Nro33//nakwAAAAAADkJDYV3TVr1tR//vMfbd26NcNl4uLi9Pnnn6tixYpasGCBwwICAAAAAJBd2XR6+b59+zR27Fg1atRInp6eqlGjhkJCQuTp6alLly5p37592rt3r6pXr67x48eradOmzs4NAAAAAMBDz6Yj3Xnz5tWECRN05swZffzxxwoLC9P58+d1+PBhSVKXLl20bds2bdq0iYIbAAAAAID/sflCapLk5eWltm3bqm3bts7KAwAAAABAjmHzLcMAAAAAAIB9KLoBAAAAAHASim4AAAAAAJyEohsAAAAAACeh6AYAAAAAwElsunr5Dz/8YPMGW7RokekwAAAAAADkJDYV3S1btrRpYyaTScnJyfeTBwAAAACAHMOmojslJcXZOQAAAAAAyHEY0w0AAAAAgJPYdKT7o48+snmDL7zwQqbDAAAAAACQk9hUdE+cONGmjZlMJopuAAAAAAD+x6ai+9ixY87OAQAAAABAjsOYbgAAAAAAnMSmI913OnXqlH744QedOHFCSUlJVvMmTJjgkGAAAAAAAGR3dhfdq1evVosWLVSiRAkdOHBAFStW1PHjx2UYhqpXr+6MjAAAAAAAZEt2n14+fPhwDR06VLt375anp6cWLFig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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "em.plot_distribution_of_scores()" ] }, { "cell_type": "markdown", "id": "93b72120-4578-4d5c-a408-a24ee78bf6cb", "metadata": {}, "source": [ "## Entity Clustering\n", "\n", "It takes as input the similarity graph produced by Entity Matching and partitions it into a set of equivalence clusters, with every cluster corresponding to a distinct real-world object." ] }, { "cell_type": "code", "execution_count": 25, "id": "500d2ef7-7017-4dba-bbea-acdba8abf5b7", "metadata": {}, "outputs": [], "source": [ "from pyjedai.clustering import ConnectedComponentsClustering" ] }, { "cell_type": "code", "execution_count": 26, "id": "aebd9329-3a4b-48c9-bd05-c7bd4aed3ca9", "metadata": {}, "outputs": [], "source": [ "ec = ConnectedComponentsClustering()\n", "clusters = ec.process(pairs_graph, data, similarity_threshold=0.3)" ] }, { "cell_type": "code", "execution_count": 27, "id": "3d2aa574", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Connected Components Clustering\n", "***************************************************************************************************************************\n", "Method name: Connected Components Clustering\n", "Parameters: \n", "\tSimilarity Threshold: 0.3\n", "Runtime: 0.0396 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 76.45% \n", "\tRecall: 43.99%\n", "\tF1-score: 55.85%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "_ = ec.evaluate(clusters)" ] }, { "cell_type": "markdown", "id": "6e44642b-b0d9-4f8d-9fe4-4fca2ad716aa", "metadata": {}, "source": [ "# Workflow with Similarity Joins\n", "\n", "In this notebook we created the bellow archtecture:\n", "\n", "![workflow2-cora.png](https://github.com/AI-team-UoA/pyJedAI/blob/main/documentation/workflow2-cora.png?raw=true)\n", "\n" ] }, { "cell_type": "markdown", "id": "2b07ea13-58cb-498a-949a-4702ea9ee4ce", "metadata": { "tags": [] }, "source": [ "## Data Reading" ] }, { "cell_type": "markdown", "id": "a0b7acf5-32b3-45b1-8347-197dfa869fb9", "metadata": {}, "source": [ "Data is the connecting module of all steps of the workflow" ] }, { "cell_type": "code", "execution_count": 28, "id": "3006b051-8348-4922-a627-56441a1db7b7", "metadata": { "tags": [] }, "outputs": [], "source": [ "from pyjedai.datamodel import Data\n", "d1 = pd.read_csv(\"./../data/der/cora/cora.csv\", sep='|')\n", "gt = pd.read_csv(\"./../data/der/cora/cora_gt.csv\", sep='|', header=None)\n", "attr = ['Entity Id','author', 'title']\n", "data = Data(\n", " dataset_1=d1,\n", " id_column_name_1='Entity Id',\n", " ground_truth=gt,\n", " attributes_1=attr\n", ")" ] }, { "cell_type": "markdown", "id": "b3eedb4c-b86f-4f98-abf2-9d6f7d0271c5", "metadata": {}, "source": [ "## Similarity Joins" ] }, { "cell_type": "code", "execution_count": 29, "id": "afd97b7e-4bf8-4256-b9fc-a301e413e834", "metadata": {}, "outputs": [], "source": [ "from pyjedai.joins import EJoin, TopKJoin" ] }, { "cell_type": "code", "execution_count": 30, "id": "7bc8ba43-b059-4839-8958-0b31fab95e46", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "EJoin (jaccard): 0%| | 0/1295 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw(g)" ] }, { "cell_type": "code", "execution_count": 34, "id": "a4c57244-0c98-4598-8ae2-06cdd0c48385", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Top-K Join\n", "***************************************************************************************************************************\n", "Method name: Top-K Join\n", "Parameters: \n", "\tsimilarity_threshold: 0.25547445255474455\n", "\tK: 20\n", "\tmetric: jaccard\n", "\ttokenization: qgrams\n", "\tqgrams: 3\n", "Runtime: 15.0497 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 58.34% \n", "\tRecall: 63.75%\n", "\tF1-score: 60.92%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] }, { "data": { "text/plain": [ "{'Precision %': 58.340434597358325,\n", " 'Recall %': 63.74534450651769,\n", " 'F1 %': 60.923248053392655,\n", " 'True Positives': 10954,\n", " 'False Positives': 7822,\n", " 'True Negatives': 814451.0,\n", " 'False Negatives': 6230}" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "topk_join.evaluate(g)" ] }, { "cell_type": "markdown", "id": "e686ba55-cbbe-4133-8256-fa5339e70720", "metadata": {}, "source": [ "## Entity Clustering" ] }, { "cell_type": "code", "execution_count": 35, "id": "e48627ef-0be6-45dd-b3ba-863818eadbfb", "metadata": {}, "outputs": [], "source": [ "from pyjedai.clustering import ConnectedComponentsClustering" ] }, { "cell_type": "code", "execution_count": 36, "id": "a9d5a28d-79f0-479f-b154-f5f7e3661897", "metadata": {}, "outputs": [], "source": [ "ccc = ConnectedComponentsClustering()\n", "\n", "clusters = ccc.process(g, data)" ] }, { "cell_type": "code", "execution_count": 37, "id": "f95539fe-2569-4569-8929-2f4220f14157", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "***************************************************************************************************************************\n", " Method: Connected Components Clustering\n", "***************************************************************************************************************************\n", "Method name: Connected Components Clustering\n", "Parameters: \n", "\tSimilarity Threshold: None\n", "Runtime: 0.1237 seconds\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "Performance:\n", "\tPrecision: 2.05% \n", "\tRecall: 100.00%\n", "\tF1-score: 4.02%\n", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n" ] } ], "source": [ "_ = ccc.evaluate(clusters)" ] }, { "cell_type": "markdown", "id": "778b9b19-0964-4095-a293-a8336fe0607a", "metadata": {}, "source": [ "
\n", "
\n", "K. Nikoletos, J. Maciejewski, G. Papadakis & M. Koubarakis\n", "
\n", "
\n", "Apache License 2.0\n", "
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.0" } }, "nbformat": 4, "nbformat_minor": 5 }