پیاده سازی رگرسیون لجستیک از صفر

مقدمهدر مطلب قبلی که در ویرگول پست کردم با رگرسیون خطی ساده و نحوه‌ی پیاده سازی آن از صفر آشنا شدیم (لینک) ، در این مطلب یک مدل یادگیری ماشین دیگر به نام رگرسیون لجستیک را بررسی می‌کنیم. رگرسیون لجستیک از دسته الگوریتم‌های نظارت شده (Supervised) می‌باشد و برای دسته‌بندی (Classification) مورد استفاده قرار می‌گیرد. رگرسیون لجستیک یکی از پرکاربرد‌ترین الگوریتم‌های یادگیری ماشین است که در ادامه به تفصیل آن را بررسی می‌کنیم.محدودیت الگوریتم رگرسیون خطی در دسته‌بندیدر این مطلب هدف به دست آوردن الگوریتمی برای دسته‌بندی گروهی از داده‌ها می‌باشد. اما اول باید به این سوال پاسخ دهیم که چرا به الگوریتم جدیدی برای دسته‌بندی نیاز داریم، آيا نمی‌توان از الگوریتم رگرسیون خطی برای این امر استفاده کرد؟ برای پاسخ به این سوال تلاش می‌کنیم تا به کمک الگوریتم رگرسیون خطی، داده‌های زیر را دسته بندی کنیم. نمودار زیر نشان‌دهنده‌ی رابطه‌ی احتمال بیمار بودن و وزن شش (۶) موش مختلف می‌باشد، به این شکل که بر روی محور عرض‌ها (y) احتمال بیمار بودن یا نبودن موش مورد نظر مشخص شده و بر روی محور طول‌ها (x) وزن موش مورد نظر به واحد گِرم (g) نمایش داده شده است. نتایج به دست آمده در آزمایشگاه نشان می‌دهند که سه موش سنگین وزن شرکت کرده در این آزمایش بیمار هستند.شکل یک (۱): نمودار نسبت وزن به احتمال بیمار بودن در موش‌هاحال الگوریتم رگرسیون خطی ساده را با داده‌های ارائه شده در بالا آموزش می‌دهیم و آستانه‌ی انتخاب (Threshold) را ۰/۵ در نظر می‌گیریم. آستانه‌ی انتخاب به این معنی است که اگر مدل رگرسیون خطی برای وزن یک موش، عددی بزرگتر از ۰/۵ پیش‌بینی کرد موش را بیمار در نظر می‌گیریم و اگر عددی کوچکتر از ۰/۵ را پیش‌بینی کرد موش را سالم در نظر می‌گیریم، در نمودار پایین خط نقطه‌چین مشکی نشان‌دهنده‌ی آستانه‌ی انتخاب یا مقدار ۰/۵ می‌باشد به عبارت دیگر اگر بر روی محور طول‌ها (x) از خط نقطه‌چین به سمت راست حرکت کنیم، مقدار پیش‌بینی شده بزرگتر از ۰/۵ و موش، بیمار می‌باشد، ولی اگر به سمت چپ حرکت کنیم مقدار پیش‌بینی شده توسط مدل رگرسیون خطی ساده کوچکتر از ۰/۵ و موش مورد نظر، سالم می‌باشد.شکل دو (۲): نمودار نسبت وزن به احتمال بیماری با نمایش آستانه‌ی انتخاب (Threshold)واضح است که مدل رگرسیون خطی ساده در دسته بندی این موش‌ها بسیار خوب و تا حدی بدون نقص عمل می‌کند. حال یک موش بسیار سنگین وزن به آزمایش اضافه می‌کنیم و رگرسیون خطی را دوباره اجرا می‌کنیم.شکل سه (۳): نمودار نسبت وزن به احتمال بیماری که اضافه شدن موش سنگین وزن باعث خراب شدن عملکرد رگرسیون خطی می‌گردد.با اضافه شدن یک داده‌ی پرت، الگوریتم رگرسیون خطی نمی‌تواند عملیات دسته‌بندی را به درستی اجرا کند و یکی از موش‌های بیمار را در دسته‌ی سالم پیش‌بینی می‌کند. از طرفی می‌دانیم مقادیر به دست آمده از طریق الگوریتم رگرسیون خطی می‌توانند بسیار بیشتر از یک و بسیار کمتر از صفر باشند فلذا نیاز به مدلی داریم که خروجی آن در بازه‌ی ۰ تا ۱ باشد.دو مشکل الگوریتم رگرسیون خطی ساده در دسته‌بندی، عبارتند از: ۱ـ عملکرد ضعیف و ۲ـ تولید مقادیری که تفسیر آنها مشکل است.تابع سیگموئیدتوابع سیگموئیدی به توابعی کراندار، مشتق‌پذیر و حقیقی گفته می‌شود که نمودار آنها شکل حرف s انگلیسی دارد. یکی از معروف‌ترین این توابع، تابع لجستیک می‌باشد که مدل رگرسیون لجستیک نام خود را از این تابع وام گرفته است. نمودار این تابع را در شکل زیر می‌بینیم. این تابع اعداد حقیقی در بازه‌ی (∞+،∞-) را به بازه‌ی (۰،۱) نگاشت می‌کند. این کار باعث ساده‌سازی تفسیر خروجی مدل به عنوان احتمال می‌گردد و مشکل اعداد بزرگتر از یک (۱) و کوچکتر از صفر (۰) در رگرسیون خطی را برطرف می‌سازد.شکل چهار (۴): نمودار تابع لجستیک این تابع به کمک معادله‌ی زیر محاسبه می‌گردد.معادله‌ی یک (۱): تابع لجستیکمدل رگرسیون لجستیکدر مساله احتمال بیماری موش‌ها که در بالا بررسی کردیم فقط یک عامل (وزن) را در بیمار بودن موش‌ها موثر دانستیم و تاثیر آن را بررسی کردیم، در صورتی که در دنیای واقعی عوامل زیادی هستند که در نتیجه‌ی یک اتفاق (Event) موثر هستند از طرفی هر عامل به اندازه‌ی متفاوتی در نتیجه تاثیر دارد تاثیر این عوامل مختلف را با یک ضریب عددی وارد معادله کرده و آنها را وزن می‌نامیم. به این روش برای لحاظ کردن تاثیر وزن‌ها بر مدل حاصل‌جمع وزن‌دار گفته می‌شود که در پاراگراف بعدی آن را توضیح می‌دهم.فرض کنید مجموعه‌ی دادگانی دارای n ویژگی (Feature) باشد، همچنین در مجموعه‌ی دادگان m داده داشته باشیم. این مجموعه داده را به شکل زیر می‌توان نشان داد.شکل پنج (۵): نمایش مجموعه دادگانحاصل‌جمع وزن‌دار برای هر عضو از مجموعه‌ی دادگان نشان داده شده در بالا به شکل زیر محاسبه می‌گردد.معادله‌ی دو (۲): حاصل‌جمع وزن‌داربه منظور ساده‌سازی معادلات همچنین استفاده‌ی حداکثری از توان کامپیوتر (موازی سازی) فرمول بالا را به کمک جبر خطی و به شکل برداری بازنویسی می‌کنیم. در صورتی که وزن‌ها و متغیر‌ها را به شکل دو بردار زیر نشان دهیم، حاصل‌جمع وزن دار را می‌توانیم به شکل ضرب بردار نمایش دهیم که در آن T، ترانهاده‌ی بردار می‌باشد.معادله‌ی سه (۳): نمایش برداری وزن‌ها و متغیر‌هامعادله‌ی چهار (۴): نمایش برداری حاصل‌جمع وزن‌دارمفهوم بایاس (Bias) و الزام استفاده از آن خارج از بحث این مطلب می‌باشد اما به طور خلاصه به منظور عملکرد بهتر مدل و یادگیری روابط پیچیده‌تر، بایاس را نیز به عبارت بالا اضافه می‌نماییم و حاصل به دست آمده را z نام‌گذاری می‌کنیم.معادله‌ی پنج (۵): نمایش برداری حاصل‌جمع وزن دار با اضافه شدن بایاسحاصل عبارت بالا یک بردار از اعداد حقیقی خواهد بود که آن را به عنوان ورودی به تابع لجستیک می‌دهیم، در این گفتار تابع لجستیک را با نماد σ (سیگمای کوچک) نمایش می‌دهیم.معادله‌ی شش (۶): مدل رگرسیون لجستیکعبارت به دست آمده در بالا مدل (فرضیه، Hypothesis، h_θ(x)) رگرسیون لجستیک می‌باشد. گفتنی‌است که حاصل به دست‌آمده از طریق تابع لجستیک یک بردار به اندازه‌ی m از اعداد در بازه‌ی (۰،۱) می‌باشد. هر عدد به دست آمده از طریق این معادله‌ (مدل) را می‌توان به صورت عبارت زیر که یک احتمال شرطی یا برشی می‌باشد تفسیر کرد. به طور مثال در مورد موشها عدد حاصل شده از مدل احتمال بیمار بودن موش، به شرط وزن آن می‌باشد.معادله‌ی هفت (۷): تفسیر جواب رگرسیون لجستیک به کمک احتمال شرطیتابع هزینهجهت ارزیابی عملکرد مدل همچنین بهبود آن به کمک الگوریتم گرادیان‌کاهشی که در ادامه به آن می‌پردازیم باید ابتدا یک تابع هزینه تعریف کنیم. تابع هزینه‌ای که از آن استفاده میکنیم Cross Entropy Cost Function یا به اختصار CEC می‌باشد، تابع هزینه را برای رگرسیون لجستیک به شکل زیر تعریف می‌کنیم.معادله‌ی هشت (۸): تابع هزینه‌ی رگرسیون لجستیک گرادیان کاهشیمفهوم گرادیان کاهشی را در مطلب قبلی که در ویرگول پست کردم (لینک)، توضیح دادم اما به طور خلاصه باید گفت که گرادیان کاهشی یک الگوریتم بهینه سازیست که در اینجا برای کمینه (Minimize) کردن تابع هزینه از آن استفاده می‌کنیم. شبه کد گرادیان کاهشی به شکل زیر می‌باشد.شبه کد یک (۱): شبه کد الگوریتم گرادیان کاهشیبرای استفاده از گرادیان کاهشی، نیاز به محاسبه‌ی مشتق جزئی تابع هزینه نسبت به پارامتر θ داریم. این عملیات مشتق‌گیری نیاز به استفاده از قانون مشتق زنجیره‌ای (Chain Rule) دارد.معادله‌ی نه (۹): عملیات مشتق گرفتن از تابع هزینه و حاصل به دست آمده از آنحال که همه‌ی المان‌های مورد نیاز را داریم آنها را به کد تبدیل می‌کنیم.کدکد قابل اجرا و کامل این مطلب را می‌توانید از این مخزن گیتهاب دریافت کنید (لینک).مرحله‌ی اول import کردن کتابخانه‌ی numpy می‌باشد که برای انجام محاسبات ریاضی از آن کمک می‌گیریم.کد یک (۱): وارد کردن کتابخانه‌های مورد نیازحال داده‌ها را وارد برنامه می‌کنیم، داده‌های استفاده شده در این گفتار داده‌های مربوط به سرطان سینه هستند که در کتابخانه‌ی scikit موجود هستند. (لینک دادگان)کد دو (۲): وارد کردن داده‌ها‌ی سرطان سینه به کمک scikitحال مجموعه دادگان وارد شده را به دو گروه test و train تقسیم می‌کنیم. ۲۵ درصد از دادگان را در مجموعه‌ی test قرار داده و بقیه را در مجموعه‌ی train همچنین اگر می‌خواهید نتایج به دست آمده در این گفتار را تکرار کنید می‌توانید random_state را برابر با مقدار 42 قرار دهید، دقت کنید که در این امر اجباری نیست.کد سه (۳): تقسیم مجموعه دادگان به آموزش و تستحال کلاس رگرسیون لجستیک را تعریف می‌کنیم، در تابع سازند‌ه‌ی این کلاس دو پارامتر max_iter و learning_rate را مقداردهی می‌کنیم، این دو پارامتر هردو مربوط به الگوریتم گرادیان کاهشی می‌باشند، دقت کنید که به منظور ساده‌سازی موضوع از شرط همگرایی در گرادیان کاهشی صرف نظر کردیم، اما در گیتهاب کد مربوط به اعمال شرط همگرایی نیز موجود است.در متد fit ابتدا ابعاد مجموعه‌ی دادگان را میگیریم و آن را در دو متغیر n_samples (تعداد اعضای مجموعه) و n_features تعداد ویژگی‌ها میریزیم. سپس به کمک کتابخانه‌ی numpy بردار theta را با مقدار صفر مقداردهی می‌کنیم.در حلقه‌ی تکرار در هر مرتبه ابتدا حاصل‌جمع وزن دار را محاسبه می‌کنیم، دقت کنید که چون کتابخانه‌ی پانداس داده‌ها را به شکلی که ما در گفتار بالا بررسی کردیم، برنمی‌گرداند، در محاسبه‌ی حاصلجمع وزن‌دار مجبوریم مقادیر بردار دادگان (X) را نیز ترانهاده کنیم.پس از محسابه‌ی حاصل‌جمع وزن دار و محاسبه‌ی مقدار لجستیک نوبت به اجرای گرادیان کاهشی می‌رسد. دقت کنید که با محاسبه‌ی گرادیان بایاس متوجه می‌شویم، مقدار آن از رابطه‌ی زیر محاسبه می‌شود.معادله‌ی ده (۱۰): معادله‌ی گرادیان بایاس کد چهار(۴): کلاس رگرسیون لجستیکحال که کلاس را داریم از آن استفاده کرده و دقت را محاسبه می‌کنیم.کد پنج (۵): استفاده از کلاسکد شش (۶): محسابه‌ی دقت