FA-TOOLS — Header Component

آموزش pipeline در scikit-learn

رفیق برنامه‌نویس، بیا با هم یه سفر بریم تو دل دنیای پایتون و یادگیری ماشین، اونم با Scikit-learn. امروز می‌خوایم درباره یه قابلیت فوق‌العاده صحبت کنیم: Pipelineها. اگه تا حالا حس کردی کار با داده‌ها و مدل‌ها یه کم شلوغ پلوغه و هی باید کدای تکراری بزنی، Pipeline اومده تا نجاتت بده! اینجا قراره بهت یاد بدم چطور باهاش کدهات رو تمیز، قابل مدیریت و کارآمد کنی. راستی، اگه دنبال ابزارهای خفن برنامه‌نویسی یا اسنیپت‌های آماده می‌گردی که کارت رو راه بندازه، حتماً یه سری به فروشگاه ابزارهای ما بزن؛ کلی چیز باحال اونجا منتظرته!

✨ نقشه راه Pipeline در Scikit-learn ✨

1️⃣

مقدمه و مفهوم Pipeline

چرا نیاز داریم؟ تمیزی و کارایی.

2️⃣

ساختار اصلی

مراحل متوالی: ترنسفورمرها و استیمیتور.

3️⃣

پیاده‌سازی ساده

کدهای پایتون برای شروع کار.

4️⃣

پیش‌پردازش و مدل

ترکیب عملیات مختلف در یک خط.

5️⃣

تکنیک‌های پیشرفته

Grid Search و ColumnTransformer.

6️⃣

مزایا و عیب‌یابی

چرا استفاده کنیم؟ مشکلات و راه‌حل‌ها.

Pipeline چیست و چرا به آن نیاز داریم؟

آموزش pipeline در scikit-learn — تصویر 1

تصور کن توی یه کارگاه نجاری هستی و می‌خوای یه میز بسازی. اول باید چوب رو برش بدی، بعد سمباده بزنی، بعدش شاید رنگش کنی و در آخر، قطعات رو به هم وصل کنی. اگه این مراحل رو هر بار دستی و جداگانه انجام بدی، هم وقتت گرفته میشه، هم ممکنه یه مرحله رو فراموش کنی، یا حتی ترتیب کار بهم بریزه. Pipeline در Scikit-learn دقیقاً همین کار رو براتون می‌کنه.

Pipeline یه ابزار کارآمده که به ما اجازه میده چند تا مرحله پردازش داده و مدل‌سازی رو پشت سر هم و به صورت زنجیره‌ای به هم وصل کنیم. این مراحل می‌تونن شامل کارهایی مثل پر کردن مقادیر گمشده (Imputation)، استانداردسازی داده‌ها (Scaling)، یا حتی کاهش ابعاد (Dimensionality Reduction) با PCA باشن، و در نهایت یه مدل یادگیری ماشن (مثل رگرسیون یا دسته‌بندی).

مشکلات رایج بدون Pipeline

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

اجزای اصلی یک Pipeline

آموزش pipeline در scikit-learn — تصویر 2

یه Pipeline از یه سری “مرحله” تشکیل شده. هر مرحله معمولاً یه ترنسفورمر (Transformer) یا در آخرین قدم، یه “استیمیتور (Estimator)” هستش.

💡 ترنسفورمر (Transformer)

اینا چیزایی هستن که داده‌ها رو تغییر میدن ولی خروجی رو پیش‌بینی نمی‌کنن. مثل StandardScaler (مقیاس‌بندی) یا SimpleImputer (پر کردن مقادیر گمشده). اینا متد fit و transform دارن.

🎯 استیمیتور (Estimator)

معمولاً آخرین مرحله Pipeline هست و مدل نهایی ماست که خروجی رو پیش‌بینی می‌کنه. مثل LogisticRegression یا RandomForestClassifier. اینا متد fit و predict دارن.

ساخت یک Pipeline ساده در Scikit-learn

آموزش pipeline در scikit-learn — تصویر 3

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


import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

# ساخت یه دیتاست نمونه
X, y = make_classification(n_samples=100, n_features=10, random_state=42)
# اضافه کردن مقادیر گمشده
X[0, 0] = np.nan
X[1, 5] = np.nan

