xml2Corpus

openthesaurus eingebunden
This commit is contained in:
jannis.grundmann 2017-08-29 15:01:17 +02:00
commit 6292ee6cc7
6 changed files with 37826 additions and 0 deletions

97
.gitignore vendored Normal file
View File

@ -0,0 +1,97 @@
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

37174
openthesaurus.csv Normal file

File diff suppressed because it is too large Load Diff

261
preprocessing.py Normal file
View File

@ -0,0 +1,261 @@
# -*- coding: utf-8 -*-
import csv
import random
import re
import spacy
import textacy
import sys
"""
import keras
import numpy as np
from keras.layers import Dense, SimpleRNN, LSTM, TimeDistributed, Dropout
from keras.models import Sequential
import keras.backend as K
"""
csv.field_size_limit(sys.maxsize)
def printRandomDoc(textacyCorpus):
print()
print("len(textacyCorpus) = %i" % len(textacyCorpus))
randIndex = int((len(textacyCorpus) - 1) * random.random())
print("Index: {0} ; Text: {1} ; Metadata: {2}".format(randIndex, textacyCorpus[randIndex].text, textacyCorpus[randIndex].metadata))
print()
def getFirstSynonym(word, thesaurus_gen):
word = word.lower()
# TODO word cleaning https://stackoverflow.com/questions/3939361/remove-specific-characters-from-a-string-in-python
# durch den thesaurrus iterieren
for syn_block in thesaurus_gen: # syn_block ist eine liste mit Synonymen
# durch den synonymblock iterieren
for syn in syn_block:
syn = syn.lower().split(" ") # aus synonym mach liste (um evtl. sätze zu identifieziren)
# falls das wort in dem synonym enthalten ist (also == einem Wort in der liste ist)
if word in syn:
# Hauptform suchen
if "auptform" in syn:
# nicht ausgeben, falls es in Klammern steht
for w in syn:
if not re.match(r'\([^)]+\)', w):
return w
# falls keine hauptform enthalten ist, das erste Synonym zurückgeben, was kein satz ist und nicht in klammern steht
if len(syn) == 1:
w = syn[0]
if not re.match(r'\([^)]+\)', w):
return w
return word # zur Not die eingabe ausgeben
def cleanText(string,custom_stopwords=None, custom_symbols=None, custom_words=None, customPreprocessing=None, lemmatize=False):
import re
# use preprocessing
if customPreprocessing is not None:
string = customPreprocessing(string)
if custom_stopwords is not None:
custom_stopwords = custom_stopwords
else:
custom_stopwords = []
if custom_words is not None:
custom_words = custom_words
else:
custom_words = []
if custom_symbols is not None:
custom_symbols = custom_symbols
else:
custom_symbols = []
# custom stoplist
# https://stackoverflow.com/questions/9806963/how-to-use-pythons-import-function-properly-import
stop_words = __import__("spacy." + PARSER.lang, globals(), locals(), ['object']).STOP_WORDS
stoplist =list(stop_words) + custom_stopwords
# List of symbols we don't care about either
symbols = ["-----","---","...","","",".","-","<",">",",","?","!","..","nt","n't","|","||",";",":","","s","'s",".","(",")","[","]","#"] + custom_symbols
# get rid of newlines
string = string.strip().replace("\n", " ").replace("\r", " ")
# replace twitter
mentionFinder = re.compile(r"@[a-z0-9_]{1,15}", re.IGNORECASE)
string = mentionFinder.sub("MENTION", string)
# replace emails
emailFinder = re.compile(r"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b", re.IGNORECASE)
string = emailFinder.sub("EMAIL", string)
# replace urls
urlFinder = re.compile(r"^(?:https?:\/\/)?(?:www\.)?[a-zA-Z0-9./]+$", re.IGNORECASE)
string = urlFinder.sub("URL", string)
# replace HTML symbols
string = string.replace("&amp;", "and").replace("&gt;", ">").replace("&lt;", "<")
# parse with spaCy
spacy_doc = PARSER(string)
tokens = []
added_entities = ["WORK_OF_ART","ORG","PRODUCT", "LOC"]#,"PERSON"]
added_POS = ["NOUN", "NUM" ]#,"VERB","ADJ"] #IDEE NUM mit in den Corpus aufnehmen, aber fürs TopicModeling nur Nomen http://aclweb.org/anthology/U15-1013
# append Tokens to a list
for tok in spacy_doc:
if tok.pos_ in added_POS:
if lemmatize:
tokens.append(tok.lemma_.lower().strip())
else:
tokens.append(tok.text.lower().strip())
# add entities
if tok.ent_type_ in added_entities:
tokens.append(tok.text.lower())
# remove stopwords
tokens = [tok for tok in tokens if tok not in stoplist]
# remove symbols
tokens = [tok for tok in tokens if tok not in symbols]
# remove custom_words
tokens = [tok for tok in tokens if tok not in custom_words]
# remove single characters
tokens = [tok for tok in tokens if len(tok)>1]
# remove large strings of whitespace
while "" in tokens:
tokens.remove("")
while " " in tokens:
tokens.remove(" ")
while "\n" in tokens:
tokens.remove("\n")
while "\n\n" in tokens:
tokens.remove("\n\n")
#TODO hier thsaurus einbinden?
return " ".join(tokens)
def generateTextfromXML(path2xml, clean=True, field='Beschreibung'):
import xml.etree.ElementTree as ET
tree = ET.parse(path2xml, ET.XMLParser(encoding="utf-8"))
root = tree.getroot()
for subject in root.iter(field):
if clean:
yield cleanText(subject.text)
else:
yield subject.text
def generateMetadatafromXML(path2xml, keys=["Loesung","Kategorie","Zusammenfassung"]):
import xml.etree.ElementTree as ET
tree = ET.parse(path2xml, ET.XMLParser(encoding="utf-8"))
root = tree.getroot()
metadata = dict.fromkeys(keys)
for ticket in root.findall('ticket'):
for key in metadata:
metadata[key] = ticket.find(key).text #TODO hier thsaurus einbinden?
yield metadata
####################'####################'####################'####################'####################'##############
DATAPATH = "ticketSamples.xml"
DATAPATH_thesaurus = "openthesaurus.csv"
LANGUAGE = 'de'
####################'####################'####################'####################'####################'##############
PARSER = spacy.load(LANGUAGE)
THESAURUS_gen = textacy.fileio.read_csv(DATAPATH_thesaurus, delimiter=";") # generator [[a,b,c,..],[a,b,c,..],...]
## files to textacy-corpus
textacyCorpus = textacy.Corpus(PARSER)
print("add texts to textacy-corpus...")
textacyCorpus.add_texts(texts=generateTextfromXML(DATAPATH), metadatas=generateMetadatafromXML(DATAPATH))
#printRandomDoc(textacyCorpus)
print(textacyCorpus[len(textacyCorpus)-1].text)

