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


- بخش اول: در این قسمت، مباحث اولیه و اساسی مربوط به رگرسیون خطی آورده شده و فرمولهای مرتبط نیز ارائه میشوند.
- بخش دوم: کدها و برنامههایی که برای مدلسازی رگرسیون خطی ساده و چندگانه در پایتون لازم است در این قسمت ارائه میشوند.
برای آشنایی بیشتر با مفاهیم اولیه در رگرسیون خطی، نوشتارهای رگرسیون خطی — مفهوم و محاسبات به زبان ساده، رگرسیون خطی چندگانه (Multiple Linear Regression) — به زبان ساده را بخوانید. همچنین خواندن مطلب هم خطی در مدل رگرسیونی — به زبان ساده نیز خالی از لطف نیست.
کدهای پایتون برای رگرسیون خطی
به منظور پیادهسازی «رگرسیون خطی ساده» (Simple Linear Regression) و «رگرسیون چندگانه» (Multiple Regression) و بررسی فرضیات آن به یک مجموعه داده احتیاج داریم که در قسمت اول این نوشتار، به بررسی آن میپردازیم.
در مجموعه دادهای که مربوط به 1030 مشاهده از مقاوت فشاری کامل (Complete Compressive Strength) یک ترکیب از مواد اولیه مختلف است، هشت متغیر توصیفی مطابق با فهرست زیر قرار دارد.
- سیمان (Cement)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- سربار کوره بلند (Blast Furnace Slag)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- خاکستر (Fly Ash)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- آب (Water)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- پلاستیزایر (Superplasticizer)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- ماسه درشت دانه (Coarse Aggregate)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- ماسه ریز دانه (Fine Aggregate)، برحسب کیلوگرم در مخلوط یک متر مکعب.
- طول عمر (Age) برحسب روز که در محدوده ۱ تا ۳۶۵ قرار دارد.
این مجموعه دادهها را میتوانید با نام Concrete_Data.csv از اینجا با قالب فشرده دریافت کنید. در تصویر زیر نمونهای از دادههای این فایل را در اکسل مشاهده میکنید.

