NLP stuff
4.05K subscribers
147 photos
1 video
2 files
277 links
مطالب خوب و به‌دردبخور در حوزه‌ی هوش مصنوعی و پردازش زبان طبیعی!

شکرشکن شوند همه طوطیان هند
زین قند پارسی که به بنگاله می‌رود

اگر انتقاد، پیشنهاد و یا مطلب مفیدی (لینک، پست و ...) داشتید:
@AliAkbarBadri
@mmsamiei
@MmahdiAghajani
加入频道
بررسی اهمیت فیچرها

احتمالا تا حالا پیش اومده که می‌خواستید اهمیت فیچر‌ها رو در یک تسک بسنجید. در چنین شرایطی استفاده از معیار feature_importance در دسته‌بندهای درختی مثل random forest شاید اولین گزینه‌ای باشه که به ذهن آدم میرسه. در این دسته‌بندها با توجه به اینکه در هر گره فیچری برای جداسازی داده انتخاب میشه که بیشترین کاهش رو در معیار impurity داشته باشه، مهم‌ترین فیچرها اون‌هایی هستند که به ریشه درخت نزدیک‌تر هستند. به عبارت دیگه فیچرهایی بیشترین importance رو به‌دست میارند که به‌صورت وزندار بیشترین کاهش رو در معیار impurity بر روی داده داشته باشند. اما لزوما اولین گزینه بهترین گزینه نیست. در واقع اگه شما در دیتاست‌تون فیچرهای categorical زیادی داشته باشید احتمالا این معیار، شما رو به اشتباه میندازه. در واقع دسته‌بندهای درختی به فیچرهای numerical که مقادیر unique value زیادی دارند حساس‌تر هستند. به خاطر همین ممکنه در ایجاد درخت تصمیم به فیچرهای categorical اهمیت کمتری بدند. این موضوع به‌خاطر اینه که این دسته‌بندها برای ایجاد درخت تصمیم از معیاری به نام impurity استفاده می‌کنند. مقدار feature importance که براساس معیار impurity در درخت‌های تصمیم حساب میشه می‌تونه ما رو به اشتباه بندازه. حالا چاره کار، استفاده از روش دیگه‌ای به نام permutation_importance است. در این روش در هر iteration یک فیچر انتخاب میشه و مقادیر اون به صورت رندم shuffle میشه ( در هر نمونه ورودی مقادیر همه فیچر‌ها ثابت می‌مونه و فقط یک فیچر بین نمونه‌های مختلف ورودی شافل میشه) و بعد، دیتاست شافل‌شده به مدل داده میشه تا ببینیم چه مقدار افت کیفیت پیدا می‌کنه. طبیعتا اون فیچری که بعد از شافل شدن افت عملکرد بیشتری رو به مدل تحمیل می‌کنه از اهمیت بالاتری برخورداره. همون‌طور که می‌بینید این روش model agnostic هست و بر روی هر مدل از‌قبل‌ترین‌شده‌ای کار می‌کنه. از طرفی می‌تونید این معیار رو هم بر روی مجموعه تست و هم مجموعه ترین محاسبه کنید در حالیکه impurity-based feature importanceها عملا بر روی داده ترین فقط محاسبه شده‌اند. مقایسه اهمیت برخی فیچرها در دیتای تست و ترین و تفاوت اون‌ها می‌تونه سرنخی از وقوع اورفیت باشه. در واقع فیچری که در دیتای ترین اهمیت بالایی داره ولی موقع تست و inference اهمیت پایینی داره می‌تونه باعث اورفیت بشه. پیاده‌سازی و نحوه استفاده از این روش رو در پکیج scikit می‌تونید مشاهده کنید.

لینک توضیح permutation_importance:
https://scikit-learn.org/stable/modules/permutation_importance.html#permutation-importance

پ.ن. از این به بعد یه هشتگ جدید راه انداختیم که توش می‌خوایم نکات نغز و دلکش تکنیکال رو بگیم. کانال رو به بقیه هم معرفی کنید.

#handsOn

@nlp_stuff
معیار silhouette؛ بایدها و نبایدها