61
test.py Normal file
View File

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
import re
import spacy
import textacy
DATAPATH_thesaurus = "openthesaurus.csv"
# read .csv
thesaurus = textacy.fileio.read_csv(DATAPATH_thesaurus, delimiter=";") # generator [[a,b,c,..],[a,b,c,..],...]
wort = "(anmachen)"
if not re.match(r'\([^)]+\)', wort):
print(wort)
#if "Pass" in wort: # "Pass" muss irgendwo drin sein
# print(wort.lower())
#if "Passwort" in wort.split(" "): # Pass muss gleich einem Wort sein
# print(wort.lower())
def getFirstSynonym(word, thesaurus_gen):
word = word.lower()
#TODO word cleaning https://stackoverflow.com/questions/3939361/remove-specific-characters-from-a-string-in-python
# durch den thesaurrus iterieren
for syn_block in thesaurus_gen: # syn_block ist eine liste mit Synonymen
# durch den synonymblock iterieren
for syn in syn_block:
syn = syn.lower().split(" ") # aus synonym mach liste (um evtl. sätze zu identifieziren)
# falls das wort in dem synonym enthalten ist (also == einem Wort in der liste ist)
if word in syn:
# Hauptform suchen
if "auptform" in syn:
#nicht ausgeben, falls es in Klammern steht
for w in syn:
if not re.match(r'\([^)]+\)',w):
return w
# falls keine hauptform enthalten ist, das erste Synonym zurückgeben, was kein satz ist und nicht in klammern steht
if len(syn) == 1:
w = syn[0]
if not re.match(r'\([^)]+\)', w):
return w
return word #zur Not die eingabe ausgeben
print(getFirstSynonym(wort,thesaurus))

