Billede af redaktør
Med den stigende interesse for naturlig sprogbehandling rammer flere og flere praktikere muren, ikke fordi de ikke kan bygge eller finjustere LLM'er, men fordi deres data er rodet!
Vi vil vise enkle, men meget effektive kodningsprocedurer til fastsættelse af støjende etiketter i tekstdata. Vi vil behandle 2 almindelige scenarier i tekstdata fra den virkelige verden:
- At have en kategori, der indeholder blandede eksempler fra et par andre kategorier. Jeg elsker at kalde denne slags kategori for en metakategori.
- At have 2 eller flere kategorier, der bør slås sammen til 1 kategori, fordi tekster, der tilhører dem, refererer til det samme emne.
Vi vil bruge ITSM (IT Service Management) datasæt oprettet til denne øvelse (CCO-licens). Den er tilgængelig på Kaggle fra nedenstående link:
https://www.kaggle.com/datasets/nikolagreb/small-itsm-dataset
Det er tid til at starte med import af alle nødvendige biblioteker og grundlæggende dataundersøgelse. Forbered dig, 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 række repræsenterer én indgang i ITSM-databasen. Vi vil forsøge at forudsige kategorien af billetten baseret på teksten i billetten skrevet af en bruger. Lad os undersøge dybere de vigtigste felter for beskrevne business use cases.
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 tager et kig på de to første billetter, selvom en billet er på tysk, kan vi se, at de beskrevne problemer refererer til den samme software? - Asana, men de bærer forskellige etiketter. Dette starter distribution af vores kategorier:
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
Den nødvendige hjælp ser mistænkelig ud, ligesom den kategori, der kan indeholde billetter fra flere andre kategorier. Også kategorier Outlook og Mail lyder ens, måske skal de slås sammen til én kategori. Før vi dykker dybere ned i de nævnte kategorier, vil vi slippe af med manglende værdier i kolonner af vores 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)
Der er ikke en gyldig erstatning for undersøgelse af data med det blotte øje. Den smarte funktion til at gøre det i pandaer er .sample(), så vi vil gøre præcis det en gang til, nu for den mistænkelige kategori:
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.
---------------------------------------------------------------------------
Vi har naturligvis billetter, der taler om Discord, Asana og CRM. Så navnet på kategorien bør ændres fra "Hjælp nødvendig" til eksisterende, mere specifikke kategorier. Til det første trin i omfordelingsprocessen vil vi oprette den nye kolonne "Søgeord", der giver oplysningerne, hvis 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)
Bemærk også, at brug af "hvis ord i str(ord_kategorier)" i stedet for "hvis ord i ord_kategorier" ville fange ord fra kategorier med mere end 1 ord (internetbrowser i vores tilfælde), men ville også kræve mere dataforbehandling. For at holde tingene enkle og lige til sagen, vil vi gå med koden for kategorier lavet af kun ét ord. Sådan ser vores datasæt ud nu:
df.head(2)
output som billede:
Efter at have udtrukket søgeordskolonnen, antager vi kvaliteten af billetterne. Vores hypotese:
- Billet med kun 1 nøgleord i tekstfeltet, der er den samme som kategorien, som billetten tilhører, ville være let at klassificere.
- Billet med flere nøgleord i tekstfeltet, hvor mindst et af nøgleordene er det samme som kategorien, som billetten tilhører, ville være let at klassificere i de fleste tilfælde.
- Den billet, der har nøgleord, men ingen af dem er lig med navnet på den kategori, som billetten tilhører, er sandsynligvis en støjende etiketkasse.
- Andre billetter er neutrale baseret på nøgleord.
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 lavede vores nye distribution, og nu er det tid til at undersøge billetter, der er klassificeret som et potentielt problem. I praksis ville det følgende trin kræve meget mere sampling og se på de større bidder af data med det blotte øje, men begrundelsen ville være den samme. Det er meningen, at du skal finde problematiske billetter og beslutte, om du kan forbedre deres kvalitet, eller om du skal droppe dem fra datasættet. Når du står over for et stort datasæt, forbliv rolig, og glem ikke, at dataundersøgelse og dataforberedelse normalt tager meget mere tid end at 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-kategorier er relateret til det samme problem, så vi vil flette disse 2 kategorier og forbedre resultaterne af vores fremtidige ML-klassificeringsalgoritme.
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
Sidst, men ikke mindst, ønsker vi at ommærke nogle billetter fra metakategorien "Hjælp nødvendig" til den rigtige 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 ommærkede og rensede vores data, men vi bør ikke kalde os selv dataforskere, hvis vi ikke laver mindst ét videnskabeligt eksperiment og tester virkningen af vores arbejde på den endelige klassificering. Det vil vi gøre ved at implementere The Complement Naive Bayes-klassifikator i sklearn. Prøv gerne andre, mere komplekse algoritmer. Vær også opmærksom på, at der kan foretages yderligere datarensning - for eksempel kan vi også droppe alle tilbageværende billetter i kategorien "Nødvendig hjælp".
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
Ret imponerende, ikke? Datasættet, vi brugte, er lille (med vilje, så du nemt kan se, hvad der sker i hvert trin), så forskellige tilfældige frø kan give forskellige resultater, men i langt de fleste tilfælde vil modellen yde væsentligt bedre på datasættet efter rensning sammenlignet til det originale datasæt. Vi gjorde et godt stykke arbejde!
Nikola Greb kodet i mere end fire år, og de seneste to år har han specialiseret sig i NLP. Før han vendte sig til datavidenskab, havde han succes inden for salg, HR, skrivning og skak.
- SEO Powered Content & PR Distribution. Bliv forstærket i dag.
- Platoblokkæde. Web3 Metaverse Intelligence. Viden forstærket. Adgang her.
- Udmøntning af fremtiden med Adryenn Ashley. Adgang 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
- Konto
- nøjagtighed
- Efter
- Agent
- algoritme
- algoritmer
- Alle
- også
- Skønt
- an
- ,
- ER
- AS
- At
- til rådighed
- baseret
- grundlæggende
- BE
- fordi
- været
- før
- jf. nedenstående
- Bedre
- blokeret
- browser
- bygge
- Bygning
- virksomhed
- men
- by
- ringe
- CAN
- bære
- tilfælde
- tilfælde
- KAT
- brydning
- kategorier
- Boligtype
- lave om
- skak
- klassificering
- klassificeret
- Klassificere
- Rengøring
- Cluster
- kode
- Kodning
- Kolonne
- Kolonner
- KOM
- Fælles
- selskab
- sammenlignet
- komplement
- komplekse
- Tilslut
- tilslutning
- indeholder
- kunne
- skabe
- oprettet
- CRM
- data
- Dataforberedelse
- datalogi
- Database
- deal
- beskæftiger
- beslutte
- dybere
- beskrevet
- DID
- forskellige
- disharmoni
- fordeling
- do
- Don
- Drop
- hver
- nemt
- Effektiv
- aktiveret
- indrejse
- Ether (ETH)
- præcist nok
- eksempel
- eksempler
- eksisterende
- forventet
- eksperiment
- forklarede
- øje
- vender
- få
- felt
- Fields
- endelige
- Finde
- Fornavn
- efter
- Til
- fire
- Gratis
- fra
- funktion
- yderligere
- fremtiden
- Tysk
- få
- Giv
- giver
- Go
- godt
- sker
- Have
- he
- hovedtelefoner
- hjælpe
- rammer
- Hvordan
- hr
- HTTPS
- HubSpot
- i
- billede
- KIMOs Succeshistorier
- gennemføre
- importere
- vigtigt
- imponerende
- Forbedre
- in
- indeks
- oplysninger
- i stedet
- interesse
- Internet
- ind
- spørgsmål
- IT
- It -service
- lige
- bare en
- KDnuggets
- Holde
- Venlig
- etiket
- Etiketter
- Sprog
- laptop
- stor
- større
- biblioteker
- Licens
- ligesom
- LINK
- Liste
- Se
- leder
- UDSEENDE
- kærlighed
- lavet
- Flertal
- ledelse
- mange
- Marketing
- Medier
- Medlemmer
- Hukommelse
- nævnte
- Flet
- Meta
- Metrics
- måske
- mangler
- blandet
- ML
- model
- mere
- mest
- flere
- navn
- Natural
- Naturligt sprog
- Natural Language Processing
- behov
- Neutral
- Ny
- NLP
- notesbog
- nu
- nummer
- bedøvet
- objekt
- of
- Office
- Gammel
- on
- ONE
- Option
- or
- ordrer
- original
- Andet
- vores
- Outlook
- output
- pandaer
- forbi
- PC
- udføre
- pipeline
- plato
- Platon Data Intelligence
- PlatoData
- Vær venlig
- Punkt
- mulig
- potentiale
- praksis
- forudsige
- sandsynligvis
- Problem
- problemer
- procedurer
- behandle
- forarbejdning
- producere
- passende
- formål
- kvalitet
- tilfældig
- virkelige verden
- relaterede
- repræsenterer
- kræver
- svar
- Resultater
- afkast
- Rid
- stigende
- RÆKKE
- salg
- samme
- scenarier
- Videnskab
- forskere
- se
- frø
- synes
- tjeneste
- sæt
- bør
- Vis
- betydeligt
- lignende
- Simpelt
- siden
- lille
- So
- Social
- sociale medier
- Software
- løsninger
- nogle
- Lyd
- specialiserede
- specifikke
- delt
- starte
- Starter
- forblive
- Trin
- stoppet
- lige
- String
- vellykket
- formodes
- mistænksom
- Tag
- Tal
- taler
- hold
- Holdkammerater
- prøve
- end
- at
- oplysninger
- deres
- Them
- Der.
- Disse
- de
- ting
- denne
- billet
- billetter
- tid
- til
- også
- emne
- I alt
- Tog
- Kurser
- Drejning
- tutorial
- forstå
- Opdatering
- opdateret
- us
- Brug
- brug
- anvendte
- Bruger
- ved brug af
- sædvanligvis
- Værdier
- Vast
- meget
- via
- Væglampe
- var
- we
- Hvad
- hvornår
- som
- hvem
- vilje
- vinduer
- med
- uden
- ord
- ord
- Arbejde
- arbejder
- ville
- skrivning
- skriftlig
- X
- år
- dig
- dig selv
- zephyrnet