یکی از معیارهایی که برای سنجش کیفیت خوشه‌بندی ازش میشه استفاده کرد معیار silhouette است. در مسایلی که برچسب ground truth وجود نداره، برای ارزیابی کیفیت خوشه‌بندی باید از معیارهای ریاضیاتی استفاده کنیم تا کیفیت خوشه‌بندی مشخص بشه. این معیار به ازای هر سمپل در دیتا محاسبه میشه و برای محاسبه روی کل دیتا معمولا یه تجمیع مثلا از جنس میانگین بر روی اون انجام میشه. این معیار در واقع تشویق می‌کنه که سمپل‌های هر خوشه بهم نزدیک باشند و همزمان سمپل‌های یک خوشه بیشترین فاصله رو از نزدیکترین خوشه به خودشون داشته باشند. به همین دلیل هر چقدر خوشه‌ها چگال‌تر باشند و بهتر از هم جدا شده باشند، مقدار بزرگ‌تری به خودش می‌گیره. خروجی این معیار بین -۱ تا +۱ است که هر چقدر به +۱ نزدیک‌تر باشه نشون میده خوشه‌بندی بهتر انجام شده و هر چقدر به -۱ نزدیک‌تر باشه نشون میده سمپل‌ها به خوشه‌های اشتباهی تخصیص داده شدند. مقادیر نزدیک به صفر هم نشون‌دهنده اینه که خوشه‌ها به مقدار زیادی با هم همپوشانی دارند. اما یه نکته مهم که معمولا در استفاده از این معیار بهش توجه نمیشه، اون پیش‌فرضی هست که برای محاسبه این معیار درنظر گرفته شده. در واقع این معیار همواره برای خوشه‌هایی که شکل دایره‌ای تر دارند بیشتر از خوشه‌های غیر دایره‌ای شکل (همانند خوشه‌هایی که روشی مانند DBSCAN براتون درمیاره) خواهد بود. در صورتی که فهمیدید شکل خوشه‌ها از حالت دایره‌ای خارج شده باید از معیارهای دیگه‌ای برای سنجش کیفیت خوشه‌بندی استفاده کنید. یکی از این معیارها Bayes Information Criterion است که فرمولش رو در تصویر می‌تونید ببینید.

پ.ن: در تصویر زیر به ترتیب ۳ نوع دیتاست می‌بینید که در بالای تصویر امتیاز silhouette برای هر سه دیتاست به ترتیب و برای روش های مختلف کلاسترینگ نشون داده شده. همون ‌طور که میبینید برای دیتاست اول و دوم در حالی که روش mini-batch kmeans به طور اشتباه خوشه‌بندی رو انجام داده اما امتیاز بالاتری گرفته.

منابع:
[1] https://scikit-learn.org/stable/modules/clustering.html#silhouette-coefficient
[2] Hands-on Machine Learning with Scikit-Learn, Keras, and TensorFlow: Chapter 9

#handsOn

@nlp_stuff
چاله‌ای به نام model drift!