227
ticketSamples.xml Normal file
View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<verzeichnis>
<ticket>
<Zusammenfassung>Telephone Contract</Zusammenfassung>
<Kategorie>Neuanschluss</Kategorie>
<Beschreibung>
Telefon-Neuanschluss
Antragsteller:
Melanie Hinrichs
melanie.hinrichs@tu-dortmund.de
 
 
 
Terminvorschlag unbestimmt
Einrichtung Dezernat 3
Abteilung Abteilung 2
PSP Element L-11-10000-100-302300
UniAccount myvowest(Westerdorf, Yvonne)
Gebäude Pavillon 8
Raum ID 031 (63292)
Telefondose keine vorhanden
Telefonnr. -
Eintrag Telefonbuch
E-Mail melanie.hinrichs@tu-dortmund.de
Voicemail Nicht erwünscht
Ansprechpartner Melanie Hinrichs
Tel. Ansprechpartner 5848
Verantwortlicher Nutzer -
Type Amt
Bemerkung:
Es wird ein Telefon benötigt,ein Telefon mit 6 Speicherpl.f.die Gruppenfunktion ist ausreichend. Die Möbel werden am 10.06.2015 aufgestellt.Weder Netzwerkdose noch Telefondose vorhanden. Dez.6 hat Vorbereitungen getroffen.
</Beschreibung>
<Loesung>Frau Hinrichs überdenkt die Situation und macht dann neue Anträge.
Dieses Ticket wird geschlossen</Loesung>
</ticket>
<ticket>
<Zusammenfassung>LSF/BOSS Datenexport</Zusammenfassung>
<Kategorie>LSF</Kategorie>
<Beschreibung>Sehr geehrter ITMC Service,
ich muss mir jedes Semester meine Veranstaltungen für das kommende
Semester zusammen suchen und stelle mir die Frage "Wie weit bin ich mit
meinem Studium? Welche Module kann ich wann belegen?". Gerade bei
mehreren Wahlmodulen gestaltet sich dies ja doch etwas schwieriger.
Daher möchte ich gerne, zunächst als experimentelle Privatprojekt, eine
leichtgewichtige Webseite erstellen, die mir dabei helfen soll. Meine
Vision ist, dies in weiteren Stufen meinen Kommilitonen der
Informatik-Fakultät und danach allen Studierenden zu Verfügung zu stellen.
Statt "das Rad neu zu erfinden" möchte ich einfach eine andere
Sichtweise auf die Daten in LSF und BOSS schaffen.
Zentraler Aspekt ist hier der Studienplan des Studiengangs, der
gleichzeitig eine Übersicht über noch zu erledigende Module und die
aktuelle Gesamt-Creditzahl liefern soll. Diese Ansicht soll auch dazu
dienen festzulegen, in welchem Semester man welches Modul machen möchte.
Darauf aufbauend möchte ich in einer nächsten Stufe gerne detaillierte
Veranstaltungsinformationen, ähnlich dem LSF, in einer
Facettensuche(ähnlich anzeigen. Dadurch sollen diese nach Studiengang,
Fakultät, Dozent, Semester, Turnus, etc. durchsuchbar werden.
Um den Studenten eine Orientierung zu liefern, wäre es zudem in einer
zukünftigen Version vorstellbar, den Studenten anhand der Studienpläne
und Modulabhängigkeiten (vorausgesetzte/erwünschte Kentnisse)
Veranstaltungen für das kommende Semester vorzuschlagen und
automatisiert Stundenpläne zu erstellen.
Daher möchte ich erfragen, ob
- es möglich ist einen Datenbank-Dump der Veranstaltungs-Basisdaten(z.B.
Titel, Dozent, Turnus, Uhrzeit, Beschreibung, etc.) zu erhalten
- das LSF und/oder das BOSS eine Programmierschnittstelle zur
Datenabfrage haben, welche nicht auf einem Login mit
Benutzername/Passwort basiert
- es möglich ist für einzelne Benutzer mit deren Erlaubnis eine Liste
aller Studienleistungen inkl. Veranstaltungs/BOSS-Nummer in einem
maschinenlesbaren Format (z.B. CSV oder XML, nicht PDF) abzufragen
Falls Sie noch offene Fragen haben, lassen Sie es mich wissen. Gerne
können wir diese auch in einem persönlichen Gespräch klären.
Vielen Dank!
 
Mit freundlichen Grüßen,
Tobias Brennecke
</Beschreibung>
<Loesung>alt</Loesung>
</ticket>
<ticket>
<Zusammenfassung>Zurücksetzung Passwort BOSS</Zusammenfassung>
<Kategorie>ITMC_Störungen</Kategorie>
<Beschreibung>Hallo.
Bitte setzen Sie mein Passwort zurück.
Ich würde gerne eine neues wählen.
Mit freundlichen Grüßen,
Ahmann.
IMAP0013 OK Completed (0.000 sec
IMAP0013 OK Completed (0.000 sec
IMAP0013 OK Completed (0.000 sec</Beschreibung>
<Loesung>können Sie sich im Service Portal einloggen?
Wenn ja, dann löschen Sie Ihre Cookies und den Cache.
Anschließend sollte auch die BOSS Anmeldung klappen.
Verwenden Sie Firefox oder Chrome.
Achten Sie darauf, dass der Account klein geschrieben ist, wenn sie sich mit einem Mobilgerät einloggen.
Sollte die Anmeldung im Service Portal nicht funktionieren, dann können Sie persönlich im Service Desk vorbeikommen und gegen Vorlage Ihres Personalausweises/Unicard Ihre Anmelde-Daten erhalten. Auch können wir Ihnen Ihre Zugangsdaten per Post zuschicken. Dazu müssen Sie allerdings ein paar Sicherheitsfragen beantworten:
1. Wie lautet Ihr Unimail-Namenskürzel (beginnend mit 'm' oder 'sm')
2. Wie lautet Ihre Matrikel-Nummer?
3. Wie lautet Ihr Geburtsdatum?
4. Wie lautet Ihre hinterlegte Post-Adresse?
5. Wie lautet die Antwort auf Ihre Sicherheitsfrage Geburtsname der Mutter?
6. Wie lautet Ihre aktuelle Post-Adresse?
</Loesung>
</ticket>
<ticket>
<Zusammenfassung>Forschungsantrag - Geräteanfrage</Zusammenfassung>
<Kategorie>Video</Kategorie>
<Beschreibung>Sehr geehrtes ITMC-Team,
für einen Forschungsantrag benötige ich einige technische Informationen
und bitte Sie herzlich um Unterstützung:
Zur Unterrichtsaufzeichnung möchte ich gern mit GoPro-Kameras arbeiten.
Ich möchte 4 Kameras beantragen. Könnten Sie mich beraten, welche
zusätzlichen Geräte man benötigt, um die Informationen dann für Lehre und
Forschung zu verarbeiten? Ich bin nicht sicher: gibt es Geräte, die eine
parallele Betrachtung ermöglichen? Benötigt man zusätzliche
Speicherkapazitäten? Sehr dankbar wäre ich, wenn Sie die Infos gleich mit
Kostenkalkulationen für den Antrag verbinden könnten.
Eine weitere Frage gleich nebenbei: Wird es an der TU auch die Möglichkeit
geben, in den Hörsälen direkt zentral Podcasts der Vorlesungen
aufzuzeichnen? Die Kollegen an der RUB verfügen über diese Möglichkeit
jenseits individueller Camtasia-Aufzeichnungen. Dort wird das zentral und
standardmäßig gemacht.
Ich arbeite momentan vom heimischen Schreibtisch aus. Sollten sie
Rückfragen telefonisch machen wollen, erreichten Sie mich unter
02302-9147798.
Ganz herzlichen Dank für Ihre Unterstützung!
Mit herzlichen Grüßen
Gudrun Marci-Boehncke
Prof. Dr. Gudrun Marci-Boehncke
TU Dortmund
Institut für deutsche Sprache und Literatur
Emil-Figge Str. 50, 3.241
44227 Dortmund
IMAP0013 OK Completed (0.000 sec
IMAP0013 OK Completed (0.000 sec
IMAP0013 OK Completed (0.000 sec
</Beschreibung>
<Loesung>Problem wurde telefonisch besprochen und eine Beratung ist dort erfolgt. Weitere Kommunikation erfolgt via eMail.</Loesung>
</ticket>
</verzeichnis>