{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"%%capture\n",
"%load_ext autoreload\n",
"%autoreload 2\n",
"import sys\n",
"sys.path.append(\"..\")\n",
"import statnlpbook.util as util\n",
"import statnlpbook.parsing as parsing\n",
"from statnlpbook.transition import *\n",
"\n",
"util.execute_notebook('Transition-based dependency parsing.ipynb')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"\n",
"$$\n",
"\\newcommand{\\Xs}{\\mathcal{X}}\n",
"\\newcommand{\\Ys}{\\mathcal{Y}}\n",
"\\newcommand{\\y}{\\mathbf{y}}\n",
"\\newcommand{\\balpha}{\\boldsymbol{\\alpha}}\n",
"\\newcommand{\\bbeta}{\\boldsymbol{\\beta}}\n",
"\\newcommand{\\aligns}{\\mathbf{a}}\n",
"\\newcommand{\\align}{a}\n",
"\\newcommand{\\source}{\\mathbf{s}}\n",
"\\newcommand{\\target}{\\mathbf{t}}\n",
"\\newcommand{\\ssource}{s}\n",
"\\newcommand{\\starget}{t}\n",
"\\newcommand{\\repr}{\\mathbf{f}}\n",
"\\newcommand{\\repry}{\\mathbf{g}}\n",
"\\newcommand{\\x}{\\mathbf{x}}\n",
"\\newcommand{\\prob}{p}\n",
"\\newcommand{\\a}{\\alpha}\n",
"\\newcommand{\\b}{\\beta}\n",
"\\newcommand{\\vocab}{V}\n",
"\\newcommand{\\params}{\\boldsymbol{\\theta}}\n",
"\\newcommand{\\param}{\\theta}\n",
"\\DeclareMathOperator{\\perplexity}{PP}\n",
"\\DeclareMathOperator{\\argmax}{argmax}\n",
"\\DeclareMathOperator{\\argmin}{argmin}\n",
"\\newcommand{\\train}{\\mathcal{D}}\n",
"\\newcommand{\\counts}[2]{\\#_{#1}(#2) }\n",
"\\newcommand{\\length}[1]{\\text{length}(#1) }\n",
"\\newcommand{\\indi}{\\mathbb{I}}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Dependency Parsing"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Motivation \n",
"\n",
"Constituent Parsers **more complex than needed**:\n",
"* Often we only need grammatical **relations between words**\n",
"* Annotation **costly** and **error prone**\n",
" * To annotate a sentence with a parse tree, you need substantial expertise"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Dependency Parsing** addresses this...\n",
"\n",
"[spaCy](https://demos.explosion.ai/displacy/)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Anatomy of a Dependency Tree\n",
"\n",
"* Nodes:\n",
" * Tokens of sentence\n",
" * a ROOT node (akin to the S symbol in CFGs)\n",
"* Edges:\n",
" * Directed from token child to ** syntactic head**\n",
" * Each **non-ROOT **token has **exactly one parent**\n",
" * the word that controls its syntactic function, or\n",
" * the word \"it depends on\"\n",
"* ROOT **has no parent**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Example"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"hideCode": true,
"hidePrompt": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
" "
],
"text/plain": [
""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tokens = [\"ROOT\", \"Economic\", \"news\", \"had\", \"little\", \"effect\", \"on\", \"financial\", \"markets\", \".\"]\n",
"arcs = set([(0,3, \"root\"), (0,9,\"p\"), (2,1,\"amod\"),(3,2,\"nsubj\"), (3, 5, \"dobj\"), (5,4,\"amod\"), (5,6, \"prep\"), (6,8,\"pmod\"), (8,7,\"amod\")])\n",
"\n",
"render_displacy(*transition.to_displacy_graph(arcs, tokens),\"900px\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Dependency Parsing Approaches"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Graph-Based Parsing\n",
"* define $s_\\params(\\x,\\y)$ over sentences $\\Xs$ and dependency graphs $\\Ys$\n",
"* $s_\\params(\\x,\\y)$ decomposes into per (hyper)edge scores:\n",
"$$\n",
"s_\\params(\\x,\\y) = \\sum_{(h,c) \\in \\y} s(h,c,\\x)=\\sum_{(h,c) \\in \\y}\\langle \\mathbf{f}(h,c,\\x),\\mathbf{w} \\rangle\n",
"$$ \n",
"* **Labelled** version uses $\\langle \\mathbf{f}(h,c,l,\\x),\\mathbf{w} \\rangle$ where $l$ is label"
]
},
{
"cell_type": "markdown",
"metadata": {
"hidePrompt": false,
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"How would you define features $\\mathbf{f}(h,c,\\x)$?"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"hideCode": true,
"hidePrompt": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tokens = [\"ROOT\", \"Economic\", \"news\", \"had\", \"little\", \"effect\", \"on\", \"financial\", \"markets\", \".\"]\n",
"arcs = set([(3, 5, \"dobj\")])\n",
"\n",
"render_displacy(*transition.to_displacy_graph(arcs, tokens),\"900px\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Search/Parsing\n",
"\n",
"Find the **tree** with maximal total score\n",
"\n",
"$$\n",
"\\argmax_{\\y} \\sum_{(h,c) \\in \\y} s(h,c,\\x)\n",
"$$\n",
"\n",
"Corresponds to **finding maximum spanning trees**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Example Maximum Spanning Tree\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
" \n",
" \n",
"\n"
]
},
{
"cell_type": "raw",
"metadata": {
"hide_egal": false,
"is_egal": true
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Problem\n",
"higher order dependencies\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
" \n",
" \n",
"\n"
]
},
{
"cell_type": "raw",
"metadata": {
"hide_egal": false,
"is_egal": true,
"slideshow": {
"slide_type": "-"
}
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Transition-Based Parsing\n",
"* learn to perform the right action / transition in a bottom-up left-right parser\n",
"* Train classifiers $p(y|\\x)$ where $y$ is an action, and $\\x$ is solution built so far, and the remaining sentence\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Currently the state-of-the-art..."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Parsing State \n",
"Akin to bottom up parsing for CFGs..."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"A token \n",
"### Buffer\n",
"of **remaining tokens**"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"hidePrompt": true,
"scrolled": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"ROOT Economic news had little effect on financial markets . | | \n",
" \n",
" | INIT |
"
],
"text/plain": [
".Output at 0x7f16909726a0>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[0:1], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"A token \n",
"### Stack\n",
"of earlier tokens to **attach to later**"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"hidePrompt": true,
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"news had little effect on financial markets . | ROOT Economic | \n",
" \n",
" | shift |
"
],
"text/plain": [
".Output at 0x7f1690972668>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[2:3],tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"hidePrompt": false,
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"A current \n",
"### Parse \n",
"built so far"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"hidePrompt": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"on financial markets . | ROOT had effect | \n",
" \n",
" | rightArc-dobj |
"
],
"text/plain": [
".Output at 0x7f16909722e8>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[9:10], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"hidePrompt": false,
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We use the following \n",
"### Actions"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Shift\n",
"\n",
"push the word at the top of the buffer to the stack \n",
"\n",
"$$\n",
"(S, i|B, A)\\rightarrow(S|i, B, A)\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"hidePrompt": true,
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"ROOT Economic news had little effect on financial markets . | | \n",
" \n",
" | INIT |
\n",
"Economic news had little effect on financial markets . | ROOT | \n",
" \n",
" | shift |
"
],
"text/plain": [
".Output at 0x7f169094e908>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[0:2], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Reduce\n",
"\n",
"pop the word at the top of the stack if it has a head \n",
"\n",
"$$\n",
"(S|i, B, A)\\rightarrow(S, B, A)\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"hidePrompt": true,
"scrolled": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
". | ROOT had effect on markets | \n",
" \n",
" | rightArc-pmod |
\n",
". | ROOT had effect on | \n",
" \n",
" | reduce |
"
],
"text/plain": [
".Output at 0x7f169094e400>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[13:15], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## rightArc-[label]\n",
"\n",
"add labeled arc from top of stack \\\\(i\\\\) to top of the buffer \\\\(j\\\\) \n",
"\n",
"$$\n",
"(S|i, j|B, A) \\rightarrow (S|i|j, B, A\\cup\\{(i,j,l)\\})\n",
"$$\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"had little effect on financial markets . | ROOT | \n",
" \n",
" | leftArc-nsubj |
\n",
"little effect on financial markets . | ROOT had | \n",
" \n",
" | rightArc-root |
"
],
"text/plain": [
".Output at 0x7f169094e668>"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[5:7], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### leftArc-[label] \n",
"\n",
"add labeled arc from top of buffer, \\\\(j\\\\), to top of stack, \\\\(i\\\\), if \\\\(i\\\\) has no head \n",
"\n",
"$$\n",
"(S|i, j|B, A) \\rightarrow (S, j|B, A\\cup\\{(j,i,l)\\})\n",
"$$\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"news had little effect on financial markets . | ROOT Economic | \n",
" \n",
" | shift |
\n",
"news had little effect on financial markets . | ROOT | \n",
" \n",
" | leftArc-amod |
"
],
"text/plain": [
".Output at 0x7f169094eef0>"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[2:4], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Full Example"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"buffer | stack | parse | action |
\n",
"ROOT Economic news had little effect on financial markets . | | \n",
" \n",
" | INIT |
\n",
"Economic news had little effect on financial markets . | ROOT | \n",
" \n",
" | shift |
\n",
"news had little effect on financial markets . | ROOT Economic | \n",
" \n",
" | shift |
\n",
"news had little effect on financial markets . | ROOT | \n",
" \n",
" | leftArc-amod |
\n",
"had little effect on financial markets . | ROOT news | \n",
" \n",
" | shift |
\n",
"had little effect on financial markets . | ROOT | \n",
" \n",
" | leftArc-nsubj |
\n",
"little effect on financial markets . | ROOT had | \n",
" \n",
" | rightArc-root |
\n",
"effect on financial markets . | ROOT had little | \n",
" \n",
" | shift |
\n",
"effect on financial markets . | ROOT had | \n",
" \n",
" | leftArc-amod |
\n",
"on financial markets . | ROOT had effect | \n",
" \n",
" | rightArc-dobj |
\n",
"financial markets . | ROOT had effect on | \n",
" \n",
" | rightArc-prep |
\n",
"markets . | ROOT had effect on financial | \n",
" \n",
" | shift |
\n",
"markets . | ROOT had effect on | \n",
" \n",
" | leftArc-amod |
\n",
". | ROOT had effect on markets | \n",
" \n",
" | rightArc-pmod |
\n",
". | ROOT had effect on | \n",
" \n",
" | reduce |
\n",
". | ROOT had effect | \n",
" \n",
" | reduce |
\n",
". | ROOT had | \n",
" \n",
" | reduce |
\n",
". | ROOT | \n",
" \n",
" | reduce |
\n",
" | ROOT . | \n",
" \n",
" | rightArc-p |
\n",
" | ROOT . | \n",
" \n",
" | TERMINAL |
"
],
"text/plain": [
".Output at 0x7f169094ef98>"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"render_transitions_displacy(transitions[:], tokenized_sentence)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Machine Learning\n",
"\n",
"How to decide what action to take? \n",
"\n",
"* Learn a discriminative classifier $p(y | \\x)$ where \n",
" * $\\x$ is a representation of buffer, stack and parse. \n",
" * $y$ is the action to choose\n",
"* Current state-of-the-art systems use neural networks as classifiers (e.g. Parsey McParseFace)\n",
"* Use **greedy search** or **beam search** to find the highest scoring sequence of steps"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Summary\n",
"\n",
"* Dependency parsing predicts word-to-word dependencies \n",
"* simpler annotations\n",
"* faster parsing\n",
"* sufficient for most down-stream applications"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Background Material\n",
"\n",
"* [EACL 2014 tutorial](http://stp.lingfil.uu.se/~nivre/eacl14.html)"
]
}
],
"metadata": {
"celltoolbar": "Hide code",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}