پیش بینی مقادیر مفقود شده با رگرسیون خطی و جنگل تصادفی در پایتون

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

import pandas as pd
df = pd.read_csv("winemag-data-130k-v2.csv") 

پنج ردیف اول را چاپ می کنیم.

print(df.head()) 

۵ سطر اول داده ۵ سطر اول داده

بیایید یک نمونه تصادفی  500 تایی  از این داده ها بگیریم. این به سرعت بخشیدن به آموزش و آزمون مدل (model training and testing) کمک می کند ،  به راحتی می توانید این مقدار نمونه را تغییر دهید:

import pandas as pd
df = pd.read_csv("winemag-data-130k-v2.csv").sample(n=500, random_state = 42) 

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

print(df.info()) 

تابع info

چندین ستون مقداری کمتر از 500 (غیر تهی) دارند که نشان از مقادیر مفقود شده دارند. ابتدا بیایید ساختن مدلی را که  مقادیر “قیمت (price)” گم شده را  با استفاده از “امتیاز (points)” جایگزاری می کند  را  در نظر بگیریم. برای شروع ، بیایید همبستگی (correlation) بین “قیمت” و “امتیاز” را چاپ کنیم:

print("Correlation: ", df['points'].corr(df['price'])) 

ضریب همبستگی بین قیمت و امتیاز

می بینیم که همبستگی مثبت ضعیفی وجود دارد. بیایید یک مدل رگرسیون خطی (linear regression model)  ایجاد کنیم که از “امتیاز” برای پیش بینی “قیمت” استفاده می کند. ابتدا ماژول “LinearRegresssion” را از “scikit-Learn” وارد می کنیم:

from sklearn.linear_model import LinearRegression 

می خواهیم  داده های خود را برای آموزش و آزمون تقسیم کنیم ، اما برای پیش بینی های خود باید از قیمت های معتبر استفاده کنیم.  پس دیتافریم  را بر اساس مقادیر مثبت قیمت  فیلتر می کنیم:

import numpy as np 
df_filter = df[df['price'] > 0].copy() 

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

y_pred = []
y_true = []
 

برای اعتبار سنجی مدل از K-fold cross  استفاده خواهیم کرد.

from sklearn.model_selection import KFold
kf = KFold(n_splits=10, random_state = 42)
for train_index, test_index in kf.split(df_filter):
    df_test = df_filter.iloc[test_index]
    df_train = df_filter.iloc[train_index] 

اکنون می توانیم ورودی و خروجی خود را تعریف کنیم:

for train_index, test_index in kf.split(df_filter):
    ...
    X_train = np.array(df_train['points']).reshape(-1, 1)     
    y_train = np.array(df_train['price']).reshape(-1, 1)
    X_test = np.array(df_test['points']).reshape(-1, 1)  
    y_test = np.array(df_test['price']).reshape(-1, 1) 

حال مدل رگرسیون خود را فیت (fit) می کنیم.

for train_index, test_index in kf.split(df_filter):
    ۰۰۰
    model = LinearRegression()
    model.fit(X_train, y_train) 

در کد زیر پیش بینی های خود را تولید و ذخیره می کنیم:

for train_index, test_index in kf.split(df_filter):
    ...
    y_pred.append(model.predict(X_test)[0])
    y_true.append(y_test[0]) 

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

print("Mean Square Error: ", mean_squared_error(y_true, y_pred)) 

خطای میانگین مربعات

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

df_filter = df[df['price'] <= df['price'].mean() + df['price'].std() ].copy()
...
print("Mean Square Error: ", mean_squared_error(y_true, y_pred)) 

خطای میانگین مربعات بهبود داده شده

در حالی که این ترفند به طور قابل توجهی عملکرد را بهبود می بخشد ، اما این روش به قیمت عدم توانایی تشخیص مقادیر دقیق نوشیدنی های بسیار گران قیمت تمام می شود. به جای مدل رگرسیون که از یک ویژگی (single feature) استفاده می کند،   می توانیم از مدل های مبتنی بر درخت(tree base models)  مانند جنگل های تصادفی (random forests)  برای پیش بینی قیمت استفاده کنیم که می تواند از متغیرهای کمی و کیفی استفاده کند. بیایید یک مدل رگرسیون جنگلی تصادفی ایجاد کنیم که از “کشور” ، “استان” ، “تنوع” ، “کارخانه” و “امتیاز” برای پیش بینی “قیمت” نوشیدنی استفاده کند. ابتدا ، متغیرهای کیفی  را به کد تبدیل می کنیم که توسط مدل جنگل های تصادفی قابل استفاده باشد:

