{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f8bbee6d-40fc-4d6c-ac66-7af4476b6ae0",
   "metadata": {
    "tags": [
     "remove-cell"
    ]
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7dd5f94a-67ce-47f9-9130-a9ab4b5d6afa",
   "metadata": {},
   "source": [
    "# Set-based (Jaccard) similarity\n",
    "\n",
    "Exact matches are easy to test, and tests for exact matches give yes-no answers.  It is sometimes useful to know if two strings are similar, and the string matching procedure needs to be able to give answers for input strings that are not the same length.  The most straightforward approach of testing character-by-character to see the fraction of characters that match does not work well for variable-length strings or strings that can be similar if the order of their contents is changed.  \n",
    "\n",
    "Another approach to imprecise string matching that can handle inputs of different length is the strategy of breaking the strings into substrings and check the fraction of exact matches among substrings.  How many of the parts of `string1` have exact matches for parts of `string2`?   If two strings are identical for most of their length, most of the substrings will still match even if the strings are not identical.\n",
    "\n",
    "We will digest strings into pieces for analysis called tokens, count the tokens, and measure similarity by counting tokens shared and not shared.  This procedure was independently developed in meteorology(in the 1880s)[^*], ecology (in the 1910s)[^**], and computer science^[***].  \n",
    "\n",
    "The similarity score takes slightly different forms depending on whether we count tokens with presence-or-absence only (sets), or whether we count the number of occurrences of each token (multi-sets)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8524ce0f-5dea-404b-91db-f454eac14238",
   "metadata": {},
   "source": [
    "## Tokenization\n",
    "\n",
    "To start with, to find partial matches we need objects that represent less than all of the objects we are comparing.  Tokenization is the process of breaking a string (or document) into pieces that will be the objects of analysis.\n",
    "\n",
    "The first step in finding set-based Jaccard similarity is to tokenize the input string.  Tokens can be individual words, pairs of words, triplets (or more) of words, individual letters, letter pairs, or more, or parts of words.  For some applications, tokens smaller than words are indicated; some tokenizers split words into meaningful parts (by encoding plural noun endings and inflected verb endings as separate tokens).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85184325-1d3c-4870-813d-01bff8edfec4",
   "metadata": {},
   "source": [
    "One tokenization approach (suited for documents) is to tokenize on words:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "42c5d34f-272a-454b-8ba4-2897bd1d93e6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Crash',\n",
       " 'data',\n",
       " 'shows',\n",
       " 'information',\n",
       " 'about',\n",
       " 'each',\n",
       " 'traffic',\n",
       " 'crash',\n",
       " 'on',\n",
       " 'city',\n",
       " 'streets.']"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "content = \"Crash data shows information about each traffic crash on city streets.\"\n",
    "content.split()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d39ed3b-5fa4-49f7-9088-477e9e223448",
   "metadata": {},
   "source": [
    "Note that this attaches punctuation marks to words if there are no intervening spaces.  Depending on your application you may want to remove (or preserve) punctuation, spacing, capitalization, or other features of the encoding."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ab8a7f3-35a1-44eb-aabd-ee7d8dcab2a7",
   "metadata": {},
   "source": [
    "## n-gram tokenization"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe9dcf51-154d-471b-8494-b28d418a8d43",
   "metadata": {},
   "source": [
    "Another approach to digesting text into tokens is to use fixed-length, overlapping substrings.  This breaks text up into constant-sized pieces.  The overlapping, fixed-length \n",
    "tokens are called n-grams or k-mers.  \n",
    "\n",
    "As an example, the word `WORD` can be digested into the two-letter subsets (called bigrams) `WO`, `OR`, and `RD`.  This particular digestion treats the first and final letter off the text differently; W and D are included only once (while all the other letters are included twice).  A convention that mitigates this \"edge effect\" is to add symbols to the beginning and the end of the string before digesting it that allow the edge letters to be included in every possible position in a bigram.  Breaking `#WORD#` into n-grams of length 2 (bigrams) results in `#W`, `WO`, `OR`, `RD`, and `D#`.  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1bf0403e-93c3-48d5-9644-1ac6e7f1ba07",
   "metadata": {},
   "source": [
    "This function adds \"#\" before and after the string and digests a string of length n into n+1 bigrams:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0c215615-08c4-4ffb-8ef9-c08606f82b6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def tokenizebigrams(s):\n",
    "    '''Return a list of all two-character subsets\n",
    "    of a string, including each input character twice.'''\n",
    "    #  add dummy symbols at beginning and end:\n",
    "    paddeds = \"#\" + s + \"#\"\n",
    "    bigrams = []\n",
    "    for i in range(len(paddeds)-2 ):\n",
    "        bigrams.append( paddeds[i:i+2])\n",
    "    return bigrams"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbfb81d0-7a2d-490e-8d10-6013175791b7",
   "metadata": {},
   "source": [
    "Note that each character in the input appears in two of the bigrams.\n",
    "\n",
    "And before we use this, we can devise a test that confirms that `tokenizebigrams` gives the correct output for a brief input:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9f0fb5f7-12ad-42f3-9811-170e65662ed6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokenizebigrams(\"HELP\") == [ \"#H\", \"HE\", \"EL\", \"LP\", \"P#\" ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1a637224-4ead-48b9-be67-cea55373c191",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['#H', 'HE', 'EL', 'LP']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokenizebigrams(\"HELP\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12628e25-4ba1-4cd1-b4dd-ea4c6f0cd56a",
   "metadata": {},
   "source": [
    "This is not the right answer: every letter in the input string is included in two bigrams except \"P\".  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd23220d-8c51-4c00-9a1f-ef20dee4ae34",
   "metadata": {},
   "source": [
    "It is good that we tested this, since there is an off-by-one error that I would not have seen just staring at it.  The final letter \"P\" is only present in one bigram, not two as intended."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "14682567-72b9-44e0-aeef-345c3e3e309b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['#H', 'HE', 'EL', 'LL', 'LO', 'O#']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def tokenizebigrams(s):\n",
    "    '''Return a list of all two-character subsets\n",
    "    of a string, including each input character twice.'''\n",
    "    #  add dummy symbols at beginning and end:\n",
    "    paddeds = \"#\" + s + \"#\"\n",
    "    bigrams = []\n",
    "    for i in range(len(paddeds)-1 ):\n",
    "        bigrams.append( paddeds[i:i+2])\n",
    "    return bigrams\n",
    "tokenizebigrams(\"HELLO\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79480022-9ca7-48df-9f19-a7566b6ad27e",
   "metadata": {},
   "source": [
    "Now that we have a way to turn strings into lists of tokens, we need to count tokens.  Python's `set` datatype makes counting distinct tokens particularly simple.  The builtin `len()` command returns the number of (distinct) elements in a set, and the builtin `set()` will return a set from a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b4f3a18b-06b8-45cf-95d6-5080be05d4e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'O#', 'LL', 'HE', '#H', 'EL', 'LO'}\n",
      "{'P#', 'LP', 'HE', '#H', 'EL'}\n"
     ]
    }
   ],
   "source": [
    "tokens1 = set(tokenizebigrams(\"HELLO\"))\n",
    "tokens2 = set(tokenizebigrams(\"HELP\"))\n",
    "print(tokens1 )\n",
    "print(tokens2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c2fa162-d0c0-4609-83ae-5a260f607b95",
   "metadata": {},
   "source": [
    "Note that sets do not preserve the order of the elements, only their identity (and presence/absence).\n",
    "\n",
    "Now we can construct the set all the tokens in common with the `set.union()` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ee94fd32-0c18-43a3-8de3-44dee198e975",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'P#', 'O#', 'LP', 'LL', 'HE', '#H', 'EL', 'LO'}\n"
     ]
    }
   ],
   "source": [
    "print(tokens1.union(tokens2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97a20455-3c41-4c96-83d0-553594c95fe4",
   "metadata": {},
   "source": [
    "And the set of all common tokens using `set.intersection()` :\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d58a37b8-ce62-4588-83e7-c0fde8fb715c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'#H', 'EL', 'HE'}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokens1.intersection(tokens2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1ee2f40b-8a6b-4c52-91e4-f67e1c8cc897",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6 tokens in HELLO\n",
      "5 tokens in HELP\n",
      "8 tokens in union\n",
      "3 tokens in intersection\n"
     ]
    }
   ],
   "source": [
    "print( len(tokens1), \"tokens in HELLO\")\n",
    "print( len(tokens2), \"tokens in HELP\")\n",
    "print( len(tokens1.union(tokens2)), \"tokens in union\")\n",
    "print( len(tokens1.intersection(tokens2)), \"tokens in intersection\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0e66717-9a50-42ca-9d4f-29f8f4a2083b",
   "metadata": {},
   "source": [
    "## Jaccard similarity"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d097220a-8bcf-41cd-9df7-f21e27166056",
   "metadata": {},
   "source": [
    "The Jaccard index is defined as the ratio of the number of elements in the intersection to the number of elements in the union:\n",
    "\n",
    "$$ J(s_1, s_2)  =  { n_{12} \\over n_1 + n_2 - n_{12} } $$\n",
    "\n",
    "where $n_1$ are the number of tokens in $s_1$ and $s_2$, respectively, and $n_{12}$ is the number of tokens that are shared by both $s_1$ and $s_2$.  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64550e95-5d0e-416c-9e31-1445ad5fadbb",
   "metadata": {},
   "source": [
    "If we need a distance, the Jaccard distance is just one minus the Jaccard similarity:\n",
    "    \n",
    "$$ d_{Jaccard}(s_1, s_2) = 1 - J(s_1, s_2)  $$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f4e8a00-f670-4454-b3d1-20ef259b769c",
   "metadata": {},
   "source": [
    "Where $n_{12}$ is the number of tokens common to $s_1$ and $s_2$ and $  { (n_1 + n_2 - n_{12}) }$  is the number of tokens in either $s_1$, $s_2$, or both.  (Note that $n_1 + n_2$ would double-count tokens in the intersection.)\n",
    "\n",
    "We can put these set-counting functions and the definition into a function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "f778c7cc-2ef1-4eb6-bc0f-13d9fa17f21b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def J(s1, s2):\n",
    "    '''return jaccard similarity between two strings s1 and s2'''\n",
    "    t1 = set(tokenizebigrams(s1))\n",
    "    t2 = set(tokenizebigrams(s2))\n",
    "    #print(len(t1), len(t2), len(t1.union(t2)), len(t1.intersection(t2)))\n",
    "    return ( len(t1.intersection(t2)) / len(t2.union(t1) ) )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f94dd2be-fc29-4b25-a9fb-7bb948929b79",
   "metadata": {},
   "source": [
    "A brief investigation of test cases shows that Jaccard similarity of strings with no tokens in common is zero:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "34f7c3ac-dfad-41b9-a7e1-684b70a25762",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "J(\"cat\", \"dog\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0cd451c8-b246-4fb5-9b09-75549f0dba66",
   "metadata": {},
   "source": [
    "and Jaccard similarity of identical strings, which have identical sets of tokens, is 1:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1d67c2bf-84b0-4bc6-84ab-a26fd22489bd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "J(\"exact\", \"exact\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5eff1276-7661-4035-85cd-7e6a8c1efe88",
   "metadata": {},
   "source": [
    "From the definition as the ratio of number-in-intersection to number-in-union, we see that the Jaccard similarity between HELP and HELLO is 3/8.  \n",
    "\n",
    "Since we know the answer, we should test our function: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "797574ac-1b81-4fa7-844f-4c0de2e6f98b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.375"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "J(\"HELLO\", \"HELP\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc8d8834-7ff5-4e10-ab04-def49bd951f1",
   "metadata": {},
   "source": [
    "This is acceptable.   We can now calculate a number between 0 and 1 that tells us something about whether strings are similar or not."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad627214-29c5-4de8-a8c8-615006b4ffbe",
   "metadata": {},
   "source": [
    "## Example: similarities between number words"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d86c376-3fd9-4d23-9515-020103b1f287",
   "metadata": {},
   "source": [
    "As a toy example, let us find the Jaccard similarity between the first twenty counting numbers in English:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "e3b41115-1bf4-47bf-ae36-91cce31b9d0b",
   "metadata": {},
   "outputs": [],
   "source": [
    "numbers2 = [\"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"ten\",\n",
    "           \"eleven\", \"twelve\", \"thirteen\", \"fourteen\", \"fifteen\", \"sixteen\", \"seventeen\",\n",
    "           \"eighteen\", \"nineteen\", \"twenty\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "09e42fb4-dbf7-4ccd-8108-d6dd3c18c44c",
   "metadata": {},
   "outputs": [],
   "source": [
    "d = np.zeros((20,20))\n",
    "# Calculate distance between all pairs of strings in numbers2\n",
    "for i in range(len(numbers2)):\n",
    "    for j in range(len(numbers2)):\n",
    "        d[i][j] = J ( numbers2[i], numbers2[j])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "6aed2d9c-8cc9-4d23-ab64-7d774c7e6de8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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RowYAQcHB4SHh2P37t04cuSInEUtVrdu3dJplkqi/GCNAREVu6z25Rs3bkiLH6nVajx+/FineM+ePcOoUaMAAI0bN8b3338vW1lLgoULF+Lhw4fo06cPhg4dinfeeadA58s5UiK3WAqFAufOnStQLCoZWGNARMXuzp07uH37NtavX4+pU6cCyGxfbt68OcqXL5/vOElJSahQoQJGjRoFW1tbODo64vz587h79y527txZWMUvFqmpqTh8+DD27duHx48f6zQHRU6TXE2YMEGn8ly+fDnbugvbtm3TKRYVL9YYEFGxk6t9uV+/fggODsbLly9hb2+Pa9euwdHRUac285Luxo0b+OOPPxAXF6fzZEITJkyQJrkyMTHBzp07dU4Mxo4di1WrVuk9XJGKHxMDInprWFtbo3///jhz5gxMTEwghEB4eDj27NlT7JMuyaljx45o2rQphg4dCi8vLxgbG+sUR6VSoXXr1lITgD4VyDY2NujcubPO51PJwaYEInqr5DYpka2tbTGVSH4ZGRkwMTHB48ePUa1aNZ3jzJw5E5UqVcKBAwcwbNgwJCQk4KuvvtIpVs+ePaFSqWRZd4GKFxMDIiID4+vri/Xr1+Off/7BhQsXMHr0aJ0XZDpy5Aiio6N1muTqVTmtv8Chh4aJiQERkYHp2LEjQkND4erqipMnT+q8zgVRTnSbLouIiIqNkZER1Go1FAoF1Go1NBpNcReJ3iLsfEhEZGAWLlwIpVKJa9euoXPnzli4cGFxF4neIqwxICIyMGfOnMGpU6fw5Zdf4p9//sHly5eLu0j0FmFiQERkYIKDg6FQKHD8+HFERkZi165dxV0keoswMSAiMjByrtRI9DomBkREBmbt2rU4e/asLCs1Er2OwxWJiIhIwhoDIiIikjAxICIiIgkTAyIiIpIwMSAiIiIJEwMiIiKSMDEgIiIiCRMDIiIikvw/psud7yKV75gAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(d)\n",
    "plt.colorbar()\n",
    "plt.title(\"Jaccard-bigram similarity between number words\")\n",
    "plt.yticks(np.arange(len(numbers2)), numbers2, fontsize=6);\n",
    "plt.xticks(np.arange(len(numbers2)), numbers2, fontsize=6, rotation=90);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd5e62ff-fad8-4eb1-9e42-661a3184fb0e",
   "metadata": {},
   "source": [
    "In this heatmap we see that all of the numbers ending in \"teen\" seem similar to each other, and the digits thirteen through nineteen have more similarity with corresponding digits between three and nine than with non-corresponding digits.   Eleven and seven are closer than most pairs in the set.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75235cdc-e8c9-4343-87c4-3a880ee06c2e",
   "metadata": {},
   "source": [
    "## Example: searching for similar (mistaken?) names "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81e3cebc-9531-4e81-b187-80aadf1c7673",
   "metadata": {},
   "source": [
    "Let us examine some real data and look for mis-encodings with Jaccard similarity fuzzy matching."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "699abdce-4809-401a-91b8-d496abd1cc1d",
   "metadata": {},
   "source": [
    "\n",
    "This is a histogram of about 4000 distinct names of New York City police officers against whom complaints were registered in the timeframe 2002-2005.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ef8b95c0-1564-44b0-80cc-ca34d7f5486f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>NAME</th>\n",
       "      <th>COUNT</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Reich,Mathew</td>\n",
       "      <td>75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Sbarra,Daniel</td>\n",
       "      <td>75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Messina,Gary</td>\n",
       "      <td>73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Tallarine,Joseph</td>\n",
       "      <td>73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Mccormack,Christophe</td>\n",
       "      <td>72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3953</th>\n",
       "      <td>Gentile,Giuseppe</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3954</th>\n",
       "      <td>Reulbach,Nicholas</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3955</th>\n",
       "      <td>Sasso,Anthony</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3956</th>\n",
       "      <td>Smiarowski,Karol</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3957</th>\n",
       "      <td>Ruiz,Jonathan</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>3958 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                      NAME  COUNT\n",
       "0             Reich,Mathew     75\n",
       "1            Sbarra,Daniel     75\n",
       "2             Messina,Gary     73\n",
       "3         Tallarine,Joseph     73\n",
       "4     Mccormack,Christophe     72\n",
       "...                    ...    ...\n",
       "3953      Gentile,Giuseppe      1\n",
       "3954     Reulbach,Nicholas      1\n",
       "3955         Sasso,Anthony      1\n",
       "3956      Smiarowski,Karol      1\n",
       "3957         Ruiz,Jonathan      1\n",
       "\n",
       "[3958 rows x 2 columns]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nametable= pd.read_csv(\"../../data/nametable.csv\")\n",
    "nametable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "d26a6724-45d4-4999-8476-32fbb3396ac9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Reich,Mathew',\n",
       " 'Sbarra,Daniel',\n",
       " 'Messina,Gary',\n",
       " 'Tallarine,Joseph',\n",
       " 'Mccormack,Christophe']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "namelist= list(nametable.NAME)\n",
    "namelist[0:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b607091-a35a-4b9b-8189-db57ded67166",
   "metadata": {},
   "source": [
    "Here we build a list of `name1`, `number1`, `name2`, `number2`, and Jaccard similarity between every pair of names by looping over len(namelist) twice.  This gives us about 16 million rows.  To save a little time, we only calculate the distance in the half of the pairs where j < i; this gives us only 8 million rows to calculate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "28daea4c-98ef-4589-94ee-3246eb2cff6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('Sbarra,Daniel', 'Reich,Mathew', 0.0),\n",
       " ('Messina,Gary', 'Reich,Mathew', 0.0),\n",
       " ('Messina,Gary', 'Sbarra,Daniel', 0.08),\n",
       " ('Tallarine,Joseph', 'Reich,Mathew', 0.0),\n",
       " ('Tallarine,Joseph', 'Sbarra,Daniel', 0.03333333333333333)]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l = []\n",
    "for i in range(len(namelist)):\n",
    "    for j in range(i):\n",
    "        l.append( (namelist[i], namelist[j], J  (namelist[i], namelist[j])  ))\n",
    "l[0:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcf29ef4-0e51-4697-a207-d5026dbbb595",
   "metadata": {},
   "source": [
    "We should check that we got 8 million rows as expected:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "104ff93e-6de5-4cce-a667-97550da79b49",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7830903"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84de8c2a-665a-42fd-a9d9-e6c81d6adc91",
   "metadata": {},
   "source": [
    "And let us repackage this into a dataframe so it is easy to sort and subset:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "992add9a-6b84-4c99-ba73-23deb7c2e3db",
   "metadata": {},
   "outputs": [],
   "source": [
    "namesim= pd.DataFrame(l, columns=[\"name1\", \"name2\", \"J\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "4419b613-74c4-415f-8918-2cd95f754e16",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name1</th>\n",
       "      <th>name2</th>\n",
       "      <th>J</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Sbarra,Daniel</td>\n",
       "      <td>Reich,Mathew</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Messina,Gary</td>\n",
       "      <td>Reich,Mathew</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Messina,Gary</td>\n",
       "      <td>Sbarra,Daniel</td>\n",
       "      <td>0.080000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Tallarine,Joseph</td>\n",
       "      <td>Reich,Mathew</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Tallarine,Joseph</td>\n",
       "      <td>Sbarra,Daniel</td>\n",
       "      <td>0.033333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7830898</th>\n",
       "      <td>Ruiz,Jonathan</td>\n",
       "      <td>Oreckinto,Francesca</td>\n",
       "      <td>0.030303</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7830899</th>\n",
       "      <td>Ruiz,Jonathan</td>\n",
       "      <td>Gentile,Giuseppe</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7830900</th>\n",
       "      <td>Ruiz,Jonathan</td>\n",
       "      <td>Reulbach,Nicholas</td>\n",
       "      <td>0.033333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7830901</th>\n",
       "      <td>Ruiz,Jonathan</td>\n",
       "      <td>Sasso,Anthony</td>\n",
       "      <td>0.076923</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7830902</th>\n",
       "      <td>Ruiz,Jonathan</td>\n",
       "      <td>Smiarowski,Karol</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>7830903 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                    name1                name2         J\n",
       "0           Sbarra,Daniel         Reich,Mathew  0.000000\n",
       "1            Messina,Gary         Reich,Mathew  0.000000\n",
       "2            Messina,Gary        Sbarra,Daniel  0.080000\n",
       "3        Tallarine,Joseph         Reich,Mathew  0.000000\n",
       "4        Tallarine,Joseph        Sbarra,Daniel  0.033333\n",
       "...                   ...                  ...       ...\n",
       "7830898     Ruiz,Jonathan  Oreckinto,Francesca  0.030303\n",
       "7830899     Ruiz,Jonathan     Gentile,Giuseppe  0.000000\n",
       "7830900     Ruiz,Jonathan    Reulbach,Nicholas  0.033333\n",
       "7830901     Ruiz,Jonathan        Sasso,Anthony  0.076923\n",
       "7830902     Ruiz,Jonathan     Smiarowski,Karol  0.000000\n",
       "\n",
       "[7830903 rows x 3 columns]"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "namesim"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a916c0b7-1c6a-48ec-87fd-494f01f44121",
   "metadata": {},
   "source": [
    "The histogram of the pairwise distances suggests that most names don't look like each other (similarities are small, less than 0.5): \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "abba4244-d08b-4574-9342-fffe1b4f2b59",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 0, 'Jaccard similarity')"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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363SpUtnORN3Ocf7bPHixXrmmWdUuXJlBQQEqHPnzlnOwLh7jPj+++919913O49hUVFRSk9P1/79+3X77bfL399foaGhevnll7PUld99vHTpUrVs2VJlypRx7jfHcf1KeRbKUv7BfvnlF0lShQoVJF0MFY888oiqV68u6eKb67HHHtPx48f13HPP5bm8N954Q3Xr1tWMGTMUEBCgG264QR07dtSaNWucfeLj43X69Gn5+vpq7dq16t+/v6SLB5MWLVqobNmy2S778OHD6t69u9q2bav58+erbNmyOn78uL744gulpaXJz89PmZmZ6tWrlzZu3KgxY8aodevWOnLkiCZOnKj27dsrPj5evr6+uW6D3W5XZGSkHnnkEY0dO1abN2/W1KlTdeTIEX366ac5zpeQkKB27dqpVKlSmjNnjipWrKjFixfneP9FQkKC7r//fo0ZM0YvvviiSpS4mH1//vlnRUZGauTIkSpVqpR+/PFHvfTSS/r222+1bt26LLX26dNHw4YN01NPPaVFixZp3LhxSk5O1rJly/T000+ratWqmjVrlgYNGqTGjRurRYsWuW7/5VJTU3Xq1CmNHj1aVapUUVpamtasWaM+ffpowYIFGjBggLPvoEGDtHDhQg0ZMkRTpkyRt7e3duzYocOHDzv7PPfcc3r++efVp08fPfnkkypTpoz27NnjDMSSdODAAYWHh2vo0KEqU6aMDh8+rNdee0233nqrdu/eLS8vL5ca+/Tpo3/9618aNmyY8wDx0EMP6b333tPo0aPVpUsX7dmzR3369NHZs2fz3OYlS5Zo+PDheuyxxzRjxgyVKFFCv/zyi/bu3ZvnvFdjn7jzHklLS9Mdd9zhfD87fnFcbsuWLerYsaM6dOjgvPwYEBCQYw1fffWVbr/9drVs2VJz585VmTJltGTJEvXr10/nz593BvWoqCi9//77mjp1qpo3b66UlBTt2bNHSUlJ+drWIUOGqEuXLlq0aJF+/fVXPfvss2rfvr2+//5757Fi4cKFGjBggHr16qV3331XXl5eeuutt9S1a1d9+eWX6tSpk4YOHapTp05p1qxZWr58uUJCQiRJDRs2VGpqqmbMmKFvv/1W4eHhki4ej3x9fRUbG+sMMWvXrpUxRp07d5Z0MWi1a9dOx44d0/jx49W0aVP98MMPeu6557R7926tWbPG+QfVI488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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "namesim.hist(\"J\", bins=100)\n",
    "plt.title(\"Pairwise bigram Jaccard similarities between 4000 names\")\n",
    "plt.xlabel(\"Jaccard similarity\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "faf65670-daf5-4268-8719-9caaa4310221",
   "metadata": {},
   "source": [
    "Let us show the pairs of names with the highest similarities :\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "eb188ca8-b2b0-4071-94b8-fefe4c4d10ca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name1</th>\n",
       "      <th>name2</th>\n",
       "      <th>J</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>4219941</th>\n",
       "      <td>Barresi,Anthony</td>\n",
       "      <td>Baresi,Anthony</td>\n",
       "      <td>0.937500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7595947</th>\n",
       "      <td>Gonzalez,Marcos</td>\n",
       "      <td>Gonzalez,Marco</td>\n",
       "      <td>0.823529</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4870890</th>\n",
       "      <td>Garcia,Roberto</td>\n",
       "      <td>Garcia,Robert</td>\n",
       "      <td>0.812500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3641329</th>\n",
       "      <td>Campbell,Dewan</td>\n",
       "      <td>Campbell,Dean</td>\n",
       "      <td>0.812500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2739228</th>\n",
       "      <td>Martinez,Louis</td>\n",
       "      <td>Martinez,Luis</td>\n",
       "      <td>0.812500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7375037</th>\n",
       "      <td>Park,Michael</td>\n",
       "      <td>Parks,Michael</td>\n",
       "      <td>0.800000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6662855</th>\n",
       "      <td>Fernandez,Antonio</td>\n",
       "      <td>Fernandes,Antonio</td>\n",
       "      <td>0.800000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2330831</th>\n",
       "      <td>Cohan,Steven</td>\n",
       "      <td>Cohn,Steven</td>\n",
       "      <td>0.785714</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>127505</th>\n",
       "      <td>King,Darrien</td>\n",
       "      <td>King,Darren</td>\n",
       "      <td>0.785714</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4470733</th>\n",
       "      <td>Rodriguez,Andres</td>\n",
       "      <td>Rodriguez,Andrew</td>\n",
       "      <td>0.777778</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                     name1              name2         J\n",
       "4219941    Barresi,Anthony     Baresi,Anthony  0.937500\n",
       "7595947    Gonzalez,Marcos     Gonzalez,Marco  0.823529\n",
       "4870890     Garcia,Roberto      Garcia,Robert  0.812500\n",
       "3641329     Campbell,Dewan      Campbell,Dean  0.812500\n",
       "2739228     Martinez,Louis      Martinez,Luis  0.812500\n",
       "7375037       Park,Michael      Parks,Michael  0.800000\n",
       "6662855  Fernandez,Antonio  Fernandes,Antonio  0.800000\n",
       "2330831       Cohan,Steven        Cohn,Steven  0.785714\n",
       "127505        King,Darrien        King,Darren  0.785714\n",
       "4470733   Rodriguez,Andres   Rodriguez,Andrew  0.777778"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "namesim.sort_values(\"J\", ascending=False)[0:10]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8f42b17-1a7f-4439-a1f2-8498680b4d0a",
   "metadata": {},
   "source": [
    "Staring at these names, I cannot tell if any of them are typos or if they are all correctly but similarly spelled names.  We would not know if multiple people on this list accidentally shared a first and last name.  \n",
    "\n",
    "A spot check on three of the rows above shows that Mr. Barressi and Mr. Baresi, Mr. Park and Mr. Parks, and Mr Gonzalez and Mr. Gonzelez all have different employee id numbers.  Although we were able to use the Jaccard similarity to find names that were similar to each other, we have not found evidence of mis-encoded names or corrupt data that needs to be fixed.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa6bafbe-571e-430f-925a-0f06194e7d1c",
   "metadata": {},
   "source": [
    "[^*]: Murphy, A.H. The Finley Affair: A Signal Event in the History of Forecast Verification.\n",
    "Weather and Forecasting v11, issue 1. (1996) p3-20. doi:10.1175/1520-0434(1996)011<0003:TFAASE>2.0.CO;2  )   \n",
    "\n",
    "[^**]: Jaccard, Paul. The distribution of the flora in the alpine zone.  New Phytologist v11 no. 2 (1912) doi:  10.1111/j.1469-8137.1912.tb05611.x\n",
    "\n",
    "[^***]:   T. T. Tanimoto, (1958) “An elementary mathematical theory of classification and prediction,” IBM Internal Report. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e7ccc279-fe0d-4ba9-abed-6d2d27e70e5d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