اگه تجربه دیپلوی مدل‌های یادگیری ماشین در پروداکشن رو داشته باشید حتما به این موضوع برخوردید که مدل‌تون بعد از مدتی ممکنه جواب‌های خوبی تولید نکنه.  یکی از علل رایج همچین اتفاقی، رخداد model drift هست که به انواع مختلف می‌تونه رخ بده.  model drift می‌تونه ناشی از data drift یا concept drift باشه.  خود data drift هم می‌تونه براساس دریفت در فیچرها و یا دریفت در لیبل رخ بده. تصور کنید می‌خواید مدل پیش‌بینی قیمت خانه رو آموزش بدید و بعد از  کرونا تقاضای خانه‌های بزرگ در بازار بیشتر شده و به همین دلیل تعداد خانه‌های کوچک در بازار بیشتر میشه و خانه‌های بزرگ کمتر. در این حالت توزیع فیچر سایز خانه عوض‌شده و منجر به data drift شده. یا در سناریوی دیگه‌ای به‌دلیل وقوع موج گرانی قیمت‌ کل خانه‌ها دچار تغییر شده باشه که در این‌جا هم data drift از نوع تغییر متغیر هدف رو داریم.
در حالت concept drift هم نه توزیع فیچرها تغییر می‌کنه و نه توزیع متغیر هدف بلکه تابع نگاشت‌کننده فیچرها به لیبل تغییر می‌کنه. تصور کنید که در مساله پیش‌بینی قیمت خانه نه فیچرها تغییر کرده باشند و نه توزیع لیبل‌ها بلکه افراد به دلیل تغییرات شرایط جامعه خانه‌های ویلایی رو بیشتر از خانه‌های آپارتمانی ترجیح بدند. در این حالت قیمت خانه‌های ویلایی به طور مضاعفی بالا میره‌ و مدلی که قبلا آموزش دیده باشه در این شرایط نمی‌تونه پیش‌بینی خوبی حداقل درباره خانه‌های ویلایی داشته باشه.
اما چاره چیه؟! در وهله اول مانیتور، مانیتور، مانیتور! یکی از اصلی‌ترین قسمت‌های دیپلوی مدل در پروداکشن، مانیتور کردن عملکرد اون به صورت دوره‌ای هست. با این روش اولین سوالی که به‌وجود میاد اینه که چه‌طور می‌تونیم یه آلارم model drift رو به موقع ارسال کنیم؟ طبیعتا نیاز داریم علاوه بر اینکه با چشم نمودارها رو کنترل می‌کنیم به صورت سیستمی هم آلارم‌ داشته باشیم. روش‌های مختلفی برای این کار وجود داره مانند استفاده از تست‌های آماری برای مقایسه توزیع فیچرهای دیتای ترین و دیتای پروداکشن. یکی از راه‌حل‌های هوشمندانه هم آموزش یک مدل دسته‌بند (مانند مدل random forest) بر روی دیتای ترین و تست به صورت همزمان هست به این صورت که به کل دیتای ترین لیبل ۱ و به کل دیتای تست لیبل صفر بزنیم. اگه مدل ما بتونه با دقت خوبی این دو تا دیتا رو از هم تفکیک کنه ینی به احتمال زیاد data drift رخ داده و چنانچه از مدل‌های درختی استفاده کرده باشید با مفهوم feature importance می‌تونید حتی متغیر دریفت کرده رو هم شناسایی کنید. (برای استفاده از این مفهوم یه بار دیگه این پست رو نگاه بندازید)
و در آخر، علل مختلفی برای وقوع model drift وجود داره که از مهمترین‌هاشون تاثیرات فصلی و مقطعی روی داده، معرفی مفاهیم  یا محصولات و یا سرویس‌های جدید به بازار هدف و یا تغییر کیفیت داده است. مهمترین راهکار هم برای رفع model drift اینه که فرآیند retrain برای مدل‌تون داشته باشید و هیچ وقت به اینکه یه مدل با کیفیت رو روی دیتای ترین آموزش دادید و روی دیتای تست نتیجه خوب گرفتید هم بسنده نکنید.

منابع:
A survey on concept drift adaptation
Design Machine Learning Systems

#handsOn

@nlp_stuff
بحر در کوزه این بار با HF!

احتمالا تا حالا شده که در مسیر تسک‌های NLP به دیوار سخت و خشن یک دیتاست بزرگ برخورده باشید (مثلا یک دیتاست در اندازه چند ده گیگابایت که شاید حتی جایی برای ذخیره‌سازیش در دیسک نداشته باشید چه برسه به رم). در این حالته که دست‌ها رو به نشانه تسلیم بالا می‌برید. اما هاگینگ‌فیس در کتابخانه Datasets🤗 این مشکل رو حل کرده. در واقع با دو قابلیت memory mapping و streaming که این کتابخانه فراهم کرده بر محدودیت رم و دیسک غلبه می‌کنید. قابلیت memory mapping (که به صورت پیش‌فرض فعاله) به این اشاره داره که با لودکردن هر دیتاستی توسط Datasets🤗 این کتابخانه یه سری cache file از دیتاست می‌سازه که بر روی دیسک ذخیره شدند و عینا همون محتویات دیتاست لود‌شده در RAM هستند. پس یه جور آیینه تمام‌نمای RAM محسوب می‌شه و از این جا به بعد دیگه این کتابخانه یه اشاره‌گر به اول این فایل باز می‌کنه و دیتا به صورت batch داخل رم لود میشه. طبیعتا آموزش مدل از اینجا به بعد I/O bounded خواهد بود اما نگران اون قسمتش هم نباشید چون فرمتی که برای کار با این فایل‌ها استفاده می‌کنه Apache Arrow هست که یه فرمت بهینه‌شده است. از طرفی برای اینکه نعمت رو بر ما تکمیل کرده باشه و حتی نگران کمبود دیسک هم نباشیم قابلیت streaming رو تعریف کرده که ینی می‌تونید از هاب دیتاست هاگینگ‌فیس، دیتاست رو به صورت batch و on the fly دانلود کنید و پردازش انجام بدید (که به صورت پیش‌فرض فعال نیست و باید streaming=True باشه). البته با استفاده از این قابلیت امکان random access به دیتاها رو از دست می‌دید (مثلا نمی‌تونید دستور dataset[2335] رو ران کنید چون آبجکتی که می‌سازه حالت iterable داره و شبیه generatorهای پایتونیه) ولی با دستور next و iterate کردن بر روی دیتاست، دقیقا سمپل‌های یک دیتاست استریم‌نشده رو می‌گیرید. پس دیگه بهونه بسه و پاشید کار با دیتاست‌های بزرگ رو شروع کنید.

