رگرسیون لجستیک: راهنمای ساده برای شهود و پیاده سازی در پایتون


نویسنده(های): مریم سیکندر

در ابتدا منتشر شد به سمت هوش مصنوعی.

منبع: عکس نوشته AltumCode در پاشیدن

وقتی صحبت از حل مسائل طبقه بندی می شود، رگرسیون لجستیک اغلب اولین الگوریتمی است که به ذهن ما می رسد. مفاهیم نظری رگرسیون لجستیک برای درک مفاهیم پیشرفته تر ضروری است یادگیری عمیق.

TO-DOs

در این وبلاگ، همه آنچه را که باید در مورد رگرسیون لجستیک بدانید را به تفکیک می پردازیم. نظریه، ریاضی و پیاده سازی در پایتون هدف من این است که این مفاهیم را تا حد امکان واضح و ساده بیان کنم. باشه…!!

بیایید شروع کنیم

مقدمه:

رگرسیون لجستیک یک الگوریتم طبقه بندی اساسی است که برای پیش بینی احتمال متغیر وابسته طبقه بندی استفاده می شود.

ایده رگرسیون لجستیک یافتن رابطه بین متغیرهای مستقل و احتمال متغیرهای وابسته است. به زبان ساده، این یک الگوریتم طبقه‌بندی است که زمانی که متغیر پاسخ طبقه‌بندی می‌شود – معمولاً باینری (مثلاً 0 یا 1) استفاده می‌شود.

یک مثال ساده

فرض کنید داده‌های بیمار دارید و می‌خواهید پیش‌بینی کنید که آیا احتمال ابتلای فرد به دیابت وجود دارد یا خیر. خروجی باینری است: یا تشخیص داده شده (1) یا سالم (0). به همین ترتیب:

  • آیا امروز باران خواهد آمد؟ (بله یا خیر)
  • آیا این ایمیل اسپم است؟ (بله یا خیر)
مشکل طبقه بندی – (تصویر توسط نویسنده)

به این نوع مشکل می گویند رگرسیون لجستیک باینری یا رگرسیون لجستیک دو جمله ای.
پس از رگرسیون لجستیک باینری، رگرسیون لجستیک نیز دارای انواع زیر است:

  • رگرسیون لجستیک چند جمله ای: زمانی که متغیر پاسخ دارای سه یا چند نتیجه باشد (مثلاً پیش بینی آب و هوا: آفتابی، بارانی یا برفی).
  • رگرسیون لجستیک ترتیبی می تواند نتایج باینری یا چند جمله ای باشد اما به ترتیب مانند رتبه بندی، رتبه بندی کلاس دانش آموز (عالی، متوسط، بد).

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

چرا فقط از رگرسیون خطی استفاده نمی کنیم؟

چرا نمی توانیم استفاده کنیم رگرسیون خطی برای نتایج باینری؟ سوال عالی!

تصور کنید سعی می کنید پیش بینی کنید که آیا کسی محصولی را خریداری می کند یا خیر (0 یا 1).

رگرسیون خطی ممکن است پیش بینی هایی مانند:

  • “1.8” (امم … این به چه معنی است؟ آنها به احتمال زیاد خرید می کنند؟)
  • “-0.3” (احتمال منفی؟ حتی ممکن نیست!)

رگرسیون لجستیک با معرفی این مشکل را برطرف می کند تابع سیگموئید؛

این خط خطی را به یک منحنی S شکل تبدیل می کند که هر مقدار را به محدوده ترسیم می کند [0, 1]. خیلی تمیز، درسته؟

عملکرد لجستیک – (تصویر توسط نویسنده)

تابع هزینه در رگرسیون لجستیک:

هدف از رگرسیون لجستیک یافتن بهترین وزن ها (پارامترهایی) است که خطا را به حداقل می رساند. در رگرسیون خطی از میانگین مربعات خطا (MSE) به عنوان تابع هزینه،

نمودار از تابع هزینه در رگرسیون خطی:

اما برای رگرسیون لجستیک، MSE خوب کار نمی کند. چرا؟ از آنجایی که تابع سیگموئید غیرخطی است، MSE منجر به یک منحنی غیر محدب می شود

تصویر توسط نویسنده

یک تابع غیر محدب دارای حداقل های محلی زیادی است که رسیدن به حداقل جهانی را برای تابع هزینه بسیار دشوار می کند و همچنین میزان خطا را افزایش می دهد. (اوه نه!).

به جای MSE، ما تابع هزینه متفاوتی را استخراج می کنیم که به نام the تابع log-loss یا متقابلآنتروپی از دست دادن.

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

Gradient Descent یک الگوریتم بهینه‌سازی است که برای یافتن مقادیر پارامترهای یک تابع (رگرسیون خطی، رگرسیون لجستیک و غیره) که برای کاهش یک تابع هزینه استفاده می‌شود، استفاده می‌شود. برای درک عمیق تر این وبلاگ را بررسی کنید گرادیان نزول

مشتق کامل ریاضی تابع لجستیک

خوب دست و پنجه نرم کن، حالا می‌خواهیم ریاضی را بگیریم

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

و در مورد نمادهایی مانند w، θ یا 𝛽 گیج نشوید – آنها فقط روش‌های متفاوتی برای بیان یک چیز هستند که معمولاً در ادبیات استفاده می‌شود.

بیایید ابتدا به تابع لجستیک (sigmoid) نگاهی بیندازیم:

مرحله 1: مشتق تابع سیگموئید

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

