תמונה מאת עורך
עם העניין הגובר בעיבוד שפה טבעית, יותר ויותר מתרגלים פוגעים בקיר לא בגלל שהם לא יכולים לבנות או לכוונן LLMs, אלא בגלל שהנתונים שלהם מבולגנים!
אנו נציג נהלי קידוד פשוטים אך יעילים מאוד לתיקון תוויות רועשות בנתוני טקסט. נעסוק בשני תרחישים נפוצים בנתוני טקסט בעולם האמיתי:
- בעלת קטגוריה המכילה דוגמאות מעורבות מכמה קטגוריות אחרות. אני אוהב לקרוא לסוג זה של קטגוריה מטא קטגוריה.
- בעל 2 קטגוריות או יותר שיש למזג אותן לקטגוריה אחת מכיוון שטקסטים השייכים להן מתייחסים לאותו נושא.
אנו נשתמש במערך נתונים של ITSM (ניהול שירות IT) שנוצר עבור מדריך זה (רישיון CCO). זה זמין ב- Kaggle מהקישור למטה:
https://www.kaggle.com/datasets/nikolagreb/small-itsm-dataset
זה הזמן להתחיל בייבוא של כל הספריות הדרושות ובדיקת נתונים בסיסיים. תתכוננו, הקוד מגיע!
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
כל שורה מייצגת ערך אחד במסד הנתונים של ITSM. ננסה לחזות את קטגוריית הכרטיס על סמך טקסט הכרטיס שנכתב על ידי משתמש. הבה נבחן לעומק את התחומים החשובים ביותר עבור מקרי שימוש עסקיים מתוארים.
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
----------------------------------------------------------------------------------------------------
אם נסתכל על שני הכרטיסים הראשונים, למרות שכרטיס אחד הוא בגרמנית, נוכל לראות שהבעיות המתוארות מתייחסות לאותה תוכנה?-?אסנה, אבל הן נושאות תוויות שונות. זו מתחילה להפיץ את הקטגוריות שלנו:
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
העזרה הדרושה נראית חשודה, כמו הקטגוריה שיכולה להכיל כרטיסים ממספר קטגוריות אחרות. כמו כן, קטגוריות Outlook ו-Mail נשמעות דומות, אולי יש למזג אותן לקטגוריה אחת. לפני שנצלול עמוק יותר לתוך הקטגוריות שהוזכרו, ניפטר מהערכים החסרים בעמודות של עניין שלנו.
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)
אין תחליף תקף לבדיקת הנתונים בעין חשופה. הפונקציה המפוארת לעשות זאת בפנדות היא .sample(), אז נעשה בדיוק את זה פעם נוספת, עכשיו לקטגוריה החשודה:
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.
---------------------------------------------------------------------------
ברור שיש לנו כרטיסים שמדברים על Discord, Asana ו-CRM. אז יש לשנות את שם הקטגוריה מ"נדרשת עזרה" לקטגוריות קיימות וספציפיות יותר. לשלב הראשון של תהליך ההקצאה מחדש, ניצור את העמודה החדשה "מילות מפתח" המספקת את המידע אם בכרטיס יש את המילה מרשימת הקטגוריות בעמודת "טקסט".
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)
כמו כן, שים לב ששימוש ב-"if word in str(words_categories)" במקום "if word in words_categories" יתפוס מילים מקטגוריות עם יותר ממילה אחת (דפדפן אינטרנט במקרה שלנו), אבל ידרוש גם יותר עיבוד נתונים מראש. כדי לשמור על דברים פשוטים וישרים לעניין, נלך עם הקוד לקטגוריות המורכבות ממילה אחת בלבד. כך נראה מערך הנתונים שלנו כעת:
df.head(2)
פלט כתמונה:
לאחר חילוץ עמודת מילות המפתח, נניח את איכות הכרטיסים. ההשערה שלנו:
- קל לסווג כרטיס עם מילת מפתח אחת בלבד בשדה טקסט זהה לקטגוריה שאליה שייך הכרטיס.
- כרטיס עם מילות מפתח מרובות בשדה טקסט, כאשר לפחות אחת ממילות המפתח זהה לקטגוריה שאליה שייך הכרטיס יהיה קל לסווג ברוב המקרים.
- הכרטיס שיש לו מילות מפתח, אבל אף אחת מהן לא שווה לשם הקטגוריה שאליה שייך הכרטיס הוא כנראה מארז תווית רועש.
- כרטיסים אחרים הם ניטרליים על סמך מילות מפתח.
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
ביצענו את ההפצה החדשה שלנו ועכשיו זה הזמן לבחון כרטיסים המסווגים כבעיה פוטנציאלית. בפועל, השלב הבא ידרוש הרבה יותר דגימה ולהסתכל על נתחי הנתונים הגדולים יותר בעין חשופה, אבל הרציונל יהיה זהה. אתה אמור למצוא כרטיסים בעייתיים ולהחליט אם אתה יכול לשפר את איכותם או שאתה צריך להוריד אותם ממערך הנתונים. כאשר אתם עומדים בפני מערך נתונים גדול הישאר רגוע, ואל תשכח שבדיקת נתונים והכנת נתונים לוקחים בדרך כלל הרבה יותר זמן מאשר בניית אלגוריתמי 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
--------------------------------------------------------------------
אנו מבינים שכרטיסים מקטגוריות Outlook ו-Mail קשורים לאותה בעיה, ולכן נמזג את 2 הקטגוריות הללו ונשפר את תוצאות האלגוריתם העתידי שלנו לסיווג 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
אחרון חביב, ברצוננו לחדש כמה כרטיסים מקטגוריית המטא "נדרשת עזרה" לקטגוריה המתאימה.
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
ביצענו את התיוג מחדש והניקיון של הנתונים שלנו, אבל אנחנו לא צריכים לקרוא לעצמנו מדעני נתונים אם לא נעשה לפחות ניסוי מדעי אחד ונבדוק את ההשפעה של העבודה שלנו על הסיווג הסופי. נעשה זאת על ידי יישום The Complement Naive Bayes classifier ב-sklearn. אל תהסס לנסות אלגוריתמים אחרים ומורכבים יותר. כמו כן, שים לב שניתן לבצע ניקוי נתונים נוסף - לדוגמה, נוכל גם להוריד את כל הכרטיסים שנותרו בקטגוריית "נדרשת עזרה".
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
די מרשים, נכון? מערך הנתונים בו השתמשנו הוא קטן (בכוונה, כך שתוכל לראות בקלות מה קורה בכל שלב), כך שזרעים אקראיים שונים עשויים להניב תוצאות שונות, אך ברוב המוחלט של המקרים, המודל יבצע ביצועים טובים משמעותית במערך הנתונים לאחר הניקוי בהשוואה למערך הנתונים המקורי. עשינו עבודה טובה!
ניקולה גרב מקודד כבר יותר מארבע שנים, ובשנתיים האחרונות התמחה ב-NLP. לפני שפנה למדעי הנתונים, הוא הצליח במכירות, משאבי אנוש, כתיבה ושחמט.
- הפצת תוכן ויחסי ציבור מופעל על ידי SEO. קבל הגברה היום.
- Platoblockchain. Web3 Metaverse Intelligence. ידע מוגבר. גישה כאן.
- הטבעת העתיד עם אדריאן אשלי. גישה כאן.
- מקור: 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
- :יש ל
- :הוא
- :לֹא
- :איפה
- 1
- 10
- 100
- 11
- 2%
- 7
- 8
- 9
- a
- אודות
- חֶשְׁבּוֹן
- דיוק
- לאחר
- סוֹכֵן
- אַלגוֹרִיתְם
- אלגוריתמים
- תעשיות
- גם
- למרות
- an
- ו
- ARE
- AS
- At
- זמין
- מבוסס
- בסיסי
- BE
- כי
- היה
- לפני
- להלן
- מוטב
- חסום
- דפדפן
- לִבנוֹת
- בִּניָן
- עסקים
- אבל
- by
- שיחה
- CAN
- לשאת
- מקרה
- מקרים
- חָתוּל
- היאבקות
- קטגוריות
- קטגוריה
- שינוי
- שחמט
- מיון
- מְסוּוָג
- לסווג
- ניקוי
- אשכול
- קוד
- סִמוּל
- טור
- עמודות
- COM
- Common
- חברה
- לעומת
- השלמה
- מורכב
- לְחַבֵּר
- הקשר
- מכיל
- יכול
- לִיצוֹר
- נוצר
- CRM
- נתונים
- הכנת נתונים
- מדע נתונים
- מסד נתונים
- עסקה
- התמודדות
- להחליט
- עמוק יותר
- מְתוּאָר
- DID
- אחר
- מחלוקת
- הפצה
- do
- דון
- ירידה
- כל אחד
- בקלות
- אפקטיבי
- מופעל
- כניסה
- Ether (ETH)
- בדיוק
- דוגמה
- דוגמאות
- קיימים
- צפוי
- לְנַסוֹת
- מוסבר
- עין
- מול
- מעטים
- שדה
- שדות
- סופי
- ראשון
- הבא
- בעד
- ארבע
- חופשי
- החל מ-
- פונקציה
- נוסף
- עתיד
- גרמנית
- לקבל
- לתת
- נותן
- Go
- טוב
- קורה
- יש
- he
- אוזניות
- לעזור
- להכות
- איך
- hr
- HTTPS
- HubSpot
- i
- תמונה
- פְּגִיעָה
- יישום
- לייבא
- חשוב
- מרשים
- לשפר
- in
- מדד
- מידע
- במקום
- אינטרס
- אינטרנט
- אל תוך
- סוגיה
- IT
- שירות IT
- רק
- רק אחד
- KDnuggets
- שמור
- סוג
- תווית
- תוויות
- שפה
- מחשב נייד
- גָדוֹל
- גדול יותר
- ספריות
- רישיון
- כמו
- קשר
- לינקדין
- רשימה
- נראה
- הסתכלות
- נראה
- אהבה
- עשוי
- הרוב
- ניהול
- רב
- שיווק
- מדיה
- להרשם/להתחבר
- זכרון
- מוּזְכָּר
- למזג
- meta
- מדדים
- יכול
- חסר
- מעורב
- ML
- מודל
- יותר
- רוב
- מספר
- שם
- טבעי
- שפה טבעית
- עיבוד שפה טבעית
- נחוץ
- נטרל
- חדש
- NLP
- מחברה
- עַכשָׁיו
- מספר
- קהות
- אובייקט
- of
- Office
- זקן
- on
- ONE
- אפשרות
- or
- להזמין
- מְקוֹרִי
- אחר
- שלנו
- Outlook
- תפוקה
- דובי פנדה
- עבר
- PC
- לבצע
- צינור
- אפלטון
- מודיעין אפלטון
- אפלטון נתונים
- אנא
- נקודה
- אפשרי
- פוטנציאל
- תרגול
- לחזות
- כנראה
- בעיה
- בעיות
- נהלים
- תהליך
- תהליך
- לייצר
- תָקִין
- מטרה
- איכות
- אקראי
- עולם אמיתי
- קָשׁוּר
- מייצג
- לדרוש
- תגובה
- תוצאות
- לַחֲזוֹר
- להיפטר
- עולה
- שׁוּרָה
- מכירות
- אותו
- תרחישים
- מדע
- מדענים
- לִרְאוֹת
- זרעים
- נראה
- שרות
- סט
- צריך
- לְהַצִיג
- באופן משמעותי
- דומה
- פָּשׁוּט
- since
- קטן
- So
- חֶברָתִי
- מדיה חברתית
- תוכנה
- פִּתָרוֹן
- כמה
- קול
- מיוחד
- ספציפי
- לפצל
- התחלה
- החל
- להשאר
- שלב
- נעצר
- ישר
- מחרוזת
- מוצלח
- אמור
- חשוד
- לקחת
- לדבר
- מדבר
- נבחרת
- חברי צוות
- מבחן
- מֵאֲשֶׁר
- זֶה
- השמיים
- המידע
- שֶׁלָהֶם
- אותם
- שם.
- אלה
- הֵם
- דברים
- זֶה
- כרטיס
- כרטיסים
- זמן
- ל
- גַם
- נושא
- סה"כ
- רכבת
- הדרכה
- פנייה
- הדרכה
- להבין
- עדכון
- מְעוּדכָּן
- us
- נוֹהָג
- להשתמש
- מְשׁוּמָשׁ
- משתמש
- באמצעות
- בְּדֶרֶך כְּלַל
- ערכים
- Vast
- מאוד
- באמצעות
- קיר
- היה
- we
- מה
- מתי
- אשר
- מִי
- יצטרך
- חלונות
- עם
- לְלֹא
- Word
- מילים
- תיק עבודות
- עובד
- היה
- כתיבה
- כתוב
- X
- שנים
- אתה
- עצמך
- זפירנט