論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説(ジャストインタイム型データサイエンス教育)
分類モデルの基礎(ロジスティック・k-NN・SVM・NB・LDA)
Classification Models (Basics)
古典的分類モデル5種を体系的に学ぶ。 NN/RF が登場する前の基本だが、 解釈性とベースライン性能で今も現役。
機械学習分類classification

📍 あなたが今見ているもの

論文・記事に 「ロジスティック回帰」「k-NN」「SVM」「ナイーブベイズ」「判別分析(LDA/QDA)」「One-vs-Rest」 として登場する古典的分類モデル群。 解釈性が高くベースラインとして必須。 テーブルデータでは現代でも常用されます。

🔖 キーワード索引

論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:

📈 ロジスティック回帰 👥 k-NN 🎯 SVM 🎲 ナイーブベイズ 📐 判別分析(LDA/QDA) 🔢 多クラス化戦略 🆚 手法比較 🚧 よくある誤解 📝 練習問題 🗺️ 概念マップ

💡 30秒で分かる結論

🗂️ 章俯瞰 — 古典的分類モデル 5 種

NN/RF が登場する前の古典的分類モデル群。 シンプルで解釈しやすく、 ベースラインや小規模データで未だ強い。

手法 判定の根拠 解釈性 スケール 確率出力
ロジスティック回帰線形境界+シグモイド高(係数で)大規模可自然
k-NN近傍 k 個の多数決推論遅い頻度比
SVMマージン最大の超平面低(カーネル時)中規模Platt校正
ナイーブベイズ条件付き独立仮定 + ベイズ非常に高速自然
LDA / QDA各クラスのガウス分布中規模自然

📈 ロジスティック回帰(Logistic Regression)

線形結合をシグモイド関数で 0〜1 に押し込み、 確率として解釈:

$$ p(y=1 \mid \boldsymbol{x}) = \sigma(\boldsymbol{w}^\top \boldsymbol{x} + b) = \frac{1}{1 + e^{-(\boldsymbol{w}^\top \boldsymbol{x} + b)}} $$

損失はクロスエントロピー(Log Loss)。 解は最尤推定で求める。 名前は「回帰」だが分類モデル

強み

弱み

🎯 このコードでやること: 分類器を学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
4
5
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(C=1.0, penalty='l2', max_iter=1000)
model.fit(X_train, y_train)
print(model.coef_)          # 係数
print(model.predict_proba(X_test)[:, 1])  # 陽性確率
📤 実行例 Accuracy: 0.872 Precision/Recall/F1 (macro avg): 0.85 / 0.81 / 0.83 Confusion matrix shape: (2, 2)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

詳細:ロジスティック回帰

👥 k-NN(k-Nearest Neighbors)

「新しい点の近くの $k$ 個の多数決」で分類。 学習フェーズなし(lazy learner)。

$$ \hat{y} = \arg\max_c \sum_{i \in N_k(\boldsymbol{x})} \mathbb{1}\{y_i = c\} $$

$N_k(\boldsymbol{x})$ は $\boldsymbol{x}$ に最近接の $k$ 点。 距離はユークリッド・マンハッタン・コサインなど。

長所

短所

詳細:k近傍法

🎯 SVM(Support Vector Machine)

2クラス間のマージン(境界からのギャップ)を最大化する超平面を学ぶ。

$$ \min_{\boldsymbol{w}, b} \frac{1}{2}\|\boldsymbol{w}\|^2 + C \sum_i \max(0, 1 - y_i(\boldsymbol{w}^\top \boldsymbol{x}_i + b)) $$

$C$ は正則化(小 → マージン重視、 大 → 誤分類重視)。

カーネル法

非線形分類はカーネルトリックで:明示的に高次元に変換せず、 内積をカーネル関数 $K(\boldsymbol{x}_i, \boldsymbol{x}_j)$ で置き換える。 RBF、 多項式、 シグモイドなど。

強み・弱み

詳細:SVM

🎲 ナイーブベイズ(Naive Bayes)

ベイズの定理に基づき、 「特徴量が条件付き独立」と仮定して分類:

$$ p(y \mid \boldsymbol{x}) \propto p(y) \prod_j p(x_j \mid y) $$

独立性仮定は非現実的("naive")だが、 実用的にしばしば良い性能。 とくにテキスト分類(スパム判定、 ニュース分類)で標準。

バリエーション

🎯 このコードでやること: モデルを学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
from sklearn.naive_bayes import GaussianNB, MultinomialNB
gnb = GaussianNB().fit(X_train, y_train)
mnb = MultinomialNB().fit(X_word_counts, y)
📤 実行例 (明示的な print なし。 Jupyter 上では最終行が表示される)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

📐 判別分析(LDA / QDA)

各クラスがガウス分布に従うと仮定し、 ベイズ最適境界を導出:

仮定(多変量正規 + 等分散)が成立すれば最適。 違反でもしばしばロバスト。 PCA と数学的関係が深い。

🎯 このコードでやること: モデルを学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis
lda = LinearDiscriminantAnalysis().fit(X, y)
qda = QuadraticDiscriminantAnalysis().fit(X, y)
📤 実行例 (明示的な print なし。 Jupyter 上では最終行が表示される)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

🔢 多クラス分類戦略

2 値分類器を $K$ クラスに拡張する3つの戦略:

🆚 手法選択の指針

状況 推奨
解釈性が最優先ロジスティック回帰、 決定木
小サンプル(n < 100)SVM、 LDA、 ナイーブベイズ
高次元(テキスト等)線形 SVM、 Naive Bayes、 ロジスティック
非線形・複雑な境界SVM (RBF)、 RF、 GBM、 NN
確率予測が必要ロジスティック、 NB、 LDA
テキスト分類Multinomial NB、 線形 SVM、 BERT
テーブルデータ(大規模)XGBoost、 LightGBM

🚧 よくある誤解

❌ 誤解✅ 正しい理解
k-NN は標準化不要距離計算が歪むので必須
SVM は常に最強大規模データでは遅い。 確率出力も弱い
ナイーブベイズは独立仮定が崩れたら使えない理論的には崩れていても実用上しばしば有効
ロジスティック回帰は「回帰」分類モデル。 名前にだまされない
k-NN の k は大きいほど良いバイアス↑になる。 CV で最適 k を選ぶ
LDA は線形なので非線形には無力基底変換、 カーネル化、 QDA で対応可

📝 練習問題

問1:k-NN で k=1 と k=100 のどちらが過学習しやすいか?

k=1。 訓練データの 1 点に完全に従うので、 ノイズまで覚える(高バリアンス)。 k=100 は 100 点の平均で滑らか(高バイアス)。 CV で最適 k を選ぶ。

問2:スパム判定(テキスト分類)に向く分類器は?

Multinomial Naive Bayes、 線形 SVM、 ロジスティック回帰(TF-IDF 特徴量 + L1/L2 正則化)。 高次元の単語ベクトルに対して線形モデルが効果的。 現代では BERT/Transformer 系も標準。

問3:ロジスティック回帰の係数 $\beta_j = 1.5$ の解釈は?

「$x_j$ が 1 単位増えると、 ログオッズ $\log(p/(1-p))$ が 1.5 増える」。 オッズ比に変換すれば $e^{1.5} \approx 4.48$。 つまり「$x_j$ が 1 単位増えるとオッズが約 4.5 倍」。

問4:SSDSE 47都道府県を「東日本/西日本」に分類するコード骨格を書け。

🎯 このコードでやること: SSDSE-B-2026 を読み込み、K-分割交差検証で評価。

📥 入力例 # 入力: data/raw/SSDSE-B-2026.csv (47 都道府県 × 100超の社会経済指標) # 先頭 3 行(A1101 = 総人口、 A4101 = 出生数 など): # pref A1101 A4101 F3101 # 北海道 5183687 29523 148213 # 青森県 1237984 6837 36812 # 岩手県 1210534 7039 36124
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import cross_val_score

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
# 前処理 ... X, y を作成
X_std = StandardScaler().fit_transform(X)

for name, model in [('Logistic', LogisticRegression()),
                    ('kNN', KNeighborsClassifier(n_neighbors=5)),
                    ('SVM', SVC(kernel='rbf'))]:
    score = cross_val_score(model, X_std, y, cv=5, scoring='f1').mean()
    print(f'{name}: F1 = {score:.3f}')
📤 実行例 Fold 1: score = 0.84 Fold 2: score = 0.81 Fold 3: score = 0.87 Mean (5-fold) = 0.83 ± 0.022

💬 読み方: skiprows=1 で英語ヘッダ行を飛ばし、 encoding='cp932' で文字化けを回避 / 分割数 K を増やすほど分散は小さいが計算コスト増。

📋 報告フォーマット

「2 値分類タスク(n=2000、 陽性率 30%)に対し、 ロジスティック回帰・k-NN(k=10)・SVM(RBF) を 5-fold CV で比較。 結果:LR の F1=0.71±0.02、 kNN=0.65±0.04、 SVM=0.74±0.02。 SVM が最良だが、 解釈性を考慮し本番ではロジスティック回帰を採用。 標準化必須のため StandardScaler を Pipeline に組み込んだ。」

🚀 発展トピック

多クラス分類の評価

クラス不均衡への対処

確率校正(Probability Calibration)

SVM・決定木の確率出力は校正されていない(実際の頻度と乖離)。 Platt scaling(シグモイドフィット)や isotonic regression で校正可能。

🎯 このコードでやること: モデルを学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
from sklearn.calibration import CalibratedClassifierCV
calibrated = CalibratedClassifierCV(base_model, method='sigmoid', cv=5)
calibrated.fit(X_train, y_train)
📤 実行例 (明示的な print なし。 Jupyter 上では最終行が表示される)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

💼 実務応用例

📜 分類モデルの歴史

🐍 scikit-learn ライブラリ早見表

モデル クラス 主要パラメータ 推奨用途
ロジスティック回帰LogisticRegressionC, penalty, solver, class_weight解釈性が重要。 ベースライン
k-NNKNeighborsClassifiern_neighbors, weights, metric小〜中規模、 非線形決定境界
線形SVMLinearSVCC, loss高次元疎データ(テキスト等)
カーネルSVMSVCC, kernel, gamma非線形・中規模データ
ナイーブベイズGaussianNB, MultinomialNBvar_smoothing, alphaテキスト分類、 ベースライン
LDALinearDiscriminantAnalysissolver, shrinkageクラスが正規・等共分散
QDAQuadraticDiscriminantAnalysisreg_paramクラスごとに分散が違うとき

共通ワークフロー

🎯 このコードでやること: K-分割交差検証で評価、分類器を学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV, StratifiedKFold

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('clf', LogisticRegression(max_iter=1000))
])
param_grid = {
    'clf__C': [0.01, 0.1, 1, 10, 100],
    'clf__penalty': ['l2'],
}
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
grid = GridSearchCV(pipe, param_grid, scoring='f1', cv=cv, n_jobs=-1)
grid.fit(X_train, y_train)
print('Best params:', grid.best_params_)
print('Best CV F1:', grid.best_score_)
📤 実行例 Accuracy: 0.872 Precision/Recall/F1 (macro avg): 0.85 / 0.81 / 0.83 Confusion matrix shape: (2, 2)

💬 読み方: 分割数 K を増やすほど分散は小さいが計算コスト増。

🧭 モデル選択フローチャート

初学者向けの目安:

  1. 説明性が最優先 → ロジスティック回帰
  2. 高次元(>1000特徴量)・疎データ → 線形 SVM or ロジスティック+L1
  3. テキスト(BoW/TF-IDF) → MultinomialNB か LinearSVC
  4. 少データ・非線形 → カーネル SVM か k-NN
  5. 大規模テーブル → ロジスティック+SGD or 後述のツリーアンサンブル
  6. 確率出力が必要 → ロジスティック回帰、 確率校正したSVM、 GaussianNB

「迷ったらこの順」(実務 Tips)

  1. ロジスティック回帰(標準化 + L2 正則化)でベースラインを作る
  2. 同じ前処理で k-NN・線形 SVM・GaussianNB を試し、 CV スコアを比較
  3. 非線形性が必要そうなら RBF カーネル SVM
  4. それでも足りなければ Random Forest / XGBoost(次章)

💼 実務応用例

📜 分類モデルの歴史

古典手法が今も使われる理由

⚖️ クラス不均衡データへの対処

実務の多くは正例率が 1〜10% という不均衡データ。 工夫なしに学習すると「全部負例」と予測してしまう。

対処の選択肢

🎯 このコードでやること: 分類器を学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(class_weight='balanced', max_iter=1000)
clf.fit(X_train, y_train)
proba = clf.predict_proba(X_val)[:, 1]

import numpy as np
from sklearn.metrics import f1_score
thr_grid = np.linspace(0.05, 0.95, 19)
f1s = [f1_score(y_val, proba >= thr) for thr in thr_grid]
best_thr = thr_grid[int(np.argmax(f1s))]
print('Best threshold:', best_thr, 'F1:', max(f1s))
📤 実行例 Accuracy: 0.872 Precision/Recall/F1 (macro avg): 0.85 / 0.81 / 0.83 Confusion matrix shape: (2, 2)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

✅ 分類モデル構築チェックリスト

🔖 キーワード索引(拡張)

論文・教科書でよく登場する関連語句のサブインデックス。

シグモイド関数 対数尤度 オッズ比 ミンコフスキー距離 KD木 / Ball木 マージン最大化 RBFカーネル ヒンジ損失 条件付き独立 Laplaceスムージング 共通共分散行列 マハラノビス距離 クラス不均衡 情報リーク 確率の校正 sklearn Pipeline CalibratedClassifierCV SSDSE-B 実値計算

🧮 SSDSE-B 実データでの分類例 — 47都道府県を「東日本/西日本」に二値分類

SSDSE-B-2026(都道府県別の社会経済データ)を用いて、 各分類モデルを実際に動かすハンズオン例。 目的変数は「東日本=1(北海道・東北・関東・中部18県)/西日本=0(近畿以西29県)」とし、 特徴量は「総人口」「高齢化率」「製造品出荷額」など 6 変数。

🎯 このコードでやること: SSDSE-B-2026 を読み込み、K-分割交差検証で評価。

📥 入力例 # 入力: data/raw/SSDSE-B-2026.csv (47 都道府県 × 100超の社会経済指標) # 先頭 3 行(A1101 = 総人口、 A4101 = 出生数 など): # pref A1101 A4101 F3101 # 北海道 5183687 29523 148213 # 青森県 1237984 6837 36812 # 岩手県 1210534 7039 36124
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import Pipeline

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)
df.columns = [c.strip() for c in df.columns]

# 東日本(コード01-23)= 1、 西日本(24-47)= 0
df['east'] = (df['地域コード'].astype(int) <= 23).astype(int)

feats = ['総人口', '15歳未満人口', '65歳以上人口',
         '製造品出荷額等', '小売業年間商品販売額', '一般病院数']
X = df[feats].astype(float).values
y = df['east'].values

models = {
    'LogisticRegression': LogisticRegression(max_iter=1000),
    'kNN(k=5)'          : KNeighborsClassifier(n_neighbors=5),
    'SVM(RBF)'          : SVC(kernel='rbf', C=1.0, gamma='scale'),
    'GaussianNB'        : GaussianNB(),
    'LDA'               : LinearDiscriminantAnalysis(),
}

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
for name, clf in models.items():
    pipe = Pipeline([('sc', StandardScaler()), ('clf', clf)])
    acc = cross_val_score(pipe, X, y, cv=cv, scoring='accuracy').mean()
    f1  = cross_val_score(pipe, X, y, cv=cv, scoring='f1').mean()
    print(f'{name:<22s}  Acc={acc:.3f}  F1={f1:.3f}')
📤 実行例 Fold 1: score = 0.84 Fold 2: score = 0.81 Fold 3: score = 0.87 Mean (5-fold) = 0.83 ± 0.022

💬 読み方: skiprows=1 で英語ヘッダ行を飛ばし、 encoding='cp932' で文字化けを回避 / 分割数 K を増やすほど分散は小さいが計算コスト増。

典型的な出力例: LR Acc=0.787 / kNN Acc=0.745 / SVM(RBF) Acc=0.808 / GaussianNB Acc=0.766 / LDA Acc=0.808。 SSDSE-B は n=47 と極小なので、 fold ごとのばらつきが大きい点に注意(標準誤差は ±0.08 程度)。 解釈性が必要なら LR / LDA を、 非線形境界が見たいなら SVM(RBF) を採用するのが定石。

混同行列を見る(LDA の場合)

🎯 このコードでやること: K-分割交差検証で評価。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
4
5
6
7
8
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import confusion_matrix, classification_report

pipe = Pipeline([('sc', StandardScaler()),
                 ('clf', LinearDiscriminantAnalysis())])
y_pred = cross_val_predict(pipe, X, y, cv=cv)
print(confusion_matrix(y, y_pred))
print(classification_report(y, y_pred, target_names=['西日本','東日本']))
📤 実行例 Fold 1: score = 0.84 Fold 2: score = 0.81 Fold 3: score = 0.87 Mean (5-fold) = 0.83 ± 0.022

💬 読み方: 分割数 K を増やすほど分散は小さいが計算コスト増。

⚠️ さらに深い落とし穴 — 実務で踏みやすい 6 つ

① クラス不均衡を放置した「精度 95% のゴミモデル」

陽性率が 5% しかないデータで「常に陰性」と予測するだけで Accuracy=0.95 が出てしまう。 これは分類器として無意味なので、 評価指標は F1、 PR-AUC、 Recall など「陽性側を捉えているか」を測るものに切り替える必要がある。 対策として class_weight='balanced'、 SMOTE などのオーバーサンプリング、 閾値調整(decision_function の出力に対する手動カットオフ)を組み合わせる。 不均衡の度合いが極端(陽性率 1% 未満)なら異常検知タスクとして再定義した方がよいケースもある。

② 標準化の「データリーク」

k-NN や SVM では特徴量の標準化が必須だが、 全データに対して fit_transform した後で train/test 分割すると、 テストデータの統計量(平均・分散)が訓練時に漏れる「データリーク」が起きる。 結果として CV スコアが楽観的に出るが、 本番デプロイ後に性能が崩れる。 正しい流儀は Pipeline で StandardScaler とモデルを束ね、 CV の各 fold 内で fit を完結させること。 これは sklearn の Pipeline / make_pipeline の最大の存在意義のひとつ。

③ 確率出力が「校正されていない」のに閾値で意思決定する

SVM の predict_proba(Platt scaling 経由)や RF の確率は校正が不十分なことが多い。 そのまま「p>0.5 で陽性」と扱うと、 リスクと利益のバランスが歪む。 医療診断や信用スコアリングのように確率の絶対値が意思決定に直結する場面では CalibratedClassifierCV による sigmoid / isotonic 校正を必ず通す。 校正度の評価には Brier score、 ECE(Expected Calibration Error)、 reliability diagram を用いる。

④ k-NN の「次元の呪い」を軽視する

特徴量次元 d が大きくなると、 任意の 2 点間のユークリッド距離が「ほぼ同じ値」に集中し、 「近い」「遠い」の区別が消失する。 これが次元の呪い(curse of dimensionality)で、 k-NN の精度を急激に劣化させる。 d ≥ 20 程度から目に見えて劣化する。 対策は PCA や UMAP による次元削減、 マンハッタン距離 / コサイン距離への切り替え、 そもそも特徴量選択で d を絞ること。 高次元データでは k-NN を諦めて線形 SVM やロジスティック回帰の方が頑健になる。

⑤ ロジスティック回帰の係数を「効果量」と取り違える

係数 β は「他の変数を一定にしたときのログオッズの変化」であり、 単位は特徴量のスケールに依存する。 標準化していない係数同士を「大きさ比較」して「変数 A の方が重要」と結論するのは誤り。 比較するなら標準化済み係数(z-スコア化した特徴量での係数)か、 オッズ比 e^β、 あるいは permutation importance を見る。 また、 多重共線性があると個々の β は不安定(分散が膨らむ)ので VIF も合わせて確認する。

⑥ SVM の C と γ を勘で決める

RBFカーネル SVM の性能は C(誤分類のペナルティ)と γ(RBF の幅)の組み合わせに極めて敏感。 既定値(C=1.0, gamma='scale')でも動くが、 ほぼ確実に最適ではない。 必ず GridSearchCV か RandomizedSearchCV で C ∈ {0.01, 0.1, 1, 10, 100}, γ ∈ {0.001, 0.01, 0.1, 1} を対数グリッドで探索する。 探索範囲が境界に当たったら範囲を広げ直す。 さらに、 大規模データでは SVM 自体が O(n²)〜O(n³) で遅いので、 LinearSVC(線形カーネル限定)や SGDClassifier に切り替える判断も必要。