# تقسیم داده‌ها
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# تعریف مراحل Pipeline
# 1. پر کردن مقادیر گمشده با میانگین
imputer_step = ('imputer', SimpleImputer(strategy='mean'))
# 2. مقیاس‌بندی داده‌ها
scaler_step = ('scaler', StandardScaler())
# 3. مدل رگرسیون لجستیک
model_step = ('model', LogisticRegression(random_state=42))

# ساخت Pipeline
pipeline = Pipeline(steps=[imputer_step, scaler_step, model_step])

# آموزش Pipeline
pipeline.fit(X_train, y_train)

# پیش‌بینی روی داده‌های تست
y_pred = pipeline.predict(X_test)

print("Pipeline با موفقیت اجرا شد!")
print(f"اولین 5 پیش‌بینی: {y_pred[:5]}")
    

دیدید چقدر راحت بود؟ فقط با یه خط fit و یه خط predict همه مراحل انجام شد. دیگه نه نگران ترتیب عملیات هستیم، نه نشت داده.

ترکیب پیش‌پردازش و مدل‌سازی: ColumnTransformer

خب، حالا فرض کن داده‌هات فقط عددی نیستن و ستون‌های دسته‌ای (Categorical) هم داری. یا می‌خوای روی هر گروه از ستون‌ها پیش‌پردازش متفاوتی انجام بدی. اینجا ColumnTransformer میاد وسط. این ابزار بهت اجازه میده روی ستون‌های خاص، ترنسفورمرهای خاصی رو اعمال کنی. خیلی قدرتمنده!

🔗 لینک داخلی مرتبط:

برای یادگیری بیشتر در مورد برنامه‌نویسی پایتون و اسنیپت‌های مفید، می‌تونی به بخش کدهای آماده و اسنیپت سایت ما سر بزنی!


import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression

# ساخت یه دیتافریم نمونه با داده‌های عددی و دسته‌ای
data = {
    'age': [25, 30, np.nan, 40, 22],
    'salary': [50000, 60000, 75000, np.nan, 45000],
    'city': ['NY', 'SF', 'NY', 'LA', 'SF'],
    'gender': ['Male', 'Female', 'Male', 'Female', 'Male']
}
df = pd.DataFrame(data)
target = [0, 1, 0, 1, 0] # هدف (مثلاً خرید کردن)

# تعریف ستون‌های عددی و دسته‌ای
numerical_features = ['age', 'salary']
categorical_features = ['city', 'gender']

# Pipeline برای ستون‌های عددی
numerical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='mean')),
    ('scaler', StandardScaler())
])

# Pipeline برای ستون‌های دسته‌ای
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')), # برای دسته‌ای‌ها معمولاً با mode پر میشه
    ('onehot', OneHotEncoder(handle_unknown='ignore'))
])

# ترکیب ترنسفورمرها با ColumnTransformer
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numerical_transformer, numerical_features),
        ('cat', categorical_transformer, categorical_features)
    ])

# Pipeline نهایی که شامل پیش‌پردازش و مدل نهایی هست
full_pipeline = Pipeline(steps=[('preprocessor', preprocessor),
                                 ('classifier', LogisticRegression(random_state=42))])

# آموزش Pipeline
full_pipeline.fit(df, target)

print("ColumnTransformer Pipeline با موفقیت اجرا شد!")
# حالا می‌تونی روی داده‌های جدید پیش‌بینی کنی
# مثال: full_pipeline.predict(new_data_df)
    

Pipelines پیشرفته: Grid Search و بهینه‌سازی پارامترها

یکی از قوی‌ترین ویژگی‌های Pipeline اینه که کاملاً با ابزارهای بهینه‌سازی هایپرپارامتر Scikit-learn مثل GridSearchCV یا RandomizedSearchCV سازگاره. این یعنی می‌تونی نه تنها پارامترهای مدل نهایی رو بهینه کنی، بلکه پارامترهای ترنسفورمرها (مثلاً استراتژی SimpleImputer) رو هم همزمان تنظیم کنی! این کار باعث افزایش بهره‌وریی و دقت مدل میشه.

⚙️ چطور با Grid Search استفاده کنیم؟

