Repository: ipums/hlink (language: python)

Issue:
Use importlib.metadata instead of pkg_resources
We're getting these warnings from the tests: 
```
/home/rileyh/open_source/hlink/hlink/scripts/main.py:12: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
    import pkg_resources
```

Instead of pkg_resources, we can use importlib.metadata, which offers a similar API in a more efficient and reliable way.


Discussion / hints:

Fix patch:
diff --git a/.flake8 b/.flake8
index 182504d..921bd87 100644
--- a/.flake8
+++ b/.flake8
@@ -1,5 +1,6 @@
 [flake8]
-ignore = C901, E501, E722, E731, W503
+# We use black for formatting, so ignore errors with code E. They're from pycodestyle.
+ignore = E, C901, W503
 max-line-length = 88
 max-complexity = 40
 select = B,C,E,F,W,T4,B9
diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index 8216057..4e42786 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -11,11 +11,11 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python_version: ["3.10", "3.11"]
+        python_version: ["3.10", "3.11", "3.12"]
     runs-on: ubuntu-latest
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - name: Build the Docker image
       run: docker build . --file Dockerfile --tag $HLINK_TAG-${{ matrix.python_version}} --build-arg PYTHON_VERSION=${{ matrix.python_version }}
 
diff --git a/docs/.buildinfo b/docs/.buildinfo
index 16a1fea..109e5e6 100644
--- a/docs/.buildinfo
+++ b/docs/.buildinfo
@@ -1,4 +1,4 @@
 # Sphinx build info version 1
 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 582a31422d320e10700e6313fd1d47c6
+config: c59a067b5cfbed0328bee3b624c32c5a
 tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docs/_static/basic.css b/docs/_static/basic.css
index 4e9a9f1..30fee9d 100644
--- a/docs/_static/basic.css
+++ b/docs/_static/basic.css
@@ -4,7 +4,7 @@
  *
  * Sphinx stylesheet -- basic theme.
  *
- * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
@@ -237,6 +237,10 @@ a.headerlink {
     visibility: hidden;
 }
 
+a:visited {
+    color: #551A8B;
+}
+
 h1:hover > a.headerlink,
 h2:hover > a.headerlink,
 h3:hover > a.headerlink,
