Bilde av redaktør
Med den økende interessen for naturlig språkbehandling, treffer flere og flere utøvere veggen, ikke fordi de ikke kan bygge eller finjustere LLM-er, men fordi dataene deres er rotete!
Vi vil vise enkle, men veldig effektive kodingsprosedyrer for å fikse støyende etiketter i tekstdata. Vi vil ta for oss to vanlige scenarier i tekstdata fra den virkelige verden:
- Å ha en kategori som inneholder blandede eksempler fra noen få andre kategorier. Jeg elsker å kalle denne typen kategori en metakategori.
- Å ha 2 eller flere kategorier som bør slås sammen til 1 kategori fordi tekster som tilhører dem refererer til samme emne.
Vi vil bruke ITSM (IT Service Management) datasett opprettet for denne opplæringen (CCO-lisens). Den er tilgjengelig på Kaggle fra lenken nedenfor:
https://www.kaggle.com/datasets/nikolagreb/small-itsm-dataset
Det er på tide å starte med import av alle nødvendige biblioteker og grunnleggende dataundersøkelse. Gjør deg klar, koden kommer!
import pandas as pd
import numpy as np
import string from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import ComplementNB
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
from sklearn import metrics df = pd.read_excel("ITSM_data.xlsx")
df.info()
RangeIndex: 118 entries, 0 to 117
Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID_request 118 non-null int64 1 Text 117 non-null object 2 Category 115 non-null object 3 Solution 115 non-null object 4 Date_request_recieved 118 non-null datetime64[ns] 5 Date_request_solved 118 non-null datetime64[ns] 6 ID_agent 118 non-null int64 dtypes: datetime64[ns](2), int64(2), object(3)
memory usage: 6.6+ KB
Hver rad representerer én oppføring i ITSM-databasen. Vi vil prøve å forutsi kategorien til billetten basert på teksten til billetten skrevet av en bruker. La oss undersøke dypere de viktigste feltene for beskrevne tilfeller av forretningsbruk.
for text, category in zip(df.Text.sample(3, random_state=2), df.Category.sample(3, random_state=2)): print("TEXT:") print(text) print("CATEGORY:") print(category) print("-"*100)
TEXT:
I just want to talk to an agent, there are too many problems on my pc to be explained in one ticket. Please call me when you see this, whoever you are. (talk to agent)
CATEGORY:
Asana
----------------------------------------------------------------------------------------------------
TEXT:
Asana funktionierte nicht mehr, nachdem ich meinen Laptop neu gestartet hatte. Bitte helfen Sie.
CATEGORY:
Help Needed
----------------------------------------------------------------------------------------------------
TEXT:
My mail stopped to work after I updated Windows.
CATEGORY:
Outlook
----------------------------------------------------------------------------------------------------
Hvis vi tar en titt på de to første billettene, selv om én billett er på tysk, kan vi se at de beskrevne problemene refererer til samme programvare?—?Asana, men de har forskjellige etiketter. Dette starter distribusjon av kategoriene våre:
df.Category.value_counts(normalize=True, dropna=False).mul(100).round(1).astype(str) + "%"
Outlook 19.1%
Discord 13.9%
CRM 12.2%
Internet Browser 10.4%
Mail 9.6%
Keyboard 9.6%
Asana 8.7%
Mouse 8.7%
Help Needed 7.8%
Name: Category, dtype: object
Hjelpen som trengs ser mistenkelig ut, som kategorien som kan inneholde billetter fra flere andre kategorier. Dessuten høres kategoriene Outlook og Mail like ut, kanskje de bør slås sammen til én kategori. Før vi dykker dypere inn i nevnte kategorier, vil vi bli kvitt manglende verdier i kolonner av interesse.
important_columns = ["Text", "Category"]
for cat in important_columns: df.drop(df[df[cat].isna()].index, inplace=True)
df.reset_index(inplace=True, drop=True)
Det er ingen gyldig erstatning for undersøkelse av data med det bare øye. Den fancy funksjonen for å gjøre det i pandaer er .sample(), så vi vil gjøre akkurat det en gang til, nå for den mistenkelige kategorien:
meta = df[df.Category == "Help Needed"] for text in meta.Text.sample(5, random_state=2): print(text) print("-"*100)
Discord emojis aren't available to me, I would like to have this option enabled like other team members have.
---------------------------------------------------------------------------
Bitte reparieren Sie mein Hubspot CRM. Seit gestern funktioniert es nicht mehr
---------------------------------------------------------------------------
My headphones aren't working. I would like to order new.
---------------------------------------------------------------------------
Bundled problems with Office since restart:
Messages not sent
Outlook does not connect, mails do not arrive
Error 0x8004deb0 appears when Connection attempt, see attachment
The company account is affected: AB123
Access via Office.com seems to be possible.
---------------------------------------------------------------------------
Asana funktionierte nicht mehr, nachdem ich meinen Laptop neu gestartet hatte. Bitte helfen Sie.
---------------------------------------------------------------------------
Tydeligvis har vi billetter som snakker om Discord, Asana og CRM. Så navnet på kategorien bør endres fra "Hjelp nødvendig" til eksisterende, mer spesifikke kategorier. For det første trinnet i omfordelingsprosessen vil vi opprette den nye kolonnen "Søkeord" som gir informasjonen om billetten har ordet fra listen over kategorier i kolonnen "Tekst".
words_categories = np.unique([word.strip().lower() for word in df.Category]) # list of categories def keywords(row): list_w = [] for word in row.translate(str.maketrans("", "", string.punctuation)).lower().split(): if word in words_categories: list_w.append(word) return list_w df["Keywords"] = df.Text.apply(keywords) # since our output is in the list, this function will give us better looking final output. def clean_row(row): row = str(row) row = row.replace("[", "") row = row.replace("]", "") row = row.replace("'", "") row = string.capwords(row) return row df["Keywords"] = df.Keywords.apply(clean_row)
Vær også oppmerksom på at bruk av "hvis ord i str(ord_kategorier)" i stedet for "hvis ord i ordkategorier" vil fange ord fra kategorier med mer enn 1 ord (nettleser i vårt tilfelle), men vil også kreve mer dataforbehandling. For å holde ting enkelt og rett på sak, vil vi gå med koden for kategorier laget av bare ett ord. Slik ser datasettet vårt ut nå:
df.head(2)
ut som bilde:
Etter å ha trukket ut nøkkelordkolonnen, vil vi anta kvaliteten på billettene. Vår hypotese:
- Billett med bare ett nøkkelord i tekstfeltet som er den samme som kategorien som billetten tilhører, ville være lett å klassifisere.
- Billett med flere nøkkelord i tekstfeltet, der minst ett av nøkkelordene er det samme som kategorien som billetten tilhører, vil være lett å klassifisere i de fleste tilfeller.
- Billetten som har nøkkelord, men ingen av dem er lik navnet på kategorien som billetten tilhører, er sannsynligvis en støyende etikettkasse.
- Andre billetter er nøytrale basert på nøkkelord.
cl_list = [] for category, keywords in zip(df.Category, df.Keywords): if category.lower() == keywords.lower() and keywords != "": cl_list.append("easy_classification") elif category.lower() in keywords.lower(): # to deal with multiple keywords in the ticket cl_list.append("probably_easy_classification") elif category.lower() != keywords.lower() and keywords != "": cl_list.append("potential_problem") else: cl_list.append("neutral") df["Ease_classification"] = cl_list
df.Ease_classification.value_counts(normalize=True, dropna=False).mul(100).round(1).astype(str) + "%"
neutral 45.6%
easy_classification 37.7%
potential_problem 9.6%
probably_easy_classification 7.0%
Name: Ease_classification, dtype: object
Vi har laget vår nye distribusjon og nå er tiden inne for å undersøke billetter klassifisert som et potensielt problem. I praksis ville det følgende trinnet kreve mye mer prøvetaking og se på de større databitene med det bare øye, men begrunnelsen ville være den samme. Det er meningen at du skal finne problematiske billetter og bestemme om du kan forbedre kvaliteten eller om du bør droppe dem fra datasettet. Når du står overfor et stort datasett, hold deg rolig, og ikke glem at dataundersøkelse og dataforberedelse vanligvis tar mye mer tid enn å bygge ML-algoritmer!
pp = df[df.Ease_classification == "potential_problem"] for text, category in zip(pp.Text.sample(5, random_state=2), pp.Category.sample(3, random_state=2)): print("TEXT:") print(text) print("CATEGORY:") print(category) print("-"*100)
TEXT:
outlook issue , I did an update Windows and I have no more outlook on my notebook ? Please help !
Outlook
CATEGORY:
Mail
-------------------------------------------------------------------- TEXT:
Please relase blocked attachements from the mail I got from name.surname@company.com. These are data needed for social media marketing campaing.
CATEGORY:
Outlook
--------------------------------------------------------------------
TEXT:
Asana funktionierte nicht mehr, nachdem ich meinen Laptop neu gestartet hatte. Bitte helfen Sie.
CATEGORY:
Help Needed
--------------------------------------------------------------------
Vi forstår at billetter fra Outlook- og Mail-kategoriene er relatert til det samme problemet, så vi vil slå sammen disse 2 kategoriene og forbedre resultatene av vår fremtidige ML-klassifiseringsalgoritme.
mail_categories_to_merge = ["Outlook", "Mail"] sum_mail_cluster = 0
for x in mail_categories_to_merge: sum_mail_cluster += len(df[df["Category"] == x]) print("Number of categories to be merged into new cluster: ", len(mail_categories_to_merge))
print("Expected number of tickets in the new cluster: ", sum_mail_cluster) def rename_to_mail_cluster(category): if category in mail_categories_to_merge: category = "Mail_CLUSTER" else: category = category return category df["Category"] = df["Category"].apply(rename_to_mail_cluster) df.Category.value_counts()
Number of categories to be merged into new cluster: 2
Expected number of tickets in the new cluster: 33
Mail_CLUSTER 33
Discord 15
CRM 14
Internet Browser 12
Keyboard 11
Asana 10
Mouse 10
Help Needed 9
Name: Category, dtype: int64
Sist, men ikke minst, ønsker vi å ommerke noen billetter fra metakategorien "Hjelp nødvendig" til riktig kategori.
df.loc[(df["Category"] == "Help Needed") & ([set(x).intersection(words_categories) for x in df["Text"].str.lower().str.replace("[^ws]", "", regex=True).str.split()]), "Category"] = "Change" def cat_name_change(cat, keywords): if cat == "Change": cat = keywords else: cat = cat return cat df["Category"] = df.apply(lambda x: cat_name_change(x.Category, x.Keywords), axis=1)
df["Category"] = df["Category"].replace({"Crm":"CRM"}) df.Category.value_counts(dropna=False)
Mail_CLUSTER 33
Discord 16
CRM 15
Internet Browser 12
Asana 11
Keyboard 11
Mouse 10
Help Needed 6
Name: Category, dtype: int64
Vi foretok ommerking og rengjøring av data, men vi bør ikke kalle oss dataforskere hvis vi ikke gjør minst ett vitenskapelig eksperiment og tester virkningen av arbeidet vårt på den endelige klassifiseringen. Vi vil gjøre det ved å implementere The Complement Naive Bayes-klassifikatoren i sklearn. Prøv gjerne andre, mer komplekse algoritmer. Vær også oppmerksom på at ytterligere datarensing kan gjøres - for eksempel kan vi også droppe alle billetter som er igjen i kategorien "Hjelp nødvendig".
model = make_pipeline(TfidfVectorizer(), ComplementNB()) # old df
df_o = pd.read_excel("ITSM_data.xlsx") important_categories = ["Text", "Category"]
for cat in important_categories: df_o.drop(df_o[df_o[cat].isna()].index, inplace=True) df_o.name = "dataset just without missing"
df.name = "dataset after deeper cleaning" for dataframe in [df_o, df]: # Split dataset into training set and test set X_train, X_test, y_train, y_test = train_test_split(dataframe.Text, dataframe.Category, test_size=0.2, random_state=1) # Training the model with train data model.fit(X_train, y_train) # Predict the response for test dataset y_pred = model.predict(X_test) print(f"Accuracy of Complement Naive Bayes classifier model on {dataframe.name} is: {round(metrics.accuracy_score(y_test, y_pred),2)}")
Accuracy of Complement Naive Bayes classifier model on dataset just without missing is: 0.48
Accuracy of Complement Naive Bayes classifier model on dataset after deeper cleaning is: 0.65
Ganske imponerende, ikke sant? Datasettet vi brukte er lite (med vilje, slik at du enkelt kan se hva som skjer i hvert trinn), så forskjellige tilfeldige frø kan gi forskjellige resultater, men i de aller fleste tilfeller vil modellen yte betydelig bedre på datasettet etter rengjøring sammenlignet til det originale datasettet. Vi gjorde en god jobb!
Nikola Greb kodet i mer enn fire år, og de siste to årene spesialiserte han seg på NLP. Før han vendte seg til datavitenskap, hadde han suksess innen salg, HR, skriving og sjakk.
- SEO-drevet innhold og PR-distribusjon. Bli forsterket i dag.
- Platoblokkkjede. Web3 Metaverse Intelligence. Kunnskap forsterket. Tilgang her.
- Minting the Future med Adryenn Ashley. Tilgang her.
- kilde: https://www.kdnuggets.com/2023/04/dealing-noisy-labels-text-data.html?utm_source=rss&utm_medium=rss&utm_campaign=dealing-with-noisy-labels-in-text-data
- : har
- :er
- :ikke
- :hvor
- 1
- 10
- 100
- 11
- 2%
- 7
- 8
- 9
- a
- Om oss
- Logg inn
- nøyaktighet
- Etter
- Agent
- algoritme
- algoritmer
- Alle
- også
- Selv
- an
- og
- ER
- AS
- At
- tilgjengelig
- basert
- grunnleggende
- BE
- fordi
- vært
- før du
- under
- Bedre
- blokkert
- nett~~POS=TRUNC leseren~~POS=HEADCOMP
- bygge
- Bygning
- virksomhet
- men
- by
- ring
- CAN
- bære
- saken
- saker
- CAT
- Catch
- kategorier
- Kategori
- endring
- Sjakk
- klassifisering
- klassifisert
- Klassifisere
- Rengjøring
- Cluster
- kode
- Koding
- Kolonne
- kolonner
- COM
- Felles
- Selskapet
- sammenlignet
- Kompletter
- komplekse
- Koble
- tilkobling
- inneholder
- kunne
- skape
- opprettet
- CRM
- dato
- Dataklargjøring
- datavitenskap
- Database
- avtale
- håndtering
- bestemme
- dypere
- beskrevet
- gJORDE
- forskjellig
- disharmoni
- distribusjon
- do
- Don
- Drop
- hver enkelt
- lett
- Effektiv
- aktivert
- entry
- Eter (ETH)
- nøyaktig
- eksempel
- eksempler
- eksisterende
- forventet
- eksperiment
- forklarte
- øye
- vendt
- Noen få
- felt
- Felt
- slutt~~POS=TRUNC
- Finn
- Først
- etter
- Til
- fire
- Gratis
- fra
- funksjon
- videre
- framtid
- Tysk
- få
- Gi
- gir
- Go
- god
- skjer
- Ha
- he
- hodetelefoner
- hjelpe
- trykke
- Hvordan
- hr
- HTTPS
- HubSpot
- i
- bilde
- Påvirkning
- implementere
- importere
- viktig
- imponerende
- forbedre
- in
- indeks
- informasjon
- i stedet
- interesse
- Internet
- inn
- utstedelse
- IT
- IT-tjeneste
- bare
- bare én
- KDnuggets
- Hold
- Type
- Etiketten
- etiketter
- Språk
- laptop
- stor
- større
- bibliotekene
- Tillatelse
- i likhet med
- LINK
- Liste
- Se
- ser
- UTSEENDE
- elsker
- laget
- Flertall
- ledelse
- mange
- Marketing
- Media
- medlemmer
- Minne
- nevnt
- Flett
- Meta
- Metrics
- kunne
- mangler
- blandet
- ML
- modell
- mer
- mest
- flere
- navn
- Naturlig
- Naturlig språk
- Natural Language Processing
- nødvendig
- Nøytral
- Ny
- nlp
- bærbare
- nå
- Antall
- følelsesløs
- objekt
- of
- Office
- Gammel
- on
- ONE
- Alternativ
- or
- rekkefølge
- original
- Annen
- vår
- Outlook
- produksjon
- pandaer
- Past
- PC
- utføre
- rørledning
- plato
- Platon Data Intelligence
- PlatonData
- vær så snill
- Point
- mulig
- potensiell
- praksis
- forutsi
- sannsynligvis
- Problem
- problemer
- prosedyrer
- prosess
- prosessering
- produsere
- ordentlig
- formål
- kvalitet
- tilfeldig
- virkelige verden
- i slekt
- representerer
- krever
- svar
- Resultater
- retur
- Kvitt
- stiger
- RAD
- salg
- samme
- scenarier
- Vitenskap
- forskere
- se
- frø
- synes
- tjeneste
- sett
- bør
- Vis
- betydelig
- lignende
- Enkelt
- siden
- liten
- So
- selskap
- sosiale medier
- Software
- løsning
- noen
- Lyd
- spesialisert
- spesifikk
- splittet
- Begynn
- Start
- opphold
- Trinn
- stoppet
- rett
- String
- vellykket
- ment
- mistenkelig
- Ta
- Snakk
- snakker
- lag
- Lag medlemmer
- test
- enn
- Det
- De
- informasjonen
- deres
- Dem
- Der.
- Disse
- de
- ting
- denne
- billett
- billetter
- tid
- til
- også
- Tema
- Totalt
- Tog
- Kurs
- Turning
- tutorial
- forstå
- Oppdater
- oppdatert
- us
- bruk
- bruke
- brukt
- Bruker
- ved hjelp av
- vanligvis
- Verdier
- enorme
- veldig
- av
- Wall
- var
- we
- Hva
- når
- hvilken
- hvem som helst
- vil
- vinduer
- med
- uten
- ord
- ord
- Arbeid
- arbeid
- ville
- skriving
- skrevet
- X
- år
- du
- deg selv
- zephyrnet