یادگیری ماشین شاخهای از هوش مصنوعی است که بر روی توسعه الگوریتمها و مدلهای آماری متمرکز است که میتوانند از دادهها یاد بگیرند و پیشبینیهایی را انجام دهند.
رگرسیون خطی همچنین یک نوع الگوریتم یادگیری ماشین است. به طور خاص یک الگوریتم یادگیری ماشین نظارتشده است که از دادههای برچسبدار یاد میگیرد و نقاط داده را به تابع خطی بهینهای نگاشت میکند که میتوان از آن برای پیشبینی در مجموعه دادههای جدید استفاده کرد.
پس گفتیم که الگوریتم های یادگیری ماشین نظارت شده نوعی از یادگیری ماشین هستند که الگوریتم از دادههای دارای برچسب یاد میگیرد.
دادههای دارای برچسب به مجموعه دادههایی گفته میشود که مقادیر هدف آنها قبلاً مشخص شده است.
یادگیری نظارتشده دو شاخه دارد:
- طبقهبندی: در آن، کلاسِ مجموعه داده بر اساس متغیرهای ورودی مستقل پیشبینی میشود. کلاسها مقادیری دستهای یا گسسته هستند، مانند اینکه تصویر یک حیوان، گربه است یا سگ.
- رگرسیون: در این شاخه، متغیرهای خروجی پیوسته بر اساس متغیرهای ورودی مستقل پیشبینی میشوند، مانند پیشبینی قیمت خانهها بر اساس عوامل مختلفی چون مدت ساخت خانه، فاصله از جادهی اصلی، موقعیت و مساحت.
رگرسیون خطی
رگرسیون خطی (Supervised Learning) نوعی الگوریتم یادگیری ماشینی نظارت شده است که رابطه خطی بین متغیر وابسته و یک یا چند ویژگی مستقل را محاسبه میکند.
زمانی که تنها یک ویژگی مستقل وجود داشته باشد به آن رگرسیون خطی تکمتغیره گفته میشود و در صورتی که بیش از یک ویژگی مستقل باشد، به آن رگرسیون خطی چندمتغیره میگویند.
هدف الگوریتم خطی یافتن بهترین معادله خطی است که بتواند مقدار متغیر وابسته را بر اساس متغیرهای مستقل پیشبینی کند. این معادله، خط مستقیمی را ارائه میدهد که رابطه بین متغیرهای وابسته و مستقل را نمایش میدهد. شیب خط نشاندهنده تغییر متغیر وابسته برای تغییر واحد در متغیر(های) مستقل است.
رگرسیون خطی در بسیاری از زمینههای مختلف مانند مسائل مالی، اقتصاد و روانشناسی استفاده میشود تا رفتار یک متغیر خاص را درک و پیشبینی کند. به عنوان مثال، در مسائل مالی، رگرسیون خطی ممکن است برای درک رابطه بین قیمت سهام یک شرکت و سود آن یا برای پیشبینی ارزش آتی یک ارز بر اساس عملکرد گذشتهاش استفاده شود.
یکی از مهمترین وظایف یادگیری ماشین نظارتشده، رگرسیون است. در رگرسیون، مجموعهای از رکوردها با مقادیر X و Y وجود دارند و این مقادیر برای یادگیری یک تابع استفاده میشوند تا اگر بخواهید Y را از X ناشناختهای پیشبینی کنید، بتوانید از این تابع یادگرفته شده استفاده کنید. در رگرسیون، باید مقدار Y را پیدا کنیم، بنابراین به یک تابع نیاز داریم که در صورت رگرسیون، Y پیوستهای را با توجه به X به عنوان ویژگیهای مستقل پیشبینی کند.
در اینجا Y به عنوان متغیر وابسته یا متغیر هدف شناخته میشود و X به عنوان متغیر مستقل نامیده میشود که همچنین به عنوان پیشبینیکننده Y شناخته میشود. انواع مختلفی از توابع یا مدلها وجود دارند که میتوانند برای رگرسیون استفاده شوند. تابع خطی سادهترین نوع تابع است. در اینجا، X ممکن است یک ویژگی تکی یا چندین ویژگی باشد که مسئله را معرفی میکنند.
رگرسیون خطی وظیفه پیشبینی مقدار یک متغیر وابسته (y) بر اساس یک متغیر مستقل داده شده (x) را انجام میدهد. از این رو، به آن رگرسیون خطی گفته میشود. در شکل بالا، X (ورودی) تجربه کاری و Y (خروجی) حقوق فرد است. خط رگرسیون، خط بهترین fit برای مدل ما است.
فرضیات مدل رگرسیون خطی
برای اینکه مدل رگرسیون خطی به درستی کار کند و نتایج قابل اتکایی ارائه دهد، باید چند فرض اساسی را برآورده کند:
✓ خطی بودن
بین متغیرهای مستقل و وابسته باید یک ارتباط خطی وجود داشته باشد، یعنی هر تغییری در متغیر مستقل باید باعث یک تغییر متناسب و خطی در متغیر وابسته شود.
✓ استقلال
هر مشاهدهای در مجموعه دادهها باید مستقل از مشاهدات دیگر باشد، به این معنی که مقدار متغیر وابسته یک نمونه نباید تحت تاثیر مقدار متغیر وابسته نمونهای دیگر باشد.
✓ واریانس همسان
واریانس خطاها در تمام سطوح متغیر(های) مستقل باید یکسان باشد، به این معنی که میزان متغیر مستقل نباید تاثیری بر میزان پراکندگی خطاها داشته باشد.
✓ نرمالیتی
خطاها در مدل باید به صورت توزیع نرمال باشند.
✓ عدم وجود همخطی چندگانه
نباید بین متغیرهای مستقل ارتباط قوی وجود داشته باشد، یعنی متغیرهای مستقل نباید به شدت به یکدیگر وابسته باشند.
تابع فرض برای رگرسیون خطی
با توجه به اینکه قبلاً فرض کردهایم ویژگی مستقل ما تجربه کاری یعنی ( X) است و حقوق متناظر ( Y) به عنوان متغیر وابسته میباشد، بیایید فرض کنیم یک رابطه خطی بین ( X) و ( Y) وجود دارد، پس میتوان حقوق را با استفاده از رابطه زیر پیشبینی کرد:
در اینجا:
– برچسبها به دادهها داده میشوند (یادگیری نظارتشده).
– ورودیها دادههای مستقل آموزشی هستند (تکمتغیره – یک متغیر ورودی (پارامتر)).
– مقادیر پیشبینی شده هستند.
مدل با پیدا کردن بهترین مقادیر برای θ1 و θ2 بهترین خط برازش رگرسیونی را به دست میآورد.
- θ1: مقدار برش با محور عمودی (عرض از مبدأ)
- θ2: ضریب ( X ) (شیب خط)
پس از یافتن بهترین مقادیر برای θ1 و θ2، ما به خطی دست پیدا میکنیم که دادهها را به بهترین شکل ممکن تطابق میدهد. بنابراین، هنگامی که مدلمان را برای پیشبینی به کار میبریم، این مدل مقدار y را برای مقدار ورودی x پیشبینی خواهد کرد.
تابع هزینه
تابع هزینه یا تابع ضرر، چیزی جز خطا یا تفاوت بین مقدار پیشبینی شده و مقدار واقعی ( Y) نیست. این مقدار، خطای میانگین مربعات (MSE) بین مقدار پیشبینی شده و مقدار واقعی است. تابع هزینه (J) میتواند به صورت زیر نوشته شود:
برای رسیدن به بهترین خط تطابق، چگونه θ1 و θ2 را بروز کنیم؟
برای به دست آوردن خط تطابق بهتر، مدل ما سعی میکند مقادیر هدف را به نحوی پیشبینی کند که تفاوت خطا میان مقادیر پیشبینی شده و مقادیر واقعی (Y) کمینه شود. پس، بروزرسانی مقادیر θ1 و θ2 برای رسیدن به کمترین میزان خطا بین مقدار پیشبینی شده (pred) و مقدار واقعی (y) اهمیت زیادی دارد.
گرادیان کاهشی
رگرسیون خطی میتواند با استفاده از الگوریتم بهینهسازی گرادیان کاهشی (Gradient Descent) آموزش داده شود، آن هم با تغییر مکرر پارامترهای مدل برای کاهش خطای میانگین مربعات (MSE) مدل در یک مجموعه داده آموزشی.
برای بهروزرسانی مقادیر θ1 و θ2 به منظور کاهش تابع هزینه (کمینه کردن مقدار RMSE) و دستیابی به خط تطابق بهتر، مدل از گرادیان کاهشی استفاده میکند. ایده این است که با مقادیر تصادفی θ1 و θ2 شروع کنیم و سپس به صورت تکراری مقادیر را بهروزرسانی کنیم تا به کمترین هزینه برسیم.
گرادیان چیزی جز مشتق نیست که تأثیرات جزئی تغییرات در ورودیها را بر خروجیهای تابع تعریف میکند.
بیایید تابع هزینه (J) را نسبت به θ1 و θ2 مشتق بگیریم:
هدف از رگرسیون خطی پیدا کردن ضرایبی برای یک معادله خطی است که دادههای آموزشی را به بهترین شکل توصیف کند. میتوان ضرایب را با حرکت در خلاف جهت شیب خطای میانگین مربعات نسبت به این ضرایب تغییر داد. برای این کار، عرض از مبدأ و ضریب مربوط به (X) را میتوان با استفاده از نرخ یادگیری به روز رسانی کرد.
ساخت مدل رگرسیون خطی از صفر
وارد کردن کتابخانههای ضروری:
import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.axes as ax
بارگذاری مجموعه دادهها و جداسازی متغیرهای ورودی و هدف
data = pd.read_csv(‘data_for_lr.csv’)
# Drop the missing values data = data.dropna() # training dataset and labels train_input = np.array(data.x[0:500]).reshape(500,1) train_output = np.array(data.y[0:500]).reshape(500,1) # valid dataset and labels test_input = np.array(data.x[500:700]).reshape(199,1) test_output = np.array(data.y[500:700]).reshape(199,1)
مراحل ساخت مدل رگرسیون خطی
- در انتشار رو به جلو، تابع رگرسیون خطی ( Y=mx+c) با اختصاص اولیه مقدار تصادفی به پارامترها (m و c) اعمال میشود.
- سپس تابعی برای یافتن تابع هزینه نوشتهایم، یعنی میانگین …
class LinearRegression: def __init__(self): self.parameters = {} def forward_propagation(self, train_input): m = self.parameters['m'] c = self.parameters['c'] predictions = np.multiply(m, train_input) + c return predictions def cost_function(self, predictions, train_output): cost = np.mean((train_output - predictions) ** 2) return cost def backward_propagation(self, train_input, train_output, predictions): derivatives = {} df = (train_output - predictions) * -1 dm = np.mean(np.multiply(train_input, df)) dc = np.mean(df) derivatives['dm'] = dm derivatives['dc'] = dc return derivatives def update_parameters(self, derivatives, learning_rate): self.parameters['m'] = self.parameters['m'] - learning_rate * derivatives['dm'] self.parameters['c'] = self.parameters['c'] - learning_rate * derivatives['dc'] def train(self, train_input, train_output, learning_rate, iters): #initialize random parameters self.parameters['m'] = np.random.uniform(0,1) * -1 self.parameters['c'] = np.random.uniform(0,1) * -1 #initialize loss self.loss = [] #iterate for i in range(iters): #forward propagation predictions = self.forward_propagation(train_input) #cost function cost = self.cost_function(predictions, train_output) #append loss and print self.loss.append(cost) print("Iteration = {}, Loss = {}".format(i+1, cost)) #back propagation derivatives = self.backward_propagation(train_input, train_output, predictions) #update parameters self.update_parameters(derivatives, learning_rate) return self.parameters, self.loss
آموزش مدل
#Example usage linear_reg = LinearRegression() parameters, loss = linear_reg.train(train_input, train_output, 0.0001, 20)
Iteration = 1, Loss = 5363.981028641572 Iteration = 2, Loss = 2437.9165904342512 Iteration = 3, Loss = 1110.3579137897523 Iteration = 4, Loss = 508.043071737168 Iteration = 5, Loss = 234.7721607488976 Iteration = 6, Loss = 110.78884574712548 Iteration = 7, Loss = 54.53747840152165 Iteration = 8, Loss = 29.016170730218153 Iteration = 9, Loss = 17.43712517102535 Iteration = 10, Loss = 12.183699375121314 Iteration = 11, Loss = 9.800214272338595 Iteration = 12, Loss = 8.718824440889573 Iteration = 13, Loss = 8.228196676299069 Iteration = 14, Loss = 8.005598315794709 Iteration = 15, Loss = 7.904605192804647 Iteration = 16, Loss = 7.858784500769819 Iteration = 17, Loss = 7.837995601770647 Iteration = 18, Loss = 7.828563654998014 Iteration = 19, Loss = 7.824284370030002 Iteration = 20, Loss = 7.822342853430061
پیشبینی نهایی و رسم خط رگرسیون
#Prediction on test data y_pred = test_input*parameters['m'] + parameters['c'] # Plot the regression line with actual data pointa plt.plot(test_input, test_output, '+', label='Actual values') plt.plot(test_input, y_pred, label='Predicted values') plt.xlabel('Test input') plt.ylabel('Test Output or Predicted output') plt.legend() plt.show()