Skip to content
Snippets Groups Projects
Commit 8d0b131d authored by Lili Gasser's avatar Lili Gasser
Browse files

work on notebook to read training files

parent efb056fb
No related branches found
No related tags found
No related merge requests found
This diff is collapsed.
#!/usr/bin/env python
# coding: utf8
"""Example of training spaCy's named entity recognizer, starting off with an
existing model or a blank model.
For more details, see the documentation:
* Training: https://spacy.io/usage/training
* NER: https://spacy.io/usage/linguistic-features#named-entities
Compatible with: spaCy v2.0.0+
"""
from __future__ import unicode_literals, print_function
import plac
import random
from pathlib import Path
import spacy
from spacy.util import minibatch, compounding
# training data
TRAIN_DATA = [
("Who is Shaka Khan?", {"entities": [(7, 17, "PERSON")]}),
("I like London and Berlin.", {"entities": [(7, 13, "LOC"), (18, 24, "LOC")]}),
]
TRAIN_DATA = [(' Gestatten Sie mir zunächst zwei Vorbemerkungen.', {'entities': []}),
(' Die Finanzkommission hat an ihrer letzten Sitzung, als sie vom Bericht der Arbeitsgruppe über die Eidgenössische Versicherungskasse Kenntnis genommen und die dringlichen Vorstösse beschlossen hat, die beiden Kommissionssprecher bestimmt.',
{'entities': [(110, 124, 'ORG'), (126, 144, 'ORG')]}),
(' Aufgrund der Tatsache, dass die Antwort des Bundesrates ja erst zu Beginn dieser Woche eingetroffen ist und die Finanzkommission erst nächste Woche wieder Sitzung hat, werden Herr Narbel und ich bezüglich den Antworten des Bundesrates nicht als Kommissionssprecher sprechen, sondern als Fraktionssprecher.',
{'entities': [(48, 59, 'ORG'), (195, 201, 'PER')]}),
('Eine zweite Vorbemerkung: Es ist heute morgen anlässlich des Verschiebungsantrages zur Traktandenliste der Vorwurf erhoben worden, die Finanzkommission würde dieses Geschäft benutzen, um mit dem Finanzminister alte Abrechnungen zu begleichen.',
{'entities': []}),
(' Es ist auch im weiteren durch den Präsidenten der Finanzkommission notabene ausgeführt worden, dass es sich eigentlich nicht um ein derart bedeutendes Geschäft handle, dass dieses heute vorgezogen auf die Traktandenliste gehöre.',
{'entities': []}),
('Ich möchte hier in aller Form in Abrede stellen, dass die Finanzkommission bei der Behandlung dieses Geschäftes sich von irgendwelchen parteipolitischen Hickhack-Überlegungen leiten liess, im Gegenteil.',
{'entities': []}),
("Die Finanzkommission musste sich Caisse fédérale d'assurance (CFA) 17 mars 1994 fragen, ob es denn nicht Aufgabe des Parlamentes im Sinne der Kontrolle sei, Fragen zur Diskussion zu stellen, Anträge und Vorschläge zu einer Angelegenheit zu machen, die nicht erst seit kurzem, sondern wie Sie wissen eigentlich seit 1988 zur Diskussion steht Ja, wir die klare Mehrheit der Finanzkommission glauben, dass es eben keine Bagatelle ist, wenn die Rechnung der Eidgenössischen Versicherungskasse seit 1988 nie mehr ordnungsgemäss testiert werden konnte, wenn seit 1988 mehrere Anläufe im Bereiche der Informatik gemacht worden und teilweise fehlgeschlagen sind, wenn bei den Verbuchungen zeitweilig Arbeitsrückstände von bis zu 18 Monaten festzustellen waren und wenn schliesslich Saldodifferenzen, kumuliert in dreistelliger Millionenzahl, festgestellt werden mussten.",
{'entities': []}),
('Wir glauben daher, dass es Aufgabe der Finanzkommissionen und des Parlamentes ist, sich darum zu kümmern, nachdem bereits in früheren Jahren durch die Finanzdelegation beider Räte und durch die Geschäftsprüfungskommissionen scheinbar ohne grossen Erfolg auf diese Missstände hingewiesen worden ist.',
{'entities': []}),
('Es hat ebenfalls nichts mit parteipolitischem Hickhack zu tun, wenn angesichts der grossen Dauer, während der diese Unvollkommenheiten und Missstände angedauert haben, die Frage fachlicher Unzulänglichkeiten und der politischen Verantwortung gestellt werden muss.',
{'entities': []}),
('Den Vorsorgeeinrichtungen der ersten und der zweiten Säule kommt in verschiedener Hinsicht eine Schlüsselrolle zu.',
{'entities': []}),
('Das Vertrauen der Versicherten in die entsprechenden Organisationen hat für die soziale Stabilität in diesem Lande, das wissen wir alle, eine hohe Bedeutung.',
{'entities': []}),
('Wenn wir die Mängel, aber auch die grundsätzlichen Probleme der Eidgenössischen Versicherungskasse ansehen, so gibt es eigentlich zwei Problemkreise.',
{'entities': []}),
('Zum einen geht es um Probleme in der Buchführung, der Informatik, um Probleme, die sicher im Zusammenhang auch mit Führungsfragen stehen, und daraus wiederum haben enorme Arbeitsrückstände resultiert, die die Versicherten wegen der Verzögerung bei der Bearbeitung von Dossiers am eigenen Leibe erfahren haben.',
{'entities': []}),
('Zum anderen das hat nichts mit Fehlern der EVK zu tun geht es aber um einige grundsätzliche Fragestellungen.',
{'entities': [(44, 47, 'ORG')]}),
(' Es geht um folgendes: 1.', {'entities': []}),
('den Problemkreis der Beziehungen zu den Regiebetrieben; 2.',
{'entities': []}),
('die rechnungsmässige Stellung der EVK gegenüber der Rechnung des Bundes; 3.',
{'entities': [(38, 41, 'ORG')]}),
('die Versicherungsform, sprich Leistungs oder Beitragsprimat; 4.',
{'entities': []}),
('die Frage des Deckungsgrades, d. h., wieviel vorhandenes Kapital in Prozenten des technisch notwendigen Kapitals vorhanden oder nicht vorhanden sein muss.',
{'entities': []}),
('Zum Zeitpunkt, als die Arbeitsgruppe der Finanzkommissionen beider Räte eingesetzt worden ist dies war im Frühling 1993 -, mussten wir feststellen, dass man immer noch mit deutlich über 10000 Versicherungsdossiers im Rückstand war und dass nach wie vor fehlende Saldonachweise sowie erhebliche Saldodifferenzen zwischen dem Regiebetrieb PTT, der Bundeskasse und der EVK vorhanden waren.',
{'entities': [(386, 389, 'ORG')]}),
('Wir mussten auch aufgrund der Berichte der Eidgenössischen Finanzkontrolle noch im Sommer 1993 zur Kenntnis nehmen, dass mit einergemäss der Finanzkontrolle raschen Behebung dieser Mängel nicht gerechnet werden könne.',
{'entities': [(43, 58, 'ORG'), (60, 75, 'ORG')]}),
('Nachdem über Jahre hinweg immer wieder Versprechungen gemacht worden sind, dass die Mängel behoben werden könnten, ist die Finanzkommission klar der Auffassung, dass es nicht mehr angehen kann, das auf der Zeitachse nun beliebig weiter hinauszuschieben.',
{'entities': []}),
('Was die schriftliche Stellungnahme des Bundesrates zu den dringlichen Interpellationen der Finanzkommission angeht, gestatte ich mir nun einige Bemerkungen, und zwar im Namen der Fraktion, wie ich gesagt habe, und nicht im Namen der Finanzkommission.',
{'entities': [(41, 52, 'ORG')]}),
('Wir begrüssen es und nehmen mit Genugtuung zur Kenntnis, dass in den letzten Quartalen weitere Fortschritte, vor allem im Bereich der Informatik, gemacht worden sind Fortschritte auch in bezug auf die Schnittstellen bei den Lohndaten zwischen dem Arbeitgeber und der EVK Wir sind aber von der Antwort des Bundesrates in folgenden fünf Punkten nicht befriedigt: 1.',
{'entities': [(273, 276, 'ORG'), (311, 322, 'ORG')]}),
('Es wird keine feste Zusage gemacht, wann der Bundesrat damit rechnet, dass die Rechnung der EVK ordnungsgemäss abgenommen werden kann.',
{'entities': [(46, 55, 'ORG')]}),
('2.', {'entities': []}),
('Die in der Antwort dargelegten Personalmassnahmen vermögen in dieser Form aufgrund unserer Beurteilung nicht zu genügen.',
{'entities': []}),
('3.', {'entities': []}),
('Bezüglich der Überprüfung der rechtlichen Form der EVKStatuten sind wir von der Antwort der Landesregierung nicht überzeugt.',
{'entities': []}),
(' Es ist ja so, dass die Statuten der EVK dem Parlament zur Genehmigung lediglich vorgelegt werden können.... (Zwischenrufe Marti Werner und Leuenberger Ernst) Wir haben mit dem Büro klar abgemacht und den Präsidenten der Finanzkommission gestern informiert das habe ich gesagt -, dass wir beide, Herr Narbel und ich, nicht befugt sind, zu den Antworten des Bundesrates als Kommissionssprecher Stellung zu nehmen, weil wir diese Antworten in der Kommission nicht behandelt haben, dass wir dazu aber als Fraktionsvertreter sprechen.',
{'entities': [(37, 40, 'ORG'),
(124, 129, 'PER'),
(130, 136, 'PER'),
(141, 152, 'PER'),
(307, 313, 'PER')]}),
(' Das ist klar, sauber und eindeutig.', {'entities': []}),
(' Diese Rednerliste ist gemacht worden, als man noch davon ausgegangen ist, dass die Kommissionssprecher zu den Berichten sprechen würden.',
{'entities': []}),
(' Ich bitte einfach darum, dass wir strikt zwischen Kommissionsreferaten und Fraktionserklärungen trennen.',
{'entities': []}),
(' Das haben wir immer so gemacht, wollen es auch heute so machen und wollen es auch in Zukunft so halten.',
{'entities': []}),
('Wir alle haben ja gelegentlich die eine und dann wieder die andere Rolle inné.',
{'entities': []}),
('Das wollen wir respektieren.', {'entities': []}),
('Herr Bührer Gerald hat seinen Auftrag als Kommissionssprecher vortrefflich erfüllt bis zu dem Punkt, als er für die Fraktion zu sprechen begann.',
{'entities': [(5, 11, 'PER'), (12, 18, 'PER')]}),
(' Das muss er unter anderem Titel machen.', {'entities': []}),
('Wenn wie das jetzt geschieht die Kommissionssprecher referieren, haben sie die Kommission zu repräsentieren und nicht die Fraktion.',
{'entities': []}),
('Es ist so, bleibt so, war immer so.', {'entities': []}),
(' Herr Bührer Gerald und Herr Narbel haben sich von in der Rednerliste eingeschriebenen Fraktionskollegen je vier Minuten abtreten lassen.',
{'entities': [(6, 12, 'PER'), (13, 19, 'PER'), (29, 35, 'PER')]}),
('Sie haben offensichtlich vereinbart, je vier Minuten nicht als Kommissionssprecher zu reden.',
{'entities': []}),
('Ich sehe, dass Unwille entstanden ist, weil die beiden Teile ihrer Referate aneinandergehängt werden.',
{'entities': []}),
('Ich möchte deshalb einen Vorschlag zur gütlichen Einigung machen: Den Teil, den die beiden Herren im Namen der Kommission sprechen, werden sie jetzt vorwegnehmen.',
{'entities': []}),
('Dann folgen die Redner und Rednerinnen gemäss Rednerliste; die beiden von Fraktionskollegen an Herrn Bührer und Herrn Narbel abgetretenen Redezeitanteilewerden nachträglich in die Rednerliste eingefügt Erscheint das als korrekt?',
{'entities': [(101, 107, 'PER'), (118, 124, 'PER')]}),
(' Es ist ja schon eigenartig, dass ein Kommissionsreferent vom Präsidenten der zuständigen Kommission während seines Referates unterbrochen wird.',
{'entities': []}),
('Ich bin nun, Frau Präsidentin, schon einige Zeit in diesem 17.',
{'entities': []}),
('März 1994 Eidgenössische Versicherungskasse (EVK) Parlament, aber in 23 Jahren habe ich das noch nie erlebt!',
{'entities': []}),
('Und damit zum Ordnungsantrag von Herrn Leuenberger Ernst von heute morgen.',
{'entities': [(39, 50, 'PER'), (51, 56, 'PER')]}),
('Ich bin der Auffassung, dass die Fragen der EVK von diesem Rat zu einer Stunde zu behandeln sind, die die Präsidentin beziehungsweise das Büro bestimmt, und nicht zu einer Stunde, die Herr Leuenberger Ernsthier wohl nur als Mitglied des Rates, aber nebenbei noch Präsident der Finanzkommission bestimmen will: dann nämlich, wenn offenbar die Medienvertreter weg sind, dann nämlich, wenn die Sonne untergegangen ist, damit wir, wie er dargelegt hat, diese Angelegenheit unter uns beraten können.',
{'entities': [(44, 47, 'ORG'), (189, 200, 'PER'), (201, 210, 'PER')]}),
('Unser Kommissionsreferent hat dargelegt, dass wir hier keine Parteipolitik und keine parteipolitischen Rankünen machen wollen.',
{'entities': []}),
('Das ist auch die Auffassung der CVP-Fraktion.', {'entities': []}),
('Aber offenbar hat Herr Leuenberger Angst, dass hier ein anderes Spiel gespielt werden soll, und deswegen will er diese Angelegenheit verschieben.',
{'entities': [(26, 37, 'PER')]}),
(' Damit komme ich nun aber zur Sache.', {'entities': []}),
('Verschiedene Tatsachen und Entwicklungen haben dazu geführt, dass die EVK in den vergangenen Jahren ins Gerede kam.',
{'entities': [(72, 75, 'ORG')]}),
('Im Vordergrund stand für unsere Fraktion namentlich die Tatsache, dass die Finanzkontrolle die Rechnung nicht mehr abnahm, und der Umstand, dass die Versicherungsnehmer keine Versicherungsausweise erhielten und so letztlich keine Uebersicht über ihre eigene Vorsorge mehr hatten.',
{'entities': []}),
('Gerüchte über Zahlungsprobleme, über Unzulänglichkeiten in den Statuten, über unlösbare Probleme in der Informatik und mit den angeschlossenen Organisationen, über das Verhältnis des Bundes zur EVK und vieles andere mehr brachten auch unsere Fraktion dazu, unmissverständlich die Einsetzung einer Arbeitsgruppe zu verlangen.',
{'entities': [(201, 204, 'ORG')]}),
(' Fast alle diese Gerüchte haben sich nachträglich leider als Halb oder teilweise sogar als Wahrheiten entpuppt Im Vordergrund stand dabei unsere Sorge über die soziale Abfederung der Versicherten, wobei wir sowohl die Bediensteten des Bundes als auch die Versicherten der angeschlossenen Organisationen im Auge haben.',
{'entities': []}),
('Die Arbeitsgruppe Gemperli brachte in der Folge einiges an den Tag.',
{'entities': [(18, 26, 'PER')]}),
('Neben der Auflistung der organisatorischen und versicherungstechnischen Ungereimtheiten ist für uns höchstens noch die Aussage beruhigend, dass die Versicherten wegen der bekannten Unzulänglichkeiten persönlich nicht zu Schaden kamen.',
{'entities': []}),
('Auch wenn diese Aussage an sich beruhigend wirkt, darf sie nicht darüber hinwegtäuschen, dass die Zustände in der EVK in mancherlei Beziehung unbefriedigend, in einigen Bereichen gar chaotisch sind.',
{'entities': [(123, 126, 'ORG')]}),
('Was letztlich die Aufarbeitung der bestehenden Probleme, die Anpassung der EVK an die gesetzlichen Erfordernisse und das Ausräumen und der Abtransport des politischen Schuttes kosten werden, wird uns die Geschichte mitteilen.',
{'entities': [(75, 78, 'ORG')]})
]
@plac.annotations(
model=("Model name. Defaults to blank 'en' model.", "option", "m", str),
output_dir=("Optional output directory", "option", "o", Path),
n_iter=("Number of training iterations", "option", "n", int),
)
def main(model=None, output_dir=None, n_iter=100):
"""Load the model, set up the pipeline and train the entity recognizer."""
if model is not None:
nlp = spacy.load(model) # load existing spaCy model
print("Loaded model '%s'" % model)
else:
nlp = spacy.blank("en") # create blank Language class
print("Created blank 'en' model")
# create the built-in pipeline components and add them to the pipeline
# nlp.create_pipe works for built-ins that are registered with spaCy
if "ner" not in nlp.pipe_names:
ner = nlp.create_pipe("ner")
nlp.add_pipe(ner, last=True)
# otherwise, get it so we can add labels
else:
ner = nlp.get_pipe("ner")
# add labels
for _, annotations in TRAIN_DATA:
for ent in annotations.get("entities"):
ner.add_label(ent[2])
# get names of other pipes to disable them during training
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != "ner"]
with nlp.disable_pipes(*other_pipes): # only train NER
# reset and initialize the weights randomly – but only if we're
# training a new model
if model is None:
nlp.begin_training()
for itn in range(n_iter):
random.shuffle(TRAIN_DATA)
losses = {}
# batch up the examples using spaCy's minibatch
batches = minibatch(TRAIN_DATA, size=compounding(4.0, 32.0, 1.001))
for batch in batches:
texts, annotations = zip(*batch)
nlp.update(
texts, # batch of texts
annotations, # batch of annotations
drop=0.5, # dropout - make it harder to memorise data
losses=losses,
)
print("Losses", losses)
# test the trained model
for text, _ in TRAIN_DATA:
doc = nlp(text)
print("Entities", [(ent.text, ent.label_) for ent in doc.ents])
print("Tokens", [(t.text, t.ent_type_, t.ent_iob) for t in doc])
# save model to output directory
if output_dir is not None:
output_dir = Path(output_dir)
if not output_dir.exists():
output_dir.mkdir()
nlp.to_disk(output_dir)
print("Saved model to", output_dir)
# test the saved model
print("Loading from", output_dir)
nlp2 = spacy.load(output_dir)
for text, _ in TRAIN_DATA:
doc = nlp2(text)
print("Entities", [(ent.text, ent.label_) for ent in doc.ents])
print("Tokens", [(t.text, t.ent_type_, t.ent_iob) for t in doc])
if __name__ == "__main__":
plac.call(main)
# Expected output:
# Entities [('Shaka Khan', 'PERSON')]
# Tokens [('Who', '', 2), ('is', '', 2), ('Shaka', 'PERSON', 3),
# ('Khan', 'PERSON', 1), ('?', '', 2)]
# Entities [('London', 'LOC'), ('Berlin', 'LOC')]
# Tokens [('I', '', 2), ('like', '', 2), ('London', 'LOC', 3),
# ('and', '', 2), ('Berlin', 'LOC', 3), ('.', '', 2)]
#!/usr/bin/env python3
from spacy import displacy
colors = {'ORG': '#73c6b6', 'LOC': '#bb8fce', 'PER': '#e59866', 'MISC': '#a6acaf'}
options = {'ents': ['ORG', 'LOC', 'PER', 'MISC'], 'colors': colors}
colors_sner = {'ORGANIZATION': '#73c6b6', 'LOCATION': '#bb8fce', 'PERSON': '#e59866', 'MISC': '#a6acaf'}
options_sner = {'ents': ['ORGANIZATION', 'LOCATION', 'PERSON', 'MISC'], 'colors': colors_sner}
def get_spacyformat_for_sner_output(text):
if isinstance(text, tuple):
title = text[0]
sometext = text[1]
elif isinstance(text, str):
title = None
sometext = text
# generate sner output as a list
list_tags_all = tagger.get_entities(sometext)
# initiliaze dictionary
somedict = {}
# specify text and title
somedict['text'] = sometext
if isinstance(title, str):
somedict['title'] = title
# generate list of entities with corresponding start und end indices
list_ents = []
remtext = sometext
overall_start_index = 0
for ent in list_tags_all:
start_index = remtext.index(ent[0])
overall_start_index += start_index
end_index = start_index + len(ent[0])
overall_end_index = overall_start_index + len(ent[0])
#print(ent, remtext[start_index:end_index], sometext[overall_start_index:overall_end_index])
remtext = remtext[end_index+1:]
if ent[1] != 'O':
list_ents.append({'start': overall_start_index, 'end': overall_end_index, 'label': ent[1]})
#print(ent)
overall_start_index += len(ent[0]) + 1
# add that to dictionary
somedict['ents'] = list_ents
return somedict
def write_to_txt(alldicts, filename):
f = open(filename, 'w')
for key, value in alldicts.items():
f.write( str(value) )
f.write( '\n\n.\n\n')
f.write('generated: ' + str(datetime.datetime.now()))
f.close()
def read_from_txt(filename):
f = open(filename,'r')
data=f.read()
f.close()
alldicts = {}
for sent in data.split('\n\n.\n\n'):
#print(sent)
try:
somedict = eval(sent)
key = somedict['title'].split('/')[-1]
alldicts[key] = somedict
except SyntaxError:
#print('SyntaxError')
pass
return alldicts
def render_dict(alldicts):
for sent_key, sent_dict in alldicts.items():
displacy.render(sent_dict, style='ent', jupyter=True, manual=True, options=options_sner)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment