Jeder, der eine bestimmte Zeit damit verbracht hat, die Systeme zu unterstĂŒtzen, ist mit dem DĂ©jĂ -vu-GefĂŒhl vertraut, als er eine neue Bewerbung erhielt: "Es war so, es wurde aussortiert, aber ich kann mich nicht erinnern, wie genau". Sie können Zeit verbringen, sich mit frĂŒheren Anwendungen befassen und versuchen, Ă€hnliche zu finden. Dies hilft: Der Vorfall wird schneller geschlossen, oder es kann sogar möglich sein, die Grundursache zu erkennen und das Problem ein fĂŒr alle Mal zu schlieĂen.
Die âjungenâ Mitarbeiter, die gerade dem Team beigetreten sind, haben keine solche Geschichte im Kopf. Höchstwahrscheinlich wissen sie nicht, dass sich ein Ă€hnlicher Vorfall beispielsweise vor sechs Monaten bis zu einem Jahr ereignete. Und der Kollege aus dem Nebenzimmer entschied diesen Vorfall.
Höchstwahrscheinlich werden die "jungen" Mitarbeiter in der Vorfalldatenbank nicht nach etwas Ăhnlichem suchen, sondern Probleme von Grund auf lösen. Verbringen Sie mehr Zeit, sammeln Sie Erfahrung und kommen Sie beim nĂ€chsten Mal schneller zurecht. Oder vielleicht vergessen sie es sofort unter dem Strom neuer Anwendungen. Und beim nĂ€chsten Mal wird alles wieder passieren.
Wir verwenden bereits ML-Modelle zur Klassifizierung von VorfĂ€llen . Um unser Team bei der effizienteren Bearbeitung von AntrĂ€gen zu unterstĂŒtzen, haben wir ein weiteres ML-Modell erstellt, um eine Liste mit âzuvor abgeschlossenen Ă€hnlichen VorfĂ€llenâ zu erstellen. Details - unter dem Schnitt.
Was brauchen wir
FĂŒr jeden eingehenden Vorfall mĂŒssen âĂ€hnlicheâ geschlossene VorfĂ€lle in der Historie gefunden werden. Die Definition von âĂhnlichkeitâ sollte zu Beginn des Vorfalls erfolgen, vorzugsweise bevor das Support-Personal mit der Analyse begonnen hat.
Zum Vergleichen von VorfĂ€llen mĂŒssen die vom Benutzer bei der Kontaktaufnahme bereitgestellten Informationen verwendet werden: eine kurze Beschreibung, eine detaillierte Beschreibung (falls vorhanden) sowie Attribute des Benutzerdatensatzes.
Das Team unterstĂŒtzt 4 Systemgruppen. Die Gesamtzahl der VorfĂ€lle, mit denen ich nach Ă€hnlichen VorfĂ€llen suchen möchte, betrĂ€gt ungefĂ€hr 10.000.
Erste Entscheidung
Es liegen keine ĂŒberprĂŒften Informationen zur "Ăhnlichkeit" der vorliegenden VorfĂ€lle vor. Daher mĂŒssen die hochmodernen Optionen fĂŒr das Training siamesischer Netzwerke vorerst verschoben werden.
Das erste, was mir in den Sinn kommt, ist eine einfache Ansammlung einer "TĂŒte mit Wörtern", die sich aus dem Inhalt der Berufungen zusammensetzt.
In diesem Fall ist der Prozess zur Behandlung von VorfÀllen wie folgt:
- Hervorheben der erforderlichen Textfragmente
- Textvorverarbeitung / -reinigung
- TF-IDF-Vektorisierung
- Finden Sie Ihren nÀchsten Nachbarn
Es ist klar, dass bei dem beschriebenen Ansatz die Ăhnlichkeit auf einem Vergleich von WörterbĂŒchern basiert: Die Verwendung derselben Wörter oder n-Gramm in zwei verschiedenen VorfĂ€llen wird als âĂhnlichkeitâ angesehen.
Dies ist natĂŒrlich ein ziemlich vereinfachter Ansatz. Denken Sie jedoch daran, dass wir die Texte von Benutzertreffern auswerten, wenn das Problem in Ă€hnlichen Worten beschrieben wird - höchstwahrscheinlich sind die VorfĂ€lle Ă€hnlich. ZusĂ€tzlich zum Text können Sie den Namen der Benutzerabteilung hinzufĂŒgen, wobei Sie erwarten, dass Benutzer derselben Abteilungen in verschiedenen Organisationen Ă€hnliche Probleme haben.
Hervorheben der erforderlichen Textfragmente
Ereignisdaten erhalten wir auf einfachste Weise von service-now.com - indem wir Benutzerberichte programmgesteuert starten und ihre Ergebnisse in Form von CSV-Dateien erhalten.
Daten zu Nachrichten, die im Rahmen des Vorfalls zwischen Support und Benutzern ausgetauscht werden, werden in diesem Fall in Form eines groĂen Textfelds mit dem gesamten Verlauf der Korrespondenz zurĂŒckgegeben.
Die Informationen ĂŒber den ersten Aufruf aus einem solchen Feld mussten durch regulĂ€re AusdrĂŒcke "herausgeschnitten" werden.
- Alle Nachrichten sind durch eine Kennlinie <wenn> - <wer> getrennt.
- Nachrichten enden hÀufig mit formellen Unterschriften, insbesondere wenn der Einspruch per E-Mail eingelegt wurde. Diese Informationen sind in der Liste der wichtigen Wörter merklich "fonil", daher musste auch die Signatur gelöscht werden.
Es stellte sich ungefĂ€hr so ââheraus:
def get_first_message(messages): res = "" if len(messages) > 0:
Vorverarbeitung von Vorfalltexten
Um die QualitÀt der Klassifizierung zu verbessern, wird der Berufungstext vorverarbeitet.
Unter Verwendung einer Reihe regulĂ€rer AusdrĂŒcke in den Vorfallbeschreibungen wurden charakteristische Fragmente gefunden: Daten, Servernamen, Produktcodes, IP-Adressen, Webadressen, falsche Namensformen usw. Solche Fragmente wurden durch die entsprechenden Konzeptmarken ersetzt.
Am Ende wurde Stottern verwendet, um Wörter zu einer gemeinsamen Form zu bringen. Dies ermöglichte es uns, die Pluralformen und Endungen von Verben loszuwerden. Der bekannte snowballstemmer
wurde als Stemmer verwendet.
Alle Verarbeitungsprozesse werden zu einer Transformationsklasse zusammengefasst, die in verschiedenen Prozessen verwendet werden kann.
Ăbrigens stellte sich (natĂŒrlich experimentell) heraus, dass die Methode stemmer.stemWord()
nicht threadsicher ist. Wenn Sie versuchen, eine parallele Textverarbeitung in der Pipeline zu implementieren, z. B. mit joblib
Prallel / verzögert, muss der Zugriff auf die allgemeine Instanz des Stemmer daher durch Sperren geschĂŒtzt werden.
__replacements = [ ('(\d{1,3}\.){3}\d{1,3}', 'IPV4'), ('(?<=\W)((\d{2}[-\/ \.]?){2}(19|20)\d{2})|(19|20)\d{2}([-\/ \.]?\d{2}){2}(?=\W)', 'YYYYMMDD'), ('(?<=\W)(19|20)\d{2}(?=\W)', 'YYYY'), ('(?<=\W)(0|1)?\d\s?(am|pm)(?=\W)', 'HOUR'), ('http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', 'SOMEURL')
Vektorisierung
Die Vektorisierung wird vom Standard- TfidfVectorizer
mit den folgenden Einstellungen durchgefĂŒhrt:
max_features
= 10000ngram
= (1,3) - in dem Versuch, stabile Kombinationen und semantische Konnektiva zu fangenmax_df
/ min_df
- standardmĂ€Ăig verlassenstop_words
- eine Standardliste mit englischen Wörtern sowie eine eigene zusÀtzliche Wortgruppe. Einige Benutzer erwÀhnten beispielsweise Analystennamen, und Eigennamen wurden hÀufig zu wichtigen Attributen.
TfidfVectorizer
selbst fĂŒhrt standardmĂ€Ăig eine L2-Normalisierung durch, sodass einfallende Vektoren bereit sind, den Kosinusabstand zwischen ihnen zu messen.
Suchen Sie nach Àhnlichen VorfÀllen
Die Hauptaufgabe des Prozesses besteht darin, eine Liste der nĂ€chsten N Nachbarn zurĂŒckzugeben. Die Klasse sklearn.neighbors.NearestNeighbors
ist dafĂŒr gut geeignet. Ein Problem besteht darin, dass die transform
nicht implementiert wird, ohne die sie nicht in der pipeline
.
Daher war es notwendig, es auf Transformer
basieren, was es erst dann in den letzten Schritt der pipeline
:
class NearestNeighborsTransformer(NearestNeighbors, TransformerMixin): def __init__(self, n_neighbors=5, radius=1.0, algorithm='auto', leaf_size=30, metric='minkowski', p=2, metric_params=None, n_jobs=None, **kwargs): super(NearestNeighbors, self).__init__(n_neighbors=n_neighbors, radius=radius, algorithm=algorithm, leaf_size=leaf_size, metric=metric, p=p, metric_params=metric_params, n_jobs=n_jobs) def transform(self, X, y=None): res = self.kneighbors(X, self.n_neighbors, return_distance=True) return res
Verarbeitungsprozess
Wenn wir alles zusammenfĂŒgen, erhalten wir einen kompakten Prozess:
p = Pipeline( steps=[ ('grp', ColumnTransformer( transformers=[ ('text', Pipeline(steps=[ ('pp', CommentsTextTransformer(n_jobs=-1)), ("tfidf", TfidfVectorizer(stop_words=get_stop_words(), ngram_range=(1, 3), max_features=10000)) ]), ['short_description', 'comments', 'u_impacted_department'] ) ] )), ("nn", NearestNeighborsTransformer(n_neighbors=10, metric='cosine')) ], memory=None)
Nach dem Training kann die pipeline
mit pickle in einer Datei gespeichert und zur Behandlung eingehender VorfÀlle verwendet werden.
Zusammen mit dem Modell speichern wir die erforderlichen Vorfallfelder, um sie spĂ€ter in der Ausgabe zu verwenden, wenn das Modell ausgefĂŒhrt wird.
Erste Anwendungsergebnisse
Die Reaktion der Kollegen auf die EinfĂŒhrung eines Systems von "Hinweisen" war im Allgemeinen sehr positiv. Wiederkehrende VorfĂ€lle wurden schneller behoben, und wir begannen mit der Fehlerbehebung.
Von dem unbeaufsichtigten Lernsystem konnte man jedoch kein Wunder erwarten. Kollegen beschwerten sich, dass das System manchmal völlig irrelevante Links bietet. Manchmal war es sogar schwierig zu verstehen, woher solche Empfehlungen stammen.
Es war klar, dass das Feld zur Verbesserung des Modells riesig ist. Einige der MĂ€ngel können behoben werden, einschlieĂlich oder ohne einige Attribute des Vorfalls. Teil - durch Auswahl eines angemessenen Grenzwerts fĂŒr den Abstand zwischen dem aktuellen Vorfall und der âEmpfehlungâ. Andere Vektorisierungsmethoden können in Betracht gezogen werden.
Das Hauptproblem war jedoch das Fehlen von QualitĂ€tsmetriken fĂŒr Empfehlungen. Und wenn ja, war es unmöglich zu verstehen, "was gut und was schlecht ist und wie viel" und einen Vergleich der Modelle darauf aufzubauen.
Wir hatten keinen Zugriff auf http-Protokolle, da das Dienstsystem remote (SaaS) arbeitet. Wir haben Nutzerbefragungen durchgefĂŒhrt - aber nur qualitativ. Es war notwendig, mit quantitativen Bewertungen fortzufahren und auf deren Grundlage klare QualitĂ€tsmetriken aufzubauen.
Aber mehr dazu im nÀchsten Teil ...