Ähnlichkeitsanalyse Text

Benrath

Community-Forum
Mitglied seit
19.05.2003
Beiträge
19.668
Reaktionen
723
Da hier ja sonst nichts passiert, nutze ich den Bereich mal wieder als meinen safe space stack overflow. Nehmen wir mal an ich habe mehrere Textabsätze („Argumente“) von denen ich weiß, dass sie in inhaltlicher Variation in längeren Emails vorkommen. Ich würde gerne durch die Emails gehen und prüfen, welche Argumente enthalten sind. Bonus wo genau in der Mail. Die Argumente sind sehr unterschiedlich lang. ~300- 3000 Zeichen. Die Mails mehrere Seiten lange, glaube z.B. knapp 30.000 Zeichen.

Haken ist, dass ich etwas eingeschränkt bei der Nutzung von Sprachmodellen etc. bin. Immerhin kann ich Python recht frei nutzen, wenn ich Pakete einfach über pip install bekomme. Externe APIs sind wegen der Art der Daten an sich auch no go. Wäre schön, wenn alles lokal bleiben kann.

Daher habe ich mir ein lokales embedding Model runtergeladen z.B. distiluse-base-multilingual-cased-v1 (https://huggingface.co/sentence-transformers/distiluse-base-multilingual-cased-v1) und versucht die Argumente zu embedden. Die Mails chunke ich mit overlap (abhängig von den Argumenten) und mach dann einen similiarity Vergleich. Testweise habe ich auch einen lokalen Vektorstore genutzt.

Packages habe ich langchain, FAISS, SentenceTransformer, HuggingFaceEmbeddings. Von mir aus kann ich auch den ganzen von ChatGPT gesponserten Code posten J

An sich funktioniert das teilweise gar nicht schlecht, wenn ich es mit alten Mails teste. Er findet viele richtig, einige zu viel, einige zu wenig. Auf meinem Rechner rattern ein paar Mails mit den ~30 Argumenten eine gute Stunde durch. Teilweise sind die Argumente fast Kopien, aber bei so langem Text wollte ich flexibel sein und dachte das direkte suche mit RegEx nicht zielführend ist, weil Formate meines Texts und in den Emails dann bestimmt abweicht.

Sieht jemand einen anderen Ansatz, den ich nutzen könnte und der auch im eingeschränkten Setup funktioniert? Könnte die Mails noch nach Länge gruppieren, dass ich nicht jedes mal alles Mails chunke je Argument.
 
Mitglied seit
21.08.2010
Beiträge
7.781
Reaktionen
958
Hm. Also was mir als erstes einfiele wäre die Möglichkeit, verschiedene Chunklängen auszuprobieren. Dann gibt es ja noch einige andere Chunkingstrategien die eventuell etwas bringen. Stärker oder weniger stark an Satzgrenzen orientieren?

Ich bin mir jetzt aber vor allem nicht sicher was Dein Problem nun konkret ist? Willst Du vornehmlich Alphafehler oder Betafehler reduzieren? Bist Du compute-constrained? Soll es langfristig in einem Prod-Setup laufen, oder ist es ein lokales Skript was auch nie außerhalb einer lokalen Maschine laufen wird?

Ich könnte mir vorstellen, dass es ein wenig der Robustheit der Ergebnisse nutzen könnte wenn Du mehrere Embeddings parallel berechnest und dann mit Deinen Beispielen vergleichst, so dass Du je Chunk mehr als nur eine "Meinung" hast. Wenn die Modelle unterschiedlich gut auf die Argumente mappen könnte das etwas bringen. Ebenso wichtig wäre es zu schauen ob unterschiedliche Distanzmaße etwas bringen. Schauen ob und wie sich TP/FP und TN/FN eventuell systematisch unterscheiden: Länge der Mail, Weitschweifigkeit der Sprache, über wie viel Text zieht sich das Argument, länger als Chunkgrenzen? … genügend Beispiele hast Du ja wenn ich Dich richtig verstehe.

Hast Du das Modell auf einer GPU deployed oder musst Du per CPU ran?
 

Benrath

Community-Forum
Mitglied seit
19.05.2003
Beiträge
19.668
Reaktionen
723
Hm. Also was mir als erstes einfiele wäre die Möglichkeit, verschiedene Chunklängen auszuprobieren. Dann gibt es ja noch einige andere Chunkingstrategien die eventuell etwas bringen. Stärker oder weniger stark an Satzgrenzen orientieren?

Ja das ist Teil meiner Frage. Vermute auch, dass es beim Chunking was zu holen wäre. Vor allem weil ich jetzt für jedes Argument individuell chunke.

Ich bin mir jetzt aber vor allem nicht sicher was Dein Problem nun konkret ist? Willst Du vornehmlich Alphafehler oder Betafehler reduzieren?

Ich wollte erstmal sehen, ob es überhaupt machbar ist. Grundsätzlich müsste ich das die Kollegen fragen, deren Aufgabe das ist. Bin da gespalten, wenn man den Text des Arguments mit dem gefundenen Chunks vergleicht ist ein False Positive vermutlich schnell idendifiziert. Eventuell ist es Ihnen auch egal, wenn sie ein paar zu viele False Positives haben und halt unnötig auf ein Argument antworten.
Bist Du compute-constrained? Soll es langfristig in einem Prod-Setup laufen, oder ist es ein lokales Skript was auch nie außerhalb einer lokalen Maschine laufen wird? Hast Du das Modell auf einer GPU deployed oder musst Du per CPU ran?

Fürs erste ist das ein lokales Skript. Und ja Compute constrained. CPU meines Laptops. Eventuell könnte ich auf einen Terinal Server mit mehr Leistung gehn.

Ich könnte mir vorstellen, dass es ein wenig der Robustheit der Ergebnisse nutzen könnte wenn Du mehrere Embeddings parallel berechnest und dann mit Deinen Beispielen vergleichst, so dass Du je Chunk mehr als nur eine "Meinung" hast. Wenn die Modelle unterschiedlich gut auf die Argumente mappen könnte das etwas bringen. Ebenso wichtig wäre es zu schauen ob unterschiedliche Distanzmaße etwas bringen. Schauen ob und wie sich TP/FP und TN/FN eventuell systematisch unterscheiden: Länge der Mail, Weitschweifigkeit der Sprache, über wie viel Text zieht sich das Argument, länger als Chunkgrenzen? … genügend Beispiele hast Du ja wenn ich Dich richtig verstehe.

Ok eventuell würde es das ganze effizienter machen, wenn ich für die Mails einmal komplett unterschiedliche Embeddings mit verschiedenen Chunkinggrenzen brechne und einmal in einem lokale Vectorstore speichere und dann die Ähnlichkeit berechne.

Dann loope ich quasi nur noch das hier über die Argumente

Code:
    # Create a vector store for the current query
    vectorstore = FAISS.from_documents(chunked_documents, embedding_model)
  
    # Perform the similarity search with scores
    docs_with_scores = vectorstore.similarity_search_with_score(query_text, k=10)




Grundsätzlich ging es mir auch einfach um den Ansatz es ohne "großes" NLP model zu machen und nur mit embedding und Ähnlichkeit.
Und welches kleine embedding model gut für Deutsch funktioniert
 
Zuletzt bearbeitet:
Oben