L'objectif est d'écrire des oracles pour des parsers shift-reduce. On va les tester sur des données Universal Dependencies qu'on récupère avec la bibliothèque datasets
.
On commence par installer nos dépendances
%pip install -U conllu datasets
Requirement already satisfied: conllu in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (4.5.2) Requirement already satisfied: datasets in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (2.4.0) Requirement already satisfied: requests>=2.19.0 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (2.28.1) Requirement already satisfied: dill<0.3.6 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (0.3.5.1) Requirement already satisfied: responses<0.19 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (0.18.0) Requirement already satisfied: pyarrow>=6.0.0 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (9.0.0) Requirement already satisfied: fsspec[http]>=2021.11.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (2022.7.1) Requirement already satisfied: packaging in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (21.3) Requirement already satisfied: xxhash in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (3.0.0) Requirement already satisfied: aiohttp in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (3.8.1) Requirement already satisfied: huggingface-hub<1.0.0,>=0.1.0 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (0.8.1) Requirement already satisfied: pandas in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (1.4.3) Requirement already satisfied: numpy>=1.17 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (1.23.2) Requirement already satisfied: multiprocess in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (0.70.13) Requirement already satisfied: tqdm>=4.62.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from datasets) (4.64.0) Requirement already satisfied: filelock in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from huggingface-hub<1.0.0,>=0.1.0->datasets) (3.8.0) Requirement already satisfied: pyyaml>=5.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from huggingface-hub<1.0.0,>=0.1.0->datasets) (6.0) Requirement already satisfied: typing-extensions>=3.7.4.3 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from huggingface-hub<1.0.0,>=0.1.0->datasets) (4.3.0) Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from packaging->datasets) (3.0.9) Requirement already satisfied: idna<4,>=2.5 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from requests>=2.19.0->datasets) (3.3) Requirement already satisfied: charset-normalizer<3,>=2 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from requests>=2.19.0->datasets) (2.1.1) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from requests>=2.19.0->datasets) (1.26.11) Requirement already satisfied: certifi>=2017.4.17 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from requests>=2.19.0->datasets) (2022.6.15) Requirement already satisfied: aiosignal>=1.1.2 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from aiohttp->datasets) (1.2.0) Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from aiohttp->datasets) (4.0.2) Requirement already satisfied: multidict<7.0,>=4.5 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from aiohttp->datasets) (6.0.2) Requirement already satisfied: yarl<2.0,>=1.0 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from aiohttp->datasets) (1.8.1) Requirement already satisfied: attrs>=17.3.0 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from aiohttp->datasets) (22.1.0) Requirement already satisfied: frozenlist>=1.1.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from aiohttp->datasets) (1.3.1) Requirement already satisfied: python-dateutil>=2.8.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from pandas->datasets) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from pandas->datasets) (2022.2.1) Requirement already satisfied: six>=1.5 in /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages (from python-dateutil>=2.8.1->pandas->datasets) (1.16.0) Note: you may need to restart the kernel to use updated packages.
from datasets import load_dataset
dataset = load_dataset(
"universal_dependencies", "fr_sequoia"
)
Downloading and preparing dataset universal_dependencies/fr_sequoia (download: 4.21 MiB, generated: 7.16 MiB, post-processed: Unknown size, total: 11.37 MiB) to /home/runner/.cache/huggingface/datasets/universal_dependencies/fr_sequoia/2.7.0/1ac001f0e8a0021f19388e810c94599f3ac13cc45d6b5b8c69f7847b2188bdf7...
Dataset universal_dependencies downloaded and prepared to /home/runner/.cache/huggingface/datasets/universal_dependencies/fr_sequoia/2.7.0/1ac001f0e8a0021f19388e810c94599f3ac13cc45d6b5b8c69f7847b2188bdf7. Subsequent calls will reuse this data.
Voyons ce qu'il a dans le ventre
dataset
DatasetDict({ train: Dataset({ features: ['idx', 'text', 'tokens', 'lemmas', 'upos', 'xpos', 'feats', 'head', 'deprel', 'deps', 'misc'], num_rows: 2231 }) validation: Dataset({ features: ['idx', 'text', 'tokens', 'lemmas', 'upos', 'xpos', 'feats', 'head', 'deprel', 'deps', 'misc'], num_rows: 412 }) test: Dataset({ features: ['idx', 'text', 'tokens', 'lemmas', 'upos', 'xpos', 'feats', 'head', 'deprel', 'deps', 'misc'], num_rows: 456 }) })
train_dataset = dataset["train"]
print(train_dataset.info.description)
Universal Dependencies is a project that seeks to develop cross-linguistically consistent treebank annotation for many languages, with the goal of facilitating multilingual parser development, cross-lingual learning, and parsing research from a language typology perspective. The annotation scheme is based on (universal) Stanford dependencies (de Marneffe et al., 2006, 2008, 2014), Google universal part-of-speech tags (Petrov et al., 2012), and the Interset interlingua for morphosyntactic tagsets (Zeman, 2008).
Les données auront cette tête
train_dataset[5]
{'idx': 'annodis.er_00007', 'text': 'Amélioration de la sécurité', 'tokens': ['Amélioration', 'de', 'la', 'sécurité'], 'lemmas': ['amélioration', 'de', 'le', 'sécurité'], 'upos': [0, 2, 8, 0], 'xpos': [None, None, None, None], 'feats': ["{'Gender': 'Fem', 'Number': 'Sing'}", 'None', "{'Definite': 'Def', 'Gender': 'Fem', 'Number': 'Sing', 'PronType': 'Art'}", "{'Gender': 'Fem', 'Number': 'Sing'}"], 'head': ['0', '4', '4', '1'], 'deprel': ['root', 'case', 'det', 'nmod'], 'deps': ['None', 'None', 'None', 'None'], 'misc': ['None', 'None', 'None', 'None']}
On va d'abord écrire une fonction qui va nous transformer ces données de façon à ne garder que ce qui nous intéresse : identifiants et têtes (et forme pour l'affichage).
from typing import Union
from dataclasses import dataclass
# On pourrait simplement utiliser des tuples
# mais c'est plus lisible comme ça
@dataclass
class Node:
identifier: int
form: str
head: int
def buffer_from_dict(d):
# On gère les multiword tokens qu'on repère parce que
# leur tête est `"None"`, oui, oui, la chaine de caractères,
# par l'objet `None`
words_with_heads = [
(w, int(h))
for w, h in zip(d["tokens"], d["head"])
if h != "None"
]
return [
Node(
identifier=i,
form=w,
head=h,
)
for i, (w, h) in enumerate([("ROOT", 0), *words_with_heads])
]
buffer_from_dict(train_dataset[6])
[Node(identifier=0, form='ROOT', head=0), Node(identifier=1, form='Le', head=2), Node(identifier=2, form='maire', head=4), Node(identifier=3, form='a', head=4), Node(identifier=4, form='invité', head=0), Node(identifier=5, form='les', head=6), Node(identifier=6, form='membres', head=4), Node(identifier=7, form='de', head=9), Node(identifier=8, form='le', head=9), Node(identifier=9, form='conseil', head=6), Node(identifier=10, form='à', head=11), Node(identifier=11, form='élaborer', head=4), Node(identifier=12, form='le', head=13), Node(identifier=13, form='programme', head=11), Node(identifier=14, form="d'", head=15), Node(identifier=15, form='amélioration', head=13), Node(identifier=16, form='de', head=18), Node(identifier=17, form='la', head=18), Node(identifier=18, form='voirie', head=15), Node(identifier=19, form='communale', head=18), Node(identifier=20, form='et', head=23), Node(identifier=21, form='de', head=23), Node(identifier=22, form='la', head=23), Node(identifier=23, form='sécurité', head=18), Node(identifier=24, form='routière', head=23), Node(identifier=25, form='pour', head=27), Node(identifier=26, form="l'", head=27), Node(identifier=27, form='année', head=13), Node(identifier=28, form='1999', head=27), Node(identifier=29, form='.', head=4)]
Un oracle pour le système de transition arc-standard (Nivre, 2004)) :
from typing import List, Iterable
from collections import Counter
def arc_standard_oracle(buffer: List[Node]) -> Iterable[str]:
# On copie le buffer pour ne pas le détruire et on le retourne pour
# pouvoir `pop`er optimalement
# On pourrait aussi écrire `list(reversed(buffer))`
buffer = buffer[::-1]
# Comme d'habitude, une liste c'est une pile, on commence avec la racine
# dessus
stack = [buffer.pop()]
# Pour ne pas réduire un nœud avant d'avoir trouvé tous ses dépendants,
# on les compte (On pourrait utiliser un générateur
# plutôt qu'une boucle)
remaining_dependents = Counter()
for node in buffer:
remaining_dependents[node.head] += 1
while buffer or stack:
print([t.form for t in stack], [t.form for t in reversed(buffer)], sep="\t")
if len(stack) < 2:
if buffer:
yield "SHIFT"
stack.append(buffer.pop())
continue
else:
break
stack_top = stack[-1]
stack_under = stack[-2]
if stack_top.head == stack_under.identifier and not remaining_dependents[stack_top.identifier]:
yield "REDUCE-RIGHT"
remaining_dependents[stack_under.identifier] -= 1
stack.pop()
elif stack_top.identifier == stack_under.head and not remaining_dependents[stack_under.identifier]:
yield "REDUCE-LEFT"
remaining_dependents[stack_top.identifier] -= 1
stack.pop(-2)
else:
if buffer:
yield "SHIFT"
stack.append(buffer.pop())
else:
raise ValueError("Non-projective tree")
list(arc_standard_oracle(buffer_from_dict(train_dataset[5])))
['ROOT'] ['Amélioration', 'de', 'la', 'sécurité'] ['ROOT', 'Amélioration'] ['de', 'la', 'sécurité'] ['ROOT', 'Amélioration', 'de'] ['la', 'sécurité'] ['ROOT', 'Amélioration', 'de', 'la'] ['sécurité'] ['ROOT', 'Amélioration', 'de', 'la', 'sécurité'] [] ['ROOT', 'Amélioration', 'de', 'sécurité'] [] ['ROOT', 'Amélioration', 'sécurité'] [] ['ROOT', 'Amélioration'] [] ['ROOT'] []
['SHIFT', 'SHIFT', 'SHIFT', 'SHIFT', 'REDUCE-LEFT', 'REDUCE-LEFT', 'REDUCE-RIGHT', 'REDUCE-RIGHT']
def arc_eager_oracle(buffer: List[Node]) -> List[str]:
buffer = buffer[::-1]
stack = [buffer.pop()]
# On pourrait aussi le faire quand on pousse sur la stack
has_left_dependents = set()
for node in buffer[:-1]:
if node.identifier < node.head:
has_left_dependents.add(node.head)
# Nécessaire uniquement si on a pas de garantie que l'arbre soit
# projectif
has_head = {node.identifier: False for node in buffer[:-1]}
while buffer:
print([t.form for t in stack], [t.form for t in reversed(buffer)], sep="\t")
stack_top = stack[-1]
buffer_top = buffer[-1]
if stack_top.head == buffer_top.identifier:
# Superflu mais agréable
has_head[stack_top.identifier] = True
yield "LEFT-ARC"
stack.pop()
elif stack_top.identifier == buffer_top.head:
yield "RIGHT-ARC"
has_head[buffer_top.identifier] = True
stack.append(buffer.pop())
# Trick galaxy brain de la projectivité: si on a `… A B …`
# avec un arc qui part de ou qui arrive à B et dont l'autre
# extrémité est à gauche de A, alors A nepeut pas avoir d'arc
# qui le relie à un truc à droite.
# Donc la tête de A est à sa gauche (ce n'est pas B sinon
# on aurait left-arc), donc on l'a déjà trouvée (et c'est même
# le nœud juste en dessous).
elif buffer_top.identifier in has_left_dependents:
if not has_head[stack_top.identifier]:
raise ValueError("Non-projective tree")
yield "REDUCE"
stack.pop()
else:
yield "SHIFT"
stack.append(buffer.pop())
while len(stack) > 1:
print([t.form for t in stack], [t.form for t in reversed(buffer)], sep="\t")
# On pourrait pop ici mais c'est sale
if not has_head[stack[-1].identifier]:
raise ValueError("Non-projective tree")
yield "REDUCE"
stack.pop()
list(arc_eager_oracle(buffer_from_dict(train_dataset[5])))
['ROOT'] ['Amélioration', 'de', 'la', 'sécurité'] ['ROOT', 'Amélioration'] ['de', 'la', 'sécurité'] ['ROOT', 'Amélioration', 'de'] ['la', 'sécurité'] ['ROOT', 'Amélioration', 'de', 'la'] ['sécurité'] ['ROOT', 'Amélioration', 'de'] ['sécurité'] ['ROOT', 'Amélioration'] ['sécurité'] ['ROOT', 'Amélioration', 'sécurité'] [] ['ROOT', 'Amélioration'] []
['RIGHT-ARC', 'SHIFT', 'SHIFT', 'LEFT-ARC', 'LEFT-ARC', 'RIGHT-ARC', 'REDUCE', 'REDUCE']
list(arc_eager_oracle(buffer_from_dict(train_dataset[6])))
['ROOT'] ['Le', 'maire', 'a', 'invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'Le'] ['maire', 'a', 'invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT'] ['maire', 'a', 'invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'maire'] ['a', 'invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'maire', 'a'] ['invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'maire'] ['invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT'] ['invité', 'les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité'] ['les', 'membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'les'] ['membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité'] ['membres', 'de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres'] ['de', 'le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres', 'de'] ['le', 'conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres', 'de', 'le'] ['conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres', 'de'] ['conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres'] ['conseil', 'à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres', 'conseil'] ['à', 'élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres', 'conseil', 'à'] ['élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres', 'conseil'] ['élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'membres'] ['élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité'] ['élaborer', 'le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer'] ['le', 'programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'le'] ['programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer'] ['programme', "d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme'] ["d'", 'amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', "d'"] ['amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme'] ['amélioration', 'de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration'] ['de', 'la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'de'] ['la', 'voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'de', 'la'] ['voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'de'] ['voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration'] ['voirie', 'communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie'] ['communale', 'et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale'] ['et', 'de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale', 'et'] ['de', 'la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale', 'et', 'de'] ['la', 'sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale', 'et', 'de', 'la'] ['sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale', 'et', 'de'] ['sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale', 'et'] ['sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'communale'] ['sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie'] ['sécurité', 'routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité'] ['routière', 'pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité', 'routière'] ['pour', "l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité', 'routière', 'pour'] ["l'", 'année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité', 'routière', 'pour', "l'"] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité', 'routière', 'pour'] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité', 'routière'] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie', 'sécurité'] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration', 'voirie'] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'amélioration'] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme'] ['année', '1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'année'] ['1999', '.'] ['ROOT', 'invité', 'élaborer', 'programme', 'année', '1999'] ['.'] ['ROOT', 'invité', 'élaborer', 'programme', 'année', '1999', '.'] []
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [9], in <cell line: 1>() ----> 1 list(arc_eager_oracle(buffer_from_dict(train_dataset[6]))) Input In [8], in arc_eager_oracle(buffer) 45 # On pourrait pop ici mais c'est sale 46 if not has_head[stack[-1].identifier]: ---> 47 raise ValueError("Non-projective tree") 48 yield "REDUCE" 49 stack.pop() ValueError: Non-projective tree