Scikit-learn (sklearn) Cheat Sheet: דף עזר
עודכן לאחרונה
טעינה ופיצול של הנתונים
הפרידו test set לפני כל דבר אחר, ותסתכלו עליו רק בסוף ממש.
| משימה | קוד |
|---|---|
| ייבוא הפונקציה לפיצול | from sklearn.model_selection import train_test_split |
| פיצ'רים ומטרה מתוך DataFrame | X = df.drop(columns="target")
y = df["target"] |
| Dataset מובנה כ-pandas | from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True, as_frame=True) |
| נתונים סינתטיים לניסויים | from sklearn.datasets import make_classification
X, y = make_classification(n_samples=500, n_features=8, random_state=0) |
| פיצול 80/20 ל-train ו-test | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
| שמירה על יחסי המחלקות בשני החלקים | train_test_split(X, y, test_size=0.2, stratify=y, random_state=42) |
| Train, validation ו-test (60/20/20) | X_tmp, X_test, y_tmp, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
X_train, X_val, y_train, y_val = train_test_split(X_tmp, y_tmp, test_size=0.25, random_state=0) |
Preprocessing לפיצ'רים
בצעו fit ל-transformer על נתוני האימון בלבד, ואז transform לשני הסטים. fit על נתוני ה-test מדליף מידע.
| משימה | קוד |
|---|---|
| ייבוא | from sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder, OrdinalEncoder |
| נרמול לממוצע 0 וסטיית תקן 1 | scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train[["age", "income"]])
X_test_s = scaler.transform(X_test[["age", "income"]]) |
| נרמול לטווח 0 עד 1 | MinMaxScaler().fit_transform(X_train[["age", "income"]]) |
| One-hot encoding לקטגוריות | enc = OneHotEncoder(handle_unknown="ignore", sparse_output=False)
enc.fit_transform(X_train[["city"]]) |
| קידוד קטגוריות מסודרות כמספרים | OrdinalEncoder(categories=[["low", "mid", "high"]]).fit_transform([["mid"], ["high"]]) |
| מילוי ערכים חסרים | from sklearn.impute import SimpleImputer
SimpleImputer(strategy="median").fit_transform(X_train[["age", "income"]]) |
| פיצ'רים פולינומיים ואינטראקציות | from sklearn.preprocessing import PolynomialFeatures
PolynomialFeatures(degree=2, include_bias=False).fit_transform(X_train[["age", "income"]]) |
| לקבל DataFrames במקום מערכים | scaler.set_output(transform="pandas") |
| תוויות טקסט למספרים שלמים | from sklearn.preprocessing import LabelEncoder
LabelEncoder().fit_transform(["cat", "dog", "cat"]) |
בחירת מודל
התחילו פשוט, והשאירו את המודל הפשוט בתור הציון שצריך לנצח.
| בעיה | להתחיל עם | אחר כך לנסות |
|---|---|---|
| חיזוי מספר (רגרסיה) | LinearRegression(), Ridge(alpha=1.0) | RandomForestRegressor(), HistGradientBoostingRegressor() |
| חיזוי מחלקה (סיווג) | LogisticRegression(max_iter=1000) | RandomForestClassifier(), HistGradientBoostingClassifier() |
| מעט נתונים, נקודות דומות חולקות תווית | KNeighborsClassifier(n_neighbors=5) | SVC(kernel="rbf") |
| חוקים שאפשר לקרוא | DecisionTreeClassifier(max_depth=3) | RandomForestClassifier() |
| קיבוץ שורות בלי תוויות | KMeans(n_clusters=3) | DBSCAN(eps=0.5) |
| פחות פיצ'רים לגרפים או למהירות | PCA(n_components=2) | TSNE(n_components=2) |
| מציאת שורות חריגות | IsolationForest(random_state=0) | LocalOutlierFactor() |
אימון מודל (fit)
כל estimator עובד לפי אותה תבנית: יוצרים אותו עם ההגדרות שלו, ואז קוראים ל-fit.
| משימה | קוד |
|---|---|
| התבנית לכל מודל | model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train) |
| רגרסיה לינארית | from sklearn.linear_model import LinearRegression
LinearRegression() |
| רגרסיה לינארית עם רגולריזציה | from sklearn.linear_model import Ridge, Lasso
Ridge(alpha=1.0), Lasso(alpha=0.1) |
| רגרסיה לוגיסטית (סיווג) | from sklearn.linear_model import LogisticRegression
LogisticRegression(C=1.0, max_iter=1000) |
| k השכנים הקרובים | from sklearn.neighbors import KNeighborsClassifier
KNeighborsClassifier(n_neighbors=5) |
| עץ החלטה | from sklearn.tree import DecisionTreeClassifier
DecisionTreeClassifier(max_depth=3, random_state=0) |
| Random forest | from sklearn.ensemble import RandomForestClassifier
RandomForestClassifier(n_estimators=200, random_state=0) |
| Gradient boosting, מהיר על נתונים גדולים | from sklearn.ensemble import HistGradientBoostingClassifier
HistGradientBoostingClassifier(random_state=0) |
| Support vector machine | from sklearn.svm import SVC
SVC(kernel="rbf", C=1.0) |
| Naive Bayes | from sklearn.naive_bayes import GaussianNB
GaussianNB() |
| Baseline שתמיד מנחש את הרוב | from sklearn.dummy import DummyClassifier
DummyClassifier(strategy="most_frequent") |
חיזוי ובדיקה
| משימה | קוד |
|---|---|
| חיזוי מחלקות או ערכים | y_pred = model.predict(X_test) |
| ההסתברות של המחלקה החיובית | model.predict_proba(X_test)[:, 1] |
| ציון מהיר: accuracy או R² | model.score(X_test, y_test) |
| המקדמים של מודל לינארי | model.coef_, model.intercept_ |
| Feature importance של מודל עצים | pd.Series(forest.feature_importances_, index=X_train.columns).sort_values() |
| חשיבות לפי ערבוב של כל פיצ'ר | from sklearn.inspection import permutation_importance
permutation_importance(model, X_test, y_test, random_state=0).importances_mean |
| תוויות המחלקות שהמודל מכיר | model.classes_ |
| קריאה ושינוי של הגדרות | model.get_params(), model.set_params(C=0.5) |
| שרטוט עץ החלטה | from sklearn.tree import plot_tree
plot_tree(tree, filled=True, feature_names=list(X_train.columns)) |
מטריקות לסיווג
Accuracy לבדה מסתירה את השגיאות במחלקה נדירה. בדקו גם precision, recall ואת ה-confusion matrix.
| משימה | קוד |
|---|---|
| ייבוא | from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score |
| Accuracy | accuracy_score(y_test, y_pred) |
| Precision, recall ו-F1 | precision_score(y_test, y_pred), recall_score(y_test, y_pred), f1_score(y_test, y_pred) |
| F1 לכמה מחלקות | f1_score(y_test, y_pred, average="macro") |
| כל המטריקות לכל מחלקה | from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred)) |
| Confusion matrix | from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_pred) |
| שרטוט ה-confusion matrix | from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_estimator(model, X_test, y_test) |
| ROC AUC מתוך הסתברויות | from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, model.predict_proba(X_test)[:, 1]) |
| שרטוט עקומת ה-ROC | from sklearn.metrics import RocCurveDisplay
RocCurveDisplay.from_estimator(model, X_test, y_test) |
| Accuracy למחלקות לא מאוזנות | from sklearn.metrics import balanced_accuracy_score
balanced_accuracy_score(y_test, y_pred) |
| סף החלטה משלכם | y_pred = (model.predict_proba(X_test)[:, 1] >= 0.3).astype(int) |
מטריקות לרגרסיה
מטריקות שגיאה הן ביחידות של משתנה המטרה (נמוך יותר עדיף). R² הוא חלק השונות שמוסבר (1 זה מושלם).
| משימה | קוד |
|---|---|
| ייבוא | from sklearn.metrics import mean_absolute_error, mean_squared_error, root_mean_squared_error, r2_score |
| שגיאה מוחלטת ממוצעת (MAE) | mean_absolute_error(y_test, y_pred) |
| שגיאה ריבועית ממוצעת והשורש שלה | mean_squared_error(y_test, y_pred), root_mean_squared_error(y_test, y_pred) |
| ציון R² | r2_score(y_test, y_pred) |
| שגיאת אחוז מוחלטת ממוצעת (MAPE) | from sklearn.metrics import mean_absolute_percentage_error
mean_absolute_percentage_error(y_test, y_pred) |
| גרף של חיזוי מול ערך אמיתי | from sklearn.metrics import PredictionErrorDisplay
PredictionErrorDisplay.from_predictions(y_test, y_pred, kind="actual_vs_predicted") |
Pipelines
Pipeline משרשר preprocessing ומודל ל-estimator אחד, כך ש-cross-validation ו-grid search מבצעים fit לכל שלב על ה-folds של האימון בלבד.
| משימה | קוד |
|---|---|
| ייבוא | from sklearn.pipeline import make_pipeline, Pipeline |
| נרמול, ואז fit למודל | pipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
pipe.fit(X_train, y_train) |
| שלבים עם שמות משלכם | pipe = Pipeline([("scale", StandardScaler()), ("model", LogisticRegression(max_iter=1000))]) |
| גישה לשלב בפנים | pipe.named_steps["model"], pipe[-1] |
| שלבים שונים לעמודות שונות | from sklearn.compose import ColumnTransformer
pre = ColumnTransformer([
("num", StandardScaler(), ["age", "income"]),
("cat", OneHotEncoder(handle_unknown="ignore"), ["city"]),
]) |
| Preprocessing ומודל באובייקט אחד | model = make_pipeline(pre, RandomForestClassifier(random_state=0))
model.fit(X_train, y_train)
model.score(X_test, y_test) |
| בחירת עמודות לפי סוג | from sklearn.compose import make_column_selector
make_column_selector(dtype_include="number")(X_train) |
| השלמת ערכים, ואז נרמול | make_pipeline(SimpleImputer(strategy="median"), StandardScaler()) |
| שמות פיצ'רי הפלט | pre.get_feature_names_out() |
Cross-validation
Cross-validation מאמן ומעריך את המודל על כמה פיצולים, מה שנותן הערכה יציבה יותר מ-test set אחד.
| משימה | קוד |
|---|---|
| ייבוא | from sklearn.model_selection import cross_val_score, cross_validate, KFold, StratifiedKFold |
| ציון על 5 folds | scores = cross_val_score(pipe, X, y, cv=5)
scores.mean(), scores.std() |
| בחירת המטריקה | cross_val_score(pipe, X, y, cv=5, scoring="f1_macro") |
| Folds מעורבבים | cv = KFold(n_splits=5, shuffle=True, random_state=0) |
| אותו איזון מחלקות בכל fold | cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0) |
| כמה מטריקות וציוני אימון | cross_validate(pipe, X, y, cv=cv, scoring=["accuracy", "f1"], return_train_score=True) |
| חיזוי לכל שורה, מחוץ ל-fold שלה | from sklearn.model_selection import cross_val_predict
cross_val_predict(pipe, X, y, cv=5) |
| Folds לפי קבוצה, folds לפי סדר זמן | from sklearn.model_selection import GroupKFold, TimeSeriesSplit
GroupKFold(n_splits=5), TimeSeriesSplit(n_splits=5) |
| כל שמות ה-scoring החוקיים | from sklearn.metrics import get_scorer_names
get_scorer_names() |
Grid search וכיוונון
חיפוש מאמן את המודל לכל הגדרה עם cross-validation, שומר את הטובה ביותר ומאמן אותה מחדש על כל נתוני האימון.
| משימה | קוד |
|---|---|
| ייבוא | from sklearn.model_selection import GridSearchCV, RandomizedSearchCV |
| ניסיון של כל הצירופים | grid = GridSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": [50, 100], "max_depth": [None, 5]}, cv=5)
grid.fit(X_train, y_train) |
| ההגדרות הטובות ביותר והציון שלהן | grid.best_params_, grid.best_score_ |
| שימוש במודל הטוב ביותר | grid.best_estimator_.predict(X_test), grid.score(X_test, y_test) |
| כיוונון שלב בתוך pipeline | GridSearchCV(pipe, {"logisticregression__C": [0.1, 1, 10]}, cv=5).fit(X_train, y_train) |
| הגדרות אקראיות מתוך התפלגויות | from scipy.stats import randint
search = RandomizedSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": randint(50, 150)}, n_iter=5, cv=3, random_state=0)
search.fit(X_train, y_train) |
| שימוש בכל ליבות ה-CPU | GridSearchCV(pipe, {"logisticregression__C": [0.1, 1]}, cv=5, n_jobs=-1) |
| כל התוצאות כטבלה | pd.DataFrame(grid.cv_results_).sort_values("rank_test_score") |
Clustering והורדת ממדים
מודלים לא מפוקחים לומדים מ-X בלבד. נרמלו קודם את הפיצ'רים, כי שניהם משתמשים במרחקים.
| משימה | קוד |
|---|---|
| אשכולות k-means | from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=0)
labels = km.fit_predict(X) |
| מרכזי האשכולות ו-inertia | km.cluster_centers_, km.inertia_ |
| עד כמה האשכולות מופרדים | from sklearn.metrics import silhouette_score
silhouette_score(X, labels) |
| אשכולות לפי צפיפות, רעש הוא -1 | from sklearn.cluster import DBSCAN
DBSCAN(eps=0.5, min_samples=5).fit_predict(X) |
| הטלה על 2 רכיבים | from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_2d = pca.fit_transform(X) |
| השונות שכל רכיב מסביר | pca.explained_variance_ratio_ |
| שמירה על 95% מהשונות | PCA(n_components=0.95).fit_transform(X) |
scikit-learn 1.9: צורות ישנות ומה לכתוב היום
קוד שהועתק ממדריכים ישנים עלול להיכשל או להציג אזהרות ב-scikit-learn 1.9. כתבו במקום זאת את הצורות שבעמודת scikit-learn 1.9.
| משימה | scikit-learn 1.9 | צורה ישנה |
|---|---|---|
| שורש השגיאה הריבועית הממוצעת (RMSE) | root_mean_squared_error(y_test, y_pred) | mean_squared_error(y_test, y_pred, squared=False) |
| פלט one-hot צפוף (dense) | OneHotEncoder(sparse_output=False) | OneHotEncoder(sparse=False) |
| רגרסיה לוגיסטית עם L1 (lasso) | LogisticRegression(l1_ratio=1, solver="liblinear") | LogisticRegression(penalty="l1", solver="liblinear") |
| רגרסיה לוגיסטית בלי רגולריזציה | LogisticRegression(C=np.inf) | LogisticRegression(penalty=None) |
שמירה, טעינה ושחזור
| משימה | קוד |
|---|---|
| שמירת מודל או pipeline מאומן | import joblib
joblib.dump(model, "model.joblib") |
| טעינה חזרה | model = joblib.load("model.joblib") |
| אותה תוצאה בכל הרצה | random_state=0 |
| איזו גרסה מותקנת | import sklearn
sklearn.__version__ |
קוד ה-scikit-learn שמאחורי workflow אמיתי של machine learning, בסדר שבו כותבים אותו: טעינה ופיצול של הנתונים, preprocessing, בחירת מודל, fit ו-predict, מדידת התוצאה, חיבור השלבים ל-pipeline, cross-validation וכיוונון עם grid search. כל שורה היא קטע קוד קצר שאפשר להדביק, ועוד שורה אחת שמסבירה מה הוא עושה.
לכל המודלים ב-scikit-learn יש אותו API: fit לומד מנתוני האימון, ו-predict ו-transform מפעילים את מה שנלמד. הכול כאן כתוב ל-scikit-learn 1.9, הגרסה ש-Coddy מריץ, עם X עבור הפיצ'רים ו-y עבור משתנה המטרה. scikit-learn עובד עם מערכי NumPy ועם DataFrames של pandas, ודף העזר של Matplotlib מכסה את הגרפים. חדשים ב-Python עצמו? התחילו עם Python cheat sheet.
שאלות נפוצות על ה-Scikit-learn Cheat Sheet
האם ה-scikit-learn cheat sheet הזה חינמי?
האם sklearn זה אותו דבר כמו scikit-learn?
pip install scikit-learn), ו-sklearn הוא השם שמייבאים בקוד (from sklearn.linear_model import LinearRegression). sklearn cheat sheet ו-scikit-learn cheat sheet מכסים בדיוק את אותו הדבר.מה ההבדל בין fit, transform ו-fit_transform?
fit לומד מהנתונים: scaler לומד את הממוצע של כל עמודה, ומודל לומד את המשקלים שלו. transform מפעיל את מה שנלמד, ו-fit_transform עושה את שניהם בקריאה אחת. השתמשו ב-fit_transform על סט האימון ורק ב-transform על סט ה-test, אחרת נתוני ה-test דולפים לאימון. Pipeline עושה את זה בשבילכם.צריך לנרמל את הפיצ'רים?
עם איזה מודל של scikit-learn כדאי להתחיל?
LinearRegression לחיזוי מספרים, LogisticRegression לחיזוי מחלקות. אחר כך נסו RandomForestClassifier או HistGradientBoostingClassifier (או גרסאות ה-regressor שלהם), השוו ביניהם עם cross-validation, וכווננו את הטוב ביותר עם GridSearchCV.באיזו גרסה של scikit-learn דף העזר הזה עוסק?
squared=False ב-mean_squared_error, sparse=False ב-OneHotEncoder והארגומנט penalty של LogisticRegression, נמצאות בטבלת הצורות הישנות לצד מה שצריך לכתוב במקומן.