برای هر مرحله توی Pipeline، می‌تونی اسم مرحله رو (همون رشته‌ای که به عنوان اولین عنصر تاپل میدی) به همراه دو تا آندرسکور __ و بعد اسم پارامتر رو مشخص کنی. مثلاً: 'classifier__C' برای پارامتر C در مرحله classifier.


from sklearn.model_selection import GridSearchCV

# Pipeline که قبلاً ساختیم
# pipeline = Pipeline(steps=[imputer_step, scaler_step, model_step])

# تعریف فضای پارامترها برای Grid Search
param_grid = {
    'imputer__strategy': ['mean', 'median'], # پارامتر برای مرحله imputer
    'scaler__with_mean': [True, False], # پارامتر برای مرحله scaler
    'model__C': [0.1, 1.0, 10.0] # پارامتر برای مرحله model (LogisticRegression)
}

# ساخت GridSearchCV
grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1)

# اجرای Grid Search
grid_search.fit(X_train, y_train)

print(f"بهترین پارامترها: {grid_search.best_params_}")
print(f"بهترین امتیاز: {grid_search.best_score_:.2f}")

# حالا می‌تونی بهترین مدل رو استفاده کنی
best_pipeline = grid_search.best_estimator_
y_pred_tuned = best_pipeline.predict(X_test)
    

مزایای استفاده از Pipeline

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

  • کاهش پیچیدگی کد: دیگه نیاز نیست مراحل رو یکی یکی دستی اجرا کنی.
  • جلوگیری از نشت داده (Data Leakage): Pipeline تضمین می‌کنه که fit فقط روی داده‌های آموزشی اعمال میشه و transform یا predict روی داده‌های تست بدون دیدن اطلاعات آموزشی.
  • مدیریت آسان‌تر مراحل: تغییر یا اضافه کردن یه مرحله جدید خیلی راحته.
  • سازگاری با ابزارهای Scikit-learn: کاملاً با GridSearchCV، RandomizedSearchCV و cross_val_score کار می‌کنه.
  • قابلیت تکرار (Reproducibility): مدل و مراحل پیش‌پردازش رو میشه به راحتی ذخیره و بارگذاری کرد و نتایج رو تکرار کرد.

عیب‌یابی سریع (Troubleshooting)

هیچ کاری بی‌عیب و ایراد نیست، و Pipeline هم ممکنه گاهی اوقات چالش‌هایی داشته باشه. اینجا چند تا مشکل رایج و راه‌حلشون رو با هم مرور می‌کنیم:

مشکل رایج راه‌حل
TypeError در یکی از مراحل مطمئن شو که ورودی هر مرحله (خروجی مرحله قبلی) از نوع داده‌ای هست که اون ترنسفورمر انتظار داره. مثلاً OneHotEncoder معمولاً ستون‌های دسته‌ای رو می‌خواد که از قبل انتخاب شدن.
خطا در GridSearchCV هنگام بهینه‌سازی اسم پارامترها رو با دقت چک کن. باید حتماً به فرمت 'اسم_مرحله__اسم_پارامتر' باشن. مثلاً 'scaler__with_mean'.
نشت داده (Data Leakage) در پیش‌پردازش با استفاده از Pipeline، این مشکل به شدت کاهش پیدا می‌کنه. اما اگه دستی پیش‌پردازش می‌کنی، حواست باشه که fit فقط روی داده‌های آموزشی و transform روی هر دو مجموعه آموزشی و تست انجام بشه. Pipeline این رو برات تضمین می‌کنه.
نتیجه غیرمنتظره از مدل نهایی گاهی اوقات باید مراحل Pipeline رو جداگانه تست کنی تا ببینی هر مرحله چه تغییری در داده‌ها ایجاد می‌کنه. از متد named_steps['اسم_مرحله'].transform(X) استفاده کن تا خروجی هر مرحله رو ببینی.

نتیجه‌گیری

رفیق، دیگه وقتشه که از Pipelineهای Scikit-learn استفاده کنی و پروژه‌های یادگیری ماشينت رو حرفه‌ای‌تر پیش ببری. با این ابزار قدرتمند، نه تنها کدهات تمیزتر و قابل فهم‌تر میشن، بلکه از خیلی از خطاهای رایج مثل نشت داده هم جلوگیری می‌کنی. پس بدون معطلی برو و امتحانش کن!

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

Table of Contents

آخرین نوشته‌ها