Docs: Update readme.md with company_deduplicator.py changes
This commit is contained in:
49
readme.md
49
readme.md
@@ -39,7 +39,7 @@ V. DAS KLASSIFIZIERUNGS-SYSTEM (Job-Titel-Analyse)
|
||||
└── knowledge_base_builder.py (Baut die Wissensbasis FÜR die Klassifizierung)
|
||||
|
||||
VI. DAS STANDALONE-WERKZEUG
|
||||
└── duplicate_checker_old.py (Eigenständiger Duplikats-Check)
|
||||
└── company_deduplicator.py (Eigenständiger Duplikats-Check für externe und interne Listen)
|
||||
|
||||
VII. DAS FUNDAMENT
|
||||
└── config.py (Einstellungen & Konstanten für ALLE)
|
||||
@@ -476,10 +476,21 @@ Das Ziel ist es, die automatische und präzise Klassifizierung neuer, unbekannte
|
||||
|
||||
Dieser Bereich enthält Skripte, die als eigenständige Werkzeuge für spezifische Aufgaben konzipiert sind.
|
||||
|
||||
### `duplicate_checker_old.py` (Duplikats-Check)
|
||||
### `company_deduplicator.py` (Duplikats-Check)
|
||||
|
||||
#### Hauptfunktion
|
||||
Das Skript `duplicate_checker_old.py` (Version 2.15) ist ein spezialisiertes Werkzeug zur Identifizierung von potenziellen Duplikaten zwischen zwei Unternehmenslisten in Google Sheets: einer Matching-Liste (`Matching_Accounts`) und einer Referenz-CRM-Liste (`CRM_Accounts`). Es verwendet einen gewichteten, heuristischen Algorithmus, um für jeden Eintrag in der Matching-Liste den wahrscheinlichsten Treffer im CRM-Bestand zu finden und bewertet diesen mit einem numerischen Score.
|
||||
Das Skript `company_deduplicator.py` (ehemals `duplicate_checker_old.py`) ist ein spezialisiertes Werkzeug zur Identifizierung von potenziellen Unternehmens-Duplikaten. Es operiert in zwei Modi:
|
||||
|
||||
1. **Externer Vergleich:** Identifiziert Duplikate zwischen einer externen Liste (`Matching_Accounts`) und der internen CRM-Liste (`CRM_Accounts`). Dies ist die ursprüngliche Funktionalität.
|
||||
2. **Interne Deduplizierung:** Findet Duplikate *innerhalb* der `CRM_Accounts`-Liste, gruppiert diese und markiert sie zur weiteren Bearbeitung.
|
||||
|
||||
Es verwendet einen gewichteten, heuristischen Algorithmus, um Ähnlichkeiten zu bewerten und nutzt bekannte Unternehmenshierarchien (`Parent Account`), um Falsch-Positive zu reduzieren.
|
||||
|
||||
#### Neue Features (Interne Deduplizierung)
|
||||
- **Zwei-Modi-Betrieb:** Das Skript fragt beim Start interaktiv ab, ob ein externer Vergleich oder eine interne Deduplizierung durchgeführt werden soll.
|
||||
- **Gruppierung & ID-Zuweisung:** Im internen Modus werden gefundene Duplikatspaare zu Clustern zusammengefasst (z.B. wenn A=B und B=C, dann ist A,B,C eine Gruppe). Jede Gruppe erhält eine eindeutige ID (z.B. `Dup_0001`), die in eine neue Spalte `Duplicate_ID` im `CRM_Accounts`-Sheet geschrieben wird.
|
||||
- **Nutzung von Unternehmenshierarchien:** Das Skript liest die Spalte `Parent Account` aus dem `CRM_Accounts`-Sheet. Bekannte Eltern-Kind-Beziehungen werden automatisch von der Duplikatsprüfung ausgeschlossen, was die Genauigkeit erheblich verbessert.
|
||||
- **Handlungsempfehlungen:** Findet das Skript eine Duplikatsgruppe, in der bei keinem der Mitglieder ein `Parent Account` gepflegt ist, wird dies in einer neuen Spalte `Duplicate_Hint` vermerkt. Dies dient als Hinweis, dass hier möglicherweise eine Hierarchie im CRM nachgepflegt werden sollte.
|
||||
|
||||
#### Abhängigkeiten
|
||||
- **`pandas`**: Zur Datenmanipulation und -analyse.
|
||||
@@ -498,21 +509,23 @@ Die Logik des Skripts wird durch mehrere Konstanten am Anfang der Datei gesteuer
|
||||
- **Prefiltering**: `PREFILTER_MIN_PARTIAL` (70) und `PREFILTER_LIMIT` (30) zur Vorauswahl potenzieller Kandidaten, um die Performance zu verbessern.
|
||||
- **Stop-Wörter**: `STOP_TOKENS_BASE` und `CITY_TOKENS` (dynamisch generiert) enthalten Begriffe, die bei Namensvergleichen ignoriert werden, um die Signalqualität zu erhöhen.
|
||||
|
||||
#### Ablauf-Logik
|
||||
1. **Initialisierung**: Das Skript richtet das Logging ein, lädt API-Schlüssel (optional für SerpAPI) und initialisiert den `GoogleSheetHandler`.
|
||||
2. **Daten laden**: Die Daten aus den beiden Google Sheets (`CRM_Accounts` und `Matching_Accounts`) werden in Pandas DataFrames geladen.
|
||||
3. **SerpAPI-Fallback (Optional)**: Für Einträge in der Matching-Liste ohne Website wird versucht, über die SerpAPI eine URL zu finden. Das Vertrauen in die gefundene URL wird bewertet (`hoch`, `mittel`, `niedrig`).
|
||||
4. **Normalisierung**: Unternehmensnamen, Domains, Orte und Länder in beiden DataFrames werden standardisiert (z.B. Kleinschreibung, Entfernung von Rechtsformzusätzen).
|
||||
5. **Index-Erstellung**: Zur Optimierung der Suche werden mehrere "Blocking"-Indizes aus den CRM-Daten erstellt:
|
||||
- Ein `domain_index` für schnelle Suchen über die Website-Domain.
|
||||
- Ein `token_index` für die Suche nach einzelnen Namensbestandteilen.
|
||||
- Eine `token_freq` Zählung, um seltene und damit aussagekräftige Namensbestandteile zu identifizieren.
|
||||
6. **Iteratives Matching**: Das Skript durchläuft jeden Datensatz der Matching-Liste:
|
||||
a. **Kandidatenauswahl**: Anstatt jeden Eintrag mit der gesamten CRM-Liste zu vergleichen, wird eine kleine, relevante Untergruppe von Kandidaten ausgewählt. Die Auswahl erfolgt priorisiert: zuerst über Domain-Übereinstimmung, dann über den seltensten Namens-Token und zuletzt über einen allgemeinen Prefilter.
|
||||
b. **Scoring**: Jeder Kandidat wird mit dem aktuellen Matching-Datensatz verglichen. Die Funktion `calculate_similarity` berechnet einen Score basierend auf einer gewichteten Formel, die Namensähnlichkeit, Domain-Match, Standortübereinstimmung, Boni und Strafen berücksichtigt.
|
||||
c. **Bester Treffer**: Der Kandidat mit dem höchsten Score wird als potenzielles Duplikat ausgewählt.
|
||||
7. **Ergebnis-Aggregation**: Die Ergebnisse (bester Treffer, Score, Begründung der Bewertung) werden gesammelt.
|
||||
8. **Daten zurückschreiben**: Die Matching-Liste wird um die Ergebnisspalten (`Match`, `Score`, `Match_Grund`) erweitert und vollständig in das Google Sheet `Matching_Accounts` zurückgeschrieben. Ein lokales CSV-Backup wird ebenfalls erstellt.
|
||||
#### Ablauf-Logik (Gekürzt)
|
||||
1. **Modus-Auswahl**: Das Skript fragt den Benutzer nach dem gewünschten Modus (Extern vs. Intern).
|
||||
2. **Initialisierung & Daten laden**: Richtet das Logging ein und lädt die relevanten Google Sheets. Im internen Modus wird auch die `Parent Account`-Spalte geladen.
|
||||
3. **Normalisierung & Index-Erstellung**: Unternehmensnamen, Domains, Orte und Parent Accounts werden standardisiert. Zur Optimierung der Suche werden "Blocking"-Indizes (z.B. für Domains und Namens-Tokens) erstellt.
|
||||
4. **Matching-Prozess**:
|
||||
- **Extern:** Jeder Eintrag aus `Matching_Accounts` wird mit Kandidaten aus `CRM_Accounts` verglichen.
|
||||
- **Intern:** Jeder Eintrag aus `CRM_Accounts` wird mit nachfolgenden Kandidaten aus derselben Liste verglichen, wobei bekannte Hierarchien übersprungen werden.
|
||||
5. **Scoring & Gruppierung**: Kandidatenpaare werden bewertet. Im internen Modus werden Paare über dem Schwellenwert zu Gruppen zusammengefasst.
|
||||
6. **Daten zurückschreiben**:
|
||||
- **Extern:** Die Ergebnisse (`Match`, `Score`) werden in das `Matching_Accounts`-Sheet geschrieben.
|
||||
- **Intern:** Die `Duplicate_ID` und `Duplicate_Hint` werden in neue Spalten im `CRM_Accounts`-Sheet geschrieben.
|
||||
|
||||
#### To-Dos & Nächste Schritte
|
||||
- **Scoring-Schwellenwert erhöhen:** Der `SCORE_THRESHOLD` von 80 ist für die interne Deduplizierung zu niedrig und sollte auf 95 oder höher angehoben werden, um Falsch-Positive zu reduzieren.
|
||||
- **Stop-Wort-Liste erweitern:** Die `STOP_TOKENS_BASE`-Liste um generische Branchenbegriffe wie 'energy', 'services', 'group', 'solutions' etc. erweitern.
|
||||
- **Scoring-Logik anpassen:** Die Gewichtung sollte angepasst werden, sodass eine hohe Namensähnlichkeit in Kombination mit einem Standort-Match stärker bewertet wird.
|
||||
- **Debugging-Log verbessern:** Die Log-Ausgabe für gefundene Paare sollte die komplette Scoring-Zusammensetzung ausgeben, um die Analyse von Ergebnissen zu erleichtern.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user