# Source: content/notes/ml/probabilistic-and-instance-models.md
# Independent CPU example; use the curriculum environment.
# See /notes/ml/#example-environment or /notes/deep-learning/#example-environment.

import numpy as np
from sklearn.datasets import load_wine
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis
from sklearn.metrics import accuracy_score, log_loss
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

X, y = load_wine(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, stratify=y, random_state=17)
for name, estimator in [
    ("LDA shrinkage", LinearDiscriminantAnalysis(solver="lsqr", shrinkage="auto")),
    ("QDA regularized", QuadraticDiscriminantAnalysis(reg_param=0.1)),
    ("Gaussian NB", GaussianNB()),
]:
    model = make_pipeline(StandardScaler(), estimator)
    model.fit(X_train, y_train)
    pred = model.predict(X_test)
    prob = model.predict_proba(X_test)
    assert np.allclose(prob.sum(axis=1), 1)
    print(name, accuracy_score(y_test, pred), log_loss(y_test, prob))
projection = make_pipeline(StandardScaler(), LinearDiscriminantAnalysis(n_components=2))
projection.fit(X_train, y_train)
embedded = projection.transform(X_test)
assert embedded.shape == (len(X_test), 2)
print("Supervised projection shape:", embedded.shape)