پ.ن: در تصاویر یه سری نمونه کد‌هایی آوردیم که از فصل ۱۰ کتاب گران‌سنگ NLP with Transformers گرفته شده که اثری جاوید از هاگینگ‌فیسه.

#handsOn

@nlp_stuff
همه ممکن است نشت کنند!

یکی از مهمترین بخش‌های پایپ‌لاین دیتا، نحوه صحیح تقسیم‌بندی دیتا به داده‌ی train و test است. نکات زیادی داره که مهمتریناش اینه که نباید نشتی داشته باشید؛ یعنی از داده‌ی آموزش نباید توی داده‌ی ولیدیشن و تست داشته باشید وگرنه می‌بینید متریکتون به شکل غیرواقعی خوب میشه. باز یکی دیگه از نکاتش اینه که قرار نیست توزیع داده آموزش و تست تفاوت زیادی کنند وگرنه می‌بینید که روی داده تست نتایجتون خیلی ضعیف میشه. یا اینکه قرار نیست هر جور که دوست دارید دادتون رو تقسیم کنید و گاهی مثلا اگر مساله با سری زمانی در ارتباطه، لازمه روی خط زمانی تقسیم کنید و گاهی لازمه شافل کنید و رندوم تقسیم کنید. نکات بیشتر و دقیق‌تری رو در فصل یک و دو کتاب hands on ml میتونید پیدا کنید.

شاید با خودتون فکر کنید خب اینکه خیلی راحته؛ ولی اینطور نیست. استاد پوروطنِ ما همیشه این مثل معروف رو می‌گفت که: شیطان در جزئیاته.
سال ۲۰۱۷ اندرو انگِ گولاخ و شرکا یک مقاله با عنوان CheXNet: Radiologist-Level Pneumonia Detection on Chest X-Rays with Deep Learning دادند (تریلی اسم مقاله رو نمی‌کشه). اونجا یه مدل CNNای ارائه دادند و روی صد هزار تا تصویر رادیولوژی از ۳۰ هزار تا بیمار آموزش دادند تا بتونند بیماری ذات الریه رو تشخیص بدن (اولا عظمت دیتا رو داشته باشید. ثانیا دقت کردید که چند تا تصویر برای یک بیمار وجود داشته). بعد اومدند این دیتا رو ۸۰ به ۲۰ بین آموزش و تست به صورت رندوم تقسیم کردند. چشمتون مشکل رو دید؟ اگر شما بیاید دیتا رو به صورت رندوم تقسیم کنید تصاویر یک بیمار می‌تونه توی هر دو تا داده‌ی ترین و تست باشه و مدل می‌تونه از فیچرهای مربوط به بیمار کلی استفاده کنه؛ حتی اگر این فیچرها مستقیما مربوط به خود بیماری ذات الریه نباشه. مثلا یک زخمی از عمل رو توی یه عکس آموزش میبینه و یاد میگیره این مربوط به کلاس اوله. بعد دیگه هر جا عین همون زخم رو ببینه زرتی میگه کلاس اوله و دیگه فکر نمیکنه. یعنی یه میان‌بر پیدا کرد. بعد از  ۱۱ روز فهمیدند مشکل داره و اومدند این رو درست کردند و دوباره مقاله رو منتشر کردند. در عکس دوم ضمیمه‌شده به پست می‌تونید ببینید که جمله‌ی there was 𝗻𝗼 𝗽𝗮𝘁𝗶𝗲𝗻𝘁 𝗼𝘃𝗲𝗿𝗹𝗮𝗽 between the sets رو در تصویر راست (نسخه اصلاح شده) نسبت به تصویر چپ (نسخه اولیه) اضافه کردند و نحوه تقسیم رو تغییر دادند.

