تصویر توسط ویرایشگر
با افزایش علاقه به پردازش زبان طبیعی، تمرینکنندگان بیشتر و بیشتری به دیوار ضربه میزنند، نه به این دلیل که نمیتوانند LLM را بسازند یا تنظیم دقیق کنند، بلکه به این دلیل که دادههای آنها نامرتب است!
ما رویههای کدگذاری ساده و در عین حال بسیار مؤثر را برای رفع برچسبهای نویز در دادههای متنی نشان خواهیم داد. ما با 2 سناریو رایج در داده های متنی دنیای واقعی سر و کار خواهیم داشت:
- داشتن یک دسته که شامل نمونه های ترکیبی از چند دسته دیگر است. من دوست دارم این نوع دسته بندی را یک دسته بندی متا بنامم.
- داشتن 2 یا چند دسته که باید در 1 دسته ادغام شوند زیرا متون متعلق به آنها به یک موضوع اشاره دارد.
ما از مجموعه داده های ITSM (IT Service Management) ایجاد شده برای این آموزش (مجوز 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
----------------------------------------------------------------------------------------------------
اگر به دو بلیط اول نگاهی بیندازیم، اگرچه یک بلیط به زبان آلمانی است، می بینیم که مشکلات توصیف شده مربوط به همان نرم افزار است؟—? Asana، اما برچسب های مختلفی دارند. این شروع توزیع دسته های ما است:
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» میتواند کلمات را از دستههایی با بیش از 1 کلمه بگیرد (در مورد ما مرورگر اینترنت)، اما به پیشپردازش دادههای بیشتری نیز نیاز دارد. برای اینکه همه چیز ساده و سرراست به سر اصل مطلب بپردازیم، با کد دستههایی که فقط از یک کلمه ساخته شدهاند، صحبت میکنیم. اکنون مجموعه داده ما به این صورت است:
df.head(2)
خروجی به صورت تصویر:
پس از استخراج ستون کلمات کلیدی، کیفیت بلیط ها را فرض می کنیم. فرضیه ما:
- بلیط با تنها 1 کلمه کلیدی در قسمت Text که همان دسته ای است که بلیط به آن تعلق دارد، طبقه بندی آسان خواهد بود.
- بلیط با چند کلمه کلیدی در قسمت Text، که در آن حداقل یکی از کلمات کلیدی با دسته ای که بلیط به آن تعلق دارد یکسان باشد، در اکثر موارد به راحتی طبقه بندی می شود.
- بلیطی که دارای کلمات کلیدی است، اما هیچ یک از آنها با نام دسته ای که بلیط به آن تعلق دارد برابری نمی کند، احتمالاً یک برچسب پر سر و صدا است.
- سایر بلیط ها بر اساس کلمات کلیدی خنثی هستند.
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 به یک مشکل مرتبط هستند، بنابراین ما این ۲ دسته را ادغام میکنیم و نتایج الگوریتم طبقهبندی 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 در 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 و توزیع روابط عمومی. امروز تقویت شوید.
- پلاتوبلاک چین. 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
- و
- هستند
- AS
- At
- در دسترس
- مستقر
- اساسی
- BE
- زیرا
- بوده
- قبل از
- در زیر
- بهتر
- مسدود شده
- مرورگر
- ساختن
- بنا
- کسب و کار
- اما
- by
- صدا
- CAN
- حمل
- مورد
- موارد
- CAT
- کشتی
- دسته
- دسته بندی
- تغییر دادن
- شطرنج
- طبقه بندی
- طبقه بندی
- طبقه بندی کنید
- تمیز کاری
- خوشه
- رمز
- برنامه نویسی
- ستون
- ستون ها
- COM
- مشترک
- شرکت
- مقایسه
- متمم
- پیچیده
- اتصال
- ارتباط
- شامل
- میتوانست
- ایجاد
- ایجاد شده
- CRM
- داده ها
- آماده سازی داده ها
- علم اطلاعات
- پایگاه داده
- مقدار
- معامله
- تصمیم گیری
- عمیق تر
- شرح داده شده
- DID
- مختلف
- اختلاف
- توزیع
- do
- دان
- قطره
- هر
- به آسانی
- موثر
- فعال
- ورود
- اتر (ETH)
- کاملا
- مثال
- مثال ها
- موجود
- انتظار می رود
- تجربه
- توضیح داده شده
- چشم
- نما
- کمی از
- رشته
- زمینه
- نهایی
- پیدا کردن
- نام خانوادگی
- پیروی
- برای
- چهار
- رایگان
- از جانب
- تابع
- بیشتر
- آینده
- آلمانی
- دریافت کنید
- دادن
- می دهد
- Go
- خوب
- اتفاق می افتد
- آیا
- he
- هدفون
- کمک
- ضربه زدن
- چگونه
- hr
- HTTPS
- HubSpot
- i
- تصویر
- تأثیر
- اجرای
- واردات
- مهم
- موثر
- بهبود
- in
- شاخص
- اطلاعات
- در عوض
- علاقه
- اینترنت
- به
- موضوع
- IT
- خدمات فناوری اطلاعات
- تنها
- فقط یکی
- kdnuggets
- نگاه داشتن
- نوع
- برچسب
- برچسب ها
- زبان
- لپ تاپ
- بزرگ
- بزرگتر
- کتابخانه ها
- مجوز
- پسندیدن
- ارتباط دادن
- لینک
- فهرست
- نگاه کنيد
- به دنبال
- مطالب
- عشق
- ساخته
- اکثریت
- مدیریت
- بسیاری
- بازار یابی (Marketing)
- رسانه ها
- اعضا
- حافظه
- ذکر شده
- ادغام کردن
- متا
- متریک
- قدرت
- گم
- مخلوط
- ML
- مدل
- بیش
- اکثر
- چندگانه
- نام
- طبیعی
- زبان طبیعی
- پردازش زبان طبیعی
- ضروری
- خنثی
- جدید
- nlp
- دفتر یادداشت
- اکنون
- عدد
- بی حس
- هدف
- of
- دفتر
- قدیمی
- on
- ONE
- گزینه
- or
- سفارش
- اصلی
- دیگر
- ما
- چشم انداز
- تولید
- پانداها
- گذشته
- PC
- انجام دادن
- خط لوله
- افلاطون
- هوش داده افلاطون
- PlatoData
- لطفا
- نقطه
- ممکن
- پتانسیل
- تمرین
- پیش بینی
- شاید
- مشکل
- مشکلات
- روش
- روند
- در حال پردازش
- تولید کردن
- مناسب
- هدف
- کیفیت
- تصادفی
- دنیای واقعی
- مربوط
- نشان دهنده
- نیاز
- پاسخ
- نتایج
- برگشت
- خلاص شدن از شر
- طلوع
- ROW
- حراجی
- همان
- سناریوها
- علم
- دانشمندان
- دیدن
- دانه
- به نظر می رسد
- سرویس
- تنظیم
- باید
- نشان
- به طور قابل توجهی
- مشابه
- ساده
- پس از
- کوچک
- So
- آگاهی
- رسانه های اجتماعی
- نرم افزار
- راه حل
- برخی از
- صدا
- تخصصی
- خاص
- انشعاب
- شروع
- راه افتادن
- ماندن
- گام
- متوقف شد
- راست
- رشته
- موفق
- مفروض
- مشکوک
- گرفتن
- صحبت
- سخنگو
- تیم
- اعضای تیم
- آزمون
- نسبت به
- که
- La
- اطلاعات
- شان
- آنها
- آنجا.
- اینها
- آنها
- اشیاء
- این
- بلیط
- بلیط
- زمان
- به
- هم
- موضوع
- جمع
- قطار
- آموزش
- عطف
- آموزش
- فهمیدن
- بروزرسانی
- به روز شده
- us
- استفاده
- استفاده کنید
- استفاده
- کاربر
- با استفاده از
- معمولا
- ارزشها
- وسیع
- بسیار
- از طريق
- دیوار
- بود
- we
- چی
- چه زمانی
- که
- هرکس
- اراده
- پنجره
- با
- بدون
- کلمه
- کلمات
- مهاجرت کاری
- کارگر
- خواهد بود
- نوشته
- کتبی
- X
- سال
- شما
- خودت
- زفیرنت