df['country_cat'] = df['country'].astype('category')
df['country_cat'] = df['country_cat'].cat.codes
df['province_cat'] = df['province'].astype('category')
df['province_cat'] = df['province_cat'].cat.codes
df['winery_cat'] = df['winery'].astype('category')
df['winery_cat'] = df['winery_cat'].cat.codes
df['variety_cat'] = df['variety'].astype('category')
df['variety_cat'] = df['variety_cat'].cat.codes 

بیایید اندازه نمونه تصادفی را به 5000 افزایش دهیم:

df = pd.read_csv("winemag-data-130k-v2.csv").sample(n=5000, random_state = 42)
 

در گام بعد ،  ماژول رگرسیون جنگل تصادفی را از scikit-Learn  واردمی کنیم. سپس لیستی از ویژگی هایی که برای آموزش مدل خود استفاده خواهیم کرد نیز تعریف کنیم:

from sklearn.ensemble import RandomForestRegressor
features = ['points', 'country_cat', 'province_cat', 'winery_cat', 'variety_cat'] 

حال مدل خود را با استفاده از یک جنگل تصادفی با n_estimators = 1000 و max_depth = 1000 موزش می دهیم. سپس پیش بینی هایی را تولید  و آنها را در لیست جدیدی اضافه می کنیم:

for train_index, test_index in kf.split(df_filter):
    df_test = df_filter.iloc[test_index]
    df_train = df_filter.iloc[train_index]
    X_train = np.array(df_train[features])
    y_train = np.array(df_train['price'])
    X_test = np.array(df_test[features])
    y_test = np.array(df_test['price'])
    model = RandomForestRegressor(n_estimators = 1000, max_depth = 1000, random_state = 42)
    model.fit(X_train, y_train)
    y_pred_rf.append(model.predict(X_test)[0])
    y_true_rf.append(y_test[0]) 

در آخر ، بیایید خطای میانگین مربعات  را برای هر دو مدل جنگل تصادفی و  رگرسیون خطی ارزیابی کنیم:

print("Mean Square Error (Linear Regression): ", mean_squared_error(y_true, y_pred))
print("Mean Square Error (Random Forest): ", mean_squared_error(y_pred_rf, y_true_rf)) 

خطای میانگین مربعات دو مدل جنگل تصادفی و  رگرسیون

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

df_missing = df[df['price'].isnull()].copy()
X_test_lr = np.array(df_missing['points']).reshape(-1, 1)
X_test_rf = np.array(df_missing[features])
X_train_lr = np.array(df_filter['points']).reshape(-1, 1)    
y_train_lr = np.array(df_filter['price']).reshape(-1, 1)
X_train_rf = np.array(df_filter[features])
y_train_rf = np.array(df_filter['price'])
model_lr = LinearRegression()
model_lr.fit(X_train_lr, y_train_lr)
print("Linear regression predictions: ", model_lr.predict(X_test_lr)[0][0])
model_rf = RandomForestRegressor(n_estimators = 1000, max_depth = 1000, random_state = 42)
model_rf.fit(X_train_rf, y_train_rf)
print("Random forests regression predictions: ", model_rf.predict(X_test_rf)[0]) 

پیش بینی مقادیر گمشده توصیه می کنم که در انتخاب ویژگی ها و تنظیم پارامترها بیش از اندازه بازی کنید تا ببینید آیا می توانید عملکرد را بهبود ببخشید.  بعلاوه ، من شما را تشویق می کنم که از این الگو  برای مقادیر گمشده دیگر از جمله “region_1” و “designation’” استفاده کنید.

دیدگاه‌ خود را بنویسید

Your email address will not be published. Required fields are marked *