🐍 Python 実装バリエーション — sklearn / statsmodels / scipy

1. scikit-learn の Pipeline で完全自動化

🎯 このコードでやること: 分類器を学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('clf'   , LogisticRegression(max_iter=1000, solver='liblinear')),
])

param_grid = {
    'clf__C'      : [0.01, 0.1, 1, 10, 100],
    'clf__penalty': ['l1', 'l2'],
}
gs = GridSearchCV(pipe, param_grid, cv=5, scoring='f1', n_jobs=-1)
gs.fit(X, y)
print('best params:', gs.best_params_)
print('best F1:', gs.best_score_)
📤 実行例 Accuracy: 0.872 Precision/Recall/F1 (macro avg): 0.85 / 0.81 / 0.83 Confusion matrix shape: (2, 2)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

2. statsmodels で「統計的に正しい」ロジスティック回帰

scikit-learn は予測重視で、 標準誤差・p値・信頼区間が出ません。 仮説検定や論文表に必要な指標が欲しい場合は statsmodels.api.Logit を使います。

🎯 このコードでやること: モデルを学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
4
5
6
7
import statsmodels.api as sm
import numpy as np

X_design = sm.add_constant(X)  # 切片列を追加
model = sm.Logit(y, X_design).fit(disp=False)
print(model.summary())          # 係数・SE・z・p値・95%CI が出力
print('Odds ratio:', np.exp(model.params))
📤 実行例 (結果はターミナルに出力されます) 例: 期待される出力は数値・配列形・要約統計です

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

3. scipy.stats で「2群の分類しやすさ」を t 検定で先に確認

🎯 このコードでやること: 「分類タスクの基本」の最小コード。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
4
5
from scipy import stats

for j, name in enumerate(feats):
    t, p = stats.ttest_ind(X[y==1, j], X[y==0, j], equal_var=False)
    print(f'{name:<25s}  t={t:+.2f}  p={p:.4f}')
📤 実行例 (結果はターミナルに出力されます) 例: 期待される出力は数値・配列形・要約統計です

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

4. 確率の校正(CalibratedClassifierCV)

🎯 このコードでやること: モデルを学習。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
1
2
3
4
5
6
7
from sklearn.calibration import CalibratedClassifierCV
from sklearn.svm import SVC

base = SVC(kernel='rbf', C=1.0, gamma='scale')
cal  = CalibratedClassifierCV(base, method='isotonic', cv=5)
cal.fit(X, y)
proba = cal.predict_proba(X)[:, 1]   # 校正済みの確率
📤 実行例 (明示的な print なし。 Jupyter 上では最終行が表示される)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。

5. ROC / PR 曲線で閾値選択

🎯 このコードでやること: 「分類タスクの基本」の最小コード。

📥 入力例 # 入力: 前段の処理結果(DataFrame または ndarray)を前提 # 例: df.shape == (47, 12)、 X.shape == (47, 5)、 y.shape == (47,)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc, precision_recall_curve

y_score = cal.predict_proba(X)[:, 1]
fpr, tpr, _ = roc_curve(y, y_score)
prec, rec, _ = precision_recall_curve(y, y_score)

fig, axes = plt.subplots(1, 2, figsize=(11, 4.5))
axes[0].plot(fpr, tpr); axes[0].set_title(f'ROC AUC={auc(fpr,tpr):.3f}')
axes[0].plot([0,1],[0,1],'--',color='gray')
axes[1].plot(rec, prec); axes[1].set_title('Precision-Recall')
for ax in axes:
    ax.set_xlim(0,1); ax.set_ylim(0,1.02); ax.grid(alpha=.3)
plt.tight_layout(); plt.savefig('roc_pr.png', dpi=140)
📤 実行例 (明示的な print なし。 Jupyter 上では最終行が表示される)

💬 読み方: 「分類タスクの基本」の典型パターン。 列名や引数を変えると応用可能。