کدهای پایتون برای اجرای رگرسیون خطی
برای انجام تحلیل رگرسیونی روی مجموعه داده Concrete_Data.csv به کتابخانههای numpy, pandas, matplotlib احتیاج داریم.
بارگذاری و فراخوانی این کتابخانهها در کد زیر صورت گرفته است.
فرض بر این است که فایل داده، در محل پیشفرض (Working Directory) پایتون قرار دارد. در غیر اینصورت باید مسیر دسترسی به این فایل را نیز در تابع pd.read_csv مشخص کنید. به این ترتیب متغیرهای توصیفی (مستقل) در متغیر x و مقادیر متغیر وابسته در y ثبت میشوند.
تفکیک دادهها به دو بخش آموزشی و آزمایشی
در این قسمت، مشاهدات را به دو گروه آموزشی (Training Set) و آزمایشی (Test Set) تقسیم میکنیم. این کار توسط کتابخانه sklearn صورت میگیرد.
همانطور که مشخص است ۸۰٪ از دادهها برای بخش آموزش و ۲۰٪ برای آزمایش در نظر گرفته شدهاند.
رگرسیون خطی با کتابخانه sklearn
به کمک کتابخانه sklearn و کلاس LinearRegression، محاسبات مربوط به مدل رگرسیونی در متغیر lm ثبت میشود. نتیجه مقادیر برازش شده توسط مدل نیز برای دادههای آموزشی محاسبه میشود.
خروجی با فراخوانی ـlm.coef به صورت زیر ظاهر میشود.
همانطور که مشخص است، هر یک از این مقادیر به ترتیب، ضرایب متغیرهای توصیفی X1 تا X8 هستند. به منظور ثبت این متغیرها در یک چارچوب داده (DataFrame) از دستور زیر کمک میگیرم.
نتیجه به صورت زیرخواهد بود.
برای نمایش مقدار عرض از مبدا یا میانگین کل نیز از کد زیر استفاده میکنیم.
به این ترتیب مدل رگرسیونی چندگانه مطابق با خروجیهای ایجاد شده، شکل میگیرد. بر این اساس میتوان مقادیر پیشبینی شده را هم نمایش داد و باقیمانده یا خطاها را هم محاسبه کرد.
برای محاسبه ضریب تعیین یا نیز که ابزاری برای سنجش کارایی مدل است، از دستورات زیر استفاده میکنیم.
این طور به نظر میرسد که مقدار مناسب است و مدل به خوبی شکل گرفته است زیرا مقدار ضریب تعیین بزرگتر از ۰٫۶ است.
رگرسیون خطی با کتابخانه statmodels
در این قسمت با استفاده از کلاس OLS، مدل رگرسیون خطی چندگانه را روی دادههای y_train و x_train برازش میدهیم.
نکته: متاسفانه در مدلی که توسط sm.OLS تولید میشود، عرض از مبدا یا مقدار میانگین کل در مدل بطور خودکار وجود ندارد و باید این گزینه را توسط sm.add_constant درخواست کنیم.
خلاصه مدل حاصل توسط دستور summary به دست میآید. خروجی را در ادامه میبینید.
همانطور که مشاهده میکنید، خروجی ایجاد شده توسط دستور summary، بسیار مفصل است و مباحث مربوط به وجود همخطی و نرمال بودن باقیماندهها، توسط آزمونهای «دوربین واتسون» (Durbin-Warson) و «جارک برا» (Jarque-Bera) صورت گرفته است که مشخص است فرض نرمال بودن با توجه به بزرگ بودن مقدار احتمال رد نمیشود.
مشخص است که نتایج حاصل از دستور summary در اینجا با نتایج حاصل از مدلی که توسط lm از کتابخانه sklearn تولید شده، اندکی متفاوت است که ناشی از خطای محاسباتی است. زیرا مقادیر پیشبینی در هر دو مدل یکسان است.
در قسمتی از خروجی، یک جدول تحلیل واریانس (ANOVA) را مشاهده میکنید که به ضرایب و همچنین مقدار احتمال برای معنیداری هر یک از ضرایب مدل رگرسیونی پرداخته است. به غیر از عرض از مبدا (Constant) که دارای مقدار احتمال بزرگتر از ۵٪ است، بقیه متغیرها میتوانند در مدل حضور داشته باشند. از طرفی بزرگ بودن مقدار F-statistic و همینطور کوچک بودن مقدار احتمال (Prob F-statistic) نشان از مناسب بودن مدل است.
در انتها نیز به منظور برآورد مقادیر متغیر وابسته از کد زیر کمک میگیریم.
نکته: مقادیر برآورد شده در y_pred2 و y_pred برابر هستند ولی با استفاده از دو روش متفاوت بدست آمدهاند.
ارزیابی صحت مدل رگرسیون خطی با پایتون
همانطور که در قسمت اول این نوشتار خواندید، ارزیابی مناسب بودن مدل میتواند توسط ضریب تعیین صورت گیرد. در این قسمت با استفاده از و مدل را ارزیابی میکنیم.
در ادامه بدون هیچ تابعی و به کمک فرمولهایی که در بخش اول این نوشتارها مشاهده کردهاید، این شاخصها را محاسبه میکنیم.
نتیجه اجرا برای مدل تولید شده توسط statsmodels به صورت زیر است:
از آنجایی که ضریب تعیین و حتی ضریب تعیین تعدیل شده برای مدل بزرگتر از ۰٫۶ است، مدل مناسب به نظر میرسد.
شناسایی دادههای دورافتاده (Outlier)
یکی از شرایط اجرای مدل رگرسیونی، نداشتن دادههای پرت در میان مجموعه داده است. بنابراین باید دادهها را از جهت نداشتن چنین مشاهداتی مورد بررسی قرار دهیم. برای انجام این کار، ابتدا مقادیر استاندارد شده باقیماندهها (Studentize Residuals) را محاسبه میکنیم. این کار به کمک تابع get_influence صورت میگیرد و نتیجه در متغیر resid_student ثبت میشود.
با ترکیب مجموعه آموزشی و باقیماندهها، جدولی به صورت زیر خواهیم داشت.
این خروجی توسط دستور زیر حاصل شده است که در آن مقادیر و بقایماندهها را برای ۵ مشاهده اول در جدول بالا میبینید.
نکته: برآورد باقیمانده استاندارد شده (Studentize Residuals)، برحسب واریانس برآورده شده برای متغیر وابسته و یک ضریب اصلاح است. که به صورت زیر محاسبه میشود:
که عناصر قطر اصلی ماتریس هستند. اگر مقدار باقیمانده استاندارد شده (Studentize Residuals) بزرگتر از ۳ یا کوچکتر از ۳- باشد، آن مشاهده را مقدار دور افتاده در نظر میگیریم. در نتیجه به نظر میرسد که مشاهده شماره 649، مقدار دورافتاده است.
خروجی بالا به کمک دستور زیر بدست آمده است. توجه داشته باشید که شماره مشاهده مورد نظر در متغیر ind ذخیره شده است.
به منظور خارج کردن این مشاهده در مدل رگرسیونی از دستورات زیر استفاده میکنیم. تابع drop به این منظور در کد زیر گنجانده شده است.
شناسایی همخطی چندگانه و اصلاح آن
در ادامه شاخص VIF یا همان عامل یا «فاکتور تورم واریانس» (Variance Inflation Factor) را بدست میآوریم تا مشخص کنیم که آیا مدل دچار مشکل همخطی است یا خیر. در حقیقیت میخواهیم بدانیم چه ترکیبی از متغیرها توصیفی با یکدیگر وابستگی خطی دارند.
مقادیر حاصل از محاسبه VIF برای هر یک از متغیرها در ادامه دیده میشود.
معمولا اگر متغیری دارای VIF بزرگتر از ۵ باشد، آن را از مدل خارج میکنیم. بنابراین کدهای زیر به منظور شناسایی این امر و خارج کردن چنین متغیری از مدل به کار گرفته میشوند. در اینجا thresh، ملاک خروج متغیر از مدل است که همان مقدار ۵ را دارد.
به این ترتیب متغیرهای چهارم (Water)، ششم و هفتم یعنی ماسه درشت (Coarse Aggregate) و ریز دانه (Fine Aggregate) از متغیرهای مدل خارج میشوند.
با این کار، مجموعه دادهها به صورت زیر در خواهند آمد.
نکته: شمارههایی که در ستون اول این جدول مشاهده میکنید، شماره ردیف مشاهدات مربوط به مجموعه آموزشی هستند.
خارج کردن این متغیرها توسط کد زیر صورت گرفته است.
در ادامه لیستی از مقادیر مجموعه آزمایشی با خروج متغیرهایی که باعث همخطی شده بودند، دیده میشود.
حال به بررسی مدل رگرسیونی پس از خارج کردن این مقادیر میپردازیم.
همانطور که مشاهده میکنید تعداد اعضای مجموعه آموزشی از ۸۲۴ مشاهده به ۸۲۳ مشاهده رسیده زیرا یکی از اعضا که نقطه دورافتاده بود، از دادهها خارج شده است. همچنین درجه آزادی مدل (Df Model) که برابر با تعداد متغیرهای توصیفی است از ۸ به ۵ رسیده است که حاصل خارج کردن متغیرهایی است که مشکل همخطی داشتند.
همانطور که مشاهده میکنید، مقدار ضریب R-squared و Adj. R-squared نسبت به حالتی که همه متغیرها وجود داشتند کاهش داشته ولی این کاهش برای Adj. R-squared کمتر است. همین اختلاف زیاد بین دو شاخص در دو حالت گواهی دیگر بر وجود مشکل همخطی است.
بررسی نرمال بودن باقیماندهها
آمارههای دوربین واستون (Durbin-Watson) با مقدار ۲٫۰۹۰ و همچنین آزمون جارک برا (Jarque-Bera) با مقدار ۰٫۹۴۵ کوچک هستند و فرض نرمال بودن باقیماندهها را تایید میکنند.
نکته: برای آزمون نرمال بودن باقیماندهها میتوانید از آزمون «شاپیرو ویلک» (Shapiro-Wilk's test) نیز استفاده کنید. کد مربوط به اجرای این آزمون در ادامه آورده شده است.
همانطور که مشاهده میکنید، آماره شاپیرو کوچک و مقدار احتمال آن که برابر با 0٫626988 است، بزرگتر از 0٫05 است در نتیجه فرض صفر که نرمال بودن باقیماندهها است رد نخواهد شد.
آزمون همواریانسی (Homoscedasticity)
آزمون گلدفلد کوانت (Goldfeld-Quandt Test)، آخرین گام برای ارزیابی نتایج مدل رگرسیونی است. فرض صفر این آزمون، ثابت بودن واریانس و وجود همواریانسی است. این امر به این معنی است که واریانس متغیر وابسته تحت تاثیر متغیرهای توصیفی نبوده و در نتیجه ثابت خواهد بود.
نتبجه اجرای این دستورات، نشانگر آن است که مقدار آماره F کوچک (0٫9903) و مقدار احتمال (p value=0٫539) است در نتیجه فرض همواریانسی برای این مدل رد نمیشود. در اینجا هم باز هم صحت مدل مورد ارزیابی قرار میگیرد.
خلاصه و جمعبندی
رگرسیون یک تکنیک آماری است که در یادگیری ماشین و دادهکاوی به کار میرود. به همین علت کسانی که در علم داده مشغول فعالیت هستند، لازم است که بر این روش آماری مسلط شوند. در این نوشتار با جنبههای مختلف رگرسیون خطی در پایتون و نحوه پیادهسازی آن آشنا شدیم و از کتابخانههای مختلف آن برای حل مسائل رگرسیون خطی ساده و چندگانه کمک گرفتیم. در این بین نحوه ارزیابی صحت مدل نیز ارائه شده و مورد بحث قرار گرفت.
اگر مطلب بالا برای شما مفید بوده است، آموزشهایی که در ادامه آمدهاند نیز به شما پیشنهاد میشوند:
- مجموعه آموزش های آمار و احتمالات
- آموزش همبستگی و رگرسیون خطی در SPSS
- مجموعه آموزشهای داده کاوی و یادگیری ماشین
- رگرسیون کمترین زاویه (LAR Regression) — به زبان ساده
- رگرسیون خطی — مفهوم و محاسبات به زبان ساده
- تحلیل واریانس (Anova) — مفاهیم و کاربردها
^^













module ‘statsmodels.formula.api’ has no attribute ‘OLS’ هر کاری میکنم قبول نمیکند تا نمودار ols بدهد برای بار دوم چرا ؟ من یک هفته هست که گیر کردم سز این مسیله
import statsmodels.api as sma
import statsmodels.formula.api as sm
train_out = sma.add_constant(train_out) ## let’s add an intercept (beta_0) to our model
x_test.drop([“Water”,”CA”,”FA”],axis = 1,inplace = True)
X_test = sma.add_constant(x_test)
lm2 = sm.OLS(y_train,train_out).fit()
lm2.summary()
سلام چزا درقسمت train_out = sma.add_constant(train_out) وارد میکنم اخطار name ‘train_out’ is not defined میده؟
مثل همیشه دکتر ری بد خوب بود.
در قسمت تفکیک داده ها، می بایست cross_validation با ساب ماژول model_selection جایگزین شود زیرا cross_validation منسوخ شده است!
مرسی عالی بود
بسیار عالی و مفید بود