{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iGB4oSeeEYGE"
      },
      "source": [
        "# NLP for Data Science using Spacy & Co.\n",
        "\n",
        "Many language processing tasks are already covered in [Spacy 101 - Everything you need to know](https://spacy.io/usage/spacy-101).\n",
        "\n",
        "Spacy is an open source library made by the company [explosion.ai](https://explosion.ai/)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xlZptrO5lMRY"
      },
      "source": [
        "## Lemmatization, Part-of-speech tagging, and dependency parsing\n",
        "\n",
        "Many language analysis tasks involve a whole pipeline of models. Spacy models are trained to perform a combination of tasks, which is also a source of robustness of these models. When using these models, you can access multiple features produced by the model pipeline and use them for your own tasks."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 394
        },
        "id": "zaRttKAZPAK0",
        "outputId": "9d595d86-0789-4662-e9b2-88156354bd72"
      },
      "outputs": [
        {
          "ename": "OSError",
          "evalue": "[E050] Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory.",
          "output_type": "error",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mOSError\u001b[0m                                   Traceback (most recent call last)",
            "Cell \u001b[0;32mIn[1], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mspacy\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m nlp \u001b[38;5;241m=\u001b[39m \u001b[43mspacy\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43men_core_web_sm\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m      4\u001b[0m doc \u001b[38;5;241m=\u001b[39m nlp(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mApple is looking at buying U.K. startup for $1 billion\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m      6\u001b[0m pd\u001b[38;5;241m.\u001b[39mDataFrame(((token\u001b[38;5;241m.\u001b[39mtext, token\u001b[38;5;241m.\u001b[39mlemma_, token\u001b[38;5;241m.\u001b[39mpos_, token\u001b[38;5;241m.\u001b[39mtag_, token\u001b[38;5;241m.\u001b[39mdep_,\n\u001b[1;32m      7\u001b[0m             token\u001b[38;5;241m.\u001b[39mshape_, token\u001b[38;5;241m.\u001b[39mis_alpha, token\u001b[38;5;241m.\u001b[39mis_stop) \u001b[38;5;28;01mfor\u001b[39;00m token \u001b[38;5;129;01min\u001b[39;00m doc),\n\u001b[1;32m      8\u001b[0m              columns\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mText\tLemma\tPOS\tTag\tDep\tShape\talpha\tstop\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39msplit())\n",
            "File \u001b[0;32m~/micromamba/lib/python3.11/site-packages/spacy/__init__.py:51\u001b[0m, in \u001b[0;36mload\u001b[0;34m(name, vocab, disable, enable, exclude, config)\u001b[0m\n\u001b[1;32m     27\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mload\u001b[39m(\n\u001b[1;32m     28\u001b[0m     name: Union[\u001b[38;5;28mstr\u001b[39m, Path],\n\u001b[1;32m     29\u001b[0m     \u001b[38;5;241m*\u001b[39m,\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     34\u001b[0m     config: Union[Dict[\u001b[38;5;28mstr\u001b[39m, Any], Config] \u001b[38;5;241m=\u001b[39m util\u001b[38;5;241m.\u001b[39mSimpleFrozenDict(),\n\u001b[1;32m     35\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Language:\n\u001b[1;32m     36\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Load a spaCy model from an installed package or a local path.\u001b[39;00m\n\u001b[1;32m     37\u001b[0m \n\u001b[1;32m     38\u001b[0m \u001b[38;5;124;03m    name (str): Package name or model path.\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     49\u001b[0m \u001b[38;5;124;03m    RETURNS (Language): The loaded nlp object.\u001b[39;00m\n\u001b[1;32m     50\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[0;32m---> 51\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mutil\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload_model\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m     52\u001b[0m \u001b[43m        \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     53\u001b[0m \u001b[43m        \u001b[49m\u001b[43mvocab\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvocab\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     54\u001b[0m \u001b[43m        \u001b[49m\u001b[43mdisable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdisable\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     55\u001b[0m \u001b[43m        \u001b[49m\u001b[43menable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43menable\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     56\u001b[0m \u001b[43m        \u001b[49m\u001b[43mexclude\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mexclude\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     57\u001b[0m \u001b[43m        \u001b[49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     58\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n",
            "File \u001b[0;32m~/micromamba/lib/python3.11/site-packages/spacy/util.py:472\u001b[0m, in \u001b[0;36mload_model\u001b[0;34m(name, vocab, disable, enable, exclude, config)\u001b[0m\n\u001b[1;32m    470\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m OLD_MODEL_SHORTCUTS:\n\u001b[1;32m    471\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(Errors\u001b[38;5;241m.\u001b[39mE941\u001b[38;5;241m.\u001b[39mformat(name\u001b[38;5;241m=\u001b[39mname, full\u001b[38;5;241m=\u001b[39mOLD_MODEL_SHORTCUTS[name]))  \u001b[38;5;66;03m# type: ignore[index]\u001b[39;00m\n\u001b[0;32m--> 472\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(Errors\u001b[38;5;241m.\u001b[39mE050\u001b[38;5;241m.\u001b[39mformat(name\u001b[38;5;241m=\u001b[39mname))\n",
            "\u001b[0;31mOSError\u001b[0m: [E050] Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory."
          ]
        }
      ],
      "source": [
        "import spacy\n",
        "\n",
        "# prepare this model download via: python -m spacy download en_core_web_sm\n",
        "nlp = spacy.load(\"en_core_web_sm\")\n",
        "doc = nlp(\"Apple is looking at buying U.K. startup for $1 billion\")\n",
        "\n",
        "pd.DataFrame(((token.text, token.lemma_, token.pos_, token.tag_, token.dep_,\n",
        "            token.shape_, token.is_alpha, token.is_stop) for token in doc),\n",
        "             columns=\"Text\tLemma\tPOS\tTag\tDep\tShape\talpha\tstop\".split())\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Q6vCayK4PEKs"
      },
      "source": [
        "## Named entity resolution (NER)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "id": "ezcO4rx6O_ZO",
        "outputId": "cda6fb7e-6cd4-4355-ed99-d95861cceb9c"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-a6b2ffa5-4955-4842-8a4a-7b2450d9d77f\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>entity</th>\n",
              "      <th>start</th>\n",
              "      <th>end</th>\n",
              "      <th>type</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>Apple</td>\n",
              "      <td>0</td>\n",
              "      <td>5</td>\n",
              "      <td>ORG</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>U.K.</td>\n",
              "      <td>27</td>\n",
              "      <td>31</td>\n",
              "      <td>GPE</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>$1 billion</td>\n",
              "      <td>44</td>\n",
              "      <td>54</td>\n",
              "      <td>MONEY</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-a6b2ffa5-4955-4842-8a4a-7b2450d9d77f')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-a6b2ffa5-4955-4842-8a4a-7b2450d9d77f button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-a6b2ffa5-4955-4842-8a4a-7b2450d9d77f');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "       entity  start  end   type\n",
              "0       Apple      0    5    ORG\n",
              "1        U.K.     27   31    GPE\n",
              "2  $1 billion     44   54  MONEY"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "### Entity highlighting using displacy"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<div class=\"entities\" style=\"line-height: 2.5; direction: ltr\">\n",
              "<mark class=\"entity\" style=\"background: #7aecec; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;\">\n",
              "    Apple\n",
              "    <span style=\"font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem\">ORG</span>\n",
              "</mark>\n",
              " is looking at buying \n",
              "<mark class=\"entity\" style=\"background: #feca74; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;\">\n",
              "    U.K.\n",
              "    <span style=\"font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem\">GPE</span>\n",
              "</mark>\n",
              " startup for \n",
              "<mark class=\"entity\" style=\"background: #e4e7d2; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;\">\n",
              "    $1 billion\n",
              "    <span style=\"font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem\">MONEY</span>\n",
              "</mark>\n",
              "</div>"
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import spacy\n",
        "from spacy import displacy\n",
        "from IPython.display import HTML, Markdown\n",
        "import pandas as pd\n",
        "\n",
        "nlp = spacy.load(\"en_core_web_sm\")\n",
        "doc = nlp(\"Apple is looking at buying U.K. startup for $1 billion\")\n",
        "\n",
        "def make_ents():\n",
        "  for ent in doc.ents:\n",
        "      yield (ent.text, ent.start_char, ent.end_char, ent.label_)\n",
        "\n",
        "display(pd.DataFrame(make_ents(), columns=\"entity start end type\".split()))\n",
        "\n",
        "# aside: some notebook TOC generators (e.g. Jupyter, but not Colab) pick up generated headings\n",
        "display(Markdown(\"### Entity highlighting using displacy\"))\n",
        "\n",
        "HTML(displacy.render(doc,\n",
        "                     #style='dep',\n",
        "                     style='ent',\n",
        "                     ))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ACeYqU2-DNBJ"
      },
      "source": [
        "## Constituency Parsing\n",
        "\n",
        "To generate the constituency tree, a more compehensive library is needed, constituent_treelib by Oren Halvani), that uses spacy as a feature extractor."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "hjKQuY_LCkkv"
      },
      "outputs": [],
      "source": [
        "#!pip install constituent-treelib"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "YNAuNNRTCo_O",
        "outputId": "eb366071-6106-43c4-9261-2905fdc49b21"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "[nltk_data] Downloading package benepar_en3 to /usr/share/nltk_data...\n",
            "[nltk_data]   Package benepar_en3 is already up-to-date!\n"
          ]
        }
      ],
      "source": [
        "from constituent_treelib import ConstituentTree, BracketedTree, Language, Structure\n",
        "\n",
        "# Define the language for the sentence as well as for the spaCy and benepar models\n",
        "language = Language.English\n",
        "\n",
        "# Define which specific SpaCy model should be used (default is Medium)\n",
        "spacy_model_size = ConstituentTree.SpacyModelSize.Medium\n",
        "\n",
        "# Create the pipeline (note, the required models will be downloaded and installed automatically)\n",
        "nlp = ConstituentTree.create_pipeline(language, spacy_model_size)\n",
        "\n",
        "without_token_leaves = ConstituentTree(sentence, nlp, Structure.WithoutTokenLeaves)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "3RwOX69WDRwX"
      },
      "outputs": [],
      "source": [
        "# Raw sentence\n",
        "sentence = 'You must construct additional pylons!'"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zlJhyEwatqHA"
      },
      "outputs": [],
      "source": [
        "\n",
        "# Parsed sentence wrapped as a BracketedTree object\n",
        "bracketed_tree_string = '(S (NP (PRP You)) (VP (MD must) (VP (VB construct) (NP (JJ additional) (NNS pylons)))) (. !))'\n",
        "bracketed_sentence = BracketedTree(bracketed_tree_string)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "nSL1UlMQEA13"
      },
      "outputs": [],
      "source": [
        "without_token_leaves = ConstituentTree(sentence, nlp, Structure.WithoutTokenLeaves)\n",
        "\n",
        "#without_inner_postag_nodes = ConstituentTree(sentence, nlp, Structure.WithoutPostagNodes)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 238
        },
        "id": "E1ZB-a1CEIL3",
        "outputId": "3ea37ddd-e79b-48be-8f96-a7d00080c88b"
      },
      "outputs": [
        {
          "data": {
            "image/svg+xml": [
              "<svg baseProfile=\"full\" height=\"216px\" preserveAspectRatio=\"xMidYMid meet\" style=\"font-family: times, serif; font-weight:normal; font-style: normal; font-size: 16px;\" version=\"1.1\" viewBox=\"0,0,200.0,216.0\" width=\"200px\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">S</text></svg><svg width=\"20%\" x=\"0%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">NP</text></svg><svg width=\"100%\" x=\"0%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">PRP</text></svg></svg><line stroke=\"black\" x1=\"50%\" x2=\"50%\" y1=\"1.2em\" y2=\"3em\" /></svg><line stroke=\"black\" x1=\"50%\" x2=\"10%\" y1=\"1.2em\" y2=\"3em\" /><svg width=\"68%\" x=\"20%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">VP</text></svg><svg width=\"23.5294%\" x=\"0%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">MD</text></svg></svg><line stroke=\"black\" x1=\"50%\" x2=\"11.7647%\" y1=\"1.2em\" y2=\"3em\" /><svg width=\"76.4706%\" x=\"23.5294%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">VP</text></svg><svg width=\"30.7692%\" x=\"0%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">VB</text></svg></svg><line stroke=\"black\" x1=\"50%\" x2=\"15.3846%\" y1=\"1.2em\" y2=\"3em\" /><svg width=\"69.2308%\" x=\"30.7692%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">NP</text></svg><svg width=\"44.4444%\" x=\"0%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">JJ</text></svg></svg><line stroke=\"black\" x1=\"50%\" x2=\"22.2222%\" y1=\"1.2em\" y2=\"3em\" /><svg width=\"55.5556%\" x=\"44.4444%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">NNS</text></svg></svg><line stroke=\"black\" x1=\"50%\" x2=\"72.2222%\" y1=\"1.2em\" y2=\"3em\" /></svg><line stroke=\"black\" x1=\"50%\" x2=\"65.3846%\" y1=\"1.2em\" y2=\"3em\" /></svg><line stroke=\"black\" x1=\"50%\" x2=\"61.7647%\" y1=\"1.2em\" y2=\"3em\" /></svg><line stroke=\"black\" x1=\"50%\" x2=\"54%\" y1=\"1.2em\" y2=\"3em\" /><svg width=\"12%\" x=\"88%\" y=\"3em\"><defs /><svg width=\"100%\" x=\"0\" y=\"0em\"><defs /><text text-anchor=\"middle\" x=\"50%\" y=\"1em\">.</text></svg></svg><line stroke=\"black\" x1=\"50%\" x2=\"94%\" y1=\"1.2em\" y2=\"3em\" /></svg>"
            ],
            "text/plain": [
              "<constituent_treelib.core.ConstituentTree at 0x7fde54ecad00>"
            ]
          },
          "execution_count": 31,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "without_token_leaves"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "OR6YhQd4EQ_J",
        "outputId": "401971ec-055f-4626-86e7-f711733afcda"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'VP': ['must construct additional pylons', 'construct additional pylons'],\n",
              " 'S': ['You must construct additional pylons !'],\n",
              " 'NP': ['additional pylons']}"
            ]
          },
          "execution_count": 36,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pos_phrases = without_token_leaves.extract_all_phrases()\n",
        "pos_phrases"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.4"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
