Pilt redaktori poolt
Seoses kasvava huviga loomuliku keele töötlemise vastu lööb üha rohkem praktikuid vastu seina mitte sellepärast, et nad ei suudaks LLM-e luua või peenhäälestada, vaid seetõttu, et nende andmed on segased!
Näitame lihtsaid, kuid väga tõhusaid kodeerimisprotseduure mürarikaste siltide fikseerimiseks tekstiandmetes. Tegeleme kahe levinud stsenaariumiga reaalsetes tekstiandmetes:
- Kategooria, mis sisaldab seganäiteid mõnest teisest kategooriast. Mulle meeldib seda tüüpi kategooriat nimetada metakategooriaks.
- 2 või enama kategooria olemasolu, mis tuleks liita 1 kategooriasse, kuna neisse kuuluvad tekstid viitavad samale teemale.
Kasutame selle õpetuse jaoks loodud ITSM-i (IT Service Management) andmestikku (CCO litsents). See on saadaval Kaggle'is allolevalt lingilt:
https://www.kaggle.com/datasets/nikolagreb/small-itsm-dataset
On aeg alustada kõigi vajalike teekide importimise ja põhiandmete uurimisega. Olge valmis, kood on tulemas!
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
Iga rida tähistab üht kirjet ITSM-i andmebaasis. Püüame ennustada pileti kategooriat kasutaja kirjutatud piletiteksti põhjal. Vaatleme üksikasjalikumalt kirjeldatud ärikasutusjuhtumite olulisemaid valdkondi.
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
----------------------------------------------------------------------------------------------------
Kui vaatame kahte esimest piletit, kuigi üks pilet on saksakeelne, näeme, et kirjeldatud probleemid viitavad samale tarkvarale?—?Asana, kuid neil on erinevad sildid. See alustab meie kategooriate levitamist:
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
Vajalik abi tundub kahtlane, nagu kategooria, mis võib sisaldada pileteid mitmest teisest kategooriast. Ka kategooriad Outlook ja Mail kõlavad sarnaselt, võib-olla tuleks need ühte kategooriasse liita. Enne mainitud kategooriatesse süvenemist vabaneme puuduvatest väärtustest meie huvipakkuvates veergudes.
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)
Andmete palja silmaga uurimist ei saa asendada. Pandade väljamõeldud funktsioon on .sample(), seega teeme seda veel kord, nüüd kahtlase kategooria jaoks:
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.
---------------------------------------------------------------------------
Ilmselgelt on meil piletid, mis räägivad Discordist, Asanast ja CRM-ist. Seega tuleks kategooria nimi "Vajalik abi" muuta olemasolevaks, täpsemaks kategooriaks. Ümbermääramise protsessi esimeseks sammuks loome uue veeru “Märksõnad”, mis annab infot, kui piletil on veerus “Tekst” kategooriate loendis olev sõna.
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)
Samuti pange tähele, et kui kasutate sõna "if sõna in str(words_categories)" asemel "kui sõna sõnades_kategooriates", püüaks sõnad kategooriatest, milles on rohkem kui 1 sõna (meie puhul Interneti-brauser), kuid see nõuab ka rohkem andmete eeltöötlust. Et asjad oleksid lihtsad ja otse asja juurde, kasutame ainult ühest sõnast koosnevate kategooriate koodi. Meie andmestik näeb praegu välja selline:
df.head(2)
väljund pildina:
Pärast märksõnade veeru väljavõtmist eeldame piletite kvaliteeti. Meie hüpotees:
- Piletit, mille tekstiväljal on vaid 1 märksõna, mis on sama, mis kategooriast, millesse pilet kuulub, oleks lihtne klassifitseerida.
- Mitme märksõnaga piletit väljal Tekst, kus vähemalt üks märksõnadest kattub kategooriaga, millesse pilet kuulub, oleks enamikul juhtudel lihtne klassifitseerida.
- Pilet, millel on märksõnad, kuid ükski neist ei võrdu selle kategooria nimega, kuhu pilet kuulub, on ilmselt mürarikas sildikohver.
- Teised piletid on märksõnade põhjal neutraalsed.
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
Tegime oma uue levitamise ja nüüd on aeg uurida võimalike probleemidena klassifitseeritud pileteid. Praktikas nõuaks järgnev samm palju rohkem valimit ja suuremate andmete tükkide vaatamist palja silmaga, kuid põhjendus oleks sama. Peate leidma probleemsed piletid ja otsustama, kas saate nende kvaliteeti parandada või peaksite need andmestikust välja jätma. Kui seisate silmitsi suure andmestikuga, olge rahulik ja ärge unustage, et andmete uurimine ja ettevalmistamine võtab tavaliselt palju rohkem aega kui ML-algoritmide koostamine!
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
--------------------------------------------------------------------
Mõistame, et Outlooki ja Maili kategooriate piletid on seotud sama probleemiga, seega ühendame need kaks kategooriat ja parandame oma tulevase ML klassifitseerimisalgoritmi tulemusi.
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
Viimaseks, kuid mitte vähemtähtsaks, tahame mõned piletid metakategooriast "Vajalik abi" ümber märgistada õigesse kategooriasse.
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
Tegime andmete ümbermärgistamise ja puhastamise, kuid me ei tohiks end nimetada andmeteadlasteks, kui me ei tee vähemalt ühte teaduslikku eksperimenti ja ei testi oma töö mõju lõplikule klassifikatsioonile. Teeme seda, rakendades sklearnis klassifikaatori The Complement Naive Bayes. Proovige julgelt teisi, keerukamaid algoritme. Samuti pidage meeles, et andmeid võidakse puhastada veelgi – näiteks võime kõik "Vaja on abi" kategooriasse jäänud piletid ära visata.
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
Päris muljetavaldav, eks? Kasutatud andmestik on väike (sihilikult, nii et saate hõlpsalt näha, mis igas etapis toimub), nii et erinevad juhuslikud seemned võivad anda erinevaid tulemusi, kuid enamikul juhtudel toimib mudel andmestikul pärast puhastamist oluliselt paremini. algsele andmekogumile. Me tegime head tööd!
Nikola Greb kodeerinud rohkem kui neli aastat ja viimased kaks aastat on ta spetsialiseerunud NLP-le. Enne andmeteaduse poole pöördumist oli ta edukas müügis, personalitöös, kirjutamises ja males.
- SEO-põhise sisu ja PR-levi. Võimenduge juba täna.
- Platoblockchain. Web3 metaversiooni intelligentsus. Täiustatud teadmised. Juurdepääs siia.
- Tuleviku rahapaja Adryenn Ashley. Juurdepääs siia.
- Allikas: 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
- :on
- :on
- :mitte
- : kus
- 1
- 10
- 100
- 11
- 2%
- 7
- 8
- 9
- a
- MEIST
- konto
- täpsus
- pärast
- Agent
- algoritm
- algoritme
- Materjal: BPA ja flataatide vaba plastik
- Ka
- Kuigi
- an
- ja
- OLEME
- AS
- At
- saadaval
- põhineb
- põhiline
- BE
- sest
- olnud
- enne
- alla
- Parem
- blokeeritud
- brauseri
- ehitama
- Ehitus
- äri
- kuid
- by
- helistama
- CAN
- viima
- juhul
- juhtudel
- CAT
- maadlus
- kategooriad
- Kategooria
- muutma
- Male
- klassifikatsioon
- salastatud
- Klassifitseerige
- puhastamine
- Cluster
- kood
- Kodeerimine
- Veerg
- Veerud
- COM
- ühine
- ettevõte
- võrreldes
- Täiendus
- keeruline
- Võta meiega ühendust
- ühendus
- sisaldab
- võiks
- looma
- loodud
- CRM
- andmed
- Andmete ettevalmistamine
- andmeteadus
- andmebaas
- tegelema
- tegelema
- otsustama
- sügavam
- kirjeldatud
- DID
- erinev
- ebakõla
- jaotus
- do
- don
- Drop
- iga
- kergesti
- Tõhus
- lubatud
- kanne
- Eeter (ETH)
- täpselt
- näide
- näited
- olemasolevate
- oodatav
- eksperiment
- selgitas
- silm
- ees
- vähe
- väli
- Valdkonnad
- lõplik
- leidma
- esimene
- Järel
- eest
- neli
- tasuta
- Alates
- funktsioon
- edasi
- tulevik
- saksa
- saama
- Andma
- annab
- Go
- hea
- juhtub
- Olema
- he
- kõrvaklapid
- aitama
- lööb
- Kuidas
- hr
- HTTPS
- HubSpot
- i
- pilt
- mõju
- rakendamisel
- import
- oluline
- muljetavaldav
- parandama
- in
- indeks
- info
- selle asemel
- huvi
- Internet
- sisse
- probleem
- IT
- IT-teenus
- lihtsalt
- ainult üks
- KDnuggets
- hoidma
- Laps
- silt
- Labels
- keel
- sülearvuti
- suur
- suurem
- raamatukogud
- litsents
- nagu
- LINK
- nimekiri
- Vaata
- otsin
- välimus
- armastus
- tehtud
- Enamus
- juhtimine
- palju
- Turundus
- Meedia
- liikmed
- Mälu
- mainitud
- Merge
- Meta
- Meetrika
- võib
- puuduvad
- segatud
- ML
- mudel
- rohkem
- kõige
- mitmekordne
- nimi
- Natural
- Loomulik keel
- Natural Language Processing
- vaja
- Neutraalne
- Uus
- nlp
- märkmik
- nüüd
- number
- tuim
- objekt
- of
- Office
- Vana
- on
- ONE
- valik
- or
- et
- originaal
- Muu
- meie
- väljavaade
- väljund
- pandas
- minevik
- PC
- täitma
- torujuhe
- Platon
- Platoni andmete intelligentsus
- PlatoData
- palun
- Punkt
- võimalik
- potentsiaal
- tava
- ennustada
- tõenäoliselt
- Probleem
- probleeme
- menetlused
- protsess
- töötlemine
- tootma
- korralik
- eesmärk
- kvaliteet
- juhuslik
- päris maailm
- seotud
- esindab
- nõudma
- vastus
- Tulemused
- tagasipöördumine
- Rid
- tõusev
- ROW
- müük
- sama
- stsenaariumid
- teadus
- teadlased
- vaata
- seemned
- tundub
- teenus
- komplekt
- peaks
- näitama
- märgatavalt
- sarnane
- lihtne
- alates
- väike
- So
- sotsiaalmeedia
- Sotsiaalse meedia
- tarkvara
- lahendus
- mõned
- heli
- spetsialiseeritud
- konkreetse
- jagada
- algus
- Käivitus
- jääma
- Samm
- peatatud
- otse
- nöör
- edukas
- peaks
- kahtlane
- Võtma
- rääkima
- rääkimine
- meeskond
- Meeskonna liikmed
- test
- kui
- et
- .
- teave
- oma
- Neile
- Seal.
- Need
- nad
- asjad
- see
- pilet
- piletid
- aeg
- et
- liiga
- teema
- Summa
- Rong
- koolitus
- Pööramine
- juhendaja
- mõistma
- Värskendused
- ajakohastatud
- us
- Kasutus
- kasutama
- Kasutatud
- Kasutaja
- kasutamine
- tavaliselt
- Väärtused
- suur
- väga
- kaudu
- Sein
- oli
- we
- M
- millal
- mis
- kes iganes
- will
- aknad
- koos
- ilma
- sõna
- sõnad
- Töö
- töö
- oleks
- kirjutamine
- kirjalik
- X
- aastat
- sa
- ise
- sephyrnet