مرحله 2: گرادیان تابع هزینه را محاسبه کنید

برای به حداقل رساندن تابع هزینه، گرادیان آن را با توجه به وزن‌های w محاسبه می‌کنیم. مشتق تابع هزینه یک نقطه داده منفرد:

مرحله 3: قانون زنجیره ای برای محاسبه ∂J(w)/∂w:

حالا گرادیان را با توجه به وزن ها محاسبه کنید. با استفاده از قانون زنجیره، از مرحله 1 و مرحله 2:

جایگزین:

مرحله 4: به روز رسانی وزن

پس از محاسبه مشتقات، با استفاده از گرادیان نزول، وزن ها را به صورت معادله زیر به روز می کنیم:

اندازه گام را بر اساس مقیاس کنید 🝛: اینجا 🝛 نرخ یادگیری است که به‌روزرسانی‌ها را کنترل می‌کند که بیش از حد بزرگ (که می‌تواند باعث شود الگوریتم به حداقل برسد) یا خیلی کوچک (که می‌تواند همگرایی را بسیار کند کند) را کنترل می‌کند. بنابراین، یافتن نرخ یادگیری بهینه بسیار مهم است و این معمولاً از طریق آزمایش انجام می شود.

منبع: تاثیر نرخ یادگیری توسط cs231n

باشه دوباره به تابع به روز رسانی وزن نگاهی بیندازید، ممکن است این سوال داشته باشید که دلیل کم کردن وزن های قدیمی با مشتقات برای به روز رسانی چیست.

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

ما به سمت ماکزیمم J(w) حرکت می کنیم، که برعکس چیزی است که هنگام کمینه سازی می خواهیم.

از آنجایی که الگوریتم نزول گرادیان یک رویکرد تکراری است، ابتدا مقادیر وزن ها را به طور تصادفی می گیریم و سپس آن را طوری تغییر می دهیم که تابع هزینه کمتر و کمتر شود تا زمانی که به حداقل برسیم.

ریاضی بس است – بیایید رگرسیون لجستیک را مرحله به مرحله در پایتون پیاده سازی کنیم!

پیاده سازی در پایتون:

ما از فرمول های ریاضی مشتق شده در بالا برای ساخت یک مدل رگرسیون لجستیک از ابتدا استفاده خواهیم کرد.

  1. numpy را وارد کنید و کلاس را راه‌اندازی کنید:
import numpy as np
class Logistic_Regression():
def __init__(self):
self.coef_ = None
self.intercept = None

2. تعریف تابع سیگموئید:

def sigmoid(self, z):
return 1 / (1 + np.exp(-z))

3. محاسبه هزینه و گرادیان:

# Cost Function: -1/m ∑[y_i * log(ŷ) + (1 - y_i) * log(1 - ŷ)] 
def cost_function(self, X, y, weights):
z = np.dot(X, weights)
predict_1 = y * np.log(self.sigmoid(z))
predict_2 = (1 - y) * np.log(1 - self.sigmoid(z))
return -sum(predict_1 + predict_2) / len(X)

4. مدل قطار:

def fit(self, X, y, lr=0.01, n_iters=1000):
# Reason to add columns of ones at first, to include the intercept term in calculation as well (X.W)
X = np.c_[np.ones((X.shape[0], 1)), X]
# Initialize weights randomly
self.weights = np.random.rand(X.shape[1])
# To track the loss over iterations
losses = []

for _ in range(n_iters):
# Compute predictions
z = np.dot(X, self.weights)
y_hat = self.sigmoid(z)

# Compute gradient
gradient = np.dot(X.T, (y_hat - y)) / len(y)

# Update weights
self.weights -= lr * gradient

# Track the loss
loss = self.cost_function(X, y, self.weights)
losses.append(loss)

self.coef_ = self.weights[1:]
self.intercept_ = self.weights[0]

5. پیش بینی کنید:

 def predict(self, X):
X = np.c_[np.ones((X.shape[0], 1)), X]
z = np.dot(X, self.weights)
predictions = self.sigmoid(z)
return [1 if i > 0.5 else 0 for i in predictions]

در اینجا کد کامل موجود است Github

تصویر توسط نویسنده

در مرحله بعد، من مدل سفارشی ساختمان را آموزش دادم تا ببینم چگونه رگرسیون لجستیک scikit-learn را جمع آوری می کند. بررسی کنید دفترچه یادداشت.

نتیجه گیری:

و این برای این وبلاگ است!

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

رگرسیون لجستیک یک الگوریتم طبقه بندی بنیادی است و درک مفاهیم آن برای قدم گذاشتن در آن بسیار مهم است. یادگیری عمیق.

برای همه کدها و پیاده سازی لطفا به این مراجعه کنید مخزن GitHub. اگر در مورد ریاضی، کد یا هر چیز دیگری سؤالی دارید؟ در تماس گرفتن دریغ نکنید!

اگر این مقاله را آموزنده و ارزشمند یافتید، از حمایت شما بسیار سپاسگزارم:

>> چند کف بزنید 👏 در Medium تا به دیگران کمک کنید این محتوا را کشف کنند (شما می توانید تا 50 بار کف بزنید). دست زدن های شما به گسترش دانش به خوانندگان بیشتر کمک می کند.

>> با من در لینکدین ارتباط برقرار کنید: مریم سیکندر

منتشر شده از طریق به سمت هوش مصنوعی



منبع: https://towardsai.net/p/machine-learning/logistic-regression-a-simple-guide-to-intuition-and-implementation-in-python