سعی کردم هرچیزی که از جلسات دوره فهمیدم رو به صورت جزوه در بیارم و در این پلتفورم با بقیه به اشتراک بذارم. کل جلسات دوره 23 تاست که سعی میکنم هفتهای دو جلسه رو منتشر کنم. تا جایی که تونستم سعی کردم خوب و کامل بنویسم، اما اگر جایی ایرادی داشت، حتما تو کامنتها بهم بگید تا درستش کنم.
در حوزه ML با یک سری داده یا تجربه روبرو هستیم که میخواهیم از آنها کمک بگیریم تا یک task رو بهتر انجام بدیم. اگر بتوانیم با استفاده از تجربهای که داریم task را طوری انجام دهیم که performance measure عدد بیشتری رو نشون بده، میگوییم learning یا یادگیری انجام شده.
ما میخواهیم از دادههای تجربه استفاده کنیم تا تصمیمات بهتری بگیریم و میخواهیم که قدرت تعمیم پیدا کنیم نسبت به چیزهایی هم که ندیدهایم.
میخواهیم یک تشخیصدهنده ایمیل اسپم از ایمیلهای غیر اسپم درست کنیم.
تسک: دستهبندی درست ایمیلها
پرفورمنس مژر: درصد یا تعداد ایمیلهایی که درست بندی شدهاند زیاد باشه
تجارب: تعدادی ایمیل که از قبل میدونیم خروجی به ازاشون چیه
در این دیتایی که داریم مشخصه که یه پترنی هست و الگویی دارد و یه رابطه ناشناخته بین ورودی و خروجی وجود داره. مشخصا باید یه تابع پیدا کنیم که ورودیهارو به خروجی مورد نظر مپ کنه و از اون استفاده کنیم.
اما دادههای تصویر زیر خیلی پرت هستن و نمیتوانیم از آنها الگویی استخراج کنیم.
بانک میخواد تصمیم بگیره از رو فرم افراد متقاضی که توش یه سری اطلاعات مثل سن و جنسیت و بدهی قبلی و حقوق و... هست بهشون وام بده یا نه.
یه دیتایی داریم از قبل که برچسب خورده در کنار این فرمها که نشون میده آیا به اون افراد میتونستیم وام بدیم یا نه. حالا قراره برای اشخاص جدید تصمیمگیری کنیم که آیا بهشون وام بدیم یا نه، ولی الگویی که داریم شناخته شده نیست و باید این رو به دست بیاریم.
ما تو مسئله یادگیری با ناظر که جلوتر بیشتر راجع بهش میخونیم، هدفمون اینکه تابعی که بین ورودی و خروجی ناشناخته هست رو حدس بزنیم.
چیزی که بهمون کمک میکنه که این تابع رو پیدا کنیم همون داده های train ماست که به شکل زوج مرتب نشونش میدیم.
همچنین، ممکنه ورودیمون بیشتر از یه ویژگی داشته باشه برای همین بردار در نظر میگیریم واسش.
یه تابع g داریم که حدس میزنیم و دلمون میخواد به تابع f (که همون تابعی است که رابطه بین ورودی و خروجی رو نشون میده) نزدیک بشه. ما f رو نداریم و از رو نمونهها میخوایم به f برسیم. یه جور مهندسی معکوسه.
هدفمون اینکه به کمک اون تابع که به دست میاریم برای دادههای علامت سوال پیشبینی انجام بدیم.
دنبال این هستیم که تابعمون رو از یه فضای فرضیه بکشیم بیرون نه کل فضا (یعنی محدودیت اعمال میکنیم).
در مدل یادگیری دنبال این هستیم که اولا فضای فرضیه خوبی انتخاب کنیم و دوما یک الگوریتم یادگیری که مدلمون با کمک نمونههایی که موجوده، از تو فضای فرضیه یه تابع خوب رو انتخاب کنه.
یک سری داده داریم که دو تا ویژگی دارن. خروجی یا مثبت میشه یا منفی.
فضای تابع فرضیه: تابع خطی استفاده میکنیم
حالا دنبال این هستیم که چه خطی رو انتخاب کنیم که مناسب باشه.
این classifier میاد به ازای هر ویژگی یه ضریب در نظر میگیره، ضریب رو در خود فیچر (ویژگی) ضرب میکنه و اگه از یه حدی بیشتر شه میگه خروجی مثبته و اگه کمتر شه میگه خروجی منفیه.
چیزایی که قراره یادگرفته بشه:
تابع فرضیه رو میتونیم به شکل زیر بنویسیم:
علامت داخل پرانتز رو ببین و بر اساس اون تصمیمگیری کن که خروجی چی باشه (مثبت یا منفی). مقدار w0 همون منفی threshold است که اومده سمت چپ نامعادله (همچنین چیزی : WX - threshold > 0)
حالا به شکل بردار بخوایم بنویسیم این جوری میشه:
همچنین میایم یه x0 با مقدار 1 در نظر میگیریم تا در w0 ضرب بشه. (notation رو عوض میکنیم که برداری بشه)
بعد ترانهاده بردار وزنهارو در ایکسها که همون فیچرهاست ضرب داخلی میکنیم.
حالا تابع رو به چه شکل از رو داده های train در بیاریم؟
تا رسیدن به همگرایی در یک حلقه هر دفعه یک داده رندوم انتخاب میکنه، اگر رو اون داده خروجیش اشتباه بشه در مقایسه با خروجی واقعیای که هست (یعنی اشتباه دستهبندی کنه) مقدار بردار W رو تصحیح میکنه.
حالا چرا بردار W رو به این شکل تصحیح میکنه؟
وقتی خروجی از 0 بیشتره یعنی حاصل اون ضرب داخلی که بالا گفتیم مثبت شده. حالا یه دادهای رو باید مثبت در میاورده تو خروجی اشتباهی منفی در آورده. یعنی باعث شده که زاویه بین بردار ایکس و w بیشتر از 90 بشه. پس میاد با تغییری که میده باعث میشه این زاویه کمتر از 90 درجه بشه و خروجی درست بشه صرفا روی همون یه نمونه. (شکل بالا سمت چپ)
درسته که داره دادههارو یکی یکی تغییر میده و چک میکنه ولی در نهایت باعث میشه که به همگرایی برسه.
حالا اگه باید منفی در میاورده و اشتباهی مثبت در آورده هم همینطوره. باید زاویه بیشتر از 90 میشده ولی کمتر از 90 شده پس میاد تصحیح میکنه و زاویه رو بیشتر از 90 میکنه. (شکل بالا سمت راست)
هر دور خط رو تغییر میده مثلا تو شکل بالا (سمت چپ پایین)، دیده یه داده قرمز غلط دسته بندی شده. پس خط رو جابجا میکنه و میشه شکل راست. بعد تو شکل راست میبینه به ازای اون داده آبی اشتباه خط رو کشیده. دوباره خط رو جابجا میکنه. انقدر جابجا میکنه که تهش باعث میشه اون خط به دستهبندی درستی برسه و دادههارو به شکل مناسبی دستهبندی کنه.
پشت این الگوریتم یه مسئله بهینه سازی وجود داره. میخواد یه خط رو از بین هزاران خط انتخاب کنه (همهی خطها که تعدادشون بی نهایته در اون بخش مربوط فرضیه قرار میگیره)
به شرطی که حتما یه خط وجود داشته باشه که بتونه دادههارو تو کلاسای مختلف قرار بده، این الگوریتم اون رو حتما پیدا میکنه و اثبات هم داره. (که اینجا به ثباتش نپرداختیم)
تا اینجا یه نمونه از تجربههارو دیدیم و لیبل داشتیم به ازای یه سری ورودی هامون. (یعنی تو دیتاست اولیه میدونستیم به ازای یه سری ورودی خروجیمون چی هست.)
موارد دیگه هم وجود داره منتها جزو مباحث این دوره نیست، مثلا:
معمولا به دوسته تقسیم میشن:
همونطور که قبلتر هم دیدیم،برای نمایش و ذخیره دیتا در یادگیری با ناظر، جدولی داریم که هر سطر یه نمونه رو نشون میده، هر ستون هم یه ویژگی رو. ستون آخر هم خروجی (هدف) رو نشون میده.
مثال تخمین خونه که قبل تر دیدیم جزو مسایل رگرسیون بود. حالا بریم یه مثال از کلسیفیکیشن ببینیم.
نمایش یک بعدی نمونهها:
نمایش دو بعدی نمونهها:
فرق یادگیری با ناظر و بدون ناظر تو اینکه ما تو یادگیری بدون ناظر، خروجی به ازای ورودی هامون نداریم ولی تو یادگیری با ناظر خروجی رو به ازای هر ورودی داریم. (همین که بالاتر گفتیم لیبل داریم یا نداریم)
نحوه نمایش نمونهها در یادگیری با ناظر شبیه تصویر زیر میتونه باشه. دادههای هر دسته با یه رنگ مشخص شدن.
در یادگیری بدون ناظر نمونهها رو شبیه شکل زیر نمایش میدن و به دستهبندی کردن دادهها در این نوع یادگیری اصطلاحا خوشهبندی میگن.
حالا در چه مواقعی از خوشهبندی استفاده میکنیم اصلا؟ ممکنه تعیین برچسب خروجی برامون خیلی هزینه بر باشه و بتونیم با همون اطلاعات ورودی دسته بندی رو باهزینه کمتر انجام بدیم.
نحوه نمایش دادهها در یادگیری بدون ناظر تو شکل زیر اومده که خیلی شبیه به یادگیری با ناظر هست، فرقش اینکه فقط ستون آخر که لیبلهامون بود رو نداره.
تو یادگیری با ناظر ورودی داریم و خروجی درست به ازای هر ورودی. ولی در یادگیری تقویتی ورودی داریم و یه خروجی انتخاب شده که لزوما درست نیست و محیط بهش میگه با یه تاخیری که خروجیش درسته یا نه. اگه درست باشه از محیط reward میگیره و اگه درست نباشه جریمه میشه.
برای درک بهتر فرض کنید مثلا یه ربات داریم، میخوایم از یه مبدا به یه مقصدی برسه و به در و دیوار نخوره. هر وقت به دیوار بخوره جریمه میکنیم که بفهمه که این کار غلط بوده و نباید دیگه به دیوار بخوره و وقتی به مقصد برسه بهش reward میدیم که بفهمه کار خوبی بوده و هدفمون بوده.
برای یه مثال دیگه از یادگیری تقویتی بازی تخته نرد رو در نظر بگیرید. حالا یه ربات داریم که میاد با خودش هی بازی میکنه و هر بازی که تموم میشه به ازای برنده شدن reward میگیره یا به ازای باختن جریمه میشه. انقدر بازی میکنه و ادامه میده که میتونه بفهمه بهترین شیوه بازی کردن چیه.
بعنوان یه مثال، تو شکل زیر برای اون نمونه داده شده در پایین چجوری دستهبندی انجام میدین؟
دو حالت میتونه وجود داشته باشه:
با دو تا نگاه مختلف به دو تا خروجی مختلف رسیدیم!
حالا یه مثال دیگه. یه سری دیتا داریم ازشون دو تا نمودار مختلف عبور دادیم (یعنی دو تابع مختلف براشون در نظر گرفتیم) حالا یه نمونه جدید (نمونه نارنجی رنگ) میاد برامون. خروجی کدوم تابع میتونه درست باشه؟
با دیدگاه قطعی هیچ تضمینی نداریم ولی با دیدگاه آماری میتونیم بگیم هرچی تعداد نمونهها بیشتر شه با احتمال بیشتری میتونیم بگیم جوابمون درسته در مورد نقاط دیگه.
هدفمون از لرنینگ اینکه روی دادههای جدید هم پیشبینی درستی داشته باشیم و فقط روی داده train نیست که بهش تعمیمپذیری میگن.
حالا این تابع g که بهش میرسیم (و بالاتر هم راجع بهش حرف زدیم) الزاما با تابع f خروجیهاش یکی نمیشه تو هر سمپل حتی ممکنه کاملا هم خروجیش فرق کنه. چیزی که برامون مهمه اینکه در مجموع بتونه تصمیمات خوبی بگیره. (اگه یادتون نیست تابع g و f چی بود تصویر زیر رو ببینید.)
قبلترها سنتی حل میکردیم مسائل رو. یعنی به ازای هر فرد مثلا میاومدیم جدا تحلیل میکردیم. چرا؟ چون دیتایی نداشتیم. الان دیتا داریم و دیگه این کارارو خودمون انجام نمیدیم. از روی دیتای کلی به یه نتیجه کلی میرسیم، بعد نتیجه رو برای هر فرد میتونیم استفاده کنیم. یه بار تحلیل میکنیم هزار بار استفاده به جای اینکه هزار بار تحلیل جدا کنیم!
تصویر ارقام دستنویس رو داریم و میخوایم عددش رو تشخیص بدیم. ده تا کلاس در نظر گرفتیم. به ازای هر عدد یه کلاس.
حالا بیایم به جای ده تا کلاس، دو کلاس در نظر بگیریم. فقط اعداد 1 و 5 رو بعنوان کلاسهامون بگیریم. به جای مسئله ده کلاسه بشه دو کلاسه. بعد میایم یه سری ویژگی استخراج میکنیم.
حالا این ویژگیهارو چجوری در بیاریم؟ قبلنا دستی بوده اما الان حتی ویژگیها هم میتونن لرن بشن. (تو این مثال به شیوه سنتی میریم جلو)
دو تا ویژگی در نظر میگیریم:
خروجی perceptron برای این مثال خیلی خوب نمیشه. چون خطی وجود نداره ک بتونه این دو تا کلاس رو از هم جدا کنه. ولی فرض کنید میایم این الگوریتم perceptron رو یه تغییری توش میدیم و میگیم اون خطی رو که کمترین خطارو داشته نگه داره، پس تبدیل میشه به الگوریتم pocket.
به صورت کلی با مفاهیم اولیه یادگیری ماشین و یک سری کلیات مثل:
آشنا شدیم و یه سری مثال مختلف دیدیم.
اگر جایی ایراد یا مشکلی بود، حتما بهم بگید تا تصحیحش کنم.