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

from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.neural_network import MLPClassifier
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, target_names=None):
    print(f"[{name}]")
    print("Accuracy :", accuracy_score(y_true, y_pred))

    # 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()


# 1) f[^ǂݍ݂ƕ
digits = load_digits()
X, y = digits.data, digits.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] Most frequent class = ",
      digits.target_names[majority_class])
print("[Baseline] Accuracy:", accuracy_score(y_test, y_pred_base), "\n")


# 2) pCvCiW  wp[Zvgj
pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("mlp", MLPClassifier(
        hidden_layer_sizes=(16, 16),  # Bw2wEe16jbg
        activation="relu",
        solver="adam",
        alpha=1e-3,  # L2 x
        learning_rate_init=1e-3,
        max_iter=1000,  # ₷悤ɂⒷ
        random_state=42
    ))
])


# 3) wp[Zvgɂ\ƕ]
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
eval_and_print("MLP", y_test, y_pred, target_names=digits.target_names)


# 4) wKȐij̉
# Pipeline 璆 MLPClassifier CX^Xo
model = pipe.named_steps["mlp"]

plt.figure()
plt.title("MLP Training Loss Curve")
plt.plot(model.loss_curve_)
plt.xlabel("Epoch"); plt.ylabel("Training Loss")
plt.grid(True)
plt.tight_layout()
plt.show()