🤖 Scikit-learn
Scikit-learn یکی از محبوبترین کتابخانههای پایتون برای یادگیری ماشین (Machine Learning) است. این کتابخانه شامل الگوریتمهای متنوعی برای یادگیری نظارتشده (طبقهبندی و رگرسیون)، یادگیری بدون نظارت (خوشهبندی و کاهش ابعاد) و ابزارهای قدرتمند برای پیشپردازش داده، ارزیابی مدل و بهینهسازی هایپرپارامتر است [citation:5][citation:6].
پیشنیاز: آشنایی با NumPy، Pandas و مفاهیم پایه یادگیری ماشین.
🔹 نصب و import
# نصب (در محیط واقعی)
# pip install scikit-learn
import sklearn
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris, load_breast_cancer, fetch_california_housing
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
print(f"Scikit-learn version: {sklearn.__version__}")
print("Scikit-learn imported successfully!")
🔹 طبقهبندی (Classification) با Pipeline
این مثال نشان میدهد چگونه یک مدل طبقهبندی کامل با پیشپردازش و Pipeline بسازیم. استفاده از Pipeline از نشت داده (Data Leakage) جلوگیری میکند و کد را قابل تکرار میسازد [citation:2][citation:3][citation:7].
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, classification_report
# بارگذاری داده
X, y = load_breast_cancer(return_X_y=True, as_frame=True)
# تقسیم داده
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# ساخت Pipeline
pipeline = Pipeline([
('scaler', StandardScaler()), # استانداردسازی ویژگیها
('classifier', LogisticRegression(max_iter=1000, random_state=42))
])
# آموزش مدل
pipeline.fit(X_train, y_train)
# پیشبینی و ارزیابی
y_pred = pipeline.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print("\nClassification Report:")
print(classification_report(y_test, y_pred))
🔹 رگرسیون (Regression) با Pipeline
در این مثال از RandomForestRegressor برای پیشبینی قیمت مسکن در کالیفرنیا استفاده میکنیم. مدلهای مبتنی بر درخت معمولاً به مقیاسسازی نیاز ندارند، اما همچنان از Pipeline برای یکپارچگی استفاده میکنیم [citation:2].
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_absolute_error, r2_score
# بارگذاری داده
X, y = fetch_california_housing(return_X_y=True, as_frame=True)
# تقسیم داده
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# ساخت Pipeline
pipeline = Pipeline([
('scaler', StandardScaler(with_mean=False)), # مقیاسسازی
('regressor', RandomForestRegressor(n_estimators=200, random_state=42))
])
# آموزش مدل
pipeline.fit(X_train, y_train)
# پیشبینی و ارزیابی
y_pred = pipeline.predict(X_test)
print(f"MAE: {mean_absolute_error(y_test, y_pred):.4f}")
print(f"R² Score: {r2_score(y_test, y_pred):.4f}")
🔹 ColumnTransformer برای دادههای ترکیبی
وقتی داده شامل ویژگیهای عددی و دستهبندی باشد، از ColumnTransformer برای اعمال پیشپردازش متفاوت روی هر نوع داده استفاده میکنیم [citation:1][citation:3][citation:7].
import pandas as pd
import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# ایجاد داده نمونه
np.random.seed(42)
data = pd.DataFrame({
'age': np.random.randint(18, 60, 200),
'income': np.random.randint(20000, 100000, 200),
'education': np.random.choice(['High School', 'Bachelor', 'Master', 'PhD'], 200),
'city': np.random.choice(['Tehran', 'Shiraz', 'Isfahan', 'Mashhad'], 200),
'purchase': np.random.choice([0, 1], 200)
})
X = data.drop('purchase', axis=1)
y = data['purchase']
# تقسیم داده
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# تعریف ستونها
numeric_features = ['age', 'income']
categorical_features = ['education', 'city']
# پیشپردازشگر
preprocessor = ColumnTransformer([
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(handle_unknown='ignore', drop='first'), categorical_features)
])
# Pipeline کامل
pipeline = Pipeline([
('preprocessor', preprocessor),
('classifier', LogisticRegression(random_state=42))
])
# آموزش و ارزیابی
pipeline.fit(X_train, y_train)
print(f"Accuracy: {pipeline.score(X_test, y_test):.4f}")
🔹 اعتبارسنجی متقابل (Cross-Validation)
با cross_val_score میتوانید مدل را روی چندین زیرمجموعه از داده ارزیابی کنید تا از تعمیمپذیری آن مطمئن شوید [citation:1][citation:4].
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.tree import DecisionTreeClassifier
X, y = load_iris(return_X_y=True)
# مدل
model = DecisionTreeClassifier(random_state=42)
# اعتبارسنجی متقابل ۵-بخشی
cv_scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"Cross-validation scores: {cv_scores}")
print(f"Mean accuracy: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")
# با StratifiedKFold برای دادههای نامتوازن
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
cv_scores_strat = cross_val_score(model, X, y, cv=skf, scoring='accuracy')
print(f"Stratified CV mean: {cv_scores_strat.mean():.4f}")
🔹 تنظیم هایپرپارامتر با GridSearchCV
GridSearchCV به صورت جستجوی جامع ترکیبهای مختلف هایپرپارامترها را امتحان میکند و بهترین ترکیب را پیدا میکند [citation:1][citation:4].
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.ensemble import RandomForestClassifier
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# مدل
model = RandomForestClassifier(random_state=42)
# فضای جستجو
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, 15, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# GridSearchCV
grid_search = GridSearchCV(
model, param_grid, cv=5, scoring='accuracy', n_jobs=-1, verbose=0
)
grid_search.fit(X_train, y_train)
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best CV score: {grid_search.best_score_:.4f}")
print(f"Test score: {grid_search.score(X_test, y_test):.4f}")
🔹 تنظیم هایپرپارامتر با RandomizedSearchCV
برای فضاهای جستجوی بزرگ، RandomizedSearchCV ترکیبهای تصادفی را امتحان میکند و کارآمدتر است [citation:4].
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
# فضای جستجو با توزیعها
param_dist = {
'n_estimators': randint(50, 300),
'max_depth': [5, 10, 15, None],
'min_samples_split': randint(2, 20),
'min_samples_leaf': randint(1, 10),
'max_features': uniform(0.1, 0.9)
}
random_search = RandomizedSearchCV(
model, param_dist, n_iter=50, cv=5, scoring='accuracy', random_state=42, n_jobs=-1
)
random_search.fit(X_train, y_train)
print(f"Best parameters: {random_search.best_params_}")
print(f"Best CV score: {random_search.best_score_:.4f}")
🔹 ترکیب Pipeline و GridSearchCV
با ترکیب Pipeline و GridSearchCV، میتوانید هم هایپرپارامترهای مدل و هم هایپرپارامترهای پیشپردازش را بهینه کنید [citation:1].
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Pipeline
pipeline = Pipeline([
('scaler', StandardScaler()),
('svm', SVC(random_state=42))
])
# فضای جستجو
param_grid = {
'scaler__with_mean': [True, False],
'svm__C': [0.1, 1, 10, 100],
'svm__kernel': ['rbf', 'poly', 'sigmoid'],
'svm__gamma': ['scale', 'auto', 0.01, 0.1, 1]
}
# GridSearchCV روی کل Pipeline
grid_search = GridSearchCV(
pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1, verbose=0
)
grid_search.fit(X_train, y_train)
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best CV score: {grid_search.best_score_:.4f}")
print(f"Test score: {grid_search.score(X_test, y_test):.4f}")
🔹 خوشهبندی (Clustering) با K-Means
یادگیری بدون نظارت (Unsupervised Learning) برای یافتن الگوهای پنهان در داده بدون برچسب استفاده میشود [citation:8].
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
X, y = load_iris(return_X_y=True)
# مقیاسسازی
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# K-Means با ۳ خوشه (چون میدانیم ۳ گونه داریم)
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
kmeans.fit(X_scaled)
# برچسبهای خوشهها
labels = kmeans.labels_
print(f"Cluster labels: {labels[:10]}")
print(f"Cluster centers shape: {kmeans.cluster_centers_.shape}")
# مقایسه با برچسبهای واقعی
from sklearn.metrics import adjusted_rand_score
ari = adjusted_rand_score(y, labels)
print(f"Adjusted Rand Index: {ari:.4f}")
🔹 کاهش ابعاد با PCA
PCA (Principal Component Analysis) یکی از روشهای کاهش ابعاد است که داده را به فضایی با ابعاد کمتر نگاشت میکند و اطلاعات اصلی را حفظ میکند [citation:8].
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
X, y = load_iris(return_X_y=True)
# PCA با ۲ مولفه
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
print(f"Original shape: {X.shape}")
print(f"Reduced shape: {X_pca.shape}")
print(f"Explained variance ratio: {pca.explained_variance_ratio_}")
# نمایش داده در فضای کاهش یافته
plt.figure(figsize=(8, 6))
for species, marker, color in zip([0, 1, 2], ['o', 's', '^'], ['red', 'blue', 'green']):
plt.scatter(X_pca[y == species, 0], X_pca[y == species, 1],
marker=marker, color=color, label=f'Species {species}')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.legend()
plt.title('PCA - Iris Dataset')
plt.show()
🔹 مثال جامع: Pipeline کامل با پیشپردازش ترکیبی
import pandas as pd
import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report, confusion_matrix
# ایجاد داده نمونه با مقادیر گمشده
np.random.seed(42)
n = 500
data = pd.DataFrame({
'age': np.random.randint(18, 60, n),
'income': np.random.randint(20000, 100000, n),
'education': np.random.choice(['High School', 'Bachelor', 'Master', 'PhD'], n),
'city': np.random.choice(['Tehran', 'Shiraz', 'Isfahan', 'Mashhad'], n),
'score': np.random.uniform(50, 100, n)
})
# افزودن مقادیر گمشده
data.loc[np.random.choice(n, 20), 'income'] = np.nan
data.loc[np.random.choice(n, 15), 'education'] = np.nan
# هدف
data['target'] = (data['score'] > 75).astype(int)
data = data.drop('score', axis=1)
X = data.drop('target', axis=1)
y = data['target']
# تقسیم داده
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# تعریف ستونها
numeric_features = ['age', 'income']
categorical_features = ['education', 'city']
# پیشپردازش اعداد: impute + scale
numeric_transformer = Pipeline([
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
# پیشپردازش دستهبندی: impute + one-hot
categorical_transformer = Pipeline([
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore', drop='first'))
])
# ColumnTransformer
preprocessor = ColumnTransformer([
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
# Pipeline کامل
pipeline = Pipeline([
('preprocessor', preprocessor),
('classifier', GradientBoostingClassifier(random_state=42))
])
# GridSearchCV
param_grid = {
'classifier__n_estimators': [50, 100, 200],
'classifier__learning_rate': [0.01, 0.05, 0.1],
'classifier__max_depth': [3, 5, 7]
}
grid_search = GridSearchCV(
pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1
)
grid_search.fit(X_train, y_train)
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best CV score: {grid_search.best_score_:.4f}")
print(f"Test accuracy: {grid_search.score(X_test, y_test):.4f}")
# ارزیابی کامل
y_pred = grid_search.predict(X_test)
print("\nClassification Report:")
print(classification_report(y_test, y_pred))
print("\nConfusion Matrix:")
print(confusion_matrix(y_test, y_pred))
📌 نکات کلیدی
- ✅ Scikit-learn شامل الگوریتمهای یادگیری نظارتشده (طبقهبندی و رگرسیون) و بدون نظارت (خوشهبندی و کاهش ابعاد) است [citation:5][citation:6].
- ✅ Pipeline برای جلوگیری از نشت داده و افزایش تکرارپذیری ضروری است [citation:2][citation:3][citation:7].
- ✅ ColumnTransformer برای اعمال پیشپردازش متفاوت روی ویژگیهای عددی و دستهبندی استفاده میشود [citation:1][citation:3][citation:7].
- ✅ StandardScaler ویژگیها را به میانگین ۰ و واریانس ۱ تبدیل میکند که برای الگوریتمهایی مثل SVM و رگرسیون لجستیک ضروری است [citation:3][citation:7].
- ✅ OneHotEncoder متغیرهای دستهبندی را به ستونهای باینری تبدیل میکند [citation:3][citation:7].
- ✅ GridSearchCV و RandomizedSearchCV برای بهینهسازی هایپرپارامتر استفاده میشوند [citation:1][citation:4].
- ✅ با cross_val_score میتوانید مدل را با اعتبارسنجی متقابل ارزیابی کنید [citation:1][citation:4].
- ✅ برای دادههای با طبقات نامتوازن، از stratify در
train_test_splitو StratifiedKFold استفاده کنید [citation:1]. - ✅ Always use Pipelines for production workflows [citation:1].