@@ -324,6 +328,7 @@ aside.sidebar {
 p.sidebar-title {
     font-weight: bold;
 }
+
 nav.contents,
 aside.topic,
 div.admonition, div.topic, blockquote {
@@ -331,6 +336,7 @@ div.admonition, div.topic, blockquote {
 }
 
 /* -- topics ---------------------------------------------------------------- */
+
 nav.contents,
 aside.topic,
 div.topic {
@@ -606,6 +612,7 @@ ol.simple p,
 ul.simple p {
     margin-bottom: 0;
 }
+
 aside.footnote > span,
 div.citation > span {
     float: left;
@@ -667,6 +674,16 @@ dd {
     margin-left: 30px;
 }
 
+.sig dd {
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.sig dl {
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
 dl > dd:last-child,
 dl > dd:last-child > :last-child {
     margin-bottom: 0;
@@ -735,6 +752,14 @@ abbr, acronym {
     cursor: help;
 }
 
+.translated {
+    background-color: rgba(207, 255, 207, 0.2)
+}
+
+.untranslated {
+    background-color: rgba(255, 207, 207, 0.2)
+}
+
 /* -- code displays --------------------------------------------------------- */
 
 pre {
diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js
index c3db08d..d06a71d 100644
--- a/docs/_static/doctools.js
+++ b/docs/_static/doctools.js
@@ -4,12 +4,19 @@
  *
  * Base JavaScript utilities for all Sphinx HTML documentation.
  *
- * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
 "use strict";
 
+const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
+  "TEXTAREA",
+  "INPUT",
+  "SELECT",
+  "BUTTON",
+]);
+
 const _ready = (callback) => {
   if (document.readyState !== "loading") {
     callback();
@@ -18,73 +25,11 @@ const _ready = (callback) => {
   }
 };
 
-/**
- * highlight a given string on a node by wrapping it in
- * span elements with the given class name.
- */
-const _highlight = (node, addItems, text, className) => {
-  if (node.nodeType === Node.TEXT_NODE) {
-    const val = node.nodeValue;
-    const parent = node.parentNode;
-    const pos = val.toLowerCase().indexOf(text);
-    if (
-      pos >= 0 &&
-      !parent.classList.contains(className) &&
-      !parent.classList.contains("nohighlight")
-    ) {
-      let span;
-
-      const closestNode = parent.closest("body, svg, foreignObject");
-      const isInSVG = closestNode && closestNode.matches("svg");
-      if (isInSVG) {
-        span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
-      } else {
-        span = document.createElement("span");
-        span.classList.add(className);
-      }
-
-      span.appendChild(document.createTextNode(val.substr(pos, text.length)));
-      parent.insertBefore(
-        span,
-        parent.insertBefore(
-          document.createTextNode(val.substr(pos + text.length)),
-          node.nextSibling
-        )
-      );
-      node.nodeValue = val.substr(0, pos);
-
-      if (isInSVG) {
-        const rect = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "rect"
-        );
-        const bbox = parent.getBBox();
-        rect.x.baseVal.value = bbox.x;
-        rect.y.baseVal.value = bbox.y;
-        rect.width.baseVal.value = bbox.width;
-        rect.height.baseVal.value = bbox.height;
-        rect.setAttribute("class", className);
-        addItems.push({ parent: parent, target: rect });
-      }
-    }
-  } else if (node.matches && !node.matches("button, select, textarea")) {
-    node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
-  }
-};
-const _highlightText = (thisNode, text, className) => {
-  let addItems = [];
-  _highlight(thisNode, addItems, text, className);
-  addItems.forEach((obj) =>
-    obj.parent.insertAdjacentElement("beforebegin", obj.target)
-  );
-};
-
 /**
  * Small JavaScript module for the documentation.
  */
 const Documentation = {
   init: () => {
-    Documentation.highlightSearchWords();
     Documentation.initDomainIndexTable();
     Documentation.initOnKeyListeners();
   },
@@ -126,51 +71,6 @@ const Documentation = {
     Documentation.LOCALE = catalog.locale;
   },
 
-  /**
-   * highlight the search words provided in the url in the text
-   */
-  highlightSearchWords: () => {
-    const highlight =
-      new URLSearchParams(window.location.search).get("highlight") || "";
-    const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
-    if (terms.length === 0) return; // nothing to do
-
-    // There should never be more than one element matching "div.body"
-    const divBody = document.querySelectorAll("div.body");
-    const body = divBody.length ? divBody[0] : document.querySelector("body");
-    window.setTimeout(() => {
-      terms.forEach((term) => _highlightText(body, term, "highlighted"));
-    }, 10);
-
-    const searchBox = document.getElementById("searchbox");
-    if (searchBox === null) return;
-    searchBox.appendChild(
-      document
-        .createRange()
-        .createContextualFragment(
-          '<p class="highlight-link">' +
-            '<a href="javascript:Documentation.hideSearchWords()">' +
-            Documentation.gettext("Hide Search Matches") +
-            "</a></p>"
-        )
-    );
-  },
-
-  /**
-   * helper function to hide the search marks again
-   */
-  hideSearchWords: () => {
-    document
-      .querySelectorAll("#searchbox .highlight-link")
-      .forEach((el) => el.remove());
-    document
-      .querySelectorAll("span.highlighted")
-      .forEach((el) => el.classList.remove("highlighted"));
-    const url = new URL(window.location);
-    url.searchParams.delete("highlight");
-    window.history.replaceState({}, "", url);
-  },
-
   /**
    * helper function to focus on search bar
    */
@@ -210,15 +110,11 @@ const Documentation = {
     )
       return;
 
-    const blacklistedElements = new Set([
-      "TEXTAREA",
-      "INPUT",
-      "SELECT",
-      "BUTTON",
-    ]);
     document.addEventListener("keydown", (event) => {
-      if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements
-      if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys
+      // bail for input elements
+      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+      // bail with special keys
+      if (event.altKey || event.ctrlKey || event.metaKey) return;
 
       if (!event.shiftKey) {
         switch (event.key) {
@@ -240,10 +136,6 @@ const Documentation = {
               event.preventDefault();
             }
             break;
-          case "Escape":
-            if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
-            Documentation.hideSearchWords();
-            event.preventDefault();
         }
       }
 
diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js
index a457d9c..003075b 100644
--- a/docs/_static/documentation_options.js
+++ b/docs/_static/documentation_options.js
@@ -1,5 +1,4 @@
-var DOCUMENTATION_OPTIONS = {
-    URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+const DOCUMENTATION_OPTIONS = {
     VERSION: '3.5.2',
     LANGUAGE: 'en',
     COLLAPSE_INDEX: false,
diff --git a/docs/_static/language_data.js b/docs/_static/language_data.js
index 2e22b06..250f566 100644
--- a/docs/_static/language_data.js
+++ b/docs/_static/language_data.js
@@ -5,7 +5,7 @@
  * This script contains the language-specific data used by searchtools.js,
  * namely the list of stopwords, stemmer, scorer and splitter.
  *
- * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
diff --git a/docs/_static/searchtools.js b/docs/_static/searchtools.js
index f2fb7d5..7918c3f 100644
--- a/docs/_static/searchtools.js
+++ b/docs/_static/searchtools.js
@@ -4,7 +4,7 @@
  *
  * Sphinx JavaScript utilities for the full-text search.
  *
- * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
@@ -57,14 +57,14 @@ const _removeChildren = (element) => {
 const _escapeRegExp = (string) =>
   string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
 
-const _displayItem = (item, highlightTerms, searchTerms) => {
+const _displayItem = (item, searchTerms, highlightTerms) => {
   const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
-  const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
   const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
   const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
   const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
+  const contentRoot = document.documentElement.dataset.content_root;
 
-  const [docName, title, anchor, descr] = item;
+  const [docName, title, anchor, descr, score, _filename] = item;
 
   let listItem = document.createElement("li");
   let requestUrl;
@@ -75,29 +75,35 @@ const _displayItem = (item, highlightTerms, searchTerms) => {
     if (dirname.match(/\/index\/$/))
       dirname = dirname.substring(0, dirname.length - 6);
     else if (dirname === "index/") dirname = "";
-    requestUrl = docUrlRoot + dirname;
+    requestUrl = contentRoot + dirname;
     linkUrl = requestUrl;
   } else {
     // normal html builders
-    requestUrl = docUrlRoot + docName + docFileSuffix;
+    requestUrl = contentRoot + docName + docFileSuffix;
     linkUrl = docName + docLinkSuffix;
   }
-  const params = new URLSearchParams();
-  params.set("highlight", [...highlightTerms].join(" "));
   let linkEl = listItem.appendChild(document.createElement("a"));
-  linkEl.href = linkUrl + "?" + params.toString() + anchor;
+  linkEl.href = linkUrl + anchor;
+  linkEl.dataset.score = score;
   linkEl.innerHTML = title;
-  if (descr)
+  if (descr) {
     listItem.appendChild(document.createElement("span")).innerHTML =
       " (" + descr + ")";
+    // highlight search terms in the description
+    if (SPHINX_HIGHLIGHT_ENABLED)  // set in sphinx_highlight.js
+      highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
+  }
   else if (showSearchSummary)
     fetch(requestUrl)
       .then((responseData) => responseData.text())
       .then((data) => {
         if (data)
           listItem.appendChild(
-            Search.makeSearchSummary(data, searchTerms, highlightTerms)
+            Search.makeSearchSummary(data, searchTerms)
           );
+        // highlight search terms in the summary
+        if (SPHINX_HIGHLIGHT_ENABLED)  // set in sphinx_highlight.js
+          highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
       });
   Search.output.appendChild(listItem);
 };
@@ -116,15 +122,15 @@ const _finishSearch = (resultCount) => {
 const _displayNextItem = (
   results,
   resultCount,
+  searchTerms,
   highlightTerms,
-  searchTerms
 ) => {
   // results left, load the summary and display it
   // this is intended to be dynamic (don't sub resultsCount)
   if (results.length) {
-    _displayItem(results.pop(), highlightTerms, searchTerms);
+    _displayItem(results.pop(), searchTerms, highlightTerms);
     setTimeout(
-      () => _displayNextItem(results, resultCount, highlightTerms, searchTerms),
+      () => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
       5
     );
   }
@@ -237,6 +243,12 @@ const Search = {
    * execute search (requires search index to be loaded)
    */
   query: (query) => {
+    const filenames = Search._index.filenames;
+    const docNames = Search._index.docnames;
+    const titles = Search._index.titles;
+    const allTitles = Search._index.alltitles;
+    const indexEntries = Search._index.indexentries;
+
     // stem the search terms and add them to the correct list
     const stemmer = new Stemmer();
     const searchTerms = new Set();
@@ -264,6 +276,10 @@ const Search = {
       }
     });
 
+    if (SPHINX_HIGHLIGHT_ENABLED) {  // set in sphinx_highlight.js
+      localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
+    }
+
     // console.debug("SEARCH: searching for:");
     // console.info("required: ", [...searchTerms]);
     // console.info("excluded: ", [...excludedTerms]);
@@ -272,6 +288,40 @@ const Search = {
     let results = [];
     _removeChildren(document.getElementById("search-progress"));
 
+    const queryLower = query.toLowerCase();
+    for (const [title, foundTitles] of Object.entries(allTitles)) {
+      if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
+        for (const [file, id] of foundTitles) {
+          let score = Math.round(100 * queryLower.length / title.length)
+          results.push([
+            docNames[file],
+            titles[file] !== title ? `${titles[file]} > ${title}` : title,
+            id !== null ? "#" + id : "",
+            null,
+            score,
+            filenames[file],
+          ]);
+        }
+      }
+    }
+
+    // search for explicit entries in index directives
+    for (const [entry, foundEntries] of Object.entries(indexEntries)) {
+      if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
+        for (const [file, id] of foundEntries) {
+          let score = Math.round(100 * queryLower.length / entry.length)
+          results.push([
+            docNames[file],
+            titles[file],
+            id ? "#" + id : "",
+            null,
+            score,
+            filenames[file],
+          ]);
+        }
+      }
+    }
+
     // lookup as object
     objectTerms.forEach((term) =>
       results.push(...Search.performObjectSearch(term, objectTerms))
@@ -318,7 +368,7 @@ const Search = {
     // console.info("search results:", Search.lastresults);
 
     // print the results
-    _displayNextItem(results, results.length, highlightTerms, searchTerms);
+    _displayNextItem(results, results.length, searchTerms, highlightTerms);
   },
 
   /**
@@ -399,8 +449,8 @@ const Search = {
     // prepare search
     const terms = Search._index.terms;
     const titleTerms = Search._index.titleterms;
-    const docNames = Search._index.docnames;
     const filenames = Search._index.filenames;
+    const docNames = Search._index.docnames;
     const titles = Search._index.titles;
 
     const scoreMap = new Map();
@@ -497,11 +547,9 @@ const Search = {
   /**
    * helper function to return a node containing the
    * search summary for a given text. keywords is a list
-   * of stemmed words, highlightWords is the list of normal, unstemmed
-   * words. the first one is used to find the occurrence, the
-   * latter for highlighting it.
+   * of stemmed words.
    */
-  makeSearchSummary: (htmlText, keywords, highlightWords) => {
+  makeSearchSummary: (htmlText, keywords) => {
     const text = Search.htmlToText(htmlText);
     if (text === "") return null;
 
@@ -519,10 +567,6 @@ const Search = {
     summary.classList.add("context");
     summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
 
-    highlightWords.forEach((highlightWord) =>
-      _highlightText(summary, highlightWord, "highlighted")
-    );
-
     return summary;
   },
 };
diff --git a/docs/_static/sphinx_highlight.js b/docs/_static/sphinx_highlight.js
new file mode 100644
index 0000000..8a96c69
--- /dev/null
+++ b/docs/_static/sphinx_highlight.js
@@ -0,0 +1,154 @@
+/* Highlighting utilities for Sphinx HTML documentation. */
+"use strict";
+
+const SPHINX_HIGHLIGHT_ENABLED = true
+
+/**
+ * highlight a given string on a node by wrapping it in
+ * span elements with the given class name.
+ */
+const _highlight = (node, addItems, text, className) => {
+  if (node.nodeType === Node.TEXT_NODE) {
+    const val = node.nodeValue;
+    const parent = node.parentNode;
+    const pos = val.toLowerCase().indexOf(text);
+    if (
+      pos >= 0 &&
+      !parent.classList.contains(className) &&
+      !parent.classList.contains("nohighlight")
+    ) {
+      let span;
+
+      const closestNode = parent.closest("body, svg, foreignObject");
+      const isInSVG = closestNode && closestNode.matches("svg");
+      if (isInSVG) {
+        span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+      } else {
+        span = document.createElement("span");
+        span.classList.add(className);
+      }
+
+      span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+      const rest = document.createTextNode(val.substr(pos + text.length));
+      parent.insertBefore(
+        span,
+        parent.insertBefore(
+          rest,
+          node.nextSibling
+        )
+      );
+      node.nodeValue = val.substr(0, pos);
+      /* There may be more occurrences of search term in this node. So call this
+       * function recursively on the remaining fragment.
+       */
+      _highlight(rest, addItems, text, className);
+
+      if (isInSVG) {
+        const rect = document.createElementNS(
+          "http://www.w3.org/2000/svg",
+          "rect"
+        );
+        const bbox = parent.getBBox();
+        rect.x.baseVal.value = bbox.x;
+        rect.y.baseVal.value = bbox.y;
+        rect.width.baseVal.value = bbox.width;
+        rect.height.baseVal.value = bbox.height;
+        rect.setAttribute("class", className);
+        addItems.push({ parent: parent, target: rect });
+      }
+    }
+  } else if (node.matches && !node.matches("button, select, textarea")) {
+    node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
+  }
+};
+const _highlightText = (thisNode, text, className) => {
+  let addItems = [];
+  _highlight(thisNode, addItems, text, className);
+  addItems.forEach((obj) =>
+    obj.parent.insertAdjacentElement("beforebegin", obj.target)
+  );
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const SphinxHighlight = {
+
+  /**
+   * highlight the search words provided in localstorage in the text
+   */
+  highlightSearchWords: () => {
+    if (!SPHINX_HIGHLIGHT_ENABLED) return;  // bail if no highlight
+
+    // get and clear terms from localstorage
+    const url = new URL(window.location);
+    const highlight =
+        localStorage.getItem("sphinx_highlight_terms")
+        || url.searchParams.get("highlight")
+        || "";
+    localStorage.removeItem("sphinx_highlight_terms")
+    url.searchParams.delete("highlight");
+    window.history.replaceState({}, "", url);
+
+    // get individual terms from highlight string
+    const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
+    if (terms.length === 0) return; // nothing to do
+
+    // There should never be more than one element matching "div.body"
+    const divBody = document.querySelectorAll("div.body");
+    const body = divBody.length ? divBody[0] : document.querySelector("body");
+    window.setTimeout(() => {
+      terms.forEach((term) => _highlightText(body, term, "highlighted"));
+    }, 10);
+
+    const searchBox = document.getElementById("searchbox");
+    if (searchBox === null) return;
+    searchBox.appendChild(
+      document
+        .createRange()
+        .createContextualFragment(
+          '<p class="highlight-link">' +
+            '<a href="javascript:SphinxHighlight.hideSearchWords()">' +
+            _("Hide Search Matches") +
+            "</a></p>"
+        )
+    );
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords: () => {
+    document
+      .querySelectorAll("#searchbox .highlight-link")
+      .forEach((el) => el.remove());
+    document
+      .querySelectorAll("span.highlighted")
+      .forEach((el) => el.classList.remove("highlighted"));
+    localStorage.removeItem("sphinx_highlight_terms")
+  },
+
+  initEscapeListener: () => {
+    // only install a listener if it is really needed
+    if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
+
+    document.addEventListener("keydown", (event) => {
+      // bail for input elements
+      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+      // bail with special keys
+      if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
+      if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
+        SphinxHighlight.hideSearchWords();
+        event.preventDefault();
+      }
+    });
+  },
+};
+
+_ready(() => {
+  /* Do not call highlightSearchWords() when we are on the search page.
+   * It will highlight words from the *previous* search query.
+   */
+  if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
+  SphinxHighlight.initEscapeListener();
+});
diff --git a/docs/column_mapping_transforms.html b/docs/column_mapping_transforms.html
index e76b801..25bd99e 100644
--- a/docs/column_mapping_transforms.html
+++ b/docs/column_mapping_transforms.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Column mapping transforms &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Comparison types, transform add-ons, aggregate features, and household aggregate features" href="comparison_types.html" />
@@ -35,7 +32,7 @@
           <div class="body" role="main">
             
   <section id="column-mapping-transforms">
-<h1>Column mapping transforms<a class="headerlink" href="#column-mapping-transforms" title="Permalink to this heading">¶</a></h1>
+<h1>Column mapping transforms<a class="headerlink" href="#column-mapping-transforms" title="Link to this heading">¶</a></h1>
 <p>Each header below represents a column mapping transform type. Transforms are used in the context of the <code class="docutils literal notranslate"><span class="pre">column_mappings</span></code> list.
 Each transform operates on a single input column and outputs a single output column.</p>
 <p>Some transforms are suffixed by “a” or “b”. These suffixes mean that the transforms apply
@@ -62,7 +59,7 @@ <h1>Column mapping transforms<a class="headerlink" href="#column-mapping-transfo
 </pre></div>
 </div>
 <section id="add-to-a">
-<h2>add_to_a<a class="headerlink" href="#add-to-a" title="Permalink to this heading">¶</a></h2>
+<h2>add_to_a<a class="headerlink" href="#add-to-a" title="Link to this heading">¶</a></h2>
 <p>Add the given <code class="docutils literal notranslate"><span class="pre">value</span></code> to a column from dataset A.</p>
 <p>Maps numerical → numerical.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[{</span><span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;add_to_a&quot;</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">11</span><span class="p">}]</span>
@@ -70,7 +67,7 @@ <h2>add_to_a<a class="headerlink" href="#add-to-a" title="Permalink to this head
 </div>
 </section>
 <section id="concat-to-a">
-<h2>concat_to_a<a class="headerlink" href="#concat-to-a" title="Permalink to this heading">¶</a></h2>
+<h2>concat_to_a<a class="headerlink" href="#concat-to-a" title="Link to this heading">¶</a></h2>
 <p>Concatenate the string <code class="docutils literal notranslate"><span class="pre">value</span></code> to the end of a column in dataset A.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[{</span><span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;concat_to_a&quot;</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="p">}]</span>
@@ -78,7 +75,7 @@ <h2>concat_to_a<a class="headerlink" href="#concat-to-a" title="Permalink to thi
 </div>
 </section>
 <section id="concat-to-b">
-<h2>concat_to_b<a class="headerlink" href="#concat-to-b" title="Permalink to this heading">¶</a></h2>
+<h2>concat_to_b<a class="headerlink" href="#concat-to-b" title="Link to this heading">¶</a></h2>
 <p>Concatenate the string <code class="docutils literal notranslate"><span class="pre">value</span></code> to the end of a column in dataset B.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[{</span><span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;concat_to_b&quot;</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="p">}]</span>
@@ -86,7 +83,7 @@ <h2>concat_to_b<a class="headerlink" href="#concat-to-b" title="Permalink to thi
 </div>
 </section>
 <section id="lowercase-strip">
-<h2>lowercase_strip<a class="headerlink" href="#lowercase-strip" title="Permalink to this heading">¶</a></h2>
+<h2>lowercase_strip<a class="headerlink" href="#lowercase-strip" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Convert alphabetical characters to lower-case and strip white
 space characters from the start and end of the strings in the column.</p>
 <p>Maps string → string.</p>
@@ -95,7 +92,7 @@ <h2>lowercase_strip<a class="headerlink" href="#lowercase-strip" title="Permalin
 </div>
 </section>
 <section id="rationalize-name-words">
-<h2>rationalize_name_words<a class="headerlink" href="#rationalize-name-words" title="Permalink to this heading">¶</a></h2>
+<h2>rationalize_name_words<a class="headerlink" href="#rationalize-name-words" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Replace the characters <code class="docutils literal notranslate"><span class="pre">?</span></code>, <code class="docutils literal notranslate"><span class="pre">*</span></code>, and <code class="docutils literal notranslate"><span class="pre">-</span></code> with spaces. Since
 people’s names in raw census data can contain these characters, replacing these characters
 can lead to better matching.</p>
@@ -105,7 +102,7 @@ <h2>rationalize_name_words<a class="headerlink" href="#rationalize-name-words" t
 </div>
 </section>
 <section id="remove-qmark-hyphen">
-<h2>remove_qmark_hyphen<a class="headerlink" href="#remove-qmark-hyphen" title="Permalink to this heading">¶</a></h2>
+<h2>remove_qmark_hyphen<a class="headerlink" href="#remove-qmark-hyphen" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Remove the characters <code class="docutils literal notranslate"><span class="pre">?</span></code> and <code class="docutils literal notranslate"><span class="pre">-</span></code> from strings in the column.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[{</span><span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;remove_qmark_hyphen&quot;</span><span class="p">}]</span>
@@ -113,7 +110,7 @@ <h2>remove_qmark_hyphen<a class="headerlink" href="#remove-qmark-hyphen" title="
 </div>
 </section>
 <section id="remove-punctuation">
-<h2>remove_punctuation<a class="headerlink" href="#remove-punctuation" title="Permalink to this heading">¶</a></h2>
+<h2>remove_punctuation<a class="headerlink" href="#remove-punctuation" title="Link to this heading">¶</a></h2>
 <p>Remove most punctuation from strings in the column. This transform removes these characters:
 <code class="docutils literal notranslate"><span class="pre">?</span> <span class="pre">-</span> <span class="pre">\</span> <span class="pre">/</span> <span class="pre">&quot;</span> <span class="pre">'</span> <span class="pre">:</span> <span class="pre">,</span> <span class="pre">.</span> <span class="pre">[</span> <span class="pre">]</span> <span class="pre">{</span> <span class="pre">}</span></code>.</p>
 <p>Maps string → string.</p>
@@ -122,7 +119,7 @@ <h2>remove_punctuation<a class="headerlink" href="#remove-punctuation" title="Pe
 </div>
 </section>
 <section id="replace-apostrophe">
-<h2>replace_apostrophe<a class="headerlink" href="#replace-apostrophe" title="Permalink to this heading">¶</a></h2>
+<h2>replace_apostrophe<a class="headerlink" href="#replace-apostrophe" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Replace each apostrophe <code class="docutils literal notranslate"><span class="pre">'</span></code> with a space.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[{</span><span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;replace_apostrophe&quot;</span><span class="p">}]</span>
@@ -130,7 +127,7 @@ <h2>replace_apostrophe<a class="headerlink" href="#replace-apostrophe" title="Pe
 </div>
 </section>
 <section id="remove-alternate-names">
-<h2>remove_alternate_names<a class="headerlink" href="#remove-alternate-names" title="Permalink to this heading">¶</a></h2>
+<h2>remove_alternate_names<a class="headerlink" href="#remove-alternate-names" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. If a string in the column contains the string <code class="docutils literal notranslate"><span class="pre">or</span></code> (”or” surrounded by spaces),
 then remove the <code class="docutils literal notranslate"><span class="pre">or</span></code> and all following characters.</p>
 <p>Maps string → string.</p>
@@ -139,7 +136,7 @@ <h2>remove_alternate_names<a class="headerlink" href="#remove-alternate-names" t
 </div>
 </section>
 <section id="remove-suffixes">
-<h2>remove_suffixes<a class="headerlink" href="#remove-suffixes" title="Permalink to this heading">¶</a></h2>
+<h2>remove_suffixes<a class="headerlink" href="#remove-suffixes" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Given a list of suffixes, remove them from the strings in the column.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[</span>
@@ -152,7 +149,7 @@ <h2>remove_suffixes<a class="headerlink" href="#remove-suffixes" title="Permalin
 </div>
 </section>
 <section id="remove-stop-words">
-<h2>remove_stop_words<a class="headerlink" href="#remove-stop-words" title="Permalink to this heading">¶</a></h2>
+<h2>remove_stop_words<a class="headerlink" href="#remove-stop-words" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Remove last words from names such as street names.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[</span>
@@ -165,7 +162,7 @@ <h2>remove_stop_words<a class="headerlink" href="#remove-stop-words" title="Perm
 </div>
 </section>
 <section id="remove-prefixes">
-<h2>remove_prefixes<a class="headerlink" href="#remove-prefixes" title="Permalink to this heading">¶</a></h2>
+<h2>remove_prefixes<a class="headerlink" href="#remove-prefixes" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Remove prefixes like “Ms.”, “Mr.”, or “Mrs.” from names.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># In some census data, &quot;ah&quot; is a prefix from Chinese names.</span>
@@ -174,7 +171,7 @@ <h2>remove_prefixes<a class="headerlink" href="#remove-prefixes" title="Permalin
 </div>
 </section>
 <section id="condense-strip-whitespace">
-<h2>condense_strip_whitespace<a class="headerlink" href="#condense-strip-whitespace" title="Permalink to this heading">¶</a></h2>
+<h2>condense_strip_whitespace<a class="headerlink" href="#condense-strip-whitespace" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. Take white space that may be more than one character or contain
 non-space characters and replace it with a single space.</p>
 <p>Maps string → string.</p>
@@ -183,7 +180,7 @@ <h2>condense_strip_whitespace<a class="headerlink" href="#condense-strip-whitesp
 </div>
 </section>
 <section id="remove-one-letter-names">
-<h2>remove_one_letter_names<a class="headerlink" href="#remove-one-letter-names" title="Permalink to this heading">¶</a></h2>
+<h2>remove_one_letter_names<a class="headerlink" href="#remove-one-letter-names" title="Link to this heading">¶</a></h2>
 <p>Used in name cleaning. If a name is a single character, remove it and leave the white space behind.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[{</span><span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;remove_one_letter_names&quot;</span><span class="p">}]</span>
@@ -191,7 +188,7 @@ <h2>remove_one_letter_names<a class="headerlink" href="#remove-one-letter-names"
 </div>
 </section>
 <section id="split">
-<h2>split<a class="headerlink" href="#split" title="Permalink to this heading">¶</a></h2>
+<h2>split<a class="headerlink" href="#split" title="Link to this heading">¶</a></h2>
 <p>Split the column value on space characters.</p>
 <p>Maps string → array of string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">column_mappings</span><span class="p">]]</span>
@@ -202,7 +199,7 @@ <h2>split<a class="headerlink" href="#split" title="Permalink to this heading">
 </div>
 </section>
 <section id="array-index">
-<h2>array_index<a class="headerlink" href="#array-index" title="Permalink to this heading">¶</a></h2>
+<h2>array_index<a class="headerlink" href="#array-index" title="Link to this heading">¶</a></h2>
 <p>If the column contains an array, select the element at the given position.</p>
 <p>This can be used as the input to another transform. In the example below, the first transform selects the second (index 1) item from  the “namefrst_split” column that contains a set of names split on white space. Then the substring 0,1 is selected, which gives the first initial of the person’s probable middle name.</p>
 <p>Maps array of T → T.</p>
@@ -217,7 +214,7 @@ <h2>array_index<a class="headerlink" href="#array-index" title="Permalink to thi
 </div>
 </section>
 <section id="mapping">
-<h2>mapping<a class="headerlink" href="#mapping" title="Permalink to this heading">¶</a></h2>
+<h2>mapping<a class="headerlink" href="#mapping" title="Link to this heading">¶</a></h2>
 <p>Map single or multiple values to a single output value, otherwise known as a “recoding.”</p>
 <p>Maps T → U.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">column_mappings</span><span class="p">]]</span>
@@ -236,7 +233,7 @@ <h2>mapping<a class="headerlink" href="#mapping" title="Permalink to this headin
 </div>
 </section>
 <section id="substring">
-<h2>substring<a class="headerlink" href="#substring" title="Permalink to this heading">¶</a></h2>
+<h2>substring<a class="headerlink" href="#substring" title="Link to this heading">¶</a></h2>
 <p>Replace a column with a substring of the data in the column.</p>
 <p>Maps string → string.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">transforms</span> <span class="o">=</span> <span class="p">[</span>
@@ -246,7 +243,7 @@ <h2>substring<a class="headerlink" href="#substring" title="Permalink to this he
 </div>
 </section>
 <section id="divide-by-int">
-<h2>divide_by_int<a class="headerlink" href="#divide-by-int" title="Permalink to this heading">¶</a></h2>
+<h2>divide_by_int<a class="headerlink" href="#divide-by-int" title="Link to this heading">¶</a></h2>
 <p>Divide data in a column by an integer value. It may leave a non-integer result.</p>
 <p>For instance, the following example takes the birthplace variable and converts it
 from the detailed version to the general version. The two least significant digits
@@ -264,7 +261,7 @@ <h2>divide_by_int<a class="headerlink" href="#divide-by-int" title="Permalink to
 </div>
 </section>
 <section id="when-value">
-<h2>when_value<a class="headerlink" href="#when-value" title="Permalink to this heading">¶</a></h2>
+<h2>when_value<a class="headerlink" href="#when-value" title="Link to this heading">¶</a></h2>
 <p>Apply conditional logic to replacement of values in a column. Works like the SQL <code class="docutils literal notranslate"><span class="pre">if()</span></code> or <code class="docutils literal notranslate"><span class="pre">case()</span></code> expressions in the SQL <code class="docutils literal notranslate"><span class="pre">select</span></code> clause.
 When the value of a column is <code class="docutils literal notranslate"><span class="pre">value</span></code> replace it with <code class="docutils literal notranslate"><span class="pre">if_value</span></code>. Otherwise replace it with <code class="docutils literal notranslate"><span class="pre">else_value</span></code>.</p>
 <p>The following example replaces all “race” IPUMS codes with 0 (white) or 1 (non-white). An IPUMS code of 100 is the “white” race category.</p>
@@ -277,7 +274,7 @@ <h2>when_value<a class="headerlink" href="#when-value" title="Permalink to this
 </div>
 </section>
 <section id="get-floor">
-<h2>get_floor<a class="headerlink" href="#get-floor" title="Permalink to this heading">¶</a></h2>
+<h2>get_floor<a class="headerlink" href="#get-floor" title="Link to this heading">¶</a></h2>
 <p>Round down to the nearest whole number.</p>
 <p>This example produces the general version of the IPUMS “relate” variable. The variable
 is coded such that detailed categories are between the hundreds (300 is child of household
@@ -390,7 +387,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/comparison_types.html b/docs/comparison_types.html
index 51eb1c4..96b22e8 100644
--- a/docs/comparison_types.html
+++ b/docs/comparison_types.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Comparison types, transform add-ons, aggregate features, and household aggregate features &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Feature Selection transforms" href="feature_selection_transforms.html" />
@@ -35,12 +32,12 @@
           <div class="body" role="main">
             
   <section id="comparison-types-transform-add-ons-aggregate-features-and-household-aggregate-features">
-<h1>Comparison types, transform add-ons, aggregate features, and household aggregate features<a class="headerlink" href="#comparison-types-transform-add-ons-aggregate-features-and-household-aggregate-features" title="Permalink to this heading">¶</a></h1>
+<h1>Comparison types, transform add-ons, aggregate features, and household aggregate features<a class="headerlink" href="#comparison-types-transform-add-ons-aggregate-features-and-household-aggregate-features" title="Link to this heading">¶</a></h1>
 <p>This page has information on the different comparison types available for the <code class="docutils literal notranslate"><span class="pre">[[comparison_features]]</span></code>
 section, along with some attributes available to all of the comparison types and some aggregate features
 that are not configurable.</p>
 <section id="comparison-types">
-<h2>Comparison types<a class="headerlink" href="#comparison-types" title="Permalink to this heading">¶</a></h2>
+<h2>Comparison types<a class="headerlink" href="#comparison-types" title="Link to this heading">¶</a></h2>
 <p>Each header below represents a comparison type.  Transforms are used in the context of <code class="docutils literal notranslate"><span class="pre">comparison_features</span></code>.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">comparison_features</span><span class="p">]]</span>
 <span class="n">alias</span> <span class="o">=</span> <span class="s2">&quot;relatematch&quot;</span>
@@ -50,7 +47,7 @@ <h2>Comparison types<a class="headerlink" href="#comparison-types" title="Permal
 </pre></div>
 </div>
 <section id="maximum-jaro-winkler">
-<h3>maximum_jaro_winkler<a class="headerlink" href="#maximum-jaro-winkler" title="Permalink to this heading">¶</a></h3>
+<h3>maximum_jaro_winkler<a class="headerlink" href="#maximum-jaro-winkler" title="Link to this heading">¶</a></h3>
 <p>Finds the greatest Jaro-Winkler value among the cartesian product of multiple columns.  For example, given an input of <code class="docutils literal notranslate"><span class="pre">column_names</span> <span class="pre">=</span> <span class="pre">['namefrst',</span> <span class="pre">'namelast']</span></code>, it would return the maximum Jaro-Winkler name comparison value among the following four comparisons:</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[(</span><span class="s1">&#39;namefrst_a&#39;</span><span class="p">,</span> <span class="s1">&#39;namefrst_b&#39;</span><span class="p">),</span>
  <span class="p">(</span><span class="s1">&#39;namefrst_a&#39;</span><span class="p">,</span> <span class="s1">&#39;namelast_b&#39;</span><span class="p">),</span>
@@ -73,7 +70,7 @@ <h3>maximum_jaro_winkler<a class="headerlink" href="#maximum-jaro-winkler" title
 </div>
 </section>
 <section id="jaro-winkler">
-<h3>jaro_winkler<a class="headerlink" href="#jaro-winkler" title="Permalink to this heading">¶</a></h3>
+<h3>jaro_winkler<a class="headerlink" href="#jaro-winkler" title="Link to this heading">¶</a></h3>
 <p>Returns the Jaro-Winkler comparison score for a given column.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -90,7 +87,7 @@ <h3>jaro_winkler<a class="headerlink" href="#jaro-winkler" title="Permalink to t
 </div>
 </section>
 <section id="jaro-winkler-street">
-<h3>jaro_winkler_street<a class="headerlink" href="#jaro-winkler-street" title="Permalink to this heading">¶</a></h3>
+<h3>jaro_winkler_street<a class="headerlink" href="#jaro-winkler-street" title="Link to this heading">¶</a></h3>
 <p>Uses an additional geographic column value to filter for major location changes before comparing street names.  If boundary column A is not equal to boundary column B, a Jaro-Winkler score of zero is returned.  If boundary column A and B are equal, the Jaro-Winkler comparison score of the street columns is returned.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -109,7 +106,7 @@ <h3>jaro_winkler_street<a class="headerlink" href="#jaro-winkler-street" title="
 </div>
 </section>
 <section id="max-jaro-winkler">
-<h3>max_jaro_winkler<a class="headerlink" href="#max-jaro-winkler" title="Permalink to this heading">¶</a></h3>
+<h3>max_jaro_winkler<a class="headerlink" href="#max-jaro-winkler" title="Link to this heading">¶</a></h3>
 <p>Returns the greatest Jaro-Winkler value from the comparisons of a list of names.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -126,7 +123,7 @@ <h3>max_jaro_winkler<a class="headerlink" href="#max-jaro-winkler" title="Permal
 </div>
 </section>
 <section id="equals">
-<h3>equals<a class="headerlink" href="#equals" title="Permalink to this heading">¶</a></h3>
+<h3>equals<a class="headerlink" href="#equals" title="Link to this heading">¶</a></h3>
 <p>Asserts that values are the same for both compared columns using SQL: <code class="docutils literal notranslate"><span class="pre">a.{column_name}</span> <span class="pre">IS</span> <span class="pre">NOT</span> <span class="pre">DISTINCT</span> <span class="pre">FROM</span> <span class="pre">b.{column_name}</span></code></p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">comparison_features</span><span class="p">]]</span>
 <span class="n">alias</span> <span class="o">=</span> <span class="s2">&quot;relatematch&quot;</span>
@@ -137,7 +134,7 @@ <h3>equals<a class="headerlink" href="#equals" title="Permalink to this heading"
 </div>
 </section>
 <section id="f1-match">
-<h3>f1_match<a class="headerlink" href="#f1-match" title="Permalink to this heading">¶</a></h3>
+<h3>f1_match<a class="headerlink" href="#f1-match" title="Link to this heading">¶</a></h3>
 <p>Evaluates if the first name initial A matches either the first name first initial B or either the first or second middle initial of B.  If so, returns 1.  Otherwise, returns 2.</p>
 <p>1 = First initial of first first name A matches first initial of any of potential match first names B</p>
 <p>2 = mismatch</p>
@@ -159,7 +156,7 @@ <h3>f1_match<a class="headerlink" href="#f1-match" title="Permalink to this head
 </div>
 </section>
 <section id="f2-match">
-<h3>f2_match<a class="headerlink" href="#f2-match" title="Permalink to this heading">¶</a></h3>
+<h3>f2_match<a class="headerlink" href="#f2-match" title="Link to this heading">¶</a></h3>
 <p>Evaluates if first middle initial A is empty/null.  If so, return 0.
 Otherwise, if either first or second middle initial A is not null and matches first name initial B, or first or second middle initial B, return 1.
 Otherwise, return 2.</p>
@@ -195,7 +192,7 @@ <h3>f2_match<a class="headerlink" href="#f2-match" title="Permalink to this head
 </div>
 </section>
 <section id="not-equals">
-<h3>not_equals<a class="headerlink" href="#not-equals" title="Permalink to this heading">¶</a></h3>
+<h3>not_equals<a class="headerlink" href="#not-equals" title="Link to this heading">¶</a></h3>
 <p>Asserts that values are distinct between compared individuals using SQL: <code class="docutils literal notranslate"><span class="pre">a.{column_name}</span> <span class="pre">IS</span> <span class="pre">DISTINCT</span> <span class="pre">FROM</span> <span class="pre">b.{column_name}</span></code>.  Used mainly in caution flag features (f_caution, m_caution, sp_caution).</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -226,7 +223,7 @@ <h3>not_equals<a class="headerlink" href="#not-equals" title="Permalink to this
 </div>
 </section>
 <section id="equals-as-int">
-<h3>equals_as_int<a class="headerlink" href="#equals-as-int" title="Permalink to this heading">¶</a></h3>
+<h3>equals_as_int<a class="headerlink" href="#equals-as-int" title="Link to this heading">¶</a></h3>
 <p>Checks for equality using equals sign and returns boolean result in integer form.  Uses SQL: <code class="docutils literal notranslate"><span class="pre">CAST(a.{col}</span> <span class="pre">=</span> <span class="pre">b.{col}</span> <span class="pre">as</span> <span class="pre">INT)</span></code></p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -243,7 +240,7 @@ <h3>equals_as_int<a class="headerlink" href="#equals-as-int" title="Permalink to
 </div>
 </section>
 <section id="all-equals">
-<h3>all_equals<a class="headerlink" href="#all-equals" title="Permalink to this heading">¶</a></h3>
+<h3>all_equals<a class="headerlink" href="#all-equals" title="Link to this heading">¶</a></h3>
 <p>Asserts whether the values in all given columns match.  Uses a SQL expression generated by joining <code class="docutils literal notranslate"><span class="pre">a.{col}</span> <span class="pre">=</span> <span class="pre">b.{col}</span></code> and <code class="docutils literal notranslate"><span class="pre">AND</span></code> for each given column.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -260,7 +257,7 @@ <h3>all_equals<a class="headerlink" href="#all-equals" title="Permalink to this
 </div>
 </section>
 <section id="not-zero-and-not-equals">
-<h3>not_zero_and_not_equals<a class="headerlink" href="#not-zero-and-not-equals" title="Permalink to this heading">¶</a></h3>
+<h3>not_zero_and_not_equals<a class="headerlink" href="#not-zero-and-not-equals" title="Link to this heading">¶</a></h3>
 <p>Checks that both values are present (not null) and nonzero and that they are not equal to one another. Evaluates
 to a boolean. This is primarily useful when a value of 0 indicates some kind of incomparibility akin to the
 value being missing.</p>
@@ -281,7 +278,7 @@ <h3>not_zero_and_not_equals<a class="headerlink" href="#not-zero-and-not-equals"
 </div>
 </section>
 <section id="or">
-<h3>or<a class="headerlink" href="#or" title="Permalink to this heading">¶</a></h3>
+<h3>or<a class="headerlink" href="#or" title="Link to this heading">¶</a></h3>
 <p>Allows for the concatenation of up to four comparison features into one feature using a SQL <code class="docutils literal notranslate"><span class="pre">OR</span></code> between the generated clause for each sub-comparison.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -311,7 +308,7 @@ <h3>or<a class="headerlink" href="#or" title="Permalink to this heading">¶</a><
 </div>
 </section>
 <section id="and">
-<h3>and<a class="headerlink" href="#and" title="Permalink to this heading">¶</a></h3>
+<h3>and<a class="headerlink" href="#and" title="Link to this heading">¶</a></h3>
 <p>Allows for the concatenation of up to four comparison features into one feature using a SQL <code class="docutils literal notranslate"><span class="pre">AND</span></code> between the generated clause for each sub-comparison.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -344,7 +341,7 @@ <h3>and<a class="headerlink" href="#and" title="Permalink to this heading">¶</a
 </div>
 </section>
 <section id="times">
-<h3>times<a class="headerlink" href="#times" title="Permalink to this heading">¶</a></h3>
+<h3>times<a class="headerlink" href="#times" title="Link to this heading">¶</a></h3>
 <p>Takes the output of two sub-comparisons and multiplies them together after casting as floats.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -375,7 +372,7 @@ <h3>times<a class="headerlink" href="#times" title="Permalink to this heading">
 </div>
 </section>
 <section id="caution-comp-3">
-<h3>caution_comp_3<a class="headerlink" href="#caution-comp-3" title="Permalink to this heading">¶</a></h3>
+<h3>caution_comp_3<a class="headerlink" href="#caution-comp-3" title="Link to this heading">¶</a></h3>
 <p>Generates an SQL expression in the form <code class="docutils literal notranslate"><span class="pre">(comparison</span> <span class="pre">A</span> <span class="pre">OR</span> <span class="pre">comparison</span> <span class="pre">B)</span> <span class="pre">AND</span> <span class="pre">comparison</span> <span class="pre">C</span></code>.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -405,7 +402,7 @@ <h3>caution_comp_3<a class="headerlink" href="#caution-comp-3" title="Permalink
 </div>
 </section>
 <section id="caution-comp-3-012">
-<h3>caution_comp_3_012<a class="headerlink" href="#caution-comp-3-012" title="Permalink to this heading">¶</a></h3>
+<h3>caution_comp_3_012<a class="headerlink" href="#caution-comp-3-012" title="Link to this heading">¶</a></h3>
 <p>Similar to <code class="docutils literal notranslate"><span class="pre">caution_comp_3</span></code>, but first checks the value of comparison C. If comparison C evaluates to false,
 then <code class="docutils literal notranslate"><span class="pre">caution_comp_3_012</span></code> evaluates to 2. Otherwise, it evaluates to the result of <code class="docutils literal notranslate"><span class="pre">caution_comp_3</span></code>, so 0 or 1.</p>
 <ul class="simple">
@@ -418,7 +415,7 @@ <h3>caution_comp_3_012<a class="headerlink" href="#caution-comp-3-012" title="Pe
 </ul>
 </section>
 <section id="caution-comp-4">
-<h3>caution_comp_4<a class="headerlink" href="#caution-comp-4" title="Permalink to this heading">¶</a></h3>
+<h3>caution_comp_4<a class="headerlink" href="#caution-comp-4" title="Link to this heading">¶</a></h3>
 <p>Generates an SQL expression in the form <code class="docutils literal notranslate"><span class="pre">(comparison</span> <span class="pre">A</span> <span class="pre">OR</span> <span class="pre">comparison</span> <span class="pre">B</span> <span class="pre">OR</span> <span class="pre">comparison</span> <span class="pre">C)</span> <span class="pre">AND</span> <span class="pre">comparison</span> <span class="pre">D</span></code>.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -450,7 +447,7 @@ <h3>caution_comp_4<a class="headerlink" href="#caution-comp-4" title="Permalink
 </div>
 </section>
 <section id="caution-comp-4-012">
-<h3>caution_comp_4_012<a class="headerlink" href="#caution-comp-4-012" title="Permalink to this heading">¶</a></h3>
+<h3>caution_comp_4_012<a class="headerlink" href="#caution-comp-4-012" title="Link to this heading">¶</a></h3>
 <p>Similar to <code class="docutils literal notranslate"><span class="pre">caution_comp_4</span></code>, but first checks the value of comparison D. If comparison D evaluates to false,
 then <code class="docutils literal notranslate"><span class="pre">caution_comp_4_012</span></code> evaluates to 2. Otherwise, it evaluates to the result of <code class="docutils literal notranslate"><span class="pre">caution_comp_4</span></code>, so 0 or 1.</p>
 <ul class="simple">
@@ -463,7 +460,7 @@ <h3>caution_comp_4_012<a class="headerlink" href="#caution-comp-4-012" title="Pe
 </ul>
 </section>
 <section id="any-equals">
-<h3>any_equals<a class="headerlink" href="#any-equals" title="Permalink to this heading">¶</a></h3>
+<h3>any_equals<a class="headerlink" href="#any-equals" title="Link to this heading">¶</a></h3>
 <p>Used to compare middle initials and first names under specific circumstances.<br />If middle initial A is not empty/null and is the same as either middle initial B or first name B,
 OR if first name A is not empty/null and is the same as middle initial B.</p>
 <ul class="simple">
@@ -481,7 +478,7 @@ <h3>any_equals<a class="headerlink" href="#any-equals" title="Permalink to this
 </div>
 </section>
 <section id="either-are-1">
-<h3>either_are_1<a class="headerlink" href="#either-are-1" title="Permalink to this heading">¶</a></h3>
+<h3>either_are_1<a class="headerlink" href="#either-are-1" title="Link to this heading">¶</a></h3>
 <p>Checks if the column value for either A or B is equal to 1.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -499,7 +496,7 @@ <h3>either_are_1<a class="headerlink" href="#either-are-1" title="Permalink to t
 </div>
 </section>
 <section id="either-are-0">
-<h3>either_are_0<a class="headerlink" href="#either-are-0" title="Permalink to this heading">¶</a></h3>
+<h3>either_are_0<a class="headerlink" href="#either-are-0" title="Link to this heading">¶</a></h3>
 <p>Checks if the column value for either A or B is equal to 0.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -517,7 +514,7 @@ <h3>either_are_0<a class="headerlink" href="#either-are-0" title="Permalink to t
 </div>
 </section>
 <section id="second-gen-imm">
-<h3>second_gen_imm<a class="headerlink" href="#second-gen-imm" title="Permalink to this heading">¶</a></h3>
+<h3>second_gen_imm<a class="headerlink" href="#second-gen-imm" title="Link to this heading">¶</a></h3>
 <p>Checks if individual A is a second-generation immigrant by looking for <code class="docutils literal notranslate"><span class="pre">nativity</span></code> value of 2, 3, or 4 (one or both parents foreign-born).</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -535,7 +532,7 @@ <h3>second_gen_imm<a class="headerlink" href="#second-gen-imm" title="Permalink
 </div>
 </section>
 <section id="rel-jaro-winkler">
-<h3>rel_jaro_winkler<a class="headerlink" href="#rel-jaro-winkler" title="Permalink to this heading">¶</a></h3>
+<h3>rel_jaro_winkler<a class="headerlink" href="#rel-jaro-winkler" title="Link to this heading">¶</a></h3>
 <p>Uses a Scala function to determine the number of people in the input column with a name similarity score (Jaro-Winkler) greater than or equal to the given <code class="docutils literal notranslate"><span class="pre">jw_threshold</span></code>, an age difference less than or equal to the given <code class="docutils literal notranslate"><span class="pre">age_threshold</span></code>, and matching sex for the sample A individual and the sample B potential match.  Takes a column generated with the feature selection transform <code class="docutils literal notranslate"><span class="pre">related_individual_rows</span></code> as input (list of person data objects to compare).  Can be used for related or unrelated individuals, depending on the input column specified.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -560,7 +557,7 @@ <h3>rel_jaro_winkler<a class="headerlink" href="#rel-jaro-winkler" title="Permal
 </div>
 </section>
 <section id="extra-children">
-<h3>extra_children<a class="headerlink" href="#extra-children" title="Permalink to this heading">¶</a></h3>
+<h3>extra_children<a class="headerlink" href="#extra-children" title="Link to this heading">¶</a></h3>
 <p>Using a Scala function, checks to see if there are children present in sample B who are not present in sample A, but based on relate codes, age, sex, and name, we would have expected to be present in A.  Returns a count of suspected “extra” children.  Takes a column generated with the feature selection transform <code class="docutils literal notranslate"><span class="pre">related_individual_rows</span></code> as input (list of person data objects to compare).</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -591,7 +588,7 @@ <h3>extra_children<a class="headerlink" href="#extra-children" title="Permalink
 </div>
 </section>
 <section id="jaro-winkler-rate">
-<h3>jaro_winkler_rate<a class="headerlink" href="#jaro-winkler-rate" title="Permalink to this heading">¶</a></h3>
+<h3>jaro_winkler_rate<a class="headerlink" href="#jaro-winkler-rate" title="Link to this heading">¶</a></h3>
 <p>Uses a Scala function to calculate the percentage of individuals who have a Jaro-Winkler score greater than or equal to the given threshold.  Rate returned as a percentage as a float data type.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -624,7 +621,7 @@ <h3>jaro_winkler_rate<a class="headerlink" href="#jaro-winkler-rate" title="Perm
 </div>
 </section>
 <section id="sum">
-<h3>sum<a class="headerlink" href="#sum" title="Permalink to this heading">¶</a></h3>
+<h3>sum<a class="headerlink" href="#sum" title="Link to this heading">¶</a></h3>
 <p>Adds the column values for A and B together (takes the sum).</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -641,7 +638,7 @@ <h3>sum<a class="headerlink" href="#sum" title="Permalink to this heading">¶</a
 </div>
 </section>
 <section id="length-b">
-<h3>length_b<a class="headerlink" href="#length-b" title="Permalink to this heading">¶</a></h3>
+<h3>length_b<a class="headerlink" href="#length-b" title="Link to this heading">¶</a></h3>
 <p>Returns the length of the column value in record B using the SQL <code class="docutils literal notranslate"><span class="pre">size()</span></code> function.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -652,7 +649,7 @@ <h3>length_b<a class="headerlink" href="#length-b" title="Permalink to this head
 </ul>
 </section>
 <section id="abs-diff">
-<h3>abs_diff<a class="headerlink" href="#abs-diff" title="Permalink to this heading">¶</a></h3>
+<h3>abs_diff<a class="headerlink" href="#abs-diff" title="Link to this heading">¶</a></h3>
 <p>Takes the absolute value of the difference between the values of the given column in datasets A and B.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -678,7 +675,7 @@ <h3>abs_diff<a class="headerlink" href="#abs-diff" title="Permalink to this head
 </div>
 </section>
 <section id="b-minus-a">
-<h3>b_minus_a<a class="headerlink" href="#b-minus-a" title="Permalink to this heading">¶</a></h3>
+<h3>b_minus_a<a class="headerlink" href="#b-minus-a" title="Link to this heading">¶</a></h3>
 <p>Returns the value of subtracting the value of column A from the value of column B.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -699,7 +696,7 @@ <h3>b_minus_a<a class="headerlink" href="#b-minus-a" title="Permalink to this he
 </div>
 </section>
 <section id="geo-distance">
-<h3>geo_distance<a class="headerlink" href="#geo-distance" title="Permalink to this heading">¶</a></h3>
+<h3>geo_distance<a class="headerlink" href="#geo-distance" title="Link to this heading">¶</a></h3>
 <p>Uses a lookup table to find the geographic distance between locations.  The SQL expression is generated by <code class="docutils literal notranslate"><span class="pre">hlink/linking/core/dist_table.py</span></code>. There are several ways to configure this feature. You can look up distances in the given file using one or two keys (specified with the <code class="docutils literal notranslate"><span class="pre">key_count</span></code> attribute).  You can also optionally have a secondary look-up table that serves as a back-up value in the case that the primary look-up does not contain a value for the locations given.  This is particularly useful for county distance, as you can set the primary join to be across counties, but set up a secondary join on state, which has much fewer combinations and thus less risk of nulls, to fill in when the counties specified aren’t in the look-up.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -783,7 +780,7 @@ <h3>geo_distance<a class="headerlink" href="#geo-distance" title="Permalink to t
 </div>
 </section>
 <section id="fetch-a">
-<h3>fetch_a<a class="headerlink" href="#fetch-a" title="Permalink to this heading">¶</a></h3>
+<h3>fetch_a<a class="headerlink" href="#fetch-a" title="Link to this heading">¶</a></h3>
 <p>Gets the value of column A.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -801,7 +798,7 @@ <h3>fetch_a<a class="headerlink" href="#fetch-a" title="Permalink to this headin
 </div>
 </section>
 <section id="fetch-b">
-<h3>fetch_b<a class="headerlink" href="#fetch-b" title="Permalink to this heading">¶</a></h3>
+<h3>fetch_b<a class="headerlink" href="#fetch-b" title="Link to this heading">¶</a></h3>
 <p>Gets the value of column B.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -819,7 +816,7 @@ <h3>fetch_b<a class="headerlink" href="#fetch-b" title="Permalink to this headin
 </div>
 </section>
 <section id="present-both-years">
-<h3>present_both_years<a class="headerlink" href="#present-both-years" title="Permalink to this heading">¶</a></h3>
+<h3>present_both_years<a class="headerlink" href="#present-both-years" title="Link to this heading">¶</a></h3>
 <p>Checks whether column A and column B are both present and both positive (&gt; 0).
 Evaluates to 1 if both are present and positive and 0 otherwise.</p>
 <ul class="simple">
@@ -852,7 +849,7 @@ <h3>present_both_years<a class="headerlink" href="#present-both-years" title="Pe
 </div>
 </section>
 <section id="neither-are-null">
-<h3>neither_are_null<a class="headerlink" href="#neither-are-null" title="Permalink to this heading">¶</a></h3>
+<h3>neither_are_null<a class="headerlink" href="#neither-are-null" title="Link to this heading">¶</a></h3>
 <p>Checks that neither column A nor column B is null or the empty string <code class="docutils literal notranslate"><span class="pre">''</span></code>.
 Evaluates to 1 if neither column is null or <code class="docutils literal notranslate"><span class="pre">''</span></code> and evaluates to 0 otherwise.</p>
 <ul class="simple">
@@ -871,7 +868,7 @@ <h3>neither_are_null<a class="headerlink" href="#neither-are-null" title="Permal
 </div>
 </section>
 <section id="present-and-matching-categorical">
-<h3>present_and_matching_categorical<a class="headerlink" href="#present-and-matching-categorical" title="Permalink to this heading">¶</a></h3>
+<h3>present_and_matching_categorical<a class="headerlink" href="#present-and-matching-categorical" title="Link to this heading">¶</a></h3>
 <p>Checks that both column A and column B are present and that they match according to SQL’s <code class="docutils literal notranslate"><span class="pre">IS</span> <span class="pre">DISTINCT</span> <span class="pre">FROM</span></code>. Evaluates to 0, 1, or 2:</p>
 <p>0 → columns are both present and match</p>
 <p>1 → columns are both present but are distinct</p>
@@ -885,7 +882,7 @@ <h3>present_and_matching_categorical<a class="headerlink" href="#present-and-mat
 </ul>
 </section>
 <section id="present-and-not-equal">
-<h3>present_and_not_equal<a class="headerlink" href="#present-and-not-equal" title="Permalink to this heading">¶</a></h3>
+<h3>present_and_not_equal<a class="headerlink" href="#present-and-not-equal" title="Link to this heading">¶</a></h3>
 <p>Checks that column A and column B are both present but are not equal.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -896,7 +893,7 @@ <h3>present_and_not_equal<a class="headerlink" href="#present-and-not-equal" tit
 </ul>
 </section>
 <section id="present-and-equal-categorical-in-universe">
-<h3>present_and_equal_categorical_in_universe<a class="headerlink" href="#present-and-equal-categorical-in-universe" title="Permalink to this heading">¶</a></h3>
+<h3>present_and_equal_categorical_in_universe<a class="headerlink" href="#present-and-equal-categorical-in-universe" title="Link to this heading">¶</a></h3>
 <p>Checks that column A and column B are both present, are not equal to the not-in-universe value NIU,
 and are equal to each other according to SQL’s <code class="docutils literal notranslate"><span class="pre">IS</span> <span class="pre">DISTINCT</span> <span class="pre">FROM</span></code>. Evaluates to 0 if either column is missing or
 if either column is the NIU value. Otherwise, evaluates to 0 if the columns are distinct or 1 if
@@ -919,7 +916,7 @@ <h3>present_and_equal_categorical_in_universe<a class="headerlink" href="#presen
 </div>
 </section>
 <section id="multi-jaro-winkler-search">
-<h3>multi_jaro_winkler_search<a class="headerlink" href="#multi-jaro-winkler-search" title="Permalink to this heading">¶</a></h3>
+<h3>multi_jaro_winkler_search<a class="headerlink" href="#multi-jaro-winkler-search" title="Link to this heading">¶</a></h3>
 <p>This is a specialized comparison feature that simplifies particular ways of searching
 multiple columns for Jaro-Winkler similarity with additional constraints on some
 other columns. It does Jaro-Winkler and equality comparisons on a variable number
@@ -977,7 +974,7 @@ <h3>multi_jaro_winkler_search<a class="headerlink" href="#multi-jaro-winkler-sea
 </ul>
 </section>
 <section id="sql-condition">
-<h3>sql_condition<a class="headerlink" href="#sql-condition" title="Permalink to this heading">¶</a></h3>
+<h3>sql_condition<a class="headerlink" href="#sql-condition" title="Link to this heading">¶</a></h3>
 <p>This is a flexible comparison type that allows users to write their own SQL expressions to be
 evaluated. Favor using a different comparison type if that’s a reasonable option. If there are
 no other comparison types that work for a particular use case, this one is a good fallback.</p>
@@ -1003,10 +1000,10 @@ <h3>sql_condition<a class="headerlink" href="#sql-condition" title="Permalink to
 </section>
 </section>
 <section id="feature-add-ons">
-<h2>Feature add-ons<a class="headerlink" href="#feature-add-ons" title="Permalink to this heading">¶</a></h2>
+<h2>Feature add-ons<a class="headerlink" href="#feature-add-ons" title="Link to this heading">¶</a></h2>
 <p>These attributes can be added to most comparison feature types above to extend the type of output returned beyond the standard comparison feature.</p>
 <section id="alias">
-<h3>alias<a class="headerlink" href="#alias" title="Permalink to this heading">¶</a></h3>
+<h3>alias<a class="headerlink" href="#alias" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1022,7 +1019,7 @@ <h3>alias<a class="headerlink" href="#alias" title="Permalink to this heading">
 </div>
 </section>
 <section id="power">
-<h3>power<a class="headerlink" href="#power" title="Permalink to this heading">¶</a></h3>
+<h3>power<a class="headerlink" href="#power" title="Link to this heading">¶</a></h3>
 <p>Raises a comparison feature to a given exponential power.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -1063,7 +1060,7 @@ <h3>power<a class="headerlink" href="#power" title="Permalink to this heading">
 </div>
 </section>
 <section id="threshold">
-<h3>threshold<a class="headerlink" href="#threshold" title="Permalink to this heading">¶</a></h3>
+<h3>threshold<a class="headerlink" href="#threshold" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1081,7 +1078,7 @@ <h3>threshold<a class="headerlink" href="#threshold" title="Permalink to this he
 </div>
 </section>
 <section id="lower-threshold">
-<h3>lower_threshold<a class="headerlink" href="#lower-threshold" title="Permalink to this heading">¶</a></h3>
+<h3>lower_threshold<a class="headerlink" href="#lower-threshold" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1110,7 +1107,7 @@ <h3>lower_threshold<a class="headerlink" href="#lower-threshold" title="Permalin
 </div>
 </section>
 <section id="upper-threshold">
-<h3>upper_threshold<a class="headerlink" href="#upper-threshold" title="Permalink to this heading">¶</a></h3>
+<h3>upper_threshold<a class="headerlink" href="#upper-threshold" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1141,7 +1138,7 @@ <h3>upper_threshold<a class="headerlink" href="#upper-threshold" title="Permalin
 </div>
 </section>
 <section id="gt-threshold">
-<h3>gt_threshold<a class="headerlink" href="#gt-threshold" title="Permalink to this heading">¶</a></h3>
+<h3>gt_threshold<a class="headerlink" href="#gt-threshold" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1172,7 +1169,7 @@ <h3>gt_threshold<a class="headerlink" href="#gt-threshold" title="Permalink to t
 </div>
 </section>
 <section id="btwn-threshold">
-<h3>btwn_threshold<a class="headerlink" href="#btwn-threshold" title="Permalink to this heading">¶</a></h3>
+<h3>btwn_threshold<a class="headerlink" href="#btwn-threshold" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1191,7 +1188,7 @@ <h3>btwn_threshold<a class="headerlink" href="#btwn-threshold" title="Permalink
 </div>
 </section>
 <section id="look-at-addl-var">
-<h3>look_at_addl_var<a class="headerlink" href="#look-at-addl-var" title="Permalink to this heading">¶</a></h3>
+<h3>look_at_addl_var<a class="headerlink" href="#look-at-addl-var" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Attributes:</p>
 <ul>
@@ -1217,30 +1214,30 @@ <h3>look_at_addl_var<a class="headerlink" href="#look-at-addl-var" title="Permal
 </section>
 </section>
 <section id="aggregate-features">
-<h2>Aggregate Features<a class="headerlink" href="#aggregate-features" title="Permalink to this heading">¶</a></h2>
+<h2>Aggregate Features<a class="headerlink" href="#aggregate-features" title="Link to this heading">¶</a></h2>
 <p>These features are not configurable.  To include them in the generated comparison features, they just need to be included in the <code class="docutils literal notranslate"><span class="pre">[training][independent_vars]</span></code> section of the config.  They are generated using the “aggregate_features” SQL template.</p>
 <section id="hits">
-<h3>hits<a class="headerlink" href="#hits" title="Permalink to this heading">¶</a></h3>
+<h3>hits<a class="headerlink" href="#hits" title="Link to this heading">¶</a></h3>
 <p>The number of potential matches generated for the given individual (counted by aggregating on <code class="docutils literal notranslate"><span class="pre">{id_column}_a</span></code>).</p>
 </section>
 <section id="hits2">
-<h3>hits2<a class="headerlink" href="#hits2" title="Permalink to this heading">¶</a></h3>
+<h3>hits2<a class="headerlink" href="#hits2" title="Link to this heading">¶</a></h3>
 <p><code class="docutils literal notranslate"><span class="pre">hits</span></code> squared.</p>
 </section>
 <section id="exact-mult">
-<h3>exact_mult<a class="headerlink" href="#exact-mult" title="Permalink to this heading">¶</a></h3>
+<h3>exact_mult<a class="headerlink" href="#exact-mult" title="Link to this heading">¶</a></h3>
 <p>Indicator for the existence of multiple potential matches with the exact same first and last name as the A sample individual within the B data.  Returns numeric boolean (0 or 1).</p>
 </section>
 </section>
 <section id="household-aggregate-features">
-<h2>Household Aggregate Features<a class="headerlink" href="#household-aggregate-features" title="Permalink to this heading">¶</a></h2>
+<h2>Household Aggregate Features<a class="headerlink" href="#household-aggregate-features" title="Link to this heading">¶</a></h2>
 <p>These features are not configurable.  To include them in the generated comparison features, they just need to be included in the <code class="docutils literal notranslate"><span class="pre">[hh_training][independent_vars]</span></code> section of the config.  They are generated using the “hh_aggregate_features” SQL template.</p>
 <section id="jw-max-a">
-<h3>jw_max_a<a class="headerlink" href="#jw-max-a" title="Permalink to this heading">¶</a></h3>
+<h3>jw_max_a<a class="headerlink" href="#jw-max-a" title="Link to this heading">¶</a></h3>
 <p>The highest Jaro-Winkler score for any of the first names in linked household A against the first name in linked household B where birth year difference is less than or equal to ten, excluding the individual A in the current potential match.  Returns <code class="docutils literal notranslate"><span class="pre">0</span></code> if no other individuals are in the household for comparison.</p>
 </section>
 <section id="jw-max-b">
-<h3>jw_max_b<a class="headerlink" href="#jw-max-b" title="Permalink to this heading">¶</a></h3>
+<h3>jw_max_b<a class="headerlink" href="#jw-max-b" title="Link to this heading">¶</a></h3>
 <p>The highest Jaro-Winkler score for any of the first names in linked household A against the first name in linked household B where sex matches and birth year difference is less than or equal to ten, excluding the individual A in the current potential match.  Returns <code class="docutils literal notranslate"><span class="pre">0</span></code> if no other individuals are in the household for comparison.</p>
 </section>
 </section>
@@ -1322,7 +1319,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/config.html b/docs/config.html
index 0f75ab9..3285de9 100644
--- a/docs/config.html
+++ b/docs/config.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Configuration &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Column mapping transforms" href="column_mapping_transforms.html" />
@@ -35,7 +32,7 @@
           <div class="body" role="main">
             
   <section id="configuration">
-<h1>Configuration<a class="headerlink" href="#configuration" title="Permalink to this heading">¶</a></h1>
+<h1>Configuration<a class="headerlink" href="#configuration" title="Link to this heading">¶</a></h1>
 <ol class="simple">
 <li><p><a class="reference external" href="#basic-config-file">Basic Example Config File</a></p></li>
 <li><p><a class="reference external" href="#advanced-config-file">Advanced Example Config File</a></p></li>
@@ -55,7 +52,7 @@ <h1>Configuration<a class="headerlink" href="#configuration" title="Permalink to
 <li><p><a class="reference external" href="#household-training-and-models">Household training and models</a></p></li>
 </ol>
 <section id="basic-config-file">
-<h2>Basic Config File<a class="headerlink" href="#basic-config-file" title="Permalink to this heading">¶</a></h2>
+<h2>Basic Config File<a class="headerlink" href="#basic-config-file" title="Link to this heading">¶</a></h2>
 <p>The config file tells the hlink program what to link and how to link it. A description of the different sections of
 a configuration file are below. For reference, here is an example of a relatively basic config file. This config file
 is used by the <code class="docutils literal notranslate"><span class="pre">examples/tutorial/tutorial.py</span></code> script for linking, and there is a more detailed discussion of the config
@@ -128,7 +125,7 @@ <h2>Basic Config File<a class="headerlink" href="#basic-config-file" title="Perm
 </div>
 </section>
 <section id="advanced-config-file">
-<h2>Advanced Config File<a class="headerlink" href="#advanced-config-file" title="Permalink to this heading">¶</a></h2>
+<h2>Advanced Config File<a class="headerlink" href="#advanced-config-file" title="Link to this heading">¶</a></h2>
 <p>Here is an example of a more complex config file that makes use of more of hlink’s features.
 It uses machine learning to probabilistically link the two datasets.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">id_column</span> <span class="o">=</span> <span class="s2">&quot;histid&quot;</span>
@@ -407,7 +404,7 @@ <h2>Advanced Config File<a class="headerlink" href="#advanced-config-file" title
 </div>
 </section>
 <section id="top-level-configs">
-<h2>Top level configs<a class="headerlink" href="#top-level-configs" title="Permalink to this heading">¶</a></h2>
+<h2>Top level configs<a class="headerlink" href="#top-level-configs" title="Link to this heading">¶</a></h2>
 <p>These configs should go at the top of your config file under no header:</p>
 <p><em>id_column</em></p>
 <p>Required.  Specify the id column that uniquely identifies a record in each dataset.</p>
@@ -421,7 +418,7 @@ <h2>Top level configs<a class="headerlink" href="#top-level-configs" title="Perm
 </div>
 </section>
 <section id="data-sources">
-<h2>Data sources<a class="headerlink" href="#data-sources" title="Permalink to this heading">¶</a></h2>
+<h2>Data sources<a class="headerlink" href="#data-sources" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header names: <code class="docutils literal notranslate"><span class="pre">datasource_a</span></code>, <code class="docutils literal notranslate"><span class="pre">datasource_b</span></code></p></li>
 <li><p>Description: Specifies your input data.</p></li>
@@ -448,7 +445,7 @@ <h2>Data sources<a class="headerlink" href="#data-sources" title="Permalink to t
 </div>
 </section>
 <section id="filter">
-<h2>Filter<a class="headerlink" href="#filter" title="Permalink to this heading">¶</a></h2>
+<h2>Filter<a class="headerlink" href="#filter" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">filter</span></code></p></li>
 <li><p>Description: Specifies filters to apply to your input data.</p></li>
@@ -476,7 +473,7 @@ <h2>Filter<a class="headerlink" href="#filter" title="Permalink to this heading"
 </div>
 </section>
 <section id="column-mappings">
-<h2><a class="reference internal" href="column_mapping_transforms.html"><span class="doc">Column Mappings</span></a><a class="headerlink" href="#column-mappings" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="column_mapping_transforms.html"><span class="doc">Column Mappings</span></a><a class="headerlink" href="#column-mappings" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">column_mappings</span></code></p></li>
 <li><p>Description: Base column mappings and transformations to extract from your input datasets.</p></li>
@@ -509,7 +506,7 @@ <h2><a class="reference internal" href="column_mapping_transforms.html"><span cl
 </div>
 </section>
 <section id="substitution-columns">
-<h2><a class="reference internal" href="substitutions.html"><span class="doc">Substitution Columns</span></a><a class="headerlink" href="#substitution-columns" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="substitutions.html"><span class="doc">Substitution Columns</span></a><a class="headerlink" href="#substitution-columns" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">substitution_columns</span></code></p></li>
 <li><p>Description: Substitutions to apply to data after column mappings.</p></li>
@@ -538,7 +535,7 @@ <h2><a class="reference internal" href="substitutions.html"><span class="doc">Su
 </div>
 </section>
 <section id="feature-selections">
-<h2><a class="reference internal" href="feature_selection_transforms.html"><span class="doc">Feature Selections</span></a><a class="headerlink" href="#feature-selections" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="feature_selection_transforms.html"><span class="doc">Feature Selections</span></a><a class="headerlink" href="#feature-selections" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">feature_selections</span></code></p></li>
 <li><p>Description: A list of feature selections to apply to the input data after substitutions and column mappings. See the <a class="reference internal" href="feature_selection_transforms.html"><span class="doc">feature selection transforms</span></a> section for more information, including information on the specific transforms available.</p></li>
@@ -571,7 +568,7 @@ <h2><a class="reference internal" href="feature_selection_transforms.html"><span
 </div>
 </section>
 <section id="potential-matches-universe">
-<h2>Potential Matches Universe<a class="headerlink" href="#potential-matches-universe" title="Permalink to this heading">¶</a></h2>
+<h2>Potential Matches Universe<a class="headerlink" href="#potential-matches-universe" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">potential_matches_universe</span></code></p></li>
 <li><p>Description: Limits the universe of created potential matches generated using an expression fed to a SQL query.</p></li>
@@ -590,7 +587,7 @@ <h2>Potential Matches Universe<a class="headerlink" href="#potential-matches-uni
 </div>
 </section>
 <section id="blocking">
-<h2>Blocking<a class="headerlink" href="#blocking" title="Permalink to this heading">¶</a></h2>
+<h2>Blocking<a class="headerlink" href="#blocking" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">blocking</span></code></p></li>
 <li><p>Description: Describes what columns to block on and how to create the blocks for the potential matches.</p></li>
@@ -619,7 +616,7 @@ <h2>Blocking<a class="headerlink" href="#blocking" title="Permalink to this head
 </div>
 </section>
 <section id="comparisons">
-<h2><a class="reference internal" href="comparison_types.html"><span class="doc">Comparisons</span></a><a class="headerlink" href="#comparisons" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="comparison_types.html"><span class="doc">Comparisons</span></a><a class="headerlink" href="#comparisons" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">comparisons</span></code></p></li>
 <li><p>Description: A list of comparisons to threshold the potential matches on. Only potential matches that pass the thresholds will be created. See <a class="reference internal" href="comparison_types.html"><span class="doc">comparison types</span></a> for more information.</p></li>
@@ -648,7 +645,7 @@ <h2><a class="reference internal" href="comparison_types.html"><span class="doc"
 </div>
 </section>
 <section id="household-comparisons">
-<h2><a class="reference internal" href="comparison_types.html"><span class="doc">Household Comparisons</span></a><a class="headerlink" href="#household-comparisons" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="comparison_types.html"><span class="doc">Household Comparisons</span></a><a class="headerlink" href="#household-comparisons" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">hh_comparisons</span></code></p></li>
 <li><p>Description: A list of comparisons to threshold the household potential matches on. Also referred to as post-blocking filters, as all household potential matches are created, then only potential matches that pass the post-blocking filters will be kept for scoring. See <a class="reference internal" href="comparison_types.html"><span class="doc">comparison types</span></a> for more information.</p></li>
@@ -670,7 +667,7 @@ <h2><a class="reference internal" href="comparison_types.html"><span class="doc"
 </div>
 </section>
 <section id="comparison-features">
-<h2><a class="reference internal" href="comparison_types.html"><span class="doc">Comparison Features</span></a><a class="headerlink" href="#comparison-features" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="comparison_types.html"><span class="doc">Comparison Features</span></a><a class="headerlink" href="#comparison-features" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">comparison_features</span></code></p></li>
 <li><p>Description: A list of comparison features to create when comparing records. Comparisons for individual and household linking rounds are both represented here – no need to duplicate comparisons if used in both rounds, simply specify the <code class="docutils literal notranslate"><span class="pre">column_name</span></code> in the appropriate <code class="docutils literal notranslate"><span class="pre">training</span></code> or <code class="docutils literal notranslate"><span class="pre">hh_training</span></code> section of the config.  See the <a class="reference internal" href="comparison_types.html"><span class="doc">comparison types</span></a> section for more information.</p></li>
@@ -705,7 +702,7 @@ <h2><a class="reference internal" href="comparison_types.html"><span class="doc"
 </div>
 </section>
 <section id="pipeline-generated-features">
-<h2><a class="reference internal" href="pipeline_features.html"><span class="doc">Pipeline-generated Features</span></a><a class="headerlink" href="#pipeline-generated-features" title="Permalink to this heading">¶</a></h2>
+<h2><a class="reference internal" href="pipeline_features.html"><span class="doc">Pipeline-generated Features</span></a><a class="headerlink" href="#pipeline-generated-features" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">pipeline_features</span></code></p></li>
 <li><p>Description: Features to be added in the model pipeline created for scoring a dataset. These features cannot be used in the <code class="docutils literal notranslate"><span class="pre">comparisons</span></code> section of the config and are for creating more robust ML models.  They typically leverage code available in the Spark Pipeline API.</p></li>
@@ -737,7 +734,7 @@ <h2><a class="reference internal" href="pipeline_features.html"><span class="doc
 </div>
 </section>
 <section id="training-and-models">
-<h2>Training and <a class="reference internal" href="models.html"><span class="doc">models</span></a><a class="headerlink" href="#training-and-models" title="Permalink to this heading">¶</a></h2>
+<h2>Training and <a class="reference internal" href="models.html"><span class="doc">models</span></a><a class="headerlink" href="#training-and-models" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">training</span></code></p></li>
 <li><p>Description: Specifies the training data set as well as a myriad of attributes related to training a model including the dependent variable within that dataset, the independent variables created from the <code class="docutils literal notranslate"><span class="pre">comparison_features</span></code> section, and the different models you want to use for either model exploration or scoring.</p></li>
@@ -792,7 +789,7 @@ <h2>Training and <a class="reference internal" href="models.html"><span class="d
 </div>
 </section>
 <section id="household-training-and-models">
-<h2>Household training and models<a class="headerlink" href="#household-training-and-models" title="Permalink to this heading">¶</a></h2>
+<h2>Household training and models<a class="headerlink" href="#household-training-and-models" title="Link to this heading">¶</a></h2>
 <ul class="simple">
 <li><p>Header name: <code class="docutils literal notranslate"><span class="pre">hh_training</span></code></p></li>
 <li><p>Description: Specifies the household training data set as well as a myriad of attributes related to training a model including the dependent var within that data set, the independent vars created from the <code class="docutils literal notranslate"><span class="pre">comparison_features</span></code> section, and the different models you want to use.</p></li>
@@ -923,7 +920,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/feature_selection_transforms.html b/docs/feature_selection_transforms.html
index 6e30b83..c580b7f 100644
--- a/docs/feature_selection_transforms.html
+++ b/docs/feature_selection_transforms.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Feature Selection transforms &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Pipeline generated features" href="pipeline_features.html" />
@@ -35,7 +32,7 @@
           <div class="body" role="main">
             
   <section id="feature-selection-transforms">
-<h1>Feature Selection transforms<a class="headerlink" href="#feature-selection-transforms" title="Permalink to this heading">¶</a></h1>
+<h1>Feature Selection transforms<a class="headerlink" href="#feature-selection-transforms" title="Link to this heading">¶</a></h1>
 <p>Each header below represents a feature selection transform.  These transforms are used in the context of <code class="docutils literal notranslate"><span class="pre">feature_selections</span></code>.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">feature_selections</span><span class="p">]]</span>
 <span class="n">input_column</span> <span class="o">=</span> <span class="s2">&quot;clean_birthyr&quot;</span>
@@ -46,7 +43,7 @@ <h1>Feature Selection transforms<a class="headerlink" href="#feature-selection-t
 </div>
 <p>There are some additional attributes available for all transforms: <code class="docutils literal notranslate"><span class="pre">checkpoint</span></code>, <code class="docutils literal notranslate"><span class="pre">override_column_a</span></code>, <code class="docutils literal notranslate"><span class="pre">override_column_b</span></code>, <code class="docutils literal notranslate"><span class="pre">set_value_column_a</span></code>, <code class="docutils literal notranslate"><span class="pre">set_value_column_b</span></code>.</p>
 <section id="bigrams">
-<h2>bigrams<a class="headerlink" href="#bigrams" title="Permalink to this heading">¶</a></h2>
+<h2>bigrams<a class="headerlink" href="#bigrams" title="Link to this heading">¶</a></h2>
 <p>Split the given string column into <a class="reference external" href="https://en.wikipedia.org/wiki/Bigram">bigrams</a>.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -65,7 +62,7 @@ <h2>bigrams<a class="headerlink" href="#bigrams" title="Permalink to this headin
 </div>
 </section>
 <section id="sql-condition">
-<h2>sql_condition<a class="headerlink" href="#sql-condition" title="Permalink to this heading">¶</a></h2>
+<h2>sql_condition<a class="headerlink" href="#sql-condition" title="Link to this heading">¶</a></h2>
 <p>Apply the given SQL.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -84,7 +81,7 @@ <h2>sql_condition<a class="headerlink" href="#sql-condition" title="Permalink to
 </div>
 </section>
 <section id="array">
-<h2>array<a class="headerlink" href="#array" title="Permalink to this heading">¶</a></h2>
+<h2>array<a class="headerlink" href="#array" title="Link to this heading">¶</a></h2>
 <p>Combine two input columns into an array output column.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -102,7 +99,7 @@ <h2>array<a class="headerlink" href="#array" title="Permalink to this heading">
 </div>
 </section>
 <section id="union">
-<h2>union<a class="headerlink" href="#union" title="Permalink to this heading">¶</a></h2>
+<h2>union<a class="headerlink" href="#union" title="Link to this heading">¶</a></h2>
 <p>Take the set union of two columns that are arrays of strings, returning another
 array of strings.</p>
 <ul class="simple">
@@ -115,7 +112,7 @@ <h2>union<a class="headerlink" href="#union" title="Permalink to this heading">
 </ul>
 </section>
 <section id="soundex">
-<h2>soundex<a class="headerlink" href="#soundex" title="Permalink to this heading">¶</a></h2>
+<h2>soundex<a class="headerlink" href="#soundex" title="Link to this heading">¶</a></h2>
 <p>Compute the <a class="reference external" href="https://en.wikipedia.org/wiki/Soundex">soundex</a> encoding of the input column.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -133,7 +130,7 @@ <h2>soundex<a class="headerlink" href="#soundex" title="Permalink to this headin
 </div>
 </section>
 <section id="power">
-<h2>power<a class="headerlink" href="#power" title="Permalink to this heading">¶</a></h2>
+<h2>power<a class="headerlink" href="#power" title="Link to this heading">¶</a></h2>
 <p>Raise the input column to a given power.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -232,7 +229,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/genindex.html b/docs/genindex.html
index ddc9deb..7ed200d 100644
--- a/docs/genindex.html
+++ b/docs/genindex.html
@@ -1,18 +1,15 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Index &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="#" />
     <link rel="search" title="Search" href="search.html" />
    
@@ -106,7 +103,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
     </div>
diff --git a/docs/index.html b/docs/index.html
index 6992845..b64a3e4 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Welcome to hlink’s documentation! &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Introduction" href="introduction.html" />
@@ -34,7 +31,7 @@
           <div class="body" role="main">
             
   <section id="welcome-to-hlink-s-documentation">
-<h1>Welcome to hlink’s documentation!<a class="headerlink" href="#welcome-to-hlink-s-documentation" title="Permalink to this heading">¶</a></h1>
+<h1>Welcome to hlink’s documentation!<a class="headerlink" href="#welcome-to-hlink-s-documentation" title="Link to this heading">¶</a></h1>
 <div class="toctree-wrapper compound">
 <ul>
 <li class="toctree-l1"><a class="reference internal" href="introduction.html">Introduction</a><ul>
@@ -89,7 +86,7 @@ <h1>Welcome to hlink’s documentation!<a class="headerlink" href="#welcome-to-h
 </div>
 </section>
 <section id="configuration-api">
-<h1>Configuration API<a class="headerlink" href="#configuration-api" title="Permalink to this heading">¶</a></h1>
+<h1>Configuration API<a class="headerlink" href="#configuration-api" title="Link to this heading">¶</a></h1>
 <div class="toctree-wrapper compound">
 <p class="caption" role="heading"><span class="caption-text">Configuration API</span></p>
 <ul>
@@ -223,7 +220,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/installation.html b/docs/installation.html
index 04849a5..e33042e 100644
--- a/docs/installation.html
+++ b/docs/installation.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Installation &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Link Tasks" href="link_tasks.html" />
@@ -35,9 +32,9 @@
           <div class="body" role="main">
             
   <section id="installation">
-<h1>Installation<a class="headerlink" href="#installation" title="Permalink to this heading">¶</a></h1>
+<h1>Installation<a class="headerlink" href="#installation" title="Link to this heading">¶</a></h1>
 <section id="requirements">
-<h2>Requirements<a class="headerlink" href="#requirements" title="Permalink to this heading">¶</a></h2>
+<h2>Requirements<a class="headerlink" href="#requirements" title="Link to this heading">¶</a></h2>
 <p>Make sure that you have each of these installed on your system before running hlink.</p>
 <ul class="simple">
 <li><p>Python 3.10 or 3.11</p></li>
@@ -46,12 +43,12 @@ <h2>Requirements<a class="headerlink" href="#requirements" title="Permalink to t
 </ul>
 </section>
 <section id="installing-from-pypi">
-<h2>Installing from PyPI<a class="headerlink" href="#installing-from-pypi" title="Permalink to this heading">¶</a></h2>
+<h2>Installing from PyPI<a class="headerlink" href="#installing-from-pypi" title="Link to this heading">¶</a></h2>
 <p>hlink is available on the Python Package Index at <a class="reference external" href="https://pypi.org">pypi.org</a> as the hlink package.
 The latest version can be installed with pip by running <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">hlink</span></code>.</p>
 </section>
 <section id="installing-from-source">
-<h2>Installing from source<a class="headerlink" href="#installing-from-source" title="Permalink to this heading">¶</a></h2>
+<h2>Installing from source<a class="headerlink" href="#installing-from-source" title="Link to this heading">¶</a></h2>
 <p>The easiest way to install hlink is through PyPI (see the instructions above). But hlink can also
 be installed from source. To install hlink from source, first clone the GitHub repository. Then
 in the root project directory, run <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">.</span></code>.</p>
@@ -136,7 +133,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/introduction.html b/docs/introduction.html
index 29b303d..6443263 100644
--- a/docs/introduction.html
+++ b/docs/introduction.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Introduction &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Installation" href="installation.html" />
@@ -35,9 +32,9 @@
           <div class="body" role="main">
             
   <section id="introduction">
-<h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this heading">¶</a></h1>
+<h1>Introduction<a class="headerlink" href="#introduction" title="Link to this heading">¶</a></h1>
 <section id="overview">
-<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this heading">¶</a></h2>
+<h2>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h2>
 <p>hlink is a Python library and command-line tool that links records between two datasets. This linking
 process identifies records in the datasets that share some characteristics and may correspond to the
 same real-world person or object. hlink can use either deterministic rules or probabilistic machine
@@ -148,7 +145,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/link_tasks.html b/docs/link_tasks.html
index bec4076..03f5b85 100644
--- a/docs/link_tasks.html
+++ b/docs/link_tasks.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Link Tasks &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Running hlink" href="running_the_program.html" />
@@ -35,25 +32,25 @@
           <div class="body" role="main">
             
   <section id="link-tasks">
-<h1>Link Tasks<a class="headerlink" href="#link-tasks" title="Permalink to this heading">¶</a></h1>
+<h1>Link Tasks<a class="headerlink" href="#link-tasks" title="Link to this heading">¶</a></h1>
 <section id="preprocessing">
-<h2>Preprocessing<a class="headerlink" href="#preprocessing" title="Permalink to this heading">¶</a></h2>
+<h2>Preprocessing<a class="headerlink" href="#preprocessing" title="Link to this heading">¶</a></h2>
 <section id="overview">
-<h3>Overview<a class="headerlink" href="#overview" title="Permalink to this heading">¶</a></h3>
+<h3>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h3>
 <p>Read in raw data and prepare it for linking. This task may include a variety of
 transformations on the data, such as stripping out whitespace and normalizing strings
 that have common abbreviations. The same transformations are applied to both input
 datasets.</p>
 </section>
 <section id="task-steps">
-<h3>Task steps<a class="headerlink" href="#task-steps" title="Permalink to this heading">¶</a></h3>
+<h3>Task steps<a class="headerlink" href="#task-steps" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Step 0: Read raw data in from Parquet or CSV files. Register the raw dataframes with the program.</p></li>
 <li><p>Step 1: Prepare the dataframes for linking. Perform substitutions, transformations, and column mappings as requested.</p></li>
 </ul>
 </section>
 <section id="related-configuration-sections">
-<h3>Related Configuration Sections<a class="headerlink" href="#related-configuration-sections" title="Permalink to this heading">¶</a></h3>
+<h3>Related Configuration Sections<a class="headerlink" href="#related-configuration-sections" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>The <a class="reference external" href="config.html#data-sources"><code class="docutils literal notranslate"><span class="pre">datasource_a</span></code> and <code class="docutils literal notranslate"><span class="pre">datasource_b</span></code></a> sections specify where to find the input data.</p></li>
 <li><p><a class="reference external" href="column_mapping_transforms.html#column-mapping-transforms"><code class="docutils literal notranslate"><span class="pre">column_mappings</span></code></a>,
@@ -65,9 +62,9 @@ <h3>Related Configuration Sections<a class="headerlink" href="#related-configura
 </section>
 </section>
 <section id="training-and-household-training">
-<h2>Training and Household Training<a class="headerlink" href="#training-and-household-training" title="Permalink to this heading">¶</a></h2>
+<h2>Training and Household Training<a class="headerlink" href="#training-and-household-training" title="Link to this heading">¶</a></h2>
 <section id="id1">
-<h3>Overview<a class="headerlink" href="#id1" title="Permalink to this heading">¶</a></h3>
+<h3>Overview<a class="headerlink" href="#id1" title="Link to this heading">¶</a></h3>
 <p>Train a machine learning model to use for classification of potential links. This
 requires training data, which is read in in the first step. Comparison features
 are generated for the training data, and then the model is trained on the data
@@ -75,7 +72,7 @@ <h3>Overview<a class="headerlink" href="#id1" title="Permalink to this heading">
 like feature importances or coefficients for the model to help with introspection.</p>
 </section>
 <section id="id2">
-<h3>Task steps<a class="headerlink" href="#id2" title="Permalink to this heading">¶</a></h3>
+<h3>Task steps<a class="headerlink" href="#id2" title="Link to this heading">¶</a></h3>
 <p>The first three steps in each of these tasks are the same:</p>
 <ul class="simple">
 <li><p>Step 0: Ingest the training data from a CSV file.</p></li>
@@ -90,7 +87,7 @@ <h3>Task steps<a class="headerlink" href="#id2" title="Permalink to this heading
 </ul>
 </section>
 <section id="id3">
-<h3>Related Configuration Sections<a class="headerlink" href="#id3" title="Permalink to this heading">¶</a></h3>
+<h3>Related Configuration Sections<a class="headerlink" href="#id3" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>The <a class="reference external" href="config.html#training-and-models"><code class="docutils literal notranslate"><span class="pre">training</span></code></a> section is the most important
 for Training and provides configuration attributes for many aspects of the task.
@@ -104,16 +101,16 @@ <h3>Related Configuration Sections<a class="headerlink" href="#id3" title="Perma
 </section>
 </section>
 <section id="matching">
-<h2>Matching<a class="headerlink" href="#matching" title="Permalink to this heading">¶</a></h2>
+<h2>Matching<a class="headerlink" href="#matching" title="Link to this heading">¶</a></h2>
 <section id="id4">
-<h3>Overview<a class="headerlink" href="#id4" title="Permalink to this heading">¶</a></h3>
+<h3>Overview<a class="headerlink" href="#id4" title="Link to this heading">¶</a></h3>
 <p>Run the linking algorithm, generating a table with potential matches between records in the two datasets.
 This is the core of hlink’s work and may take the longest of all of the tasks. Universe
 definition and blocking reduce the number of comparisons needed when
 determining potential matches, which can drastically improve the runtime of Matching.</p>
 </section>
 <section id="id5">
-<h3>Task steps<a class="headerlink" href="#id5" title="Permalink to this heading">¶</a></h3>
+<h3>Task steps<a class="headerlink" href="#id5" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Step 0: Perform blocking, separating records into different buckets to reduce the total number
 of comparisons needed during matching. Some columns may be “exploded” here if needed.</p></li>
@@ -122,7 +119,7 @@ <h3>Task steps<a class="headerlink" href="#id5" title="Permalink to this heading
 </ul>
 </section>
 <section id="id6">
-<h3>Related Configuration Sections<a class="headerlink" href="#id6" title="Permalink to this heading">¶</a></h3>
+<h3>Related Configuration Sections<a class="headerlink" href="#id6" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>The <a class="reference external" href="config.html#potential-matches-universe"><code class="docutils literal notranslate"><span class="pre">potential_matches_universe</span></code></a> section may be used to
 provide a universe for matches in the form of a SQL condition. Only records that satisfy the
@@ -143,13 +140,13 @@ <h3>Related Configuration Sections<a class="headerlink" href="#id6" title="Perma
 </section>
 </section>
 <section id="household-matching">
-<h2>Household Matching<a class="headerlink" href="#household-matching" title="Permalink to this heading">¶</a></h2>
+<h2>Household Matching<a class="headerlink" href="#household-matching" title="Link to this heading">¶</a></h2>
 <section id="id7">
-<h3>Overview<a class="headerlink" href="#id7" title="Permalink to this heading">¶</a></h3>
+<h3>Overview<a class="headerlink" href="#id7" title="Link to this heading">¶</a></h3>
 <p>Generate a table with potential matches between households in the two datasets.</p>
 </section>
 <section id="id8">
-<h3>Task steps<a class="headerlink" href="#id8" title="Permalink to this heading">¶</a></h3>
+<h3>Task steps<a class="headerlink" href="#id8" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Step 0: Block on households.</p></li>
 <li><p>Step 1: Filter households based on <code class="docutils literal notranslate"><span class="pre">hh_comparisons</span></code> configuration settings.</p></li>
@@ -157,7 +154,7 @@ <h3>Task steps<a class="headerlink" href="#id8" title="Permalink to this heading
 </ul>
 </section>
 <section id="id9">
-<h3>Related Configuration Sections<a class="headerlink" href="#id9" title="Permalink to this heading">¶</a></h3>
+<h3>Related Configuration Sections<a class="headerlink" href="#id9" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p><a class="reference external" href="config.html#comparison-features"><code class="docutils literal notranslate"><span class="pre">comparison_features</span></code></a> and <a class="reference external" href="pipeline_features.html#pipeline-generated-features"><code class="docutils literal notranslate"><span class="pre">pipeline_features</span></code></a> are used as they are in the Matching task.</p></li>
 <li><p><a class="reference external" href="config.html#household-comparisons"><code class="docutils literal notranslate"><span class="pre">hh_comparisons</span></code></a> correspond to <code class="docutils literal notranslate"><span class="pre">comparisons</span></code> in the Matching task and may be thought of as “post-blocking filters”. Only potential matches that pass these comparisons will be eligible for being scored as matches.</p></li>
@@ -166,16 +163,16 @@ <h3>Related Configuration Sections<a class="headerlink" href="#id9" title="Perma
 </section>
 </section>
 <section id="model-exploration-and-household-model-exploration">
-<h2>Model Exploration and Household Model Exploration<a class="headerlink" href="#model-exploration-and-household-model-exploration" title="Permalink to this heading">¶</a></h2>
+<h2>Model Exploration and Household Model Exploration<a class="headerlink" href="#model-exploration-and-household-model-exploration" title="Link to this heading">¶</a></h2>
 <section id="id10">
-<h3>Overview<a class="headerlink" href="#id10" title="Permalink to this heading">¶</a></h3>
+<h3>Overview<a class="headerlink" href="#id10" title="Link to this heading">¶</a></h3>
 <p>Evaluate the performance of different types of models and different parameter combinations
 on training data. These tasks are highly configurable and are typically not part of a full
 linking run. Instead, they are usually run ahead of time, and then the best-performing
 model is chosen and used for the full linking run.</p>
 </section>
 <section id="id11">
-<h3>Task steps<a class="headerlink" href="#id11" title="Permalink to this heading">¶</a></h3>
+<h3>Task steps<a class="headerlink" href="#id11" title="Link to this heading">¶</a></h3>
 <p>The steps in each of these tasks are the same:</p>
 <ul class="simple">
 <li><p>Step 0: Ingest the training data file specified in the config with the <code class="docutils literal notranslate"><span class="pre">dataset</span></code> attribute.</p></li>
@@ -187,7 +184,7 @@ <h3>Task steps<a class="headerlink" href="#id11" title="Permalink to this headin
 </ul>
 </section>
 <section id="id12">
-<h3>Related Configuration Sections<a class="headerlink" href="#id12" title="Permalink to this heading">¶</a></h3>
+<h3>Related Configuration Sections<a class="headerlink" href="#id12" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p><a class="reference external" href="config.html#training-and-models"><code class="docutils literal notranslate"><span class="pre">training</span></code></a> is used extensively by Model Exploration,
 and <a class="reference external" href="config.html#household-training-and-models"><code class="docutils literal notranslate"><span class="pre">hh_training</span></code></a> is used extensively
@@ -199,15 +196,15 @@ <h3>Related Configuration Sections<a class="headerlink" href="#id12" title="Perm
 </section>
 </section>
 <section id="reporting">
-<h2>Reporting<a class="headerlink" href="#reporting" title="Permalink to this heading">¶</a></h2>
+<h2>Reporting<a class="headerlink" href="#reporting" title="Link to this heading">¶</a></h2>
 <section id="id13">
-<h3>Overview<a class="headerlink" href="#id13" title="Permalink to this heading">¶</a></h3>
+<h3>Overview<a class="headerlink" href="#id13" title="Link to this heading">¶</a></h3>
 <p>Report on characteristics of the linked data. This task is experimental and focused
 primarily on demographic census data. At the moment, it does not allow very much
 configuration.</p>
 </section>
 <section id="id14">
-<h3>Task steps<a class="headerlink" href="#id14" title="Permalink to this heading">¶</a></h3>
+<h3>Task steps<a class="headerlink" href="#id14" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>Step 0: For households with anyone linked in Matching, report the percent of remaining household members linked in Household Matching.</p></li>
 <li><p>Step 1: Report on the representivity of linked data compared to source populations.</p></li>
@@ -215,7 +212,7 @@ <h3>Task steps<a class="headerlink" href="#id14" title="Permalink to this headin
 </ul>
 </section>
 <section id="id15">
-<h3>Related Configuration Sections<a class="headerlink" href="#id15" title="Permalink to this heading">¶</a></h3>
+<h3>Related Configuration Sections<a class="headerlink" href="#id15" title="Link to this heading">¶</a></h3>
 <ul class="simple">
 <li><p>The <code class="docutils literal notranslate"><span class="pre">alias</span></code> attributes are read from both <a class="reference external" href="config.html#data-sources"><code class="docutils literal notranslate"><span class="pre">datasource_a</span></code></a> and <a class="reference external" href="config.html#data-sources"><code class="docutils literal notranslate"><span class="pre">datasource_b</span></code></a>. The step uses them to construct the output reports.</p></li>
 </ul>
@@ -301,7 +298,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/models.html b/docs/models.html
index b5b59ca..2d5081f 100644
--- a/docs/models.html
+++ b/docs/models.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Models &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="prev" title="Substitutions" href="substitutions.html" />
@@ -34,7 +31,7 @@
           <div class="body" role="main">
             
   <section id="models">
-<h1>Models<a class="headerlink" href="#models" title="Permalink to this heading">¶</a></h1>
+<h1>Models<a class="headerlink" href="#models" title="Link to this heading">¶</a></h1>
 <p>These are models available to be used in the model evaluation, training, and household training link tasks.</p>
 <ul class="simple">
 <li><p>Attributes for all models:</p>
@@ -46,7 +43,7 @@ <h1>Models<a class="headerlink" href="#models" title="Permalink to this heading"
 </li>
 </ul>
 <section id="random-forest">
-<h2>random_forest<a class="headerlink" href="#random-forest" title="Permalink to this heading">¶</a></h2>
+<h2>random_forest<a class="headerlink" href="#random-forest" title="Link to this heading">¶</a></h2>
 <p>Uses <a class="reference external" href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.classification.RandomForestClassifier.html">pyspark.ml.classification.RandomForestClassifier</a>.  Returns probability as an array.</p>
 <ul class="simple">
 <li><p>Parameters:</p>
@@ -69,7 +66,7 @@ <h2>random_forest<a class="headerlink" href="#random-forest" title="Permalink to
 </div>
 </section>
 <section id="probit">
-<h2>probit<a class="headerlink" href="#probit" title="Permalink to this heading">¶</a></h2>
+<h2>probit<a class="headerlink" href="#probit" title="Link to this heading">¶</a></h2>
 <p>Uses <a class="reference external" href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.regression.GeneralizedLinearRegression.html">pyspark.ml.regression.GeneralizedLinearRegression</a> with <code class="docutils literal notranslate"><span class="pre">family=&quot;binomial&quot;</span></code> and <code class="docutils literal notranslate"><span class="pre">link=&quot;probit&quot;</span></code>.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">model_parameters</span> <span class="o">=</span> <span class="p">{</span>
     <span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;probit&quot;</span><span class="p">,</span>
@@ -80,7 +77,7 @@ <h2>probit<a class="headerlink" href="#probit" title="Permalink to this heading"
 </div>
 </section>
 <section id="logistic-regression">
-<h2>logistic_regression<a class="headerlink" href="#logistic-regression" title="Permalink to this heading">¶</a></h2>
+<h2>logistic_regression<a class="headerlink" href="#logistic-regression" title="Link to this heading">¶</a></h2>
 <p>Uses <a class="reference external" href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.classification.LogisticRegression.html">pyspark.ml.classification.LogisticRegression</a></p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">chosen_model</span> <span class="o">=</span> <span class="p">{</span>
     <span class="nb">type</span> <span class="o">=</span> <span class="s2">&quot;logistic_regression&quot;</span><span class="p">,</span>
@@ -91,7 +88,7 @@ <h2>logistic_regression<a class="headerlink" href="#logistic-regression" title="
 </div>
 </section>
 <section id="decision-tree">
-<h2>decision_tree<a class="headerlink" href="#decision-tree" title="Permalink to this heading">¶</a></h2>
+<h2>decision_tree<a class="headerlink" href="#decision-tree" title="Link to this heading">¶</a></h2>
 <p>Uses <a class="reference external" href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.classification.DecisionTreeClassifier.html">pyspark.ml.classification.DecisionTreeClassifier</a>.</p>
 <ul class="simple">
 <li><p>Parameters:</p>
@@ -112,7 +109,7 @@ <h2>decision_tree<a class="headerlink" href="#decision-tree" title="Permalink to
 </div>
 </section>
 <section id="gradient-boosted-trees">
-<h2>gradient_boosted_trees<a class="headerlink" href="#gradient-boosted-trees" title="Permalink to this heading">¶</a></h2>
+<h2>gradient_boosted_trees<a class="headerlink" href="#gradient-boosted-trees" title="Link to this heading">¶</a></h2>
 <p>Uses <a class="reference external" href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.classification.GBTClassifier.html">pyspark.ml.classification.GBTClassifier</a>.</p>
 <ul class="simple">
 <li><p>Parameters:</p>
@@ -212,7 +209,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/pipeline_features.html b/docs/pipeline_features.html
index 910fb21..4639d5d 100644
--- a/docs/pipeline_features.html
+++ b/docs/pipeline_features.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Pipeline generated features &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Substitutions" href="substitutions.html" />
@@ -35,9 +32,9 @@
           <div class="body" role="main">
             
   <section id="pipeline-generated-features">
-<h1>Pipeline generated features<a class="headerlink" href="#pipeline-generated-features" title="Permalink to this heading">¶</a></h1>
+<h1>Pipeline generated features<a class="headerlink" href="#pipeline-generated-features" title="Link to this heading">¶</a></h1>
 <section id="transformer-types">
-<h2>Transformer types<a class="headerlink" href="#transformer-types" title="Permalink to this heading">¶</a></h2>
+<h2>Transformer types<a class="headerlink" href="#transformer-types" title="Link to this heading">¶</a></h2>
 <p>Each header below represents a feature created using a transformation available through the Spark Pipeline API.  These transforms are used in the context of <code class="docutils literal notranslate"><span class="pre">pipeline_features</span></code>.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">pipeline_features</span><span class="p">]]</span>
 <span class="n">input_column</span> <span class="o">=</span> <span class="s2">&quot;immyear_diff&quot;</span>
@@ -53,7 +50,7 @@ <h2>Transformer types<a class="headerlink" href="#transformer-types" title="Perm
 </pre></div>
 </div>
 <section id="interaction">
-<h3>interaction<a class="headerlink" href="#interaction" title="Permalink to this heading">¶</a></h3>
+<h3>interaction<a class="headerlink" href="#interaction" title="Link to this heading">¶</a></h3>
 <p>Interact two or more features, creating a vectorized result.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">pipeline_features</span><span class="p">]]</span>
 <span class="c1"># interact the categorical features for mother caution flag, mother present flag, and mother jaro-winkler score</span>
@@ -64,7 +61,7 @@ <h3>interaction<a class="headerlink" href="#interaction" title="Permalink to thi
 </div>
 </section>
 <section id="bucketizer">
-<h3>bucketizer<a class="headerlink" href="#bucketizer" title="Permalink to this heading">¶</a></h3>
+<h3>bucketizer<a class="headerlink" href="#bucketizer" title="Link to this heading">¶</a></h3>
 <p>From the <code class="docutils literal notranslate"><span class="pre">pyspark.ml.feature.Bucketizer()</span></code> docs: “Maps a column of continuous features to a column of feature buckets.”</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -158,7 +155,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/running_the_program.html b/docs/running_the_program.html
index 438402f..12d8084 100644
--- a/docs/running_the_program.html
+++ b/docs/running_the_program.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Running hlink &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Advanced Workflow Examples" href="use_examples.html" />
@@ -35,9 +32,9 @@
           <div class="body" role="main">
             
   <section id="running-hlink">
-<h1>Running hlink<a class="headerlink" href="#running-hlink" title="Permalink to this heading">¶</a></h1>
+<h1>Running hlink<a class="headerlink" href="#running-hlink" title="Link to this heading">¶</a></h1>
 <section id="using-hlink-as-a-library">
-<h2>Using hlink as a Library<a class="headerlink" href="#using-hlink-as-a-library" title="Permalink to this heading">¶</a></h2>
+<h2>Using hlink as a Library<a class="headerlink" href="#using-hlink-as-a-library" title="Link to this heading">¶</a></h2>
 <p>hlink can be used as a Python library for scripting linking jobs. It provides some high-level classes and
 functions for interacting with Spark, handling configuration, and running linking tasks and steps.</p>
 <p>The main class in the library is <code class="docutils literal notranslate"><span class="pre">LinkRun</span></code>, which represents a complete linking job. It provides access
@@ -101,11 +98,11 @@ <h2>Using hlink as a Library<a class="headerlink" href="#using-hlink-as-a-librar
 link people between two datasets. The example includes a working config file.</p>
 </section>
 <section id="interactive-mode">
-<h2>Interactive Mode<a class="headerlink" href="#interactive-mode" title="Permalink to this heading">¶</a></h2>
+<h2>Interactive Mode<a class="headerlink" href="#interactive-mode" title="Link to this heading">¶</a></h2>
 <p>In addition to a library, hlink provides a command-line interface, which can be started
 with the <code class="docutils literal notranslate"><span class="pre">hlink</span></code> command.</p>
 <section id="starting-the-program">
-<h3>Starting the program<a class="headerlink" href="#starting-the-program" title="Permalink to this heading">¶</a></h3>
+<h3>Starting the program<a class="headerlink" href="#starting-the-program" title="Link to this heading">¶</a></h3>
 <p>The program takes as input a TOML or JSON configuration file, described in the <a class="reference internal" href="config.html"><span class="doc">Configuration</span></a> page.  Parameters described in the config include paths to input data files, paths to training data files, instructions for generating machine learning features, and model parameters.  The configuration enables reproducible runs that should produce the same results on the same input data.</p>
 <p>All input flags can be printed to the console by running <code class="docutils literal notranslate"><span class="pre">hlink</span> <span class="pre">--help</span></code>.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>cpu ~$ hlink --help
@@ -161,7 +158,7 @@ <h3>Starting the program<a class="headerlink" href="#starting-the-program" title
 </div>
 </section>
 <section id="running-linking-tasks-and-steps">
-<h3>Running Linking Tasks and Steps<a class="headerlink" href="#running-linking-tasks-and-steps" title="Permalink to this heading">¶</a></h3>
+<h3>Running Linking Tasks and Steps<a class="headerlink" href="#running-linking-tasks-and-steps" title="Link to this heading">¶</a></h3>
 <p>The program is organized into a hierarchy of tasks and steps. The five major tasks are <code class="docutils literal notranslate"><span class="pre">preprocessing</span></code>, <code class="docutils literal notranslate"><span class="pre">training</span></code>, <code class="docutils literal notranslate"><span class="pre">matching</span></code>, <code class="docutils literal notranslate"><span class="pre">hh_training</span></code>, and <code class="docutils literal notranslate"><span class="pre">hh_matching</span></code>, and within each task are multiple steps.
 To see all linking tasks, run the command <code class="docutils literal notranslate"><span class="pre">get_tasks</span></code>.  You should see something like this:</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>hlink $ get_tasks
@@ -238,7 +235,7 @@ <h3>Running Linking Tasks and Steps<a class="headerlink" href="#running-linking-
 <p>To run all steps in a task, use the <code class="docutils literal notranslate"><span class="pre">run_all_steps</span> <span class="pre">&lt;tasks&gt;</span></code> command, where <code class="docutils literal notranslate"><span class="pre">&lt;tasks&gt;</span></code> is a list of tasks you want to run all the steps for. By default this command will run all the steps for the current task.</p>
 </section>
 <section id="example-interactive-mode-workflow">
-<h3>Example interactive mode workflow<a class="headerlink" href="#example-interactive-mode-workflow" title="Permalink to this heading">¶</a></h3>
+<h3>Example interactive mode workflow<a class="headerlink" href="#example-interactive-mode-workflow" title="Link to this heading">¶</a></h3>
 <ol>
 <li><p>Create a config file and put it in your hlink config directory.
 For example:</p>
@@ -345,7 +342,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/search.html b/docs/search.html
index cf65b5b..eab27d5 100644
--- a/docs/search.html
+++ b/docs/search.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Search &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
     
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <script src="_static/searchtools.js"></script>
     <script src="_static/language_data.js"></script>
     <link rel="index" title="Index" href="genindex.html" />
@@ -125,7 +122,7 @@ <h3>Related Topics</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
     </div>
diff --git a/docs/searchindex.js b/docs/searchindex.js
index 8ccae2c..d289678 100644
--- a/docs/searchindex.js
+++ b/docs/searchindex.js
@@ -1,1 +1,1 @@
-Search.setIndex({"docnames": ["column_mapping_transforms", "comparison_types", "config", "feature_selection_transforms", "index", "installation", "introduction", "link_tasks", "models", "pipeline_features", "running_the_program", "substitutions", "use_examples"], "filenames": ["column_mapping_transforms.md", "comparison_types.md", "config.md", "feature_selection_transforms.md", "index.rst", "installation.md", "introduction.md", "link_tasks.md", "models.md", "pipeline_features.md", "running_the_program.md", "substitutions.md", "use_examples.md"], "titles": ["Column mapping transforms", "Comparison types, transform add-ons, aggregate features, and household aggregate features", "Configuration", "Feature Selection transforms", "Welcome to hlink\u2019s documentation!", "Installation", "Introduction", "Link Tasks", "Models", "Pipeline generated features", "Running hlink", "Substitutions", "Advanced Workflow Examples"], "terms": {"each": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "header": [0, 1, 2, 3, 9, 11], "below": [0, 1, 2, 3, 8, 9, 10], "repres": [0, 1, 2, 3, 9, 10], "type": [0, 2, 3, 4, 7, 8, 10, 11, 12], "ar": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12], "us": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12], "context": [0, 1, 3, 9], "column_map": [0, 2, 7], "list": [0, 1, 2, 3, 4, 8, 10, 11], "oper": [0, 2], "singl": [0, 2, 10, 12], "input": [0, 1, 2, 3, 6, 7, 10, 11], "output": [0, 1, 2, 3, 6, 7, 10, 12], "some": [0, 1, 3, 6, 7, 10], "suffix": [0, 4], "b": [0, 1, 2, 4, 10], "These": [0, 1, 2, 3, 6, 7, 8, 9], "mean": [0, 2], "appli": [0, 2, 3, 7, 12], "from": [0, 1, 2, 4, 6, 7, 8, 9, 10, 12], "onli": [0, 1, 2, 7, 12], "one": [0, 1, 2, 4, 7], "two": [0, 1, 2, 3, 6, 7, 9, 10, 12], "dataset": [0, 1, 2, 6, 7, 10, 12], "link": [0, 1, 2, 4, 6, 8], "A": [0, 1, 2, 9, 10], "most": [0, 1, 7, 10], "both": [0, 1, 2, 7, 12], "independ": [0, 2], "more": [0, 1, 2, 9, 10, 12], "than": [0, 1, 2, 8], "can": [0, 1, 2, 5, 6, 7, 8, 10, 12], "order": [0, 2, 7], "thei": [0, 1, 2, 7, 10], "re": 0, "configur": [0, 1, 6, 10, 12], "file": [0, 1, 4, 6, 7, 10, 11, 12], "so": [0, 1, 2, 5, 12], "mai": [0, 2, 6, 7, 10], "anoth": [0, 1, 3, 7], "format": 0, "The": [0, 1, 2, 3, 5, 7, 8, 9, 10, 12], "letter": [0, 4], "t": [0, 1, 2, 3, 12], "u": 0, "arbitrari": 0, "specifi": [0, 1, 2, 6, 7, 9, 10, 11], "column_nam": [0, 1, 2, 11], "attribut": [0, 1, 2, 3, 7, 8, 9, 10, 11], "under": [0, 1, 2], "its": [0, 1, 6, 10], "section": [0, 1, 2, 12], "name": [0, 1, 2, 4, 10, 11], "i": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12], "alia": [0, 2, 7], "along": [0, 1], "which": [0, 1, 2, 3, 6, 7, 9, 10, 12], "must": [0, 1, 2, 8, 9, 11], "addit": [0, 1, 2, 3, 5, 6, 10], "vari": [0, 2], "inform": [0, 1, 2, 10], "given": [0, 1, 2, 3, 8, 12], "often": [0, 10], "just": [0, 1, 2, 10, 12], "valu": [0, 1, 2, 4, 8, 9, 10, 11], "expect": [0, 1], "an": [0, 1, 2, 3, 6, 8, 10], "exampl": [0, 1, 2], "namefrst_split": [0, 2], "namefrst_clean": [0, 2], "add": [0, 4], "_": [0, 1, 2, 3, 4, 8, 9, 10], "numer": [0, 1], "11": [0, 2, 5, 9], "concat": [0, 4], "concaten": [0, 1], "string": [0, 1, 2, 3, 7, 8, 10, 11], "end": [0, 1, 2, 3, 11], "lowercas": [0, 4], "strip": [0, 4, 7], "clean": [0, 6], "convert": [0, 1, 2], "alphabet": 0, "charact": 0, "lower": [0, 1], "case": [0, 1, 2, 3, 6], "white": 0, "space": [0, 2, 3, 11], "start": [0, 11], "ration": [0, 4], "word": [0, 4], "replac": [0, 1, 4], "sinc": [0, 2], "peopl": [0, 1, 6, 10], "": [0, 1, 2, 6, 7, 10, 11], "raw": [0, 2, 7, 10], "censu": [0, 7, 12], "data": [0, 1, 4, 6, 7, 10], "contain": [0, 1, 11], "lead": 0, "better": [0, 6], "match": [0, 1, 4, 6, 10, 11, 12], "remov": [0, 4], "qmark": [0, 4], "hyphen": [0, 4], "punctuat": [0, 4], "thi": [0, 1, 2, 5, 6, 7, 9, 10, 12], "apostroph": [0, 4], "altern": [0, 2, 4], "If": [0, 1, 2, 3, 7, 8, 10, 11], "surround": 0, "all": [0, 1, 2, 3, 7, 8, 9, 10], "follow": [0, 1, 6, 10, 11, 12], "them": [0, 1, 2, 7], "jr": [0, 2], "sr": [0, 2], "ii": [0, 2], "iii": [0, 2], "stop": [0, 4], "last": [0, 1, 7, 9], "street": [0, 1], "avenu": [0, 11], "blvd": 0, "circl": 0, "court": 0, "road": 0, "prefix": [0, 4], "like": [0, 2, 7, 10], "m": [0, 1], "mr": 0, "In": [0, 1, 6, 10, 12], "ah": 0, "chines": 0, "condens": [0, 4], "whitespac": [0, 4, 7], "take": [0, 1, 2, 3, 7, 10], "non": 0, "leav": 0, "behind": 0, "arrai": [0, 2, 4, 8, 9], "index": [0, 4, 5], "select": [0, 1, 4, 6, 10, 12], "element": 0, "posit": [0, 1, 2, 4, 6], "first": [0, 1, 2, 5, 7, 10, 11], "second": [0, 1, 2, 11], "1": [0, 1, 2, 4, 7, 8, 9, 10, 12], "item": 0, "namefrst": [0, 1, 2], "set": [0, 1, 2, 3, 6, 7, 10, 12], "Then": [0, 5], "0": [0, 1, 2, 7, 8, 9, 10, 12], "give": [0, 2], "initi": [0, 1, 10], "person": [0, 1, 6], "probabl": [0, 2, 8], "middl": [0, 1], "namefrst_mid_init": [0, 1], "multipl": [0, 1, 2, 10], "otherwis": [0, 1, 9, 12], "known": 0, "recod": 0, "birthyr": [0, 2], "clean_birthyr": [0, 2, 3], "9999": [0, 2, 9], "1999": [0, 2], "9998": 0, "divid": [0, 4], "int": [0, 1, 2, 3, 4, 8], "integ": [0, 1, 2, 9], "It": [0, 1, 2, 6, 10, 12], "result": [0, 1, 6, 9, 10, 12], "For": [0, 1, 2, 7, 10, 12], "instanc": [0, 8], "birthplac": 0, "variabl": [0, 1, 2, 12], "detail": [0, 2, 10], "version": [0, 5, 12], "gener": [0, 1, 4, 6, 7, 10], "least": [0, 1], "signific": 0, "digit": 0, "make": [0, 1, 2, 5, 12], "we": [0, 1, 10, 12], "simpli": [0, 2], "drop": [0, 2, 10], "100": [0, 2, 12], "round": [0, 2], "lowest": 0, "whole": [0, 6], "number": [0, 1, 2, 7, 8, 10], "floor": [0, 4], "function": [0, 1, 2, 6, 10], "bpl": [0, 1, 2], "bpl_root": 0, "when": [0, 1, 2, 3, 4, 7, 12], "condit": [0, 1, 2, 3, 4, 7], "logic": 0, "work": [0, 1, 2, 5, 7, 10, 12], "sql": [0, 1, 2, 3, 4, 7, 10], "express": [0, 1, 2], "claus": [0, 1], "if_valu": 0, "else_valu": 0, "race": [0, 1, 2, 9, 12], "ipum": [0, 6], "code": [0, 1, 2, 5], "categori": [0, 8], "get": [0, 1, 4, 10], "down": [0, 6, 12], "nearest": 0, "produc": [0, 10], "relat": [0, 1, 2], "between": [0, 1, 2, 6, 7, 10, 12], "hundr": 0, "300": 0, "child": [0, 8], "household": [0, 4, 6, 8, 10, 12], "head": 0, "301": 0, "302": 0, "adopt": 0, "303": 0, "step": [0, 1, 2, 6], "usual": [0, 7, 12], "need": [0, 1, 2, 7, 10, 12], "2": [0, 1, 2, 3, 7, 8, 11, 12], "spous": 0, "3": [0, 1, 2, 5, 7, 8, 9, 12], "4": [0, 1, 8], "law": 0, "5": [0, 1, 2, 8, 9, 10, 12], "parent": [0, 1, 11], "6": [0, 2, 8, 9, 12], "7": [0, 1, 2, 8, 12], "sibl": 0, "12": 0, "relate_div_100": [0, 1, 2], "page": [1, 10], "ha": [1, 2, 6, 10, 12], "differ": [1, 2, 4, 6, 7], "avail": [1, 2, 3, 5, 7, 8, 9, 12], "comparison_featur": [1, 2, 7], "relatematch": [1, 2], "comparison_typ": [1, 2], "categor": [1, 2, 8, 9], "true": [1, 2, 3, 7, 9, 11, 12], "maximum": [1, 8], "jaro": [1, 9], "winkler": [1, 9], "find": [1, 7, 12], "greatest": 1, "among": 1, "cartesian": 1, "product": [1, 6, 12], "column": [1, 3, 4, 7, 9, 10, 11, 12], "namelast": [1, 2], "would": [1, 2, 12], "return": [1, 3, 8, 10], "four": 1, "namefrst_a": 1, "namefrst_b": 1, "namelast_b": 1, "namelast_a": 1, "requir": [1, 2, 3, 4, 7, 9, 10, 11], "maximum_jw": 1, "score": [1, 2, 7, 9], "compar": [1, 2, 6, 7], "namefrst_jw": [1, 2, 12], "geograph": 1, "filter": [1, 4, 7, 11], "major": [1, 10], "locat": [1, 2, 10], "chang": [1, 2, 5, 10, 12], "befor": [1, 2, 3, 5, 7], "boundari": 1, "zero": 1, "jw_street": 1, "enum_dist": 1, "max": [1, 8, 10], "member": [1, 7], "neighborhood": 1, "surnam": 1, "related_individual_max_jw": 1, "namefrst_rel": 1, "assert": [1, 10], "same": [1, 2, 6, 7, 10], "NOT": 1, "distinct": 1, "f1": 1, "evalu": [1, 2, 6, 7, 8], "either": [1, 2, 6, 11], "ani": [1, 2, 5, 8], "potenti": [1, 4, 7], "mismatch": 1, "queri": [1, 2], "fi": 1, "OR": 1, "mi0": 1, "mi1": 1, "THEN": 1, "els": [1, 2, 3], "first_init_col": 1, "namefrst_init": 1, "mid_init_col": 1, "namefrst_mid_init_2": 1, "f2": 1, "empti": 1, "null": [1, 2, 3], "AND": [1, 2], "individu": [1, 2, 7, 12], "mainli": 1, "caution": [1, 9], "flag": [1, 9, 10, 12], "f": [1, 10], "sp": 1, "m_caution": [1, 2, 9, 12], "mbpl": 1, "mother_birthyr": 1, "stepmom": 1, "momloc": 1, "comp_a": [1, 2], "comp_b": [1, 2], "comp_c": 1, "parent_step_chang": 1, "comp_d": 1, "check": [1, 10], "sign": 1, "boolean": [1, 2, 3, 11, 12], "form": [1, 7, 11], "cast": 1, "col": 1, "namelast_equal_as_int": 1, "namelast_clean": [1, 2, 3], "whether": [1, 2, 11], "join": [1, 11], "across": 1, "record": [1, 2, 6, 7], "being": [1, 7], "exact": [1, 2], "namefrst_unstd": [1, 2], "present": [1, 2, 9], "nonzero": 1, "primarili": [1, 7], "indic": [1, 12], "kind": 1, "incompar": 1, "akin": 1, "miss": [1, 10], "see": [1, 2, 5, 10, 12], "also": [1, 2, 5, 6, 7, 9, 10, 12], "univers": [1, 4, 7], "similar": 1, "fbpl_nomatch": 1, "fbpl": 1, "allow": [1, 2, 7, 12], "up": [1, 2, 10, 11], "sub": 1, "object": [1, 2, 6, 10], "document": [1, 8, 10, 12], "option": [1, 2, 3, 6, 7, 8, 10, 12], "sp_caution": [1, 2, 12], "spouse_bpl": 1, "spouse_birthyr": 1, "durmarr": [1, 2], "new_marr": [1, 2], "appear": 1, "street_jw": [1, 2, 12], "counti": 1, "statefip": [1, 2], "9": 1, "multipli": 1, "togeth": [1, 2], "after": [1, 2, 4, 8, 10], "float": [1, 2, 8], "have": [1, 2, 5, 6, 7, 8, 10, 12], "comp": 1, "c": 1, "sploc": 1, "012": 1, "fals": [1, 2, 3, 4, 6, 10], "d": 1, "specif": [1, 2, 10], "circumst": 1, "should": [1, 2, 8, 9, 10], "mid_init_match": 1, "either_1": 1, "nativ": 1, "either_0": 1, "gen": 1, "imm": [1, 2, 12], "immigr": 1, "look": [1, 10, 11], "foreign": 1, "born": 1, "sgen": [1, 2, 12], "rel": [1, 2, 12], "scala": 1, "determin": [1, 7], "greater": [1, 5], "jw_threshold": 1, "ag": [1, 2, 3], "less": [1, 2], "age_threshold": 1, "sex": [1, 2, 11], "sampl": 1, "related_individual_row": 1, "unrel": 1, "depend": [1, 2, 5, 12], "name_col": 1, "birthyr_col": 1, "namefrst_related_row": 1, "replaced_birthyr": [1, 2, 3], "extra": 1, "children": 1, "who": 1, "base": [1, 2, 7], "count": [1, 10, 12], "suspect": [1, 6], "relate_col": 1, "histid_col": 1, "id": [1, 2], "birth": 1, "year": [1, 2, 3, 4], "year_b": 1, "wa": [1, 12], "taken": 1, "minimum": [1, 8], "accept": [1, 2, 12], "consid": [1, 8], "histid": [1, 2, 12], "1910": [1, 2, 12], "8": [1, 2, 5, 10], "rate": 1, "calcul": [1, 12], "percentag": 1, "seen": 1, "neighbor": 1, "meet": 1, "95": 1, "nbor": [1, 2, 12], "namelast_neighbor": 1, "05": [1, 2], "ad": [1, 2], "namelast_popularity_sum": 1, "namelast_popular": 1, "length": [1, 2, 9], "size": 1, "ab": 1, "diff": 1, "absolut": 1, "you": [1, 2, 5, 10, 11, 12], "invalid": [1, 8], "instead": [1, 2, 5, 7], "marriag": 1, "durat": 1, "99": [1, 2], "placehold": 1, "unknown": 1, "exclud": 1, "those": [1, 2], "consider": 1, "byrdiff": [1, 2, 12], "mardurmatch": [1, 2], "14": 1, "minu": [1, 2], "subtract": 1, "geo": 1, "distanc": [1, 8], "lookup": 1, "tabl": [1, 2, 4, 7, 10, 12], "hlink": [1, 2, 5, 6, 7, 12], "core": [1, 7, 10, 12], "dist_tabl": 1, "py": [1, 2], "There": [1, 3, 7], "sever": [1, 6], "wai": [1, 5, 10], "kei": [1, 7, 10], "key_count": 1, "secondari": 1, "serv": 1, "back": 1, "primari": [1, 6], "doe": [1, 7, 12], "particularli": 1, "state": [1, 6], "much": [1, 7], "fewer": [1, 8], "combin": [1, 2, 3, 7], "thu": 1, "risk": 1, "fill": 1, "aren": 1, "ex": 1, "even": 1, "though": 1, "distances_fil": 1, "path": [1, 2, 10, 11, 12], "table_nam": 1, "what": [1, 2, 10, 12], "want": [1, 2, 10, 12], "do": [1, 3, 10, 12], "read": [1, 2, 7, 10], "onc": [1, 10], "loc_a": 1, "where": [1, 7, 10, 12], "come": 1, "loc_b": 1, "distance_col": 1, "source_column_a": 1, "sourc": [1, 4, 7, 10, 12], "source_column_b": 1, "loc_a_0": 1, "loc_a_1": 1, "loc_b_0": 1, "loc_b_1": 1, "secondary_key_count": 1, "backup": 1, "secondary_table_nam": 1, "secondary_distances_fil": 1, "secondary_source_column": 1, "secondary_loc_a": 1, "secondary_loc_b": 1, "secondary_distance_col": 1, "state_dist": 1, "state_distance_lookup": 1, "county_state_dist": 1, "csv": [1, 2, 7, 10, 11, 12], "statecode1": 1, "statecode2": 1, "dist": 1, "county_dist": [1, 2, 12], "county_distance_lookup": 1, "county_1900_1910_distances_km": 1, "from_icpsrctyi": 1, "to_icpsrctyi": 1, "from_statefip": 1, "to_statefip": 1, "distance_km": 1, "state_1900_1910_distances_km": 1, "fetch": 1, "neither": 1, "nor": 1, "mpre": 1, "m_namefrst": 1, "accord": 1, "niu": 1, "other": [1, 2, 12], "mfbplmatch": 1, "multi": 1, "search": 1, "special": 1, "simplifi": 1, "particular": [1, 2], "constraint": 1, "num_col": 1, "whose": 1, "templat": 1, "n": [1, 8, 9], "per": [1, 2, 8, 9, 10], "current": [1, 2, 10], "respect": [1, 7], "jw_col_templ": 1, "jw": 1, "pair": [1, 12], "equal_and_not_null_templ": 1, "final": [1, 2, 12], "comput": [1, 3, 7], "_namefrst": 1, "_bpl": 1, "_sex": 1, "25": 1, "nvl": 1, "sm_namefrst": 1, "sn_namefrst": 1, "sm_bpl": 1, "sn_bpl": 1, "sm_sex": 1, "sn_sex": 1, "pass": [1, 2, 7, 8], "default": [1, 2, 7, 8, 10], "flexibl": 1, "user": [1, 10], "write": [1, 10, 12], "own": [1, 2], "favor": 1, "reason": 1, "good": 1, "fallback": 1, "defin": [1, 7, 8, 9, 10], "spark": [1, 2, 5, 8, 9, 10, 12], "builtin": 1, "argument": [1, 10, 12], "namelast_jw_max": 1, "namelast1": 1, "namelast2": 1, "namelast3": 1, "abov": [1, 5], "extend": 1, "beyond": 1, "standard": [1, 11], "top": [1, 4], "level": [1, 4, 10], "everi": 1, "jw_f": [1, 2, 12], "father_namefrst": 1, "rais": [1, 3], "exponenti": 1, "squar": 1, "county_distance_squar": [1, 2, 12], "county_a": 1, "county_b": 1, "upper": 1, "gt": 1, "btwn": 1, "addl": 1, "var": [1, 2], "program": [1, 2, 7, 12], "report": [1, 4, 6, 10], "addl_var": 1, "check_val_expr": 1, "else_v": 1, "volumn": 1, "datasourc": [1, 2, 10], "yrimmig": 1, "immyear_diff": [1, 2, 9, 12], "To": [1, 5, 7, 10], "includ": [1, 2, 7, 9, 10], "train": [1, 4, 6, 8, 10], "independent_var": [1, 2, 12], "config": [1, 4, 7, 10, 12], "id_column": [1, 2], "_a": 1, "mult": 1, "exist": [1, 2, 10], "within": [1, 2, 6, 10, 11], "hh_train": [1, 2, 7, 10, 12], "hh": 1, "highest": [1, 2], "against": [1, 11], "ten": [1, 2], "tell": 2, "how": [2, 7], "descript": [2, 8, 10], "refer": 2, "here": [2, 7, 10, 12], "tutori": [2, 10], "script": [2, 6, 10], "discuss": 2, "readm": 2, "note": 2, "written": [2, 6], "toml": [2, 6, 10], "abl": 2, "json": [2, 10], "datasource_a": [2, 7], "datasource_b": [2, 7], "transform": [2, 4, 6, 7], "lowercase_strip": 2, "add_to_a": 2, "10": [2, 5, 12], "age_2": 2, "derived_from": 2, "expand_length": 2, "explod": [2, 7], "jaro_winkl": 2, "namelast_jw": [2, 12], "threshold": [2, 8, 12], "feature_nam": 2, "79": 2, "84": 2, "complex": 2, "machin": [2, 6, 7, 10, 12], "learn": [2, 6, 7, 10, 12], "probabilist": [2, 6], "drop_data_from_scored_match": 2, "us1900": 2, "us1900m_usa": 2, "p": 2, "parquet": [2, 7], "us1910": 2, "us1910m_usa": 2, "training_data_subset": 2, "serialp": 2, "rationalize_name_word": 2, "remove_qmark_hyphen": 2, "replace_apostroph": 2, "remove_suffix": 2, "remove_alternate_nam": 2, "condense_strip_whitespac": 2, "split": [2, 3, 4, 7, 8, 9, 12], "namefrst_std": [2, 11], "array_index": 2, "bpl_orig": 2, "divide_by_int": 2, "get_floor": 2, "statefip_h": 2, "output_typ": 2, "substitution_column": [2, 7, 11], "join_column": [2, 11], "join_valu": [2, 11], "substitution_fil": [2, 11], "name_std": [2, 11], "male": [2, 11], "femal": [2, 11], "feature_select": [2, 3, 7], "input_column": [2, 3, 9], "output_column": [2, 3, 9], "sql_condit": 2, "namelast_bigram": 2, "bigram": [2, 4], "bpl_clean": 2, "bpl_str": 2, "washington": 2, "bpl2_str": 2, "53": 2, "region": [2, 12], "attach_vari": 2, "region_dict": 2, "col_to_join_on": 2, "col_to_add": 2, "null_fil": 2, "col_typ": 2, "potential_matches_univers": [2, 7], "birthyr_3": 2, "namefrst_std_jw": [2, 12], "75": [2, 8, 12], "comparis": 2, "post": [2, 7], "hh_comparison": [2, 7], "threshold_expr": 2, "fetch_a": 2, "sex_equ": 2, "equal": [2, 11], "relate_a": [2, 9], "pipeline_featur": [2, 7, 9], "sex_region_interact": 2, "transformer_typ": [2, 9], "interact": [2, 4, 7, 12], "relatetyp": [2, 9], "bucket": [2, 7], "hit": [2, 10, 12], "scale_data": [2, 12], "training_data": [2, 10], "dependent_var": [2, 12], "score_with_model": [2, 12], "use_training_data_featur": [2, 7, 12], "split_by_id_a": [2, 12], "decis": [2, 4, 8, 12], "drop_duplicate_with_threshold_ratio": [2, 12], "n_training_iter": [2, 7, 12], "output_suspicious_td": [2, 12], "param_grid": [2, 12], "model_paramet": [2, 7, 8, 12], "random_forest": [2, 12], "maxdepth": [2, 8, 12], "numtre": [2, 8, 12], "005": 2, "threshold_ratio": [2, 8, 12], "logistic_regress": [2, 12], "50": [2, 12], "65": 2, "80": 2, "chosen_model": [2, 8, 12], "prediction_col": 2, "predict": [2, 12], "hh_col": 2, "hh_training_data_1900_1910": 2, "probit": [2, 4], "go": [2, 10], "your": [2, 5, 7, 10, 12], "uniqu": 2, "identifi": [2, 6, 12], "full": [2, 7, 12], "short": 2, "alphanumer": 2, "convert_ints_to_long": 2, "automat": [2, 5, 7], "long": [2, 11], "especi": 2, "assum": 2, "schema": 2, "sometim": 2, "term": 2, "bigint": 2, "thing": 2, "my_fil": 2, "subset": [2, 11], "limit": 2, "extract": 2, "new": [2, 12], "iv": 2, "v": 2, "vi": 2, "vii": 2, "viii": 2, "namelast_clean_bigram": [2, 3], "creat": [2, 6, 7, 9, 10, 11, 12], "fed": [2, 7], "prep": 2, "df": [2, 10], "men": 2, "describ": [2, 10], "newli": 2, "attempt": 2, "duplic": [2, 8], "row": 2, "conjuct": 2, "Will": 2, "conjunct": 2, "rang": [2, 9], "original_valu": 2, "plu": 2, "1870": 2, "expand": 2, "1867": 2, "1868": 2, "1869": 2, "1871": 2, "1872": 2, "1873": 2, "kept": 2, "keep": 2, "appropri": 2, "treat": [2, 9], "import": [2, 7, 10, 12], "dure": [2, 7], "hot": 2, "encod": [2, 3], "vector": [2, 9], "stage": 2, "well": 2, "upper_threshold": 2, "cannot": 2, "robust": 2, "ml": [2, 4, 8, 9], "typic": [2, 7], "leverag": 2, "api": [2, 6, 9], "piplin": 2, "regionf": 2, "sex_regionf_interact": 2, "immyear_caut": [2, 9], "myriad": 2, "explor": [2, 4, 6, 10], "part": [2, 7], "task": [2, 4, 6, 8, 12], "drop_duplicate_a": 2, "time": [2, 7, 10], "out": [2, 7, 12], "best": [2, 7], "smallest": 2, "possibl": 2, "ratio": [2, 8], "beta": [2, 8], "test": [2, 7, 12], "model_explor": [2, 10, 12], "hyper": [2, 6, 12], "paramet": [2, 6, 7, 8, 10, 12], "eval": 2, "skip": [2, 7], "apply_model": 2, "run_all_step": [2, 10, 12], "command": [2, 6, 10, 12], "try": 2, "creation": 2, "iter": 2, "scale": 2, "error": [2, 9], "1900": [2, 12], "about": [2, 10, 12], "1930": [2, 12], "1940": [2, 12], "fail": 2, "were": 2, "sure": [2, 5, 10], "scratch": 2, "although": 2, "know": 2, "haven": 2, "could": 2, "save": [2, 7, 12], "small": 2, "amount": 2, "process": [2, 6, 10], "repeatedli": 2, "help": [2, 7, 10], "neg": [2, 4, 6], "area": 2, "coverag": 2, "increas": [2, 9], "represent": [2, 7], "ensur": 2, "group": [2, 7], "a304bt": 2, "three": [2, 7], "b200": 2, "c201": 2, "d425": 2, "perform": [2, 6, 7, 11], "feature_import": [2, 7, 12], "srace": [2, 9, 12], "race_interacted_srac": [2, 9, 12], "hits2": [2, 12], "exact_mult": [2, 12], "ncount": [2, 3, 12], "ncount2": [2, 3, 12], "f_interacted_jw_f": [2, 12], "f_caution": [2, 12], "f_pre": [2, 12], "fbplmatch": [2, 12], "m_interacted_jw_m": [2, 9, 12], "jw_m": [2, 9, 12], "m_pre": [2, 9, 12], "mbplmatch": [2, 12], "sp_interacted_jw_sp": [2, 12], "jw_sp": [2, 12], "sp_pre": [2, 12], "mi": [2, 12], "fsoundex": [2, 12], "lsoundex": [2, 12], "oth": [2, 12], "imm_interacted_immyear_caut": [2, 12], "1900_1910_training_data_20191023": 2, "jw_max_a": 2, "jw_max_b": 2, "f1_match": 2, "f2_match": 2, "byrdifcat": 2, "racematch": 2, "bplmatch": 2, "imm_interacted_bplmatch": 2, "sexmatch": 2, "relatetype_interacted_relatematch": 2, "checkpoint": 3, "override_column_a": 3, "override_column_b": 3, "set_value_column_a": 3, "set_value_column_b": 3, "no_first_pad": 3, "don": 3, "prepend": 3, "provid": [3, 6, 7, 9, 10], "namefrst_unstd_bigram": 3, "namelast_frst_bigram": 3, "namelast_clean_soundex": 3, "input_col": 3, "output_col": 3, "expon": 3, "introduct": 4, "overview": 4, "instal": 4, "pypi": 4, "preprocess": [4, 6, 10, 12], "model": [4, 6, 10], "run": [4, 5, 6, 7, 12], "librari": [4, 6], "mode": [4, 5, 12], "advanc": 4, "workflow": 4, "export": [4, 7, 10], "featur": [4, 6, 7, 8, 10], "reus": 4, "basic": 4, "map": [4, 7, 9], "substitut": [4, 7], "block": [4, 7], "comparison": [4, 7], "pipelin": 4, "substr": 4, "ons": 4, "aggreg": 4, "union": 4, "soundex": 4, "power": 4, "regex": 4, "random": [4, 8], "forest": [4, 8], "logist": [4, 8], "regress": [4, 8], "tree": [4, 8], "gradient": [4, 8], "boost": [4, 8], "system": 5, "python": [5, 6, 10], "java": 5, "integr": 5, "apach": 5, "via": [5, 6], "pyspark": [5, 8, 9, 10], "packag": 5, "org": 5, "latest": 5, "pip": 5, "easiest": [5, 10], "through": [5, 7, 9, 10], "instruct": [5, 10], "But": 5, "clone": 5, "github": 5, "repositori": 5, "root": 5, "project": 5, "directori": [5, 10, 12], "develop": [5, 6], "e": 5, "dev": 5, "edit": 5, "made": 5, "built": 5, "tool": [5, 6], "line": [6, 10], "share": 6, "characterist": [6, 7], "correspond": [6, 7], "real": 6, "world": 6, "determinist": [6, 7], "rule": [6, 7], "algorithm": [6, 7], "At": [6, 7], "been": 6, "unit": 6, "census": 6, "hierarch": [6, 10], "structur": 6, "nest": 6, "howev": [6, 12], "tailor": 6, "ignor": 6, "common": [6, 7, 12], "highli": [6, 7], "languag": 6, "further": [6, 12], "broken": 6, "smaller": 6, "sequenc": 6, "linkrun": [6, 10], "prepar": [6, 7, 10], "research": 6, "experi": 6, "understand": 6, "tune": [6, 12], "relationship": 6, "varieti": 7, "normal": 7, "abbrevi": [7, 11], "regist": [7, 10], "datafram": [7, 10, 12], "request": 7, "classif": [7, 8], "ingest": 7, "mani": [7, 10], "aspect": [7, 10], "extens": 7, "longest": 7, "definit": 7, "reduc": 7, "drastic": 7, "improv": 7, "runtim": 7, "separ": 7, "total": 7, "potential_match": [7, 10], "satisfi": 7, "elig": 7, "support": [7, 8], "reshap": 7, "thought": 7, "ahead": 7, "chosen": 7, "experiment": [7, 10], "focus": 7, "demograph": 7, "moment": 7, "veri": [7, 12], "anyon": 7, "percent": 7, "remain": 7, "popul": 7, "pull": 7, "fix": 7, "width": 7, "crosswalk": 7, "construct": 7, "alpha": 8, "hyperparamet": [8, 12], "de": 8, "param": [8, 12], "label": 8, "doc": [8, 9], "commonli": 8, "explan": 8, "randomforestclassifi": 8, "depth": 8, "20": 8, "featuresubsetstrategi": 8, "node": 8, "auto": 8, "onethird": 8, "sqrt": 8, "log2": 8, "15": 8, "generalizedlinearregress": 8, "famili": 8, "binomi": 8, "85": [8, 10], "logisticregress": 8, "decisiontreeclassifi": 8, "mininstancespernod": 8, "caus": 8, "left": 8, "right": [8, 10], "discard": 8, "maxbin": 8, "bin": 8, "discret": 8, "continu": [8, 9, 12], "gbtclassifi": 8, "mother": 9, "point": [9, 12], "With": 9, "x": [9, 10], "y": 9, "hold": 9, "except": 9, "strictli": 9, "inf": 9, "explicitli": 9, "cover": 9, "doubl": 9, "outsid": 9, "job": 10, "high": 10, "class": 10, "handl": 10, "main": 10, "complet": 10, "access": [10, 12], "link_run": 10, "factori": 10, "sparkfactori": 10, "load_config": 10, "load_conf_fil": 10, "sparksess": 10, "now": 10, "let": 10, "load": 10, "our": 10, "my_conf": 10, "lr": 10, "prep_step": 10, "get_step": 10, "enumer": 10, "print": 10, "input_table_nam": 10, "output_table_nam": 10, "run_step": 10, "get_tabl": 10, "matches_df": 10, "hh_model_explor": 10, "method": [10, 12], "interfac": 10, "easili": 10, "conveni": 10, "adjust": 10, "set_loc": 10, "set_num_cor": 10, "set_executor_memori": 10, "5g": 10, "ll": 10, "dictionari": 10, "modul": 10, "pleas": 10, "enabl": [2, 7, 10], "reproduc": 10, "consol": 10, "cpu": 10, "usag": 10, "h": 10, "executor_memori": [10, 12], "execute_task": 10, "execute_command": 10, "conf": [10, 12], "show": 10, "messag": 10, "exit": 10, "memori": 10, "executor": 10, "begin": 10, "execut": 10, "seri": 10, "excute_command": 10, "filepath": 10, "sai": 10, "fullcount_1870_1880": 10, "pattern": 10, "full_count_1870_1880": 10, "prompt": 10, "enter": 10, "text": 10, "unstabl": 10, "topic": 10, "analyz": [10, 12], "set_preexisting_t": 10, "x_persist": 10, "borrow_t": 10, "get_task": 10, "set_print_sql": 10, "x_sql": 10, "x_sqlf": 10, "ipython": 10, "showf": 10, "x_summari": 10, "desc": 10, "x_crosswalk": 10, "x_tab": 10, "q": [10, 12], "x_hh_tfam": 10, "x_tfam": 10, "drop_al": 10, "reload": 10, "x_hh_tfam_2a": 10, "x_tfam_raw": 10, "drop_all_prc": 10, "x_hh_tfam_2b": 10, "x_union": 10, "drop_all_temp": 10, "x_load": 10, "get_set": 10, "set_link_task": 10, "x_parquet_from_csv": 10, "organ": 10, "hierarchi": 10, "five": 10, "hh_match": 10, "someth": 10, "choic": 10, "preexist": 10, "prepped_df_a": 10, "prepped_df_b": 10, "raw_df_b": 10, "raw_df_a": 10, "training_featur": [10, 12], "scored_potential_match": 10, "potential_matches_prep": 10, "exploded_df_b": 10, "exploded_df_a": 10, "predicted_match": 10, "hh_training_featur": [10, 12], "hh_training_data": 10, "hh_predicted_match": 10, "hh_scored_potential_match": 10, "hh_potential_match": 10, "hh_blocked_match": 10, "hh_potential_matchs_prep": 10, "model_eval_training_vector": 10, "model_eval_training_data": 10, "model_eval_repeat_fp": 10, "model_eval_training_featur": 10, "model_eval_training_result": 10, "model_eval_repeat_fn": 10, "hh_model_eval_training_vector": 10, "hh_model_eval_repeat_fp": 10, "hh_model_eval_repeat_fn": 10, "hh_model_eval_training_result": 10, "hh_model_eval_training_featur": 10, "hh_model_eval_training_data": 10, "persist": 10, "hidden": 10, "intermedi": 10, "yet": 10, "databas": 10, "tablenam": 10, "istemporari": 10, "task_nam": 10, "num": 10, "finish": 10, "By": 10, "put": [10, 12], "launch": [10, 12], "my": [10, 12], "subhead": 11, "suppli": 11, "regex_word_replac": 11, "variant": 11, "av": 11, "7th": 11, "swap": 11, "still": 11, "anywher": 11, "proceed": 11, "street_unstd": 11, "dir": 11, "substitutions_street_abbrev": 11, "span": 12, "1920": 12, "deriv": 12, "necessari": 12, "scenario": 12, "copi": 12, "use_potential_matches_featur": 12, "full_count_1900_1910": 12, "50g": 12, "ask": 12, "arg": 12, "partit": 12, "training_data_1900_1910_hlink_featur": 12, "might": 12, "shut": 12, "framework": 12, "etc": 12, "relev": 12, "matrix": 12, "implement": 12, "regular": 12, "training_data_1900_1910": 12, "weren": 12, "ident": 12, "manual": 12, "updat": 12, "isn": 12, "analysi": 12, "training_result": 12, "hh_training_result": 12, "1900_1910_training_result": 12, "repeat_fp": 12, "repeat_fn": 12, "hh_repeat_fp": 12, "hh_repeat_fn": 12, "1900_1910_potential_fp": 12, "1900_1910_potential_fn": 12, "prefer": 12, "ve": 12, "metadata": 7, "coeffici": [2, 7], "introspect": 7, "inspect": 7}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"column": [0, 2], "map": [0, 2], "transform": [0, 1, 3, 9], "add_to_a": 0, "concat_to_a": 0, "concat_to_b": 0, "lowercase_strip": 0, "rationalize_name_word": 0, "remove_qmark_hyphen": 0, "remove_punctu": 0, "replace_apostroph": 0, "remove_alternate_nam": 0, "remove_suffix": 0, "remove_stop_word": 0, "remove_prefix": 0, "condense_strip_whitespac": 0, "remove_one_letter_nam": 0, "split": 0, "array_index": 0, "substr": 0, "divide_by_int": 0, "when_valu": 0, "get_floor": 0, "comparison": [1, 2], "type": [1, 9], "add": 1, "ons": 1, "aggreg": 1, "featur": [1, 2, 3, 9, 12], "household": [1, 2, 7], "maximum_jaro_winkl": 1, "jaro_winkl": 1, "jaro_winkler_street": 1, "max_jaro_winkl": 1, "equal": 1, "f1_match": 1, "f2_match": 1, "not_equ": 1, "equals_as_int": 1, "all_equ": 1, "not_zero_and_not_equ": 1, "time": 1, "caution_comp_3": 1, "caution_comp_3_012": 1, "caution_comp_4": 1, "caution_comp_4_012": 1, "any_equ": 1, "either_are_1": 1, "either_are_0": 1, "second_gen_imm": 1, "rel_jaro_winkl": 1, "extra_children": 1, "jaro_winkler_r": 1, "sum": 1, "length_b": 1, "abs_diff": 1, "b_minus_a": 1, "geo_dist": 1, "fetch_a": 1, "fetch_b": 1, "present_both_year": 1, "neither_are_nul": 1, "present_and_matching_categor": 1, "present_and_not_equ": 1, "present_and_equal_categorical_in_univers": 1, "multi_jaro_winkler_search": 1, "sql_condit": [1, 3], "alia": 1, "power": [1, 3], "threshold": 1, "lower_threshold": 1, "upper_threshold": 1, "gt_threshold": 1, "btwn_threshold": 1, "look_at_addl_var": 1, "hit": 1, "hits2": 1, "exact_mult": 1, "jw_max_a": 1, "jw_max_b": 1, "configur": [2, 4, 7], "basic": 2, "config": 2, "file": 2, "advanc": [2, 12], "top": 2, "level": 2, "data": [2, 11, 12], "sourc": [2, 5], "filter": 2, "substitut": [2, 11], "select": [2, 3], "potenti": [2, 12], "match": [2, 7], "univers": 2, "block": 2, "pipelin": [2, 9], "gener": [2, 9, 12], "train": [2, 7, 12], "model": [2, 7, 8, 12], "bigram": 3, "arrai": 3, "union": 3, "soundex": 3, "welcom": 4, "hlink": [4, 10], "": 4, "document": 4, "api": 4, "instal": 5, "requir": 5, "from": 5, "pypi": 5, "introduct": 6, "overview": [6, 7], "link": [7, 10, 12], "task": [7, 10], "preprocess": 7, "step": [7, 10], "relat": 7, "section": 7, "explor": [7, 12], "report": 7, "random_forest": 8, "probit": 8, "logistic_regress": 8, "decision_tre": 8, "gradient_boosted_tre": 8, "interact": [9, 10], "bucket": 9, "run": 10, "us": 10, "librari": 10, "mode": 10, "start": 10, "program": 10, "exampl": [10, 12], "workflow": [10, 12], "1": 11, "tabl": 11, "regex": 11, "word": 11, "replac": 11, "export": 12, "after": 12, "reus": 12, "differ": 12, "year": 12, "ml": 12, "list": 12, "fals": 12, "posit": 12, "neg": 12, "fp": 12, "fn": 12}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}})
\ No newline at end of file
+Search.setIndex({"docnames": ["column_mapping_transforms", "comparison_types", "config", "feature_selection_transforms", "index", "installation", "introduction", "link_tasks", "models", "pipeline_features", "running_the_program", "substitutions", "use_examples"], "filenames": ["column_mapping_transforms.md", "comparison_types.md", "config.md", "feature_selection_transforms.md", "index.rst", "installation.md", "introduction.md", "link_tasks.md", "models.md", "pipeline_features.md", "running_the_program.md", "substitutions.md", "use_examples.md"], "titles": ["Column mapping transforms", "Comparison types, transform add-ons, aggregate features, and household aggregate features", "Configuration", "Feature Selection transforms", "Welcome to hlink\u2019s documentation!", "Installation", "Introduction", "Link Tasks", "Models", "Pipeline generated features", "Running hlink", "Substitutions", "Advanced Workflow Examples"], "terms": {"each": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "header": [0, 1, 2, 3, 9, 11], "below": [0, 1, 2, 3, 8, 9, 10], "repres": [0, 1, 2, 3, 9, 10], "type": [0, 2, 3, 4, 7, 8, 10, 11, 12], "ar": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12], "us": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12], "context": [0, 1, 3, 9], "column_map": [0, 2, 7], "list": [0, 1, 2, 3, 4, 8, 10, 11], "oper": [0, 2], "singl": [0, 2, 10, 12], "input": [0, 1, 2, 3, 6, 7, 10, 11], "output": [0, 1, 2, 3, 6, 7, 10, 12], "some": [0, 1, 3, 6, 7, 10], "suffix": [0, 4], "b": [0, 1, 2, 4, 10], "These": [0, 1, 2, 3, 6, 7, 8, 9], "mean": [0, 2], "appli": [0, 2, 3, 7, 12], "from": [0, 1, 2, 4, 6, 7, 8, 9, 10, 12], "onli": [0, 1, 2, 7, 12], "one": [0, 1, 2, 4, 7], "two": [0, 1, 2, 3, 6, 7, 9, 10, 12], "dataset": [0, 1, 2, 6, 7, 10, 12], "link": [0, 1, 2, 4, 6, 8], "A": [0, 1, 2, 9, 10], "most": [0, 1, 7, 10], "both": [0, 1, 2, 7, 12], "independ": [0, 2], "more": [0, 1, 2, 9, 10, 12], "than": [0, 1, 2, 8], "can": [0, 1, 2, 5, 6, 7, 8, 10, 12], "order": [0, 2, 7], "thei": [0, 1, 2, 7, 10], "re": 0, "configur": [0, 1, 6, 10, 12], "file": [0, 1, 4, 6, 7, 10, 11, 12], "so": [0, 1, 2, 5, 12], "mai": [0, 2, 6, 7, 10], "anoth": [0, 1, 3, 7], "format": 0, "The": [0, 1, 2, 3, 5, 7, 8, 9, 10, 12], "letter": [0, 4], "t": [0, 1, 2, 3, 12], "u": 0, "arbitrari": 0, "specifi": [0, 1, 2, 6, 7, 9, 10, 11], "column_nam": [0, 1, 2, 11], "attribut": [0, 1, 2, 3, 7, 8, 9, 10, 11], "under": [0, 1, 2], "its": [0, 1, 6, 10], "section": [0, 1, 2, 12], "name": [0, 1, 2, 4, 10, 11], "i": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12], "alia": [0, 2, 7], "along": [0, 1], "which": [0, 1, 2, 3, 6, 7, 9, 10, 12], "must": [0, 1, 2, 8, 9, 11], "addit": [0, 1, 2, 3, 5, 6, 10], "vari": [0, 2], "inform": [0, 1, 2, 10], "given": [0, 1, 2, 3, 8, 12], "often": [0, 10], "just": [0, 1, 2, 10, 12], "valu": [0, 1, 2, 4, 8, 9, 10, 11], "expect": [0, 1], "an": [0, 1, 2, 3, 6, 8, 10], "exampl": [0, 1, 2], "namefrst_split": [0, 2], "namefrst_clean": [0, 2], "add": [0, 4], "_": [0, 1, 2, 3, 4, 8, 9, 10], "numer": [0, 1], "11": [0, 2, 5, 9], "concat": [0, 4], "concaten": [0, 1], "string": [0, 1, 2, 3, 7, 8, 10, 11], "end": [0, 1, 2, 3, 11], "lowercas": [0, 4], "strip": [0, 4, 7], "clean": [0, 6], "convert": [0, 1, 2], "alphabet": 0, "charact": 0, "lower": [0, 1], "case": [0, 1, 2, 3, 6], "white": 0, "space": [0, 2, 3, 11], "start": [0, 11], "ration": [0, 4], "word": [0, 4], "replac": [0, 1, 4], "sinc": [0, 2], "peopl": [0, 1, 6, 10], "": [0, 1, 2, 6, 7, 10, 11], "raw": [0, 2, 7, 10], "censu": [0, 7, 12], "data": [0, 1, 4, 6, 7, 10], "contain": [0, 1, 11], "lead": 0, "better": [0, 6], "match": [0, 1, 4, 6, 10, 11, 12], "remov": [0, 4], "qmark": [0, 4], "hyphen": [0, 4], "punctuat": [0, 4], "thi": [0, 1, 2, 5, 6, 7, 9, 10, 12], "apostroph": [0, 4], "altern": [0, 2, 4], "If": [0, 1, 2, 3, 7, 8, 10, 11], "surround": 0, "all": [0, 1, 2, 3, 7, 8, 9, 10], "follow": [0, 1, 6, 10, 11, 12], "them": [0, 1, 2, 7], "jr": [0, 2], "sr": [0, 2], "ii": [0, 2], "iii": [0, 2], "stop": [0, 4], "last": [0, 1, 7, 9], "street": [0, 1], "avenu": [0, 11], "blvd": 0, "circl": 0, "court": 0, "road": 0, "prefix": [0, 4], "like": [0, 2, 7, 10], "m": [0, 1], "mr": 0, "In": [0, 1, 6, 10, 12], "ah": 0, "chines": 0, "condens": [0, 4], "whitespac": [0, 4, 7], "take": [0, 1, 2, 3, 7, 10], "non": 0, "leav": 0, "behind": 0, "arrai": [0, 2, 4, 8, 9], "index": [0, 4, 5], "select": [0, 1, 4, 6, 10, 12], "element": 0, "posit": [0, 1, 2, 4, 6], "first": [0, 1, 2, 5, 7, 10, 11], "second": [0, 1, 2, 11], "1": [0, 1, 2, 4, 7, 8, 9, 10, 12], "item": 0, "namefrst": [0, 1, 2], "set": [0, 1, 2, 3, 6, 7, 10, 12], "Then": [0, 5], "0": [0, 1, 2, 7, 8, 9, 10, 12], "give": [0, 2], "initi": [0, 1, 10], "person": [0, 1, 6], "probabl": [0, 2, 8], "middl": [0, 1], "namefrst_mid_init": [0, 1], "multipl": [0, 1, 2, 10], "otherwis": [0, 1, 9, 12], "known": 0, "recod": 0, "birthyr": [0, 2], "clean_birthyr": [0, 2, 3], "9999": [0, 2, 9], "1999": [0, 2], "9998": 0, "divid": [0, 4], "int": [0, 1, 2, 3, 4, 8], "integ": [0, 1, 2, 9], "It": [0, 1, 2, 6, 10, 12], "result": [0, 1, 6, 9, 10, 12], "For": [0, 1, 2, 7, 10, 12], "instanc": [0, 8], "birthplac": 0, "variabl": [0, 1, 2, 12], "detail": [0, 2, 10], "version": [0, 5, 12], "gener": [0, 1, 4, 6, 7, 10], "least": [0, 1], "signific": 0, "digit": 0, "make": [0, 1, 2, 5, 12], "we": [0, 1, 10, 12], "simpli": [0, 2], "drop": [0, 2, 10], "100": [0, 2, 12], "round": [0, 2], "lowest": 0, "whole": [0, 6], "number": [0, 1, 2, 7, 8, 10], "floor": [0, 4], "function": [0, 1, 2, 6, 10], "bpl": [0, 1, 2], "bpl_root": 0, "when": [0, 1, 2, 3, 4, 7, 12], "condit": [0, 1, 2, 3, 4, 7], "logic": 0, "work": [0, 1, 2, 5, 7, 10, 12], "sql": [0, 1, 2, 3, 4, 7, 10], "express": [0, 1, 2], "claus": [0, 1], "if_valu": 0, "else_valu": 0, "race": [0, 1, 2, 9, 12], "ipum": [0, 6], "code": [0, 1, 2, 5], "categori": [0, 8], "get": [0, 1, 4, 10], "down": [0, 6, 12], "nearest": 0, "produc": [0, 10], "relat": [0, 1, 2], "between": [0, 1, 2, 6, 7, 10, 12], "hundr": 0, "300": 0, "child": [0, 8], "household": [0, 4, 6, 8, 10, 12], "head": 0, "301": 0, "302": 0, "adopt": 0, "303": 0, "step": [0, 1, 2, 6], "usual": [0, 7, 12], "need": [0, 1, 2, 7, 10, 12], "2": [0, 1, 2, 3, 7, 8, 11, 12], "spous": 0, "3": [0, 1, 2, 5, 7, 8, 9, 12], "4": [0, 1, 8], "law": 0, "5": [0, 1, 2, 8, 9, 10, 12], "parent": [0, 1, 11], "6": [0, 2, 8, 9, 12], "7": [0, 1, 2, 8, 12], "sibl": 0, "12": 0, "relate_div_100": [0, 1, 2], "page": [1, 10], "ha": [1, 2, 6, 10, 12], "differ": [1, 2, 4, 6, 7], "avail": [1, 2, 3, 5, 7, 8, 9, 12], "comparison_featur": [1, 2, 7], "relatematch": [1, 2], "comparison_typ": [1, 2], "categor": [1, 2, 8, 9], "true": [1, 2, 3, 7, 9, 11, 12], "maximum": [1, 8], "jaro": [1, 9], "winkler": [1, 9], "find": [1, 7, 12], "greatest": 1, "among": 1, "cartesian": 1, "product": [1, 6, 12], "column": [1, 3, 4, 7, 9, 10, 11, 12], "namelast": [1, 2], "would": [1, 2, 12], "return": [1, 3, 8, 10], "four": 1, "namefrst_a": 1, "namefrst_b": 1, "namelast_b": 1, "namelast_a": 1, "requir": [1, 2, 3, 4, 7, 9, 10, 11], "maximum_jw": 1, "score": [1, 2, 7, 9], "compar": [1, 2, 6, 7], "namefrst_jw": [1, 2, 12], "geograph": 1, "filter": [1, 4, 7, 11], "major": [1, 10], "locat": [1, 2, 10], "chang": [1, 2, 5, 10, 12], "befor": [1, 2, 3, 5, 7], "boundari": 1, "zero": 1, "jw_street": 1, "enum_dist": 1, "max": [1, 8, 10], "member": [1, 7], "neighborhood": 1, "surnam": 1, "related_individual_max_jw": 1, "namefrst_rel": 1, "assert": [1, 10], "same": [1, 2, 6, 7, 10], "NOT": 1, "distinct": 1, "f1": 1, "evalu": [1, 2, 6, 7, 8], "either": [1, 2, 6, 11], "ani": [1, 2, 5, 8], "potenti": [1, 4, 7], "mismatch": 1, "queri": [1, 2], "fi": 1, "OR": 1, "mi0": 1, "mi1": 1, "THEN": 1, "els": [1, 2, 3], "first_init_col": 1, "namefrst_init": 1, "mid_init_col": 1, "namefrst_mid_init_2": 1, "f2": 1, "empti": 1, "null": [1, 2, 3], "AND": [1, 2], "individu": [1, 2, 7, 12], "mainli": 1, "caution": [1, 9], "flag": [1, 9, 10, 12], "f": [1, 10], "sp": 1, "m_caution": [1, 2, 9, 12], "mbpl": 1, "mother_birthyr": 1, "stepmom": 1, "momloc": 1, "comp_a": [1, 2], "comp_b": [1, 2], "comp_c": 1, "parent_step_chang": 1, "comp_d": 1, "check": [1, 10], "sign": 1, "boolean": [1, 2, 3, 11, 12], "form": [1, 7, 11], "cast": 1, "col": 1, "namelast_equal_as_int": 1, "namelast_clean": [1, 2, 3], "whether": [1, 2, 11], "join": [1, 11], "across": 1, "record": [1, 2, 6, 7], "being": [1, 7], "exact": [1, 2], "namefrst_unstd": [1, 2], "present": [1, 2, 9], "nonzero": 1, "primarili": [1, 7], "indic": [1, 12], "kind": 1, "incompar": 1, "akin": 1, "miss": [1, 10], "see": [1, 2, 5, 10, 12], "also": [1, 2, 5, 6, 7, 9, 10, 12], "univers": [1, 4, 7], "similar": 1, "fbpl_nomatch": 1, "fbpl": 1, "allow": [1, 2, 7, 12], "up": [1, 2, 10, 11], "sub": 1, "object": [1, 2, 6, 10], "document": [1, 8, 10, 12], "option": [1, 2, 3, 6, 7, 8, 10, 12], "sp_caution": [1, 2, 12], "spouse_bpl": 1, "spouse_birthyr": 1, "durmarr": [1, 2], "new_marr": [1, 2], "appear": 1, "street_jw": [1, 2, 12], "counti": 1, "statefip": [1, 2], "9": 1, "multipli": 1, "togeth": [1, 2], "after": [1, 2, 4, 8, 10], "float": [1, 2, 8], "have": [1, 2, 5, 6, 7, 8, 10, 12], "comp": 1, "c": 1, "sploc": 1, "012": 1, "fals": [1, 2, 3, 4, 6, 10], "d": 1, "specif": [1, 2, 10], "circumst": 1, "should": [1, 2, 8, 9, 10], "mid_init_match": 1, "either_1": 1, "nativ": 1, "either_0": 1, "gen": 1, "imm": [1, 2, 12], "immigr": 1, "look": [1, 10, 11], "foreign": 1, "born": 1, "sgen": [1, 2, 12], "rel": [1, 2, 12], "scala": 1, "determin": [1, 7], "greater": [1, 5], "jw_threshold": 1, "ag": [1, 2, 3], "less": [1, 2], "age_threshold": 1, "sex": [1, 2, 11], "sampl": 1, "related_individual_row": 1, "unrel": 1, "depend": [1, 2, 5, 12], "name_col": 1, "birthyr_col": 1, "namefrst_related_row": 1, "replaced_birthyr": [1, 2, 3], "extra": 1, "children": 1, "who": 1, "base": [1, 2, 7], "count": [1, 10, 12], "suspect": [1, 6], "relate_col": 1, "histid_col": 1, "id": [1, 2], "birth": 1, "year": [1, 2, 3, 4], "year_b": 1, "wa": [1, 12], "taken": 1, "minimum": [1, 8], "accept": [1, 2, 12], "consid": [1, 8], "histid": [1, 2, 12], "1910": [1, 2, 12], "8": [1, 2, 5, 10], "rate": 1, "calcul": [1, 12], "percentag": 1, "seen": 1, "neighbor": 1, "meet": 1, "95": 1, "nbor": [1, 2, 12], "namelast_neighbor": 1, "05": [1, 2], "ad": [1, 2], "namelast_popularity_sum": 1, "namelast_popular": 1, "length": [1, 2, 9], "size": 1, "ab": 1, "diff": 1, "absolut": 1, "you": [1, 2, 5, 10, 11, 12], "invalid": [1, 8], "instead": [1, 2, 5, 7], "marriag": 1, "durat": 1, "99": [1, 2], "placehold": 1, "unknown": 1, "exclud": 1, "those": [1, 2], "consider": 1, "byrdiff": [1, 2, 12], "mardurmatch": [1, 2], "14": 1, "minu": [1, 2], "subtract": 1, "geo": 1, "distanc": [1, 8], "lookup": 1, "tabl": [1, 2, 4, 7, 10, 12], "hlink": [1, 2, 5, 6, 7, 12], "core": [1, 7, 10, 12], "dist_tabl": 1, "py": [1, 2], "There": [1, 3, 7], "sever": [1, 6], "wai": [1, 5, 10], "kei": [1, 7, 10], "key_count": 1, "secondari": 1, "serv": 1, "back": 1, "primari": [1, 6], "doe": [1, 7, 12], "particularli": 1, "state": [1, 6], "much": [1, 7], "fewer": [1, 8], "combin": [1, 2, 3, 7], "thu": 1, "risk": 1, "fill": 1, "aren": 1, "ex": 1, "even": 1, "though": 1, "distances_fil": 1, "path": [1, 2, 10, 11, 12], "table_nam": 1, "what": [1, 2, 10, 12], "want": [1, 2, 10, 12], "do": [1, 3, 10, 12], "read": [1, 2, 7, 10], "onc": [1, 10], "loc_a": 1, "where": [1, 7, 10, 12], "come": 1, "loc_b": 1, "distance_col": 1, "source_column_a": 1, "sourc": [1, 4, 7, 10, 12], "source_column_b": 1, "loc_a_0": 1, "loc_a_1": 1, "loc_b_0": 1, "loc_b_1": 1, "secondary_key_count": 1, "backup": 1, "secondary_table_nam": 1, "secondary_distances_fil": 1, "secondary_source_column": 1, "secondary_loc_a": 1, "secondary_loc_b": 1, "secondary_distance_col": 1, "state_dist": 1, "state_distance_lookup": 1, "county_state_dist": 1, "csv": [1, 2, 7, 10, 11, 12], "statecode1": 1, "statecode2": 1, "dist": 1, "county_dist": [1, 2, 12], "county_distance_lookup": 1, "county_1900_1910_distances_km": 1, "from_icpsrctyi": 1, "to_icpsrctyi": 1, "from_statefip": 1, "to_statefip": 1, "distance_km": 1, "state_1900_1910_distances_km": 1, "fetch": 1, "neither": 1, "nor": 1, "mpre": 1, "m_namefrst": 1, "accord": 1, "niu": 1, "other": [1, 2, 12], "mfbplmatch": 1, "multi": 1, "search": 1, "special": 1, "simplifi": 1, "particular": [1, 2], "constraint": 1, "num_col": 1, "whose": 1, "templat": 1, "n": [1, 8, 9], "per": [1, 2, 8, 9, 10], "current": [1, 2, 10], "respect": [1, 7], "jw_col_templ": 1, "jw": 1, "pair": [1, 12], "equal_and_not_null_templ": 1, "final": [1, 2, 12], "comput": [1, 3, 7], "_namefrst": 1, "_bpl": 1, "_sex": 1, "25": 1, "nvl": 1, "sm_namefrst": 1, "sn_namefrst": 1, "sm_bpl": 1, "sn_bpl": 1, "sm_sex": 1, "sn_sex": 1, "pass": [1, 2, 7, 8], "default": [1, 2, 7, 8, 10], "flexibl": 1, "user": [1, 10], "write": [1, 10, 12], "own": [1, 2], "favor": 1, "reason": 1, "good": 1, "fallback": 1, "defin": [1, 7, 8, 9, 10], "spark": [1, 2, 5, 8, 9, 10, 12], "builtin": 1, "argument": [1, 10, 12], "namelast_jw_max": 1, "namelast1": 1, "namelast2": 1, "namelast3": 1, "abov": [1, 5], "extend": 1, "beyond": 1, "standard": [1, 11], "top": [1, 4], "level": [1, 4, 10], "everi": 1, "jw_f": [1, 2, 12], "father_namefrst": 1, "rais": [1, 3], "exponenti": 1, "squar": 1, "county_distance_squar": [1, 2, 12], "county_a": 1, "county_b": 1, "upper": 1, "gt": 1, "btwn": 1, "addl": 1, "var": [1, 2], "program": [1, 2, 7, 12], "report": [1, 4, 6, 10], "addl_var": 1, "check_val_expr": 1, "else_v": 1, "volumn": 1, "datasourc": [1, 2, 10], "yrimmig": 1, "immyear_diff": [1, 2, 9, 12], "To": [1, 5, 7, 10], "includ": [1, 2, 7, 9, 10], "train": [1, 4, 6, 8, 10], "independent_var": [1, 2, 12], "config": [1, 4, 7, 10, 12], "id_column": [1, 2], "_a": 1, "mult": 1, "exist": [1, 2, 10], "within": [1, 2, 6, 10, 11], "hh_train": [1, 2, 7, 10, 12], "hh": 1, "highest": [1, 2], "against": [1, 11], "ten": [1, 2], "tell": 2, "how": [2, 7], "descript": [2, 8, 10], "refer": 2, "here": [2, 7, 10, 12], "tutori": [2, 10], "script": [2, 6, 10], "discuss": 2, "readm": 2, "note": 2, "written": [2, 6], "toml": [2, 6, 10], "abl": 2, "json": [2, 10], "datasource_a": [2, 7], "datasource_b": [2, 7], "transform": [2, 4, 6, 7], "lowercase_strip": 2, "add_to_a": 2, "10": [2, 5, 12], "age_2": 2, "derived_from": 2, "expand_length": 2, "explod": [2, 7], "jaro_winkl": 2, "namelast_jw": [2, 12], "threshold": [2, 8, 12], "feature_nam": 2, "79": 2, "84": 2, "complex": 2, "machin": [2, 6, 7, 10, 12], "learn": [2, 6, 7, 10, 12], "probabilist": [2, 6], "drop_data_from_scored_match": 2, "us1900": 2, "us1900m_usa": 2, "p": 2, "parquet": [2, 7], "us1910": 2, "us1910m_usa": 2, "training_data_subset": 2, "serialp": 2, "rationalize_name_word": 2, "remove_qmark_hyphen": 2, "replace_apostroph": 2, "remove_suffix": 2, "remove_alternate_nam": 2, "condense_strip_whitespac": 2, "split": [2, 3, 4, 7, 8, 9, 12], "namefrst_std": [2, 11], "array_index": 2, "bpl_orig": 2, "divide_by_int": 2, "get_floor": 2, "statefip_h": 2, "output_typ": 2, "substitution_column": [2, 7, 11], "join_column": [2, 11], "join_valu": [2, 11], "substitution_fil": [2, 11], "name_std": [2, 11], "male": [2, 11], "femal": [2, 11], "feature_select": [2, 3, 7], "input_column": [2, 3, 9], "output_column": [2, 3, 9], "sql_condit": 2, "namelast_bigram": 2, "bigram": [2, 4], "bpl_clean": 2, "bpl_str": 2, "washington": 2, "bpl2_str": 2, "53": 2, "region": [2, 12], "attach_vari": 2, "region_dict": 2, "col_to_join_on": 2, "col_to_add": 2, "null_fil": 2, "col_typ": 2, "potential_matches_univers": [2, 7], "birthyr_3": 2, "namefrst_std_jw": [2, 12], "75": [2, 8, 12], "comparis": 2, "post": [2, 7], "hh_comparison": [2, 7], "threshold_expr": 2, "fetch_a": 2, "sex_equ": 2, "equal": [2, 11], "relate_a": [2, 9], "pipeline_featur": [2, 7, 9], "sex_region_interact": 2, "transformer_typ": [2, 9], "interact": [2, 4, 7, 12], "relatetyp": [2, 9], "bucket": [2, 7], "hit": [2, 10, 12], "scale_data": [2, 12], "training_data": [2, 10], "dependent_var": [2, 12], "score_with_model": [2, 12], "use_training_data_featur": [2, 7, 12], "split_by_id_a": [2, 12], "decis": [2, 4, 8, 12], "drop_duplicate_with_threshold_ratio": [2, 12], "n_training_iter": [2, 7, 12], "output_suspicious_td": [2, 12], "param_grid": [2, 12], "model_paramet": [2, 7, 8, 12], "random_forest": [2, 12], "maxdepth": [2, 8, 12], "numtre": [2, 8, 12], "005": 2, "threshold_ratio": [2, 8, 12], "logistic_regress": [2, 12], "50": [2, 12], "65": 2, "80": 2, "chosen_model": [2, 8, 12], "prediction_col": 2, "predict": [2, 12], "hh_col": 2, "hh_training_data_1900_1910": 2, "probit": [2, 4], "go": [2, 10], "your": [2, 5, 7, 10, 12], "uniqu": 2, "identifi": [2, 6, 12], "full": [2, 7, 12], "short": 2, "alphanumer": 2, "convert_ints_to_long": 2, "automat": [2, 5, 7], "long": [2, 11], "especi": 2, "assum": 2, "schema": 2, "sometim": 2, "term": 2, "bigint": 2, "thing": 2, "my_fil": 2, "subset": [2, 11], "limit": 2, "extract": 2, "new": [2, 12], "iv": 2, "v": 2, "vi": 2, "vii": 2, "viii": 2, "namelast_clean_bigram": [2, 3], "creat": [2, 6, 7, 9, 10, 11, 12], "fed": [2, 7], "prep": 2, "df": [2, 10], "men": 2, "describ": [2, 10], "newli": 2, "attempt": 2, "duplic": [2, 8], "row": 2, "conjuct": 2, "Will": 2, "conjunct": 2, "rang": [2, 9], "original_valu": 2, "plu": 2, "1870": 2, "expand": 2, "1867": 2, "1868": 2, "1869": 2, "1871": 2, "1872": 2, "1873": 2, "kept": 2, "keep": 2, "appropri": 2, "treat": [2, 9], "import": [2, 7, 10, 12], "dure": [2, 7], "hot": 2, "encod": [2, 3], "vector": [2, 9], "stage": 2, "well": 2, "upper_threshold": 2, "cannot": 2, "robust": 2, "ml": [2, 4, 8, 9], "typic": [2, 7], "leverag": 2, "api": [2, 6, 9], "piplin": 2, "regionf": 2, "sex_regionf_interact": 2, "immyear_caut": [2, 9], "myriad": 2, "explor": [2, 4, 6, 10], "part": [2, 7], "task": [2, 4, 6, 8, 12], "drop_duplicate_a": 2, "time": [2, 7, 10], "out": [2, 7, 12], "best": [2, 7], "smallest": 2, "possibl": 2, "ratio": [2, 8], "beta": [2, 8], "test": [2, 7, 12], "model_explor": [2, 10, 12], "hyper": [2, 6, 12], "paramet": [2, 6, 7, 8, 10, 12], "eval": 2, "skip": [2, 7], "apply_model": 2, "run_all_step": [2, 10, 12], "command": [2, 6, 10, 12], "try": 2, "creation": 2, "iter": 2, "scale": 2, "error": [2, 9], "1900": [2, 12], "about": [2, 10, 12], "1930": [2, 12], "1940": [2, 12], "fail": 2, "were": 2, "sure": [2, 5, 10], "scratch": 2, "although": 2, "know": 2, "haven": 2, "could": 2, "save": [2, 7, 12], "small": 2, "amount": 2, "process": [2, 6, 10], "repeatedli": 2, "help": [2, 7, 10], "neg": [2, 4, 6], "area": 2, "coverag": 2, "increas": [2, 9], "represent": [2, 7], "ensur": 2, "group": [2, 7], "a304bt": 2, "three": [2, 7], "b200": 2, "c201": 2, "d425": 2, "perform": [2, 6, 7, 11], "feature_import": [2, 7, 12], "coeffici": [2, 7], "enabl": [2, 7, 10], "srace": [2, 9, 12], "race_interacted_srac": [2, 9, 12], "hits2": [2, 12], "exact_mult": [2, 12], "ncount": [2, 3, 12], "ncount2": [2, 3, 12], "f_interacted_jw_f": [2, 12], "f_caution": [2, 12], "f_pre": [2, 12], "fbplmatch": [2, 12], "m_interacted_jw_m": [2, 9, 12], "jw_m": [2, 9, 12], "m_pre": [2, 9, 12], "mbplmatch": [2, 12], "sp_interacted_jw_sp": [2, 12], "jw_sp": [2, 12], "sp_pre": [2, 12], "mi": [2, 12], "fsoundex": [2, 12], "lsoundex": [2, 12], "oth": [2, 12], "imm_interacted_immyear_caut": [2, 12], "1900_1910_training_data_20191023": 2, "jw_max_a": 2, "jw_max_b": 2, "f1_match": 2, "f2_match": 2, "byrdifcat": 2, "racematch": 2, "bplmatch": 2, "imm_interacted_bplmatch": 2, "sexmatch": 2, "relatetype_interacted_relatematch": 2, "checkpoint": 3, "override_column_a": 3, "override_column_b": 3, "set_value_column_a": 3, "set_value_column_b": 3, "no_first_pad": 3, "don": 3, "prepend": 3, "provid": [3, 6, 7, 9, 10], "namefrst_unstd_bigram": 3, "namelast_frst_bigram": 3, "namelast_clean_soundex": 3, "input_col": 3, "output_col": 3, "expon": 3, "introduct": 4, "overview": 4, "instal": 4, "pypi": 4, "preprocess": [4, 6, 10, 12], "model": [4, 6, 10], "run": [4, 5, 6, 7, 12], "librari": [4, 6], "mode": [4, 5, 12], "advanc": 4, "workflow": 4, "export": [4, 7, 10], "featur": [4, 6, 7, 8, 10], "reus": 4, "basic": 4, "map": [4, 7, 9], "substitut": [4, 7], "block": [4, 7], "comparison": [4, 7], "pipelin": 4, "substr": 4, "ons": 4, "aggreg": 4, "union": 4, "soundex": 4, "power": 4, "regex": 4, "random": [4, 8], "forest": [4, 8], "logist": [4, 8], "regress": [4, 8], "tree": [4, 8], "gradient": [4, 8], "boost": [4, 8], "system": 5, "python": [5, 6, 10], "java": 5, "integr": 5, "apach": 5, "via": [5, 6], "pyspark": [5, 8, 9, 10], "packag": 5, "org": 5, "latest": 5, "pip": 5, "easiest": [5, 10], "through": [5, 7, 9, 10], "instruct": [5, 10], "But": 5, "clone": 5, "github": 5, "repositori": 5, "root": 5, "project": 5, "directori": [5, 10, 12], "develop": [5, 6], "e": 5, "dev": 5, "edit": 5, "made": 5, "built": 5, "tool": [5, 6], "line": [6, 10], "share": 6, "characterist": [6, 7], "correspond": [6, 7], "real": 6, "world": 6, "determinist": [6, 7], "rule": [6, 7], "algorithm": [6, 7], "At": [6, 7], "been": 6, "unit": 6, "census": 6, "hierarch": [6, 10], "structur": 6, "nest": 6, "howev": [6, 12], "tailor": 6, "ignor": 6, "common": [6, 7, 12], "highli": [6, 7], "languag": 6, "further": [6, 12], "broken": 6, "smaller": 6, "sequenc": 6, "linkrun": [6, 10], "prepar": [6, 7, 10], "research": 6, "experi": 6, "understand": 6, "tune": [6, 12], "relationship": 6, "varieti": 7, "normal": 7, "abbrevi": [7, 11], "regist": [7, 10], "datafram": [7, 10, 12], "request": 7, "classif": [7, 8], "metadata": 7, "introspect": 7, "ingest": 7, "inspect": 7, "mani": [7, 10], "aspect": [7, 10], "extens": 7, "longest": 7, "definit": 7, "reduc": 7, "drastic": 7, "improv": 7, "runtim": 7, "separ": 7, "total": 7, "potential_match": [7, 10], "satisfi": 7, "elig": 7, "support": [7, 8], "reshap": 7, "thought": 7, "ahead": 7, "chosen": 7, "experiment": [7, 10], "focus": 7, "demograph": 7, "moment": 7, "veri": [7, 12], "anyon": 7, "percent": 7, "remain": 7, "popul": 7, "pull": 7, "fix": 7, "width": 7, "crosswalk": 7, "construct": 7, "alpha": 8, "hyperparamet": [8, 12], "de": 8, "param": [8, 12], "label": 8, "doc": [8, 9], "commonli": 8, "explan": 8, "randomforestclassifi": 8, "depth": 8, "20": 8, "featuresubsetstrategi": 8, "node": 8, "auto": 8, "onethird": 8, "sqrt": 8, "log2": 8, "15": 8, "generalizedlinearregress": 8, "famili": 8, "binomi": 8, "85": [8, 10], "logisticregress": 8, "decisiontreeclassifi": 8, "mininstancespernod": 8, "caus": 8, "left": 8, "right": [8, 10], "discard": 8, "maxbin": 8, "bin": 8, "discret": 8, "continu": [8, 9, 12], "gbtclassifi": 8, "mother": 9, "point": [9, 12], "With": 9, "x": [9, 10], "y": 9, "hold": 9, "except": 9, "strictli": 9, "inf": 9, "explicitli": 9, "cover": 9, "doubl": 9, "outsid": 9, "job": 10, "high": 10, "class": 10, "handl": 10, "main": 10, "complet": 10, "access": [10, 12], "link_run": 10, "factori": 10, "sparkfactori": 10, "load_config": 10, "load_conf_fil": 10, "sparksess": 10, "now": 10, "let": 10, "load": 10, "our": 10, "my_conf": 10, "lr": 10, "prep_step": 10, "get_step": 10, "enumer": 10, "print": 10, "input_table_nam": 10, "output_table_nam": 10, "run_step": 10, "get_tabl": 10, "matches_df": 10, "hh_model_explor": 10, "method": [10, 12], "interfac": 10, "easili": 10, "conveni": 10, "adjust": 10, "set_loc": 10, "set_num_cor": 10, "set_executor_memori": 10, "5g": 10, "ll": 10, "dictionari": 10, "modul": 10, "pleas": 10, "reproduc": 10, "consol": 10, "cpu": 10, "usag": 10, "h": 10, "executor_memori": [10, 12], "execute_task": 10, "execute_command": 10, "conf": [10, 12], "show": 10, "messag": 10, "exit": 10, "memori": 10, "executor": 10, "begin": 10, "execut": 10, "seri": 10, "excute_command": 10, "filepath": 10, "sai": 10, "fullcount_1870_1880": 10, "pattern": 10, "full_count_1870_1880": 10, "prompt": 10, "enter": 10, "text": 10, "unstabl": 10, "topic": 10, "analyz": [10, 12], "set_preexisting_t": 10, "x_persist": 10, "borrow_t": 10, "get_task": 10, "set_print_sql": 10, "x_sql": 10, "x_sqlf": 10, "ipython": 10, "showf": 10, "x_summari": 10, "desc": 10, "x_crosswalk": 10, "x_tab": 10, "q": [10, 12], "x_hh_tfam": 10, "x_tfam": 10, "drop_al": 10, "reload": 10, "x_hh_tfam_2a": 10, "x_tfam_raw": 10, "drop_all_prc": 10, "x_hh_tfam_2b": 10, "x_union": 10, "drop_all_temp": 10, "x_load": 10, "get_set": 10, "set_link_task": 10, "x_parquet_from_csv": 10, "organ": 10, "hierarchi": 10, "five": 10, "hh_match": 10, "someth": 10, "choic": 10, "preexist": 10, "prepped_df_a": 10, "prepped_df_b": 10, "raw_df_b": 10, "raw_df_a": 10, "training_featur": [10, 12], "scored_potential_match": 10, "potential_matches_prep": 10, "exploded_df_b": 10, "exploded_df_a": 10, "predicted_match": 10, "hh_training_featur": [10, 12], "hh_training_data": 10, "hh_predicted_match": 10, "hh_scored_potential_match": 10, "hh_potential_match": 10, "hh_blocked_match": 10, "hh_potential_matchs_prep": 10, "model_eval_training_vector": 10, "model_eval_training_data": 10, "model_eval_repeat_fp": 10, "model_eval_training_featur": 10, "model_eval_training_result": 10, "model_eval_repeat_fn": 10, "hh_model_eval_training_vector": 10, "hh_model_eval_repeat_fp": 10, "hh_model_eval_repeat_fn": 10, "hh_model_eval_training_result": 10, "hh_model_eval_training_featur": 10, "hh_model_eval_training_data": 10, "persist": 10, "hidden": 10, "intermedi": 10, "yet": 10, "databas": 10, "tablenam": 10, "istemporari": 10, "task_nam": 10, "num": 10, "finish": 10, "By": 10, "put": [10, 12], "launch": [10, 12], "my": [10, 12], "subhead": 11, "suppli": 11, "regex_word_replac": 11, "variant": 11, "av": 11, "7th": 11, "swap": 11, "still": 11, "anywher": 11, "proceed": 11, "street_unstd": 11, "dir": 11, "substitutions_street_abbrev": 11, "span": 12, "1920": 12, "deriv": 12, "necessari": 12, "scenario": 12, "copi": 12, "use_potential_matches_featur": 12, "full_count_1900_1910": 12, "50g": 12, "ask": 12, "arg": 12, "partit": 12, "training_data_1900_1910_hlink_featur": 12, "might": 12, "shut": 12, "framework": 12, "etc": 12, "relev": 12, "matrix": 12, "implement": 12, "regular": 12, "training_data_1900_1910": 12, "weren": 12, "ident": 12, "manual": 12, "updat": 12, "isn": 12, "analysi": 12, "training_result": 12, "hh_training_result": 12, "1900_1910_training_result": 12, "repeat_fp": 12, "repeat_fn": 12, "hh_repeat_fp": 12, "hh_repeat_fn": 12, "1900_1910_potential_fp": 12, "1900_1910_potential_fn": 12, "prefer": 12, "ve": 12}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"column": [0, 2], "map": [0, 2], "transform": [0, 1, 3, 9], "add_to_a": 0, "concat_to_a": 0, "concat_to_b": 0, "lowercase_strip": 0, "rationalize_name_word": 0, "remove_qmark_hyphen": 0, "remove_punctu": 0, "replace_apostroph": 0, "remove_alternate_nam": 0, "remove_suffix": 0, "remove_stop_word": 0, "remove_prefix": 0, "condense_strip_whitespac": 0, "remove_one_letter_nam": 0, "split": 0, "array_index": 0, "substr": 0, "divide_by_int": 0, "when_valu": 0, "get_floor": 0, "comparison": [1, 2], "type": [1, 9], "add": 1, "ons": 1, "aggreg": 1, "featur": [1, 2, 3, 9, 12], "household": [1, 2, 7], "maximum_jaro_winkl": 1, "jaro_winkl": 1, "jaro_winkler_street": 1, "max_jaro_winkl": 1, "equal": 1, "f1_match": 1, "f2_match": 1, "not_equ": 1, "equals_as_int": 1, "all_equ": 1, "not_zero_and_not_equ": 1, "time": 1, "caution_comp_3": 1, "caution_comp_3_012": 1, "caution_comp_4": 1, "caution_comp_4_012": 1, "any_equ": 1, "either_are_1": 1, "either_are_0": 1, "second_gen_imm": 1, "rel_jaro_winkl": 1, "extra_children": 1, "jaro_winkler_r": 1, "sum": 1, "length_b": 1, "abs_diff": 1, "b_minus_a": 1, "geo_dist": 1, "fetch_a": 1, "fetch_b": 1, "present_both_year": 1, "neither_are_nul": 1, "present_and_matching_categor": 1, "present_and_not_equ": 1, "present_and_equal_categorical_in_univers": 1, "multi_jaro_winkler_search": 1, "sql_condit": [1, 3], "alia": 1, "power": [1, 3], "threshold": 1, "lower_threshold": 1, "upper_threshold": 1, "gt_threshold": 1, "btwn_threshold": 1, "look_at_addl_var": 1, "hit": 1, "hits2": 1, "exact_mult": 1, "jw_max_a": 1, "jw_max_b": 1, "configur": [2, 4, 7], "basic": 2, "config": 2, "file": 2, "advanc": [2, 12], "top": 2, "level": 2, "data": [2, 11, 12], "sourc": [2, 5], "filter": 2, "substitut": [2, 11], "select": [2, 3], "potenti": [2, 12], "match": [2, 7], "univers": 2, "block": 2, "pipelin": [2, 9], "gener": [2, 9, 12], "train": [2, 7, 12], "model": [2, 7, 8, 12], "bigram": 3, "arrai": 3, "union": 3, "soundex": 3, "welcom": 4, "hlink": [4, 10], "": 4, "document": 4, "api": 4, "instal": 5, "requir": 5, "from": 5, "pypi": 5, "introduct": 6, "overview": [6, 7], "link": [7, 10, 12], "task": [7, 10], "preprocess": 7, "step": [7, 10], "relat": 7, "section": 7, "explor": [7, 12], "report": 7, "random_forest": 8, "probit": 8, "logistic_regress": 8, "decision_tre": 8, "gradient_boosted_tre": 8, "interact": [9, 10], "bucket": 9, "run": 10, "us": 10, "librari": 10, "mode": 10, "start": 10, "program": 10, "exampl": [10, 12], "workflow": [10, 12], "1": 11, "tabl": 11, "regex": 11, "word": 11, "replac": 11, "export": 12, "after": 12, "reus": 12, "differ": 12, "year": 12, "ml": 12, "list": 12, "fals": 12, "posit": 12, "neg": 12, "fp": 12, "fn": 12}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 60}, "alltitles": {"Column mapping transforms": [[0, "column-mapping-transforms"]], "add_to_a": [[0, "add-to-a"]], "concat_to_a": [[0, "concat-to-a"]], "concat_to_b": [[0, "concat-to-b"]], "lowercase_strip": [[0, "lowercase-strip"]], "rationalize_name_words": [[0, "rationalize-name-words"]], "remove_qmark_hyphen": [[0, "remove-qmark-hyphen"]], "remove_punctuation": [[0, "remove-punctuation"]], "replace_apostrophe": [[0, "replace-apostrophe"]], "remove_alternate_names": [[0, "remove-alternate-names"]], "remove_suffixes": [[0, "remove-suffixes"]], "remove_stop_words": [[0, "remove-stop-words"]], "remove_prefixes": [[0, "remove-prefixes"]], "condense_strip_whitespace": [[0, "condense-strip-whitespace"]], "remove_one_letter_names": [[0, "remove-one-letter-names"]], "split": [[0, "split"]], "array_index": [[0, "array-index"]], "mapping": [[0, "mapping"]], "substring": [[0, "substring"]], "divide_by_int": [[0, "divide-by-int"]], "when_value": [[0, "when-value"]], "get_floor": [[0, "get-floor"]], "Comparison types, transform add-ons, aggregate features, and household aggregate features": [[1, "comparison-types-transform-add-ons-aggregate-features-and-household-aggregate-features"]], "Comparison types": [[1, "comparison-types"]], "maximum_jaro_winkler": [[1, "maximum-jaro-winkler"]], "jaro_winkler": [[1, "jaro-winkler"]], "jaro_winkler_street": [[1, "jaro-winkler-street"]], "max_jaro_winkler": [[1, "max-jaro-winkler"]], "equals": [[1, "equals"]], "f1_match": [[1, "f1-match"]], "f2_match": [[1, "f2-match"]], "not_equals": [[1, "not-equals"]], "equals_as_int": [[1, "equals-as-int"]], "all_equals": [[1, "all-equals"]], "not_zero_and_not_equals": [[1, "not-zero-and-not-equals"]], "or": [[1, "or"]], "and": [[1, "and"]], "times": [[1, "times"]], "caution_comp_3": [[1, "caution-comp-3"]], "caution_comp_3_012": [[1, "caution-comp-3-012"]], "caution_comp_4": [[1, "caution-comp-4"]], "caution_comp_4_012": [[1, "caution-comp-4-012"]], "any_equals": [[1, "any-equals"]], "either_are_1": [[1, "either-are-1"]], "either_are_0": [[1, "either-are-0"]], "second_gen_imm": [[1, "second-gen-imm"]], "rel_jaro_winkler": [[1, "rel-jaro-winkler"]], "extra_children": [[1, "extra-children"]], "jaro_winkler_rate": [[1, "jaro-winkler-rate"]], "sum": [[1, "sum"]], "length_b": [[1, "length-b"]], "abs_diff": [[1, "abs-diff"]], "b_minus_a": [[1, "b-minus-a"]], "geo_distance": [[1, "geo-distance"]], "fetch_a": [[1, "fetch-a"]], "fetch_b": [[1, "fetch-b"]], "present_both_years": [[1, "present-both-years"]], "neither_are_null": [[1, "neither-are-null"]], "present_and_matching_categorical": [[1, "present-and-matching-categorical"]], "present_and_not_equal": [[1, "present-and-not-equal"]], "present_and_equal_categorical_in_universe": [[1, "present-and-equal-categorical-in-universe"]], "multi_jaro_winkler_search": [[1, "multi-jaro-winkler-search"]], "sql_condition": [[1, "sql-condition"], [3, "sql-condition"]], "Feature add-ons": [[1, "feature-add-ons"]], "alias": [[1, "alias"]], "power": [[1, "power"], [3, "power"]], "threshold": [[1, "threshold"]], "lower_threshold": [[1, "lower-threshold"]], "upper_threshold": [[1, "upper-threshold"]], "gt_threshold": [[1, "gt-threshold"]], "btwn_threshold": [[1, "btwn-threshold"]], "look_at_addl_var": [[1, "look-at-addl-var"]], "Aggregate Features": [[1, "aggregate-features"]], "hits": [[1, "hits"]], "hits2": [[1, "hits2"]], "exact_mult": [[1, "exact-mult"]], "Household Aggregate Features": [[1, "household-aggregate-features"]], "jw_max_a": [[1, "jw-max-a"]], "jw_max_b": [[1, "jw-max-b"]], "Configuration": [[2, "configuration"]], "Basic Config File": [[2, "basic-config-file"]], "Advanced Config File": [[2, "advanced-config-file"]], "Top level configs": [[2, "top-level-configs"]], "Data sources": [[2, "data-sources"]], "Filter": [[2, "filter"]], "Column Mappings": [[2, "column-mappings"]], "Substitution Columns": [[2, "substitution-columns"]], "Feature Selections": [[2, "feature-selections"]], "Potential Matches Universe": [[2, "potential-matches-universe"]], "Blocking": [[2, "blocking"]], "Comparisons": [[2, "comparisons"]], "Household Comparisons": [[2, "household-comparisons"]], "Comparison Features": [[2, "comparison-features"]], "Pipeline-generated Features": [[2, "pipeline-generated-features"]], "Training and models": [[2, "training-and-models"]], "Household training and models": [[2, "household-training-and-models"]], "Feature Selection transforms": [[3, "feature-selection-transforms"]], "bigrams": [[3, "bigrams"]], "array": [[3, "array"]], "union": [[3, "union"]], "soundex": [[3, "soundex"]], "Welcome to hlink\u2019s documentation!": [[4, "welcome-to-hlink-s-documentation"]], "Configuration API": [[4, "configuration-api"], [4, null]], "Installation": [[5, "installation"]], "Requirements": [[5, "requirements"]], "Installing from PyPI": [[5, "installing-from-pypi"]], "Installing from source": [[5, "installing-from-source"]], "Introduction": [[6, "introduction"]], "Overview": [[6, "overview"], [7, "overview"], [7, "id1"], [7, "id4"], [7, "id7"], [7, "id10"], [7, "id13"]], "Link Tasks": [[7, "link-tasks"]], "Preprocessing": [[7, "preprocessing"]], "Task steps": [[7, "task-steps"], [7, "id2"], [7, "id5"], [7, "id8"], [7, "id11"], [7, "id14"]], "Related Configuration Sections": [[7, "related-configuration-sections"], [7, "id3"], [7, "id6"], [7, "id9"], [7, "id12"], [7, "id15"]], "Training and Household Training": [[7, "training-and-household-training"]], "Matching": [[7, "matching"]], "Household Matching": [[7, "household-matching"]], "Model Exploration and Household Model Exploration": [[7, "model-exploration-and-household-model-exploration"]], "Reporting": [[7, "reporting"]], "Models": [[8, "models"]], "random_forest": [[8, "random-forest"]], "probit": [[8, "probit"]], "logistic_regression": [[8, "logistic-regression"]], "decision_tree": [[8, "decision-tree"]], "gradient_boosted_trees": [[8, "gradient-boosted-trees"]], "Pipeline generated features": [[9, "pipeline-generated-features"]], "Transformer types": [[9, "transformer-types"]], "interaction": [[9, "interaction"]], "bucketizer": [[9, "bucketizer"]], "Running hlink": [[10, "running-hlink"]], "Using hlink as a Library": [[10, "using-hlink-as-a-library"]], "Interactive Mode": [[10, "interactive-mode"]], "Starting the program": [[10, "starting-the-program"]], "Running Linking Tasks and Steps": [[10, "running-linking-tasks-and-steps"]], "Example interactive mode workflow": [[10, "example-interactive-mode-workflow"]], "Substitutions": [[11, "substitutions"]], "1:1 substitution by data table": [[11, "substitution-by-data-table"]], "Substitution by regex word replace": [[11, "substitution-by-regex-word-replace"]], "Advanced Workflow Examples": [[12, "advanced-workflow-examples"]], "Export training data after generating features to reuse in different linking years": [[12, "export-training-data-after-generating-features-to-reuse-in-different-linking-years"]], "Example training data export with generated ML features": [[12, "example-training-data-export-with-generated-ml-features"]], "ML model exploration and export of lists of potential false positives/negatives in training data": [[12, "ml-model-exploration-and-export-of-lists-of-potential-false-positives-negatives-in-training-data"]], "Example model exploration and FP/FN export workflow": [[12, "example-model-exploration-and-fp-fn-export-workflow"]]}, "indexentries": {}})
\ No newline at end of file
diff --git a/docs/substitutions.html b/docs/substitutions.html
index cfa7602..9255964 100644
--- a/docs/substitutions.html
+++ b/docs/substitutions.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Substitutions &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Models" href="models.html" />
@@ -35,7 +32,7 @@
           <div class="body" role="main">
             
   <section id="substitutions">
-<h1>Substitutions<a class="headerlink" href="#substitutions" title="Permalink to this heading">¶</a></h1>
+<h1>Substitutions<a class="headerlink" href="#substitutions" title="Link to this heading">¶</a></h1>
 <ul class="simple">
 <li><p>Parent header: <code class="docutils literal notranslate"><span class="pre">substitution_columns</span></code></p></li>
 <li><p>Subheader name: <code class="docutils literal notranslate"><span class="pre">substitutions</span></code></p></li>
@@ -48,7 +45,7 @@ <h1>Substitutions<a class="headerlink" href="#substitutions" title="Permalink to
 </ul>
 <p>You must supply a substitution file and either specify <code class="docutils literal notranslate"><span class="pre">regex_word_replace=true</span></code> or supply a join value.</p>
 <section id="substitution-by-data-table">
-<h2>1:1 substitution by data table<a class="headerlink" href="#substitution-by-data-table" title="Permalink to this heading">¶</a></h2>
+<h2>1:1 substitution by data table<a class="headerlink" href="#substitution-by-data-table" title="Link to this heading">¶</a></h2>
 <p>Performs a 1:1 replacement on a filtered subset of the data table.  If the input column data equals a value in the first column of the substitution file, it is replaced with the data in the second column of the substitution file.  Used to replace variant name forms with standardized name forms, filtering on sex.</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -74,7 +71,7 @@ <h2>1:1 substitution by data table<a class="headerlink" href="#substitution-by-d
 </div>
 </section>
 <section id="substitution-by-regex-word-replace">
-<h2>Substitution by regex word replace<a class="headerlink" href="#substitution-by-regex-word-replace" title="Permalink to this heading">¶</a></h2>
+<h2>Substitution by regex word replace<a class="headerlink" href="#substitution-by-regex-word-replace" title="Link to this heading">¶</a></h2>
 <p>Performs word replacement within a column’s data string (such as replacing the abbreviation <code class="docutils literal notranslate"><span class="pre">Ave.</span></code> in the string <code class="docutils literal notranslate"><span class="pre">7th</span> <span class="pre">Ave.</span></code> with <code class="docutils literal notranslate"><span class="pre">Avenue</span></code> to create <code class="docutils literal notranslate"><span class="pre">7th</span> <span class="pre">Avenue</span></code>).</p>
 <ul class="simple">
 <li><p>Attributes:</p>
@@ -173,7 +170,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/docs/use_examples.html b/docs/use_examples.html
index 27fd572..c1bb72a 100644
--- a/docs/use_examples.html
+++ b/docs/use_examples.html
@@ -1,19 +1,16 @@
-
 <!DOCTYPE html>
 
-<html lang="en">
+<html lang="en" data-content_root="./">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
 
     <title>Advanced Workflow Examples &#8212; hlink 3.5.2 documentation</title>
-    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
-    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
-    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-    <script src="_static/jquery.js"></script>
-    <script src="_static/underscore.js"></script>
-    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
-    <script src="_static/doctools.js"></script>
+    <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
+    <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
+    <script src="_static/documentation_options.js?v=52b624fa"></script>
+    <script src="_static/doctools.js?v=888ff710"></script>
+    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
     <link rel="next" title="Configuration" href="config.html" />
@@ -35,14 +32,14 @@
           <div class="body" role="main">
             
   <section id="advanced-workflow-examples">
-<h1>Advanced Workflow Examples<a class="headerlink" href="#advanced-workflow-examples" title="Permalink to this heading">¶</a></h1>
+<h1>Advanced Workflow Examples<a class="headerlink" href="#advanced-workflow-examples" title="Link to this heading">¶</a></h1>
 <section id="export-training-data-after-generating-features-to-reuse-in-different-linking-years">
-<h2>Export training data after generating features to reuse in different linking years<a class="headerlink" href="#export-training-data-after-generating-features-to-reuse-in-different-linking-years" title="Permalink to this heading">¶</a></h2>
+<h2>Export training data after generating features to reuse in different linking years<a class="headerlink" href="#export-training-data-after-generating-features-to-reuse-in-different-linking-years" title="Link to this heading">¶</a></h2>
 <p>It is common to have a single training data set that spans two linked years, which is then used to train a model that is applied to a different set of linked years.  For example, we have a training data set that spans linked individuals from the 1900 census to the 1910 census.  We use this training data to predict links in the full count 1900-1910 linking run, but we also use this training data to link year pairs 1910-1920, 1920-1930, and 1930-1940.</p>
 <p>When this training data set is used for the years it was derived from, the only columns necessary are the HISTIDs identifying the individuals in the data and the dependent variable (usually a boolean <code class="docutils literal notranslate"><span class="pre">match</span></code> column) for the model training. Features for the machine learning model generation are created from the source data available in the full count run.</p>
 <p>However, when this training data set is used for other years, the program does not have access to the source full count files, and can’t generate the ML features from the given data.  In this scenario, you would need to save a copy of the <code class="docutils literal notranslate"><span class="pre">training_features</span></code> and <code class="docutils literal notranslate"><span class="pre">hh_training_features</span></code> Spark tables to .csv so you can point to that in the other year pair runs, and indicate the <code class="docutils literal notranslate"><span class="pre">use_potential_matches_features</span> <span class="pre">=</span> <span class="pre">true</span></code> flag in both the <code class="docutils literal notranslate"><span class="pre">training</span></code> and <code class="docutils literal notranslate"><span class="pre">hh_training</span></code> sections of the configuration.</p>
 <section id="example-training-data-export-with-generated-ml-features">
-<h3>Example training data export with generated ML features<a class="headerlink" href="#example-training-data-export-with-generated-ml-features" title="Permalink to this heading">¶</a></h3>
+<h3>Example training data export with generated ML features<a class="headerlink" href="#example-training-data-export-with-generated-ml-features" title="Link to this heading">¶</a></h3>
 <ol>
 <li><p>Create a config file and put it in your hlink config directory.</p></li>
 <li><p>Launch the hlink program in interactive mode:</p>
@@ -95,11 +92,11 @@ <h3>Example training data export with generated ML features<a class="headerlink"
 </section>
 </section>
 <section id="ml-model-exploration-and-export-of-lists-of-potential-false-positives-negatives-in-training-data">
-<h2>ML model exploration and export of lists of potential false positives/negatives in training data<a class="headerlink" href="#ml-model-exploration-and-export-of-lists-of-potential-false-positives-negatives-in-training-data" title="Permalink to this heading">¶</a></h2>
+<h2>ML model exploration and export of lists of potential false positives/negatives in training data<a class="headerlink" href="#ml-model-exploration-and-export-of-lists-of-potential-false-positives-negatives-in-training-data" title="Link to this heading">¶</a></h2>
 <p><code class="docutils literal notranslate"><span class="pre">hlink</span></code> accepts a matrix of ML models and hyper-parameters to run train/test splits for you, and outputs data you can use to select and tune your models.  You can see example <code class="docutils literal notranslate"><span class="pre">training</span></code> and <code class="docutils literal notranslate"><span class="pre">hh_training</span></code> configuration sections that implement this in the <a class="reference external" href="config.html#training-and-models">training</a> and <a class="reference external" href="config.html#household-training-and-models">household training</a> sections of the configuration documentation.</p>
 <p>The model exploration link task also allows you to export lists of potential false positives (FPs) and false negatives (FNs) in your training data.  This is calculated when running the train/test splits in the regular model exploration tasks if the <code class="docutils literal notranslate"><span class="pre">output_suspicious_TD</span></code> flag is true.</p>
 <section id="example-model-exploration-and-fp-fn-export-workflow">
-<h3>Example model exploration and FP/FN export workflow<a class="headerlink" href="#example-model-exploration-and-fp-fn-export-workflow" title="Permalink to this heading">¶</a></h3>
+<h3>Example model exploration and FP/FN export workflow<a class="headerlink" href="#example-model-exploration-and-fp-fn-export-workflow" title="Link to this heading">¶</a></h3>
 <ol>
 <li><p>Create a config file that has a <code class="docutils literal notranslate"><span class="pre">training</span></code> and/or <code class="docutils literal notranslate"><span class="pre">hh_training</span></code> section with model parameters to explore. For example:</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">training</span><span class="p">]</span>
@@ -237,7 +234,7 @@ <h3 id="searchlabel">Quick search</h3>
       &copy;2019-2022, IPUMS.
       
       |
-      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
+      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.2.6</a>
       &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
       
       |
diff --git a/hlink/linking/core/comparison.py b/hlink/linking/core/comparison.py
index 769d4ee..8d952f1 100755
--- a/hlink/linking/core/comparison.py
+++ b/hlink/linking/core/comparison.py
@@ -10,7 +10,6 @@ def get_comparison_leaves(comp):
     comp_leaves = []
 
     def _get_comp_leaf(comp, comp_leaves):
-
         if "comp_a" in comp:
             _get_comp_leaf(comp["comp_a"], comp_leaves)
             _get_comp_leaf(comp["comp_b"], comp_leaves)
diff --git a/hlink/linking/core/comparison_feature.py b/hlink/linking/core/comparison_feature.py
index 01a2b65..19a2150 100755
--- a/hlink/linking/core/comparison_feature.py
+++ b/hlink/linking/core/comparison_feature.py
@@ -522,7 +522,7 @@ def generate_comparison_feature(feature, id_col, include_as=False):
             f"multi_jaro_winkler_search with alias {feature.get('alias')}: there are {len(tuples)} subcomparisons"
         )
         sub_exprs = []
-        for (i, j) in tuples:
+        for i, j in tuples:
             jw_col_a = jw_template.replace("{n}", str(i))
             jw_col_b = jw_template.replace("{n}", str(j))
 
diff --git a/hlink/linking/link_task.py b/hlink/linking/link_task.py
index a49e101..6c327d8 100755
--- a/hlink/linking/link_task.py
+++ b/hlink/linking/link_task.py
@@ -63,7 +63,7 @@ def run_all_steps(self) -> None:
         """Run all steps in order."""
         logging.info(f"Running all steps for task {self.display_name}")
         start_all = timer()
-        for (i, step) in enumerate(self.get_steps()):
+        for i, step in enumerate(self.get_steps()):
             print(f"Running step {i}: {step}")
             logging.info(f"Running step {i}: {step}")
             step.run()
diff --git a/hlink/linking/matching/link_step_explode.py b/hlink/linking/matching/link_step_explode.py
index e92962c..9b7b744 100644
--- a/hlink/linking/matching/link_step_explode.py
+++ b/hlink/linking/matching/link_step_explode.py
@@ -65,7 +65,6 @@ def _run(self):
         )
 
     def _explode(self, df, comparisons, comparison_features, blocking, id_column, is_a):
-
         # comp_feature_names, dist_features_to_run, feature_columns = comparison_core.get_feature_specs_from_comp(
         #     comparisons, comparison_features
         # )
diff --git a/hlink/linking/preprocessing/link_step_register_raw_dfs.py b/hlink/linking/preprocessing/link_step_register_raw_dfs.py
index dc29591..9f13756 100644
--- a/hlink/linking/preprocessing/link_step_register_raw_dfs.py
+++ b/hlink/linking/preprocessing/link_step_register_raw_dfs.py
@@ -168,7 +168,7 @@ def _filter_dataframe(self, config, a_or_b):
     def _convert_ints_to_longs(self, df: DataFrame) -> DataFrame:
         df_casted = df
 
-        for (column, datatype) in df.dtypes:
+        for column, datatype in df.dtypes:
             if datatype == "int":
                 df_casted = df_casted.withColumn(column, col(column).cast("long"))
 
@@ -184,7 +184,6 @@ def _check_for_all_spaces_unrestricted_file(self, df_name):
         df_len = df.count()
 
         for column_name in string_cols:
-
             if ("name" in str.lower(column_name)) or (
                 "street" in str.lower(column_name)
             ):
diff --git a/hlink/scripts/lib/linking_ops.py b/hlink/scripts/lib/linking_ops.py
index 13c6dbf..9e1ee19 100644
--- a/hlink/scripts/lib/linking_ops.py
+++ b/hlink/scripts/lib/linking_ops.py
@@ -14,7 +14,7 @@ def show_step_info(link_task, link_run):
     steps = link_task.get_steps()
     tables = link_run.known_tables
 
-    for (i, step) in enumerate(steps):
+    for i, step in enumerate(steps):
         print(Fore.GREEN + f"step {i}: {step}" + Style.RESET_ALL)
 
         print("\tTables used:")
diff --git a/hlink/scripts/main.py b/hlink/scripts/main.py
index 2fd47fb..8bbf659 100755
--- a/hlink/scripts/main.py
+++ b/hlink/scripts/main.py
@@ -9,7 +9,7 @@
 import os
 from pathlib import Path
 import json
-import pkg_resources
+import importlib.metadata
 import readline
 import sys
 import traceback
@@ -74,7 +74,7 @@ def load_conf(conf_name, user):
 def cli():
     """Called by the hlink script."""
     if "--version" in sys.argv:
-        version = pkg_resources.get_distribution("hlink").version
+        version = importlib.metadata.version("hlink")
         print(f"Hlink version: {version}")
         return
     args = _parse_args()
@@ -239,7 +239,7 @@ def _setup_logging(conf):
     user = getpass.getuser()
     session_id = uuid.uuid4().hex
     conf_name = Path(conf["conf_path"]).stem
-    hlink_version = pkg_resources.get_distribution("hlink").version
+    hlink_version = importlib.metadata.version("hlink")
 
     log_file = log_dir / f"{conf_name}-{session_id}.log"
 
diff --git a/hlink/scripts/main_loop.py b/hlink/scripts/main_loop.py
index 314617e..973f144 100755
--- a/hlink/scripts/main_loop.py
+++ b/hlink/scripts/main_loop.py
@@ -218,7 +218,8 @@ def do_get_steps(self, split_args):
     def do_run_step(self, split_args):
         """Run the specified linking step.
         Arg 1: step number (an integer)
-        Hint: Use the command 'get_steps' to fetch a list of all the linking steps for the current task."""
+        Hint: Use the command 'get_steps' to fetch a list of all the linking steps for the current task.
+        """
         print(f"Link task: {self.current_link_task}")
         step_num = int(split_args[0])
         self.current_link_task.run_step(step_num)
diff --git a/pyproject.toml b/pyproject.toml
index 8e11ff1..dbf7d03 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,28 +11,35 @@ requires-python = ">=3.10"
 license = {file = "LICENSE.txt"}
 classifiers = [
     "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
     "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
 ]
 dependencies = [
     "colorama>=0.4.6",
-    "ipython~=8.3.0",
-    "Jinja2~=3.1.0",
+    "ipython>=8.3.0",
+    "Jinja2>=3.1.0",
     "numpy>=1.22.0",
-    "pandas>=1.4.0,<2",
+    "pandas>=1.4.0",
     "pyspark~=3.5.0",
-    "scikit-learn~=1.1.0",
-    "toml~=0.10.0",
+    "scikit-learn>=1.1.0",
+    "toml>=0.10.0",
 ]
 
 [project.optional-dependencies]
 dev = [
-    "pytest~=7.1.0",
-    "black~=22.0",
-    "flake8~=5.0",
-    "pre-commit~=2.0",
-    "twine~=4.0",
+    "pytest>=7.1.0",
+    "black>=23.0",
+    "flake8>=5.0",
+    "pre-commit>=2.0",
+    "twine>=4.0",
     "build>=0.6",
-    "sphinx==5.1.1",
+    # These are pinned so tightly because their version numbers appear in the docs.
+    # So if you use a different version, it creates a huge diff in the docs.
+    # TODO: auto-generate docs on push to GitHub instead of committing them to the
+    # repo.
+    "sphinx==7.2.6",
     "recommonmark==0.7.1",
 ]
 
diff --git a/sphinx-docs/conf.py b/sphinx-docs/conf.py
index c7325aa..fe3c5ba 100644
--- a/sphinx-docs/conf.py
+++ b/sphinx-docs/conf.py
@@ -4,7 +4,7 @@
 # list see the documentation:
 # http://www.sphinx-doc.org/en/master/config
 
-import pkg_resources
+import importlib.metadata
 
 # -- Path setup --------------------------------------------------------------
 
@@ -25,7 +25,7 @@
 copyright = "2019-2022, IPUMS"
 author = "Jacob Wellington, Kelly Thompson, Jonas Helgertz, Riley Harper"
 
-version = pkg_resources.get_distribution("hlink").version
+version = importlib.metadata.version("hlink")
 # The full version, including alpha/beta/rc tags
 release = version
 


Test patch:
diff --git a/hlink/tests/main_test.py b/hlink/tests/main_test.py
index ab3c491..50e4684 100644
--- a/hlink/tests/main_test.py
+++ b/hlink/tests/main_test.py
@@ -151,7 +151,7 @@ def test_load_conf_keys_set_no_env(monkeypatch, tmp_path):
 
     conf = load_conf(filename, "test")
 
-    for (key, value) in contents.items():
+    for key, value in contents.items():
         assert conf[key] == value
 
     # Check for extra keys added by load_conf()
@@ -300,7 +300,7 @@ def test_load_conf_keys_set_env(
 
     conf = load_conf(filename, user)
 
-    for (key, value) in contents.items():
+    for key, value in contents.items():
         assert conf[key] == value
 
     # Check for extra keys added by load_conf()
diff --git a/hlink/tests/matching_test.py b/hlink/tests/matching_test.py
index 924f925..04b80cc 100755
--- a/hlink/tests/matching_test.py
+++ b/hlink/tests/matching_test.py
@@ -32,7 +32,6 @@ def test_removal_of_duplicate_histid_b(
 
 
 def test_step_2_any_equals(spark, matching_household_conf, matching, preprocessing):
-
     matching_household_conf["column_mappings"].append(
         {
             "column_name": "namefrst_std",
@@ -119,7 +118,6 @@ def test_step_2_any_equals(spark, matching_household_conf, matching, preprocessi
 
 
 def test_step_2_sum(spark, matching_household_conf, matching, preprocessing):
-
     matching_household_conf["feature_selections"] = [
         {
             "output_col": "namelast_popularity",
diff --git a/hlink/tests/preprocessing_test.py b/hlink/tests/preprocessing_test.py
index 910b66e..86bf939 100755
--- a/hlink/tests/preprocessing_test.py
+++ b/hlink/tests/preprocessing_test.py
@@ -219,7 +219,8 @@ def test_step_0_filters_expression_and_household(
 
 def test_step_0_filters_datasource(preprocessing, spark, preprocessing_conf):
     """Test a filter run in preprocessing step 0 which selects rows from the raw data according
-    to an expression AND only applies the expression to a specified datasource (a or b)"""
+    to an expression AND only applies the expression to a specified datasource (a or b)
+    """
 
     # overwrite the config filter value to include an expression filter which includes a datasource argument.
     preprocessing_conf["filter"] = [
diff --git a/hlink/tests/reporting_test.py b/hlink/tests/reporting_test.py
index 4103e1a..86828d6 100644
--- a/hlink/tests/reporting_test.py
+++ b/hlink/tests/reporting_test.py
@@ -9,7 +9,6 @@
 
 
 def test_report_r2_percent_linked(reporting, spark, reporting_test_data_r2_pct):
-
     pdfa_path, pm_path, hhpm_path = reporting_test_data_r2_pct
 
     reporting.spark.read.csv(pdfa_path, header=True).write.mode(
@@ -57,7 +56,6 @@ def test_report_r2_percent_linked(reporting, spark, reporting_test_data_r2_pct):
 def test_report_representivity(
     reporting, spark, reporting_test_data_representivity, integration_conf
 ):
-
     rdf_path, pdf_path, pm_path, hhpm_path = reporting_test_data_representivity
 
     reporting.spark.read.csv(rdf_path, header=True).write.mode("overwrite").saveAsTable(