Syntagma Tokenizer
Contents
Syntagma Tokenizer#
This tutorial will show an example of how to apply syntagma tokenizer medkit operation on a text document.
Loading a text document#
For beginners, let’s load a text file using the TextDocument
class:
# You can download the file available in source code
# !wget https://raw.githubusercontent.com/TeamHeka/medkit/main/docs/data/text/1.txt
from pathlib import Path
from medkit.core.text import TextDocument
doc = TextDocument.from_file(Path("../../data/text/1.txt"))
The full raw text can be accessed through the text
attribute:
print(doc.text)
SUBJECTIF : Cette femme blanche de 23 ans se plaint d'allergies. Elle avait l'habitude d'avoir des allergies lorsqu'elle vivait à Seattle mais elle pense qu'elles sont pires ici. Dans le passé, elle a essayé le Claritin et le Zyrtec. Les deux ont fonctionné pendant une courte période mais ont ensuite semblé perdre de leur efficacité. Elle a également utilisé Allegra. Elle l'a utilisé l'été dernier et a recommencé à le faire il y a deux semaines. Il ne semble pas fonctionner très bien. Elle a utilisé des vaporisateurs en vente libre, mais pas de vaporisateurs nasaux sur ordonnance. Elle a de l'asthme, mais n'a pas besoin de prendre des médicaments tous les jours pour cela et ne pense pas que son asthme s'aggrave.
MÉDICAMENTS : Son seul médicament est actuellement Ortho Tri-Cyclen et l'Allegra.
ALLERGIES : Elle n'a pas d'allergies médicamenteuses connues.
EXAMEN PHYSIQUE :
Signes vitaux : Poids de 59.3 kilos et pression sanguine de 124/78.
Tete/Yeux/Oreilles/Nez/Gorge : Sa gorge était légèrement érythémateuse sans exsudat. La muqueuse nasale était érythémateuse et enflée. Seul un drainage clair était visible. Les TM étaient claires.
Cou : Souple sans adénopathie.
Poumons : Dégagés.
EVALUATION : Rhinite allergique.
PLAN :
- Elle va réessayer le Zyrtec au lieu de l'Allegra. Une autre option sera d'utiliser la loratadine. Elle ne pense pas être remboursée donc ça pourrait être moins cher.
- Echantillons de Nasonex : deux pulvérisations dans chaque narine pendant trois semaines. Une ordonnance a également été rédigée.
Defining syntagma definition rules#
To split the text document into medkit segments corresponding to a text part, we have to define a set of rules. These rules allow the operation to split the text based on regular expressions rules.
from medkit.text.segmentation.syntagma_tokenizer import SyntagmaTokenizer
separators = (
"(?<=\. )[\w\d]+", # Trigger: starts after a dot and space
"(?<=\n)[\w\d]+", # Trigger: starts after a newline
"(?<=: )\w+", # Trigger: starts after :
"(?<= )mais\s+(?=\w)", # Trigger: starts with 'mais' if space before and after
"(?<= )sans\s+(?=\w)", # Trigger: starts with 'sans' if space before and after
"(?<= )donc\s+(?=\w)", # Trigger: starts with 'donc' if space before and after
)
tokenizer = SyntagmaTokenizer(separators)
The syntagmas definition is a list of regular expressions allowing to trigger the start of a new syntagma.
As all operations, SyntagmaTokenizer
defines a run()
method. This method returns a list of Segment
objects (a Segment
is a
TextAnnotation
that represents a portion of a document’s full raw text).
As input, it also expects a list of Segment
objects. Here, we can pass a special segment containing the whole raw text of the document, that we can retrieve through the raw_segment
attribute of TextDocument
:
syntagmas = tokenizer.run([doc.raw_segment])
print(f"Number of detected syntagmas: {len(syntagmas)}")
print(f"Syntagmas label: {syntagmas[0].label}\n")
for syntagma in syntagmas:
print(f"{syntagma.spans}\t{syntagma.text!r}")
Number of detected syntagmas: 39
Syntagmas label: syntagma
[Span(start=0, end=11)] 'SUBJECTIF :'
[Span(start=12, end=64)] "Cette femme blanche de 23 ans se plaint d'allergies."
[Span(start=65, end=137)] "Elle avait l'habitude d'avoir des allergies lorsqu'elle vivait à Seattle"
[Span(start=138, end=178)] "mais elle pense qu'elles sont pires ici."
[Span(start=179, end=233)] 'Dans le passé, elle a essayé le Claritin et le Zyrtec.'
[Span(start=234, end=284)] 'Les deux ont fonctionné pendant une courte période'
[Span(start=285, end=335)] 'mais ont ensuite semblé perdre de leur efficacité.'
[Span(start=336, end=369)] 'Elle a également utilisé Allegra.'
[Span(start=370, end=449)] "Elle l'a utilisé l'été dernier et a recommencé à le faire il y a deux semaines."
[Span(start=450, end=489)] 'Il ne semble pas fonctionner très bien.'
[Span(start=490, end=538)] 'Elle a utilisé des vaporisateurs en vente libre,'
[Span(start=539, end=587)] 'mais pas de vaporisateurs nasaux sur ordonnance.'
[Span(start=588, end=607)] "Elle a de l'asthme,"
[Span(start=608, end=721)] "mais n'a pas besoin de prendre des médicaments tous les jours pour cela et ne pense pas que son asthme s'aggrave."
[Span(start=723, end=736)] 'MÉDICAMENTS :'
[Span(start=737, end=804)] "Son seul médicament est actuellement Ortho Tri-Cyclen et l'Allegra."
[Span(start=806, end=817)] 'ALLERGIES :'
[Span(start=818, end=867)] "Elle n'a pas d'allergies médicamenteuses connues."
[Span(start=869, end=886)] 'EXAMEN PHYSIQUE :'
[Span(start=887, end=902)] 'Signes vitaux :'
[Span(start=903, end=954)] 'Poids de 59.3 kilos et pression sanguine de 124/78.'
[Span(start=955, end=985)] 'Tete/Yeux/Oreilles/Nez/Gorge :'
[Span(start=986, end=1025)] 'Sa gorge était légèrement érythémateuse'
[Span(start=1026, end=1039)] 'sans exsudat.'
[Span(start=1040, end=1089)] 'La muqueuse nasale était érythémateuse et enflée.'
[Span(start=1090, end=1127)] 'Seul un drainage clair était visible.'
[Span(start=1128, end=1151)] 'Les TM étaient claires.'
[Span(start=1152, end=1157)] 'Cou :'
[Span(start=1158, end=1182)] 'Souple sans adénopathie.'
[Span(start=1183, end=1192)] 'Poumons :'
[Span(start=1193, end=1201)] 'Dégagés.'
[Span(start=1203, end=1215)] 'EVALUATION :'
[Span(start=1216, end=1235)] 'Rhinite allergique.'
[Span(start=1237, end=1295)] "PLAN :\n- Elle va réessayer le Zyrtec au lieu de l'Allegra."
[Span(start=1296, end=1343)] "Une autre option sera d'utiliser la loratadine."
[Span(start=1344, end=1377)] 'Elle ne pense pas être remboursée'
[Span(start=1378, end=1439)] 'donc ça pourrait être moins cher.\n- Echantillons de Nasonex :'
[Span(start=1440, end=1502)] 'deux pulvérisations dans chaque narine pendant trois semaines.'
[Span(start=1503, end=1542)] 'Une ordonnance a également été rédigée.'
As you can see, the text have been split into 39 medkit segments which default label is "SYNTAGMA"
. Corresponding spans
reflect the position of the text in the document’s full raw text.
Using a yaml definition file#
We have seen how to write rules programmatically.
However, it is also possible to load a yaml file containing all your rules.
First, let’s create the yaml file based on previous steps.
import pathlib
filepath = pathlib.Path("syntagma.yml")
SyntagmaTokenizer.save_syntagma_definition(
syntagma_seps=separators,
filepath=filepath,
encoding='utf-8')
with open(filepath, 'r') as f:
print(f.read())
syntagmas:
separators:
- (?<=\. )[\w\d]+
- '(?<=
)[\w\d]+'
- '(?<=: )\w+'
- (?<= )mais\s+(?=\w)
- (?<= )sans\s+(?=\w)
- (?<= )donc\s+(?=\w)
Now, we will see how to initialize the SyntagmaTokenizer
operation for using this yaml file.
# Use tokenizer initialized using a yaml file
from medkit.text.segmentation import SyntagmaTokenizer
separators = SyntagmaTokenizer.load_syntagma_definition(filepath)
print("separators = ")
for sep in separators:
print(f"- {sep!r}")
tokenizer = SyntagmaTokenizer(separators=separators)
separators =
- '(?<=\\. )[\\w\\d]+'
- '(?<=\n)[\\w\\d]+'
- '(?<=: )\\w+'
- '(?<= )mais\\s+(?=\\w)'
- '(?<= )sans\\s+(?=\\w)'
- '(?<= )donc\\s+(?=\\w)'
Now let’s run the operation. We can observe that the results are the same.
syntagmas = tokenizer.run([doc.raw_segment])
print(f"Number of detected syntagmas: {len(syntagmas)}\n")
for syntagma in syntagmas:
print(f"{syntagma.spans}\t{syntagma.text!r}")
Number of detected syntagmas: 39
[Span(start=0, end=11)] 'SUBJECTIF :'
[Span(start=12, end=64)] "Cette femme blanche de 23 ans se plaint d'allergies."
[Span(start=65, end=137)] "Elle avait l'habitude d'avoir des allergies lorsqu'elle vivait à Seattle"
[Span(start=138, end=178)] "mais elle pense qu'elles sont pires ici."
[Span(start=179, end=233)] 'Dans le passé, elle a essayé le Claritin et le Zyrtec.'
[Span(start=234, end=284)] 'Les deux ont fonctionné pendant une courte période'
[Span(start=285, end=335)] 'mais ont ensuite semblé perdre de leur efficacité.'
[Span(start=336, end=369)] 'Elle a également utilisé Allegra.'
[Span(start=370, end=449)] "Elle l'a utilisé l'été dernier et a recommencé à le faire il y a deux semaines."
[Span(start=450, end=489)] 'Il ne semble pas fonctionner très bien.'
[Span(start=490, end=538)] 'Elle a utilisé des vaporisateurs en vente libre,'
[Span(start=539, end=587)] 'mais pas de vaporisateurs nasaux sur ordonnance.'
[Span(start=588, end=607)] "Elle a de l'asthme,"
[Span(start=608, end=721)] "mais n'a pas besoin de prendre des médicaments tous les jours pour cela et ne pense pas que son asthme s'aggrave."
[Span(start=723, end=736)] 'MÉDICAMENTS :'
[Span(start=737, end=804)] "Son seul médicament est actuellement Ortho Tri-Cyclen et l'Allegra."
[Span(start=806, end=817)] 'ALLERGIES :'
[Span(start=818, end=867)] "Elle n'a pas d'allergies médicamenteuses connues."
[Span(start=869, end=886)] 'EXAMEN PHYSIQUE :'
[Span(start=887, end=902)] 'Signes vitaux :'
[Span(start=903, end=954)] 'Poids de 59.3 kilos et pression sanguine de 124/78.'
[Span(start=955, end=985)] 'Tete/Yeux/Oreilles/Nez/Gorge :'
[Span(start=986, end=1025)] 'Sa gorge était légèrement érythémateuse'
[Span(start=1026, end=1039)] 'sans exsudat.'
[Span(start=1040, end=1089)] 'La muqueuse nasale était érythémateuse et enflée.'
[Span(start=1090, end=1127)] 'Seul un drainage clair était visible.'
[Span(start=1128, end=1151)] 'Les TM étaient claires.'
[Span(start=1152, end=1157)] 'Cou :'
[Span(start=1158, end=1182)] 'Souple sans adénopathie.'
[Span(start=1183, end=1192)] 'Poumons :'
[Span(start=1193, end=1201)] 'Dégagés.'
[Span(start=1203, end=1215)] 'EVALUATION :'
[Span(start=1216, end=1235)] 'Rhinite allergique.'
[Span(start=1237, end=1295)] "PLAN :\n- Elle va réessayer le Zyrtec au lieu de l'Allegra."
[Span(start=1296, end=1343)] "Une autre option sera d'utiliser la loratadine."
[Span(start=1344, end=1377)] 'Elle ne pense pas être remboursée'
[Span(start=1378, end=1439)] 'donc ça pourrait être moins cher.\n- Echantillons de Nasonex :'
[Span(start=1440, end=1502)] 'deux pulvérisations dans chaque narine pendant trois semaines.'
[Span(start=1503, end=1542)] 'Une ordonnance a également été rédigée.'