import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.metrics import (
    accuracy_score,
    precision_score, recall_score, f1_score,roc_auc_score,
    classification_report, confusion_matrix,
    ConfusionMatrixDisplay, RocCurveDisplay
)


# ]ʂ̕\
def eval_and_print(name, y_true, y_pred, y_score=None, target_names=None):
    print(f"[{name}]")
    print("Accuracy :", accuracy_score(y_true, y_pred))
    print("Precision:", precision_score(y_true, y_pred))
    print("Recall   :", recall_score(y_true, y_pred))
    print("F1       :", f1_score(y_true, y_pred))
    if y_score is not None:
        print("ROC-AUC  :", roc_auc_score(y_true, y_score))
    print("\nClassification Report\n",
          classification_report(y_true, y_pred,
                                target_names=target_names))

    # s
    cm = confusion_matrix(y_true, y_pred)
    ConfusionMatrixDisplay(
        confusion_matrix=cm, display_labels=target_names
    ).plot(cmap="Greys")
    plt.title(f"Confusion Matrix - {name}")
    plt.show()

    # ROC Ȑ
    if y_score is not None:
        RocCurveDisplay.from_predictions(y_true, y_score, name=name)
        plt.title(f"ROC Curves - {name}")
        plt.show()


# 1) f[^ǂݍ݂ƕ
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)


# x[XCiŕpNX\j
majority_class = pd.Series(y_train).mode()[0]
y_pred_base = [majority_class] * len(y_test)
print("[Baseline] Accuracy:", accuracy_score(y_test, y_pred_base), "\n")


# 2) pCvCiW  SVM(liner kernel)j
pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("svc", SVC(kernel="linear", C=1.0,
                probability=True, random_state=42))
])


# 3) SVM(liner kernel)ɂwKƕ]
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
y_score = pipe.predict_proba(X_test)[:, 1]
eval_and_print("SVM(liner kernel)",
               y_test, y_pred, y_score, cancer.target_names)


# 3) SVM(RBF kernel)ɂwKƕ]
pipe = Pipeline([
  ("scaler", StandardScaler()),
  ("svc", SVC(kernel="rbf", C=1.0, gamma="scale",
              probability=True, random_state=42))
])


pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
y_score = pipe.predict_proba(X_test)[:, 1]
eval_and_print("SVM(RBF kernel)",
               y_test, y_pred, y_score, cancer.target_names)