Slika urednika
Z naraščajočim zanimanjem za obdelavo naravnega jezika se vedno več praktikov zaletava v zid, ne zato, ker ne morejo zgraditi ali natančno nastaviti LLM-jev, temveč zato, ker so njihovi podatki neurejeni!
Prikazali bomo preproste, a zelo učinkovite postopke kodiranja za popravljanje šumnih oznak v besedilnih podatkih. Ukvarjali se bomo z dvema pogostima scenarijema v besedilnih podatkih v resničnem svetu:
- Imeti kategorijo, ki vsebuje mešane primere iz nekaj drugih kategorij. Takšni kategoriji rad rečem metakategorija.
- Imeti 2 ali več kategorij, ki jih je treba združiti v eno kategorijo, ker se besedila, ki jim pripadajo, nanašajo na isto temo.
Uporabili bomo nabor podatkov ITSM (IT Service Management), ustvarjen za to vadnico (licenca CCO). Na voljo je na Kaggle na spodnji povezavi:
https://www.kaggle.com/datasets/nikolagreb/small-itsm-dataset
Čas je, da začnemo z uvozom vseh potrebnih knjižnic in pregledom osnovnih podatkov. Pripravite se, koda prihaja!
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
Vsaka vrstica predstavlja en vnos v bazi podatkov ITSM. Kategorijo vstopnice bomo poskušali predvideti na podlagi besedila vstopnice, ki ga je napisal uporabnik. Oglejmo si globlje najpomembnejša področja za opisane primere poslovne uporabe.
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
----------------------------------------------------------------------------------------------------
Če pogledamo prvi dve vstopnici, čeprav je ena v nemščini, vidimo, da se opisane težave nanašajo na isto programsko opremo?—?Asana, vendar nosijo različne oznake. To je začetek distribucije naših kategorij:
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
Potrebna pomoč je videti sumljiva, na primer kategorija, ki lahko vsebuje vstopnice iz več drugih kategorij. Tudi kategoriji Outlook in Mail se slišita podobno, morda ju je treba združiti v eno kategorijo. Preden se poglobimo v omenjene kategorije, se bomo znebili manjkajočih vrednosti v stolpcih, ki nas zanimajo.
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)
Ni veljavnega nadomestka za pregledovanje podatkov s prostim očesom. Modna funkcija za to v pandah je .sample(), zato bomo še enkrat storili točno to, zdaj za sumljivo kategorijo:
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.
---------------------------------------------------------------------------
Očitno imamo vstopnice, ki govorijo o Discordu, Asani in CRM. Zato je treba ime kategorije spremeniti iz »Potrebna pomoč« v obstoječe, bolj specifične kategorije. Za prvi korak postopka ponovnega dodeljevanja bomo ustvarili nov stolpec »Ključne besede«, ki bo dal informacijo, ali ima vstopnica besedo s seznama kategorij v stolpcu »Besedilo«.
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)
Upoštevajte tudi, da bi uporaba »if word in str(words_categories)« namesto »if word in words_categories« ujela besede iz kategorij z več kot eno besedo (v našem primeru internetni brskalnik), vendar bi zahtevala tudi več predhodne obdelave podatkov. Da bodo stvari preproste in jasne do bistva, bomo uporabili kodo za kategorije, sestavljeno iz samo ene besede. Takole je zdaj videti naš nabor podatkov:
df.head(2)
izpis kot slika:
Po ekstrakciji stolpca s ključnimi besedami bomo prevzeli kakovost vstopnic. Naša hipoteza:
- Vstopnico s samo 1 ključno besedo v besedilnem polju, ki je enaka kategoriji, v katero spada vstopnica, bi bilo enostavno razvrstiti.
- Vstopnico z več ključnimi besedami v polju Besedilo, kjer je vsaj ena od ključnih besed enaka kategoriji, v katero vstopnica spada, bi bilo v večini primerov enostavno razvrstiti.
- Vstopnica, ki ima ključne besede, vendar nobena od njih ni enaka imenu kategorije, v katero vstopnica spada, je verjetno primer hrupne oznake.
- Druge vstopnice so nevtralne glede na ključne besede.
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
Naredili smo novo distribucijo in zdaj je čas, da pregledamo vstopnice, ki so razvrščene kot potencialna težava. V praksi bi naslednji korak zahteval veliko več vzorčenja in pogled na večje dele podatkov s prostim očesom, vendar bi bila utemeljitev enaka. Poiskati morate problematične vstopnice in se odločiti, ali lahko izboljšate njihovo kakovost ali jih morate izključiti iz nabora podatkov. Ko se soočate z velikim naborom podatkov, bodite mirni in ne pozabite, da pregled in priprava podatkov običajno zahtevata veliko več časa kot izgradnja algoritmov ML!
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
--------------------------------------------------------------------
Zavedamo se, da so vstopnice iz kategorij Outlook in Mail povezane z isto težavo, zato bomo ti dve kategoriji združili in izboljšali rezultate našega prihodnjega algoritma za razvrščanje ML.
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
Nenazadnje želimo nekaj vstopnic iz meta kategorije »Potrebna pomoč« ponovno označiti v ustrezno kategorijo.
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
Podatke smo preoznačevali in čistili, vendar se ne bi smeli imenovati podatkovni znanstveniki, če ne izvedemo vsaj enega znanstvenega eksperimenta in preizkusimo vpliva našega dela na končno razvrstitev. To bomo storili z implementacijo klasifikacije Complement Naive Bayes v sklearn. Lahko preizkusite druge, bolj zapletene algoritme. Zavedajte se tudi, da bi lahko izvedli nadaljnje čiščenje podatkov – na primer, lahko bi tudi izpustili vse vstopnice, ki so ostale v kategoriji »Potrebna pomoč«.
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
Precej impresivno, kajne? Nabor podatkov, ki smo ga uporabili, je majhen (namenoma, tako da lahko preprosto vidite, kaj se zgodi v vsakem koraku), zato lahko različna naključna semena dajo različne rezultate, vendar bo v veliki večini primerov model po čiščenju v primerjavi z naborom podatkov deloval bistveno bolje. na izvirni nabor podatkov. Dobro smo opravili!
Nikola Greb kodira že več kot štiri leta, zadnji dve leti pa se specializira za NLP. Preden se je posvetil podatkovni znanosti, je bil uspešen v prodaji, HR, pisanju in šahu.
- Distribucija vsebine in PR s pomočjo SEO. Okrepite se še danes.
- Platoblockchain. Web3 Metaverse Intelligence. Razširjeno znanje. Dostopite tukaj.
- Kovanje prihodnosti z Adryenn Ashley. Dostopite tukaj.
- vir: 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
- :ima
- : je
- :ne
- :kje
- 1
- 10
- 100
- 11
- 2%
- 7
- 8
- 9
- a
- O meni
- Račun
- natančnost
- po
- Agent
- algoritem
- algoritmi
- vsi
- Prav tako
- Čeprav
- an
- in
- SE
- AS
- At
- Na voljo
- temeljijo
- Osnovni
- BE
- ker
- bilo
- pred
- spodaj
- Boljše
- blokirana
- brskalnik
- izgradnjo
- Building
- poslovni
- vendar
- by
- klic
- CAN
- opravlja
- primeru
- primeri
- CAT
- wrestling
- kategorije
- Kategorija
- spremenite
- Šah
- Razvrstitev
- razvrščeni
- Razvrsti
- čiščenje
- Grozd
- Koda
- Kodiranje
- Stolpec
- Stolpci
- COM
- Skupno
- podjetje
- v primerjavi z letom
- Dopolnilo
- kompleksna
- Connect
- povezava
- Vsebuje
- bi
- ustvarjajo
- ustvaril
- CRM
- datum
- Priprava podatkov
- znanost o podatkih
- Baze podatkov
- ponudba
- deliti
- odloča
- globlje
- opisano
- DID
- drugačen
- neskladje
- distribucija
- do
- don
- Drop
- vsak
- enostavno
- Učinkovito
- omogočena
- Vpis
- Eter (ETH)
- točno
- Primer
- Primeri
- obstoječih
- Pričakuje
- poskus
- razložiti
- oči
- s katerimi se sooča
- Nekaj
- Polje
- Področja
- končna
- Najdi
- prva
- po
- za
- štiri
- brezplačno
- iz
- funkcija
- nadalje
- Prihodnost
- nemški
- dobili
- Daj
- daje
- Go
- dobro
- se zgodi
- Imajo
- he
- slušalke
- pomoč
- hitting
- Kako
- hr
- HTTPS
- HubSpot
- i
- slika
- vpliv
- izvajanja
- uvoz
- Pomembno
- Impresivno
- izboljšanje
- in
- Indeks
- Podatki
- Namesto
- obresti
- Internet
- v
- vprašanje
- IT
- IT storitev
- samo
- samo en
- KDnuggets
- Imejte
- Otrok
- label
- Oznake
- jezik
- laptop
- velika
- večja
- knjižnice
- Licenca
- kot
- LINK
- Seznam
- Poglej
- si
- POGLEDI
- ljubezen
- je
- Večina
- upravljanje
- več
- Trženje
- mediji
- člani
- Spomin
- omenjeno
- Spoji
- Meta
- Meritve
- morda
- manjka
- mešano
- ML
- Model
- več
- Najbolj
- več
- Ime
- naravna
- Naravni jezik
- Obdelava Natural Language
- potrebna
- Nevtralna
- Novo
- nlp
- prenosnik
- zdaj
- Številka
- otopeli
- predmet
- of
- Office
- Staro
- on
- ONE
- Možnost
- or
- Da
- izvirno
- Ostalo
- naši
- Outlook
- izhod
- pand
- preteklosti
- PC
- opravlja
- plinovod
- platon
- Platonova podatkovna inteligenca
- PlatoData
- prosim
- Točka
- mogoče
- potencial
- praksa
- napovedati
- verjetno
- problem
- Težave
- Postopki
- Postopek
- obravnavati
- proizvodnjo
- pravilno
- Namen
- kakovost
- naključno
- resnični svet
- povezane
- predstavlja
- zahteva
- Odgovor
- Rezultati
- vrnitev
- znebi
- narašča
- ROW
- prodaja
- Enako
- scenariji
- Znanost
- Znanstveniki
- glej
- Semena
- Zdi se,
- Storitev
- nastavite
- shouldnt
- Prikaži
- bistveno
- Podoben
- Enostavno
- saj
- majhna
- So
- socialna
- družbeni mediji
- Software
- Rešitev
- nekaj
- zvok
- specializirani
- specifična
- po delih
- Začetek
- Začetek
- bivanje
- Korak
- ustavil
- naravnost
- String
- uspešno
- naj
- sumljiv
- Bodite
- Pogovor
- pogovor
- skupina
- Člani ekipe
- Test
- kot
- da
- O
- informacije
- njihove
- Njih
- Tukaj.
- te
- jih
- stvari
- ta
- Vstopnica
- vstopnice
- čas
- do
- tudi
- temo
- Skupaj za plačilo
- Vlak
- usposabljanje
- Obračalni
- Navodila
- razumeli
- Nadgradnja
- posodobljeno
- us
- Uporaba
- uporaba
- Rabljeni
- uporabnik
- uporabo
- navadno
- Vrednote
- Popravljeno
- zelo
- preko
- Wall
- je
- we
- Kaj
- kdaj
- ki
- kdorkoli
- bo
- okna
- z
- brez
- beseda
- besede
- delo
- deluje
- bi
- pisanje
- pisni
- X
- let
- jo
- sami
- zefirnet