Commit d50bd9af authored by Christof Walther's avatar Christof Walther Committed by Patrick Schlindwein
Browse files

feat: If applied, this commit will add basic intent similarity analysis structures and tests.

GitLab issue #3 "SpaCy - Ähnlichkeit der generierten ID"
parent 4abc0a51
src/ktor-server/test.js
data/testHiglighted.docx
data/~$anges-faq.docx
.vscode/settings.json
src/nlp/.vscode/settings.json
src/ktor-server/.idea/compiler.xml
src/ktor-server/.idea/gradle.xml
src/ktor-server/.idea/ktor-server.iml
src/ktor-server/.idea/misc.xml
from app.similarity.intent_cluster import IntentCluster
from app.similarity.intent import Intent
# very primitive clustering algrotihm for intents
def find_intent_clusters(intent_list: list[Intent], t: float, iterations: int) -> float:
# init
cluster_list = []
cluster_index = 0
for _ in range(0, iterations):
for current_intent in intent_list:
added_to_cluster = False
# check if current_intent is close enough to a cluster
for current_cluster in cluster_list:
# add to a close cluster
if current_intent.similarity(current_cluster.center) > t:
if current_intent not in current_cluster:
current_cluster.append(current_intent)
current_cluster.recalculate_center()
added_to_cluster = True
# if not then become a cluster center
if not added_to_cluster:
cluster_list.append(IntentCluster(
str(cluster_index), current_intent))
cluster_index += 1
return cluster_list
import spacy
import numpy as np
import math
class Intent:
nlp = spacy.load('de_core_news_sm')
def __init__(self, id: str):
self.n = Intent.nlp(id)
self.id = id
self.vector = self.n.vector
self.vector_norm = self.n.vector_norm
# calculating the smiliarity of the Intent to another intent
def similarityIntent(self, intent) -> float:
return self.n.similarity(intent.n)
# calculating the smiliarity of the Intent to another vector
def similarity(self, vector) -> float:
norm = 0
for x in vector:
norm += x ** 2
norm = math.sqrt(norm)
return np.dot(self.vector, vector) / (self.vector_norm * norm)
import statistics
from app.similarity.intent import Intent
class IntentCluster(list):
def __init__(self, label: str, intent: Intent):
self.center = intent.vector
self.append(intent)
self.label = label
# setting the center of the cluster equal to the median of all elements
def recalculate_center(self):
for i in range(0, len(self.center)):
tmp_list = []
for element in self:
tmp_list.append(element.vector[i])
self.center[i] = statistics.median(tmp_list)
from unittest import TestCase
from app.utilities.generator import IntentHandler
from app.similarity.cluster_algorithm import find_intent_clusters
from app.similarity.intent import Intent
class TestSimilarityAnalysis(TestCase):
rki_faq = [
"Was ist über den Erreger und die Krankheit bekannt?",
"Wie erfasst das RKI die Situation in Deutschland, wie schätzt das RKI die Lage ein und welche Empfehlungen gibt es für die Fachöffentlichkeit?",
"Was versteht man unter der Reproduktionszahl R, und wie wichtig ist sie für die Bewertung der Lage?",
"Welchen Zusammenhang gibt es generell zwischen erhöhten Testzahlen und erhöhten Fallzahlen?",
"Gibt es eine Saisonalität bei SARS-CoV-2?",
"Welche Rolle spielen die neuen, besorgniserregenden Varianten?",
"Wo gibt es die aktuellen Fallzahlen und Inzidenzen?",
"Was ist alles meldepflichtig?",
"Wie funktioniert der Meldeweg und welche Informationen zu den Erkrankten werden ans RKI übermittelt?",
"Werden die Meldedaten durch die wachsende Anzahl an Schnelltests verzerrt?",
"Wie entsteht die Diskrepanz zwischen Inzidenzen der Landkreise und den Angaben des RKI-Dashboards?",
"Warum sind die Fallzahlen am/nach dem Wochenende geringer als an Arbeitstagen?",
"Wie erfassen Gesundheitsämter Fälle, Ausbrüche und Infektionsumstände?",
"Wie werden Todesfälle erfasst?",
"Weiß man, wie viele COVID-19-Patienten im Krankenhaus und auf Intensivstationen behandelt werden und wie viele die akute Infektion überstanden haben?",
"Was ist der Unterschied zwischen den COVID-19-Meldedaten nach <abbr>IfSG </abbr>und SARS-CoV-2-Nachweisen aus dem Sentinel der Arbeitsgemeinschaft Influenza?",
"Warum bilden sich die COVID-19-Wellen bisher nicht bei GrippeWeb ab?",
"Wieso unterscheidet sich die Anzahl der COVID-19 Fälle aus dem ICOSARI-Krankenhaus-Sentinel von der Anzahl Intensivpatienten mit COVID-19 aus dem DIVI-Intensivregister?",
"Welche Gruppen sind besonders häufig von einem schweren Verlauf betroffen?",
"Ist man nach einer durchgemachten SARS-CoV-2-Infektion immun?",
"Was ist über COVID-19 bei Kindern und Jugendlichen bekannt?",
"Was ist über COVID-19 bei Schwangeren bekannt?",
"Ist die Blutgruppe ein Risikofaktor für COVID-19?",
"Welche Behandlungsmöglichkeiten stehen für eine COVID-19-Erkrankung zur Verfügung?",
"Warum sind bei SARS-CoV-2/COVID-19 solche weitreichenden Maßnahmen erforderlich?",
"Wie kann man sich bzw. seine Mitmenschen vor einer Ansteckung schützen?",
"Welche Rolle spielen die Impfungen gegen COVID-19, Impfungen im Rahmen der Pandemie und was gilt es beim Impfen zu beachten?",
"Welchen Vorteil bringt Abstand halten die Beschränkung sozialer Kontakte?",
"Was ist beim Tragen einer Mund-Nasen-Bedeckung bzw. eines Mund-Nasen-Schutzes (\"OP-Maske\") in der Öffentlichkeit zu beachten?",
"Welche Funktion bzw. Einsatzbereiche haben FFP2-Masken außerhalb des Arbeitsschutzes?",
"Ist der Einsatz von Visieren anstatt einer Mund-Nasen-Bedeckung im öffentlichen Raum sinnvoll?",
"Ist der Einsatz von Visieren im öffentlichen Raum sinnvoll?",
"Welche Rolle spielen Aerosole bei der Übertragung von SARS-CoV-2?",
"Was ist beim Lüften zu beachten?",
"Können Luftreinigungsgeräte bzw. mobile Luftdesinfektionsgeräte andere Hygienemaßnahmen ersetzen?",
"Was ist aus Sicht des Infektionsschutzes im Schulumfeld zu beachten?",
"Was ist beim Umgang mit an COVID-19-Verstorbenen zu beachten?",
"Was müssen Arbeitnehmerinnen und Arbeitnehmer während der COVID-19-Pandemie beachten, welche Verpflichtungen haben Arbeitgeber?",
"Was ist bei Reisen zu beachten?",
"Besteht die Gefahr, sich über Lebensmittel, Oberflächen, Gegenstände oder in der Umwelt mit SARS-CoV-2 anzustecken?",
"Welche Empfehlungen gibt es für den Umgang mit Haustieren?",
"Was versteht man unter Isolierung, was unter Quarantäne und welchen Zweck haben diese?",
"Wann und wie lange muss man in Quarantäne?",
"Was wird empfohlen bei Personen, die als genesen gelten?",
"Was versteht man unter Kontaktpersonennachverfolgung, was müssen Kontaktpersonen beachten?",
"Wie funktioniert die Corona Warn-App?",
"Wie funktioniert die Corona App?",
"Was ist ein Containment Scout?",
"Wie geht man bei Ausbruchsuntersuchungen vor?",
"Wie wird eine Infektion mit SARS-CoV-2 labordiagnostisch nachgewiesen, welche Tests gibt es?",
"Welche Anforderungen werden an Antigen-Tests gestellt?",
"Was ist bei Antigentests zur Eigenanwendung (Selbsttests) zu beachten?",
"Wann sollte ein Arzt eine Laboruntersuchung auf SARS-CoV-2 veranlassen?",
"Was sollen Betroffene mit Symptomen tun?",
"Was sollen Symptomen mit Betroffene tun?",
"Was sollen Betroffene tun?",
"Wie wird die Anzahl an Labortests in Deutschland erfasst?",
"Was bedeutet die Positivenquote?",
"Welche Rolle spielen falsch-positive Testergebnisse?",
"Ist ein Test bei Personen ohne jedes Krankheitszeichen sinnvoll? ",
"Warum sind Genomsequenzierungen wichtig?",
"Wo gibt es weitere Informationen?"
]
def test_similarty(self):
# generate 2 similary ids
ih = IntentHandler(TestSimilarityAnalysis.rki_faq[53])
ih2 = IntentHandler(TestSimilarityAnalysis.rki_faq[54])
id = ih.generate_intent_id(3).replace("_", " ")
id2 = ih2.generate_intent_id(3).replace("_", " ")
# init id vetors
intent1 = Intent(id)
intent2 = Intent(id2)
# check if they are similar
self.assertGreaterEqual(intent1.similarityIntent(intent2), 0.85)
def test_cluster(self):
intent_list = []
# generate ids for all questions and init the id vectors
for q in TestSimilarityAnalysis.rki_faq:
ih = IntentHandler(q)
id = ih.generate_intent_id(3).replace("_", " ")
intent = Intent(id)
if intent.vector_norm > 0:
intent_list.append(intent)
# generate the clusters
cluster_list = find_intent_clusters(intent_list, 0.85, 10)
# find clusters with more then 1 entry
counter = 0
for cluster in cluster_list:
if len(cluster) > 1:
counter += 1
# check if all 4 clusters were found
self.assertEqual(counter, 4)
......@@ -5,10 +5,11 @@ import de_core_news_md
import re # regular expressions
class IntentHandler:
nlp = spacy.load("de_core_news_md")
def __init__(self, intent: str):
self.intent = intent
self.nlp = spacy.load("de_core_news_md")
self.doc = self.nlp(intent)
self.doc = IntentHandler.nlp(intent)
def generate_intent_id(self, maxTokens: int):
"""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment