scikit-learn (sklearn) チートシート
最終更新
データの読み込みと分割
何よりも先にテストセットを取り分け、最後の最後まで見ないようにしましょう。
| やりたいこと | コード |
|---|---|
| 分割用の関数をインポート | from sklearn.model_selection import train_test_split |
| DataFrame から特徴量と目的変数 | X = df.drop(columns="target")
y = df["target"] |
| 組み込みデータセットを 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 で分割 | 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) |
| 訓練、検証、テスト (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) |
特徴量の前処理
変換器は訓練データだけで fit し、その後で両方のセットを変換します。テストデータで fit すると情報がリークします。
| やりたいこと | コード |
|---|---|
| インポート | 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 エンコード | 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"]]) |
| 配列ではなく DataFrame で受け取る | 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 を呼びます。
| やりたいこと | コード |
|---|---|
| 全モデル共通のパターン | 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) |
| ランダムフォレスト | from sklearn.ensemble import RandomForestClassifier
RandomForestClassifier(n_estimators=200, random_state=0) |
| 勾配ブースティング (大規模データでも高速) | from sklearn.ensemble import HistGradientBoostingClassifier
HistGradientBoostingClassifier(random_state=0) |
| サポートベクターマシン | from sklearn.svm import SVC
SVC(kernel="rbf", C=1.0) |
| ナイーブベイズ | from sklearn.naive_bayes import GaussianNB
GaussianNB() |
| 常に多数派を予測するベースライン | from sklearn.dummy import DummyClassifier
DummyClassifier(strategy="most_frequent") |
予測と確認
| やりたいこと | コード |
|---|---|
| クラスや値を予測 | y_pred = model.predict(X_test) |
| 陽性クラスの確率 | model.predict_proba(X_test)[:, 1] |
| 手軽なスコア: 正解率または R² | model.score(X_test, y_test) |
| 線形モデルの係数 | model.coef_, model.intercept_ |
| 木モデルの特徴量重要度 | 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)) |
分類の評価指標
正解率だけでは少数クラスの誤りが見えません。適合率、再現率、混同行列もあわせて確認しましょう。
| やりたいこと | コード |
|---|---|
| インポート | from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score |
| 正解率 | accuracy_score(y_test, y_pred) |
| 適合率、再現率、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)) |
| 混同行列 | from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_pred) |
| 混同行列を描画 | 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) |
| 不均衡クラス向けの正解率 | 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 |
| 平均絶対誤差 | 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) |
| 平均絶対パーセント誤差 | 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") |
パイプライン
パイプラインは前処理とモデルを1つの推定器にまとめます。そのため交差検証やグリッドサーチでも、すべての手順が訓練用の分割だけで fit されます。
| やりたいこと | コード |
|---|---|
| インポート | from sklearn.pipeline import make_pipeline, Pipeline |
| スケーリングしてからモデルを学習 | 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"]),
]) |
| 前処理とモデルを1つのオブジェクトに | 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() |
交差検証
交差検証は複数の分割でモデルを学習・評価するので、1つのテストセットより安定した推定が得られます。
| やりたいこと | コード |
|---|---|
| インポート | from sklearn.model_selection import cross_val_score, cross_validate, KFold, StratifiedKFold |
| 5分割でスコアを出す | scores = cross_val_score(pipe, X, y, cv=5)
scores.mean(), scores.std() |
| 評価指標を選ぶ | cross_val_score(pipe, X, y, cv=5, scoring="f1_macro") |
| シャッフルした分割 | cv = KFold(n_splits=5, shuffle=True, random_state=0) |
| 各分割でクラスの比率をそろえる | cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0) |
| 複数の指標と訓練スコア | cross_validate(pipe, X, y, cv=cv, scoring=["accuracy", "f1"], return_train_score=True) |
| 全行に対する out-of-fold 予測 | from sklearn.model_selection import cross_val_predict
cross_val_predict(pipe, X, y, cv=5) |
| グループ単位の分割、時系列順の分割 | 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() |
グリッドサーチとチューニング
サーチは設定ごとに交差検証でモデルを学習させ、最良の設定を残して訓練データ全体で再学習します。
| やりたいこと | コード |
|---|---|
| インポート | 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) |
| パイプライン内の手順をチューニング | 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") |
クラスタリングと次元削減
教師なしモデルは 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 | 旧書式 |
|---|---|---|
| 二乗平均平方根誤差 | root_mean_squared_error(y_test, y_pred) | mean_squared_error(y_test, y_pred, squared=False) |
| 密な one-hot 出力 | 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) |
保存、読み込み、再現性
| やりたいこと | コード |
|---|---|
| 学習済みモデルやパイプラインを保存 | import joblib
joblib.dump(model, "model.joblib") |
| 読み込み直す | model = joblib.load("model.joblib") |
| 毎回同じ結果にする | random_state=0 |
| インストール済みのバージョン | import sklearn
sklearn.__version__ |
実際の機械学習ワークフローを支える scikit-learn のコードを、書く順番に並べました。データの読み込みと分割、前処理、モデルの選択、学習と予測、結果の評価、パイプラインでの手順の連結、交差検証、グリッドサーチによるチューニングまで揃っています。各行は貼り付けてすぐ使える短いコードと、その動作を説明する一文で構成されています。
scikit-learn のモデルはすべて同じ API を持っています。fit で訓練データから学習し、predict と transform で学習した内容を適用します。すべて Coddy で動いている scikit-learn 1.9 向けに書いており、特徴量は X、目的変数は y としています。scikit-learn は NumPy 配列と pandas の DataFrame を扱え、グラフについては Matplotlib チートシートで解説しています。Python 自体が初めての方は Python チートシート から始めましょう。
scikit-learn チートシートのよくある質問
この scikit-learn チートシートは無料ですか?
sklearn と scikit-learn は同じものですか?
pip install scikit-learn)。sklearn はコードでインポートするときの名前です (from sklearn.linear_model import LinearRegression)。sklearn チートシートと scikit-learn チートシートは同じ内容を扱っています。fit、transform、fit_transform の違いは何ですか?
fit はデータから学習します。スケーラーなら各列の平均を、モデルなら重みを学習します。transform は学習した内容を適用し、fit_transform はその両方を1回で行います。訓練セットには fit_transform を使い、テストセットには transform だけを使いましょう。そうしないとテストデータが学習にリークします。パイプラインならこれを自動で処理してくれます。特徴量のスケーリングは必要ですか?
scikit-learn ではどのモデルから始めるべきですか?
LinearRegression、クラスの予測なら LogisticRegression です。次に RandomForestClassifier や HistGradientBoostingClassifier (またはその回帰版) を試し、交差検証で比較して、最も良いものを GridSearchCV でチューニングします。このチートシートはどの scikit-learn バージョンに対応していますか?
mean_squared_error の squared=False、OneHotEncoder の sparse=False、LogisticRegression の penalty 引数のように、今ではエラーや警告になる古い呼び出しは、旧書式の表で今の書き方と並べています。