حداقل دو تا درس از این موضوع میتونیم یاد بگیریم: اول. حواسمون به نشتی باشه چون همه ممکنه نشت کنیم. دوم. همه حتی اندرو انگ و شرکا هم ممکنه اشتباه کنند. پس فقط سعی کنیم یاد بگیریم، درستش کنیم و تکرار نکنیم. خجالت هم نداره.

لینک مقاله نسخه اول:
https://arxiv.org/abs/1711.05225v1

لینک مقاله نسخه اصلاح شده:
https://arxiv.org/abs/1711.05225

لینک توئیت توضیح این داستان:
https://twitter.com/svpino/status/1592140348905517056

پ.ن. شما هم اگر پست خوبی داشتید بفرستید تا به اسم خودتون توی کانال بذاریم.

#tweet
#handson

@nlp_stuff
اسپارک؛ سهل و ممتنع!

اگر در حوزه تحلیل دیتا کار کرده باشید قطعا با ابزارهای data manipulation مانند pandas یا spark کار کردید. در این پست قصد داریم رشته بلاگی رو به شما معرفی کنیم که مفاهیم پایه‌ای spark رو به شما یاد میده. فهم این مفاهیم کمک می‌کنه که کوعری‌های بهتری در اسپارک بزنید و یا علت کند اجرا شدن برخی از کوعری‌ها رو بفهمید. همون‌طور که می‌دونید spark در دوحالت cluster mode و client mode اجرا میشه که معمولا برای کارهای تحلیلی که خیلی پروداکشنی نیست از همین حالت client mode استفاده می‌کنیم که در واقع تنها کاری که برای بهره بردن از اسپارک باید انجام بدید نصب پکیج pyspark بر روی سیستمتون هست (درست مثل pandas). حسن بزرگ اسپارک اینه که محاسبات بر روی دیتای حجیم رو می‌تونه بین چندین executor بشکونه و محاسبات هر executor توی ram اجرا میشه و executorها نتایج کارشون رو با استفاده از ارتباط با driver به اشتراک می‌ذارن تا نتیجه نهایی بدست بیاد (همون‌طور که متوجه شدید معماری کل اسپارک حالت master/slave داره) این وسط با کانفیگ‌هایی که روی اسپارک انجام میدید میتونید حداکثر استفاده از ram رو تعیین کنید تا خیالتون راحت باشه که همه ram سیستم شما مورد استفاده قرار نگیره. این رشته بلاگ ابتدا مفاهیمی مانند driver و executor و scheduler رو توضیح داده و سپس به سراغ توضیح پارتیشن‌ها رفته. پارتیشن‌ها بخش‌هایی از دیتا هستند که می‌تونند به صورت توزیع‌شده باشند و یا به صورت موازی پردازش بر روی اون‌ها انجام بگیره. در واقع هر executor در لحظه می‌تونه فقط یک پارتیشن از دیتا رو پردازش کنه ولی driver می‌تونه چندین executor رو به کار بگیره برای اینکه پردازش دیتا همزمان روی چندین پارتیشن انجام بشه.
این رشته بلاگ توضیح داده که برخی از transformationها یا کوعری ها حالت narrow دارند که به این معنیه که انجام اونها منجر به repartition شدن دیتا نمیشه مانند map یا filter ولی برخی دیگه wide transformation هستند که منجر به repartition شدن دیتا میشه مانند groupby که wide transformationها می‌تونند کوعری‌های سنگین‌تری باشند.  (همون‌طور که می‌دونید کوعری‌ها در اسپارک lazy هستند به این معنی که در لحظه اجرا نمیشند بلکه مواقع خاصی مانند تبدیل نتایج به list و یا ذخیره کردن داده اجرا میشند که این به اسپارک اجازه میده از زنجیره کوعری‌ها یک گراف محاسباتی بسازه و اون رو قبل از اجرا بهینه کنه)
در نهایت اومده و memory management در اسپارک رو توضیح داده که یکی از مهم‌ترین و البته پیچیده‌ترین قسمت‌های فهم اسپارک هست و گفته که memory management در سطوح مختلف قابل تعریفه مثل driver memory و یا executor memory و ...
توصیه می‌کنیم حتما این رشته بلاگ رو بخونید و سعی کنید از این به بعد به جای pandas از spark استفاده کنید که وقتی دیتای حجیم دیدید هول نکنید!

لینک رشته بلاگ:
https://luminousmen.com/post/hadoop-yarn-spark

#handsOn
#read
#blog

@nlp_stuff