# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + slideshow={"slide_type": "skip"}
# %matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import cm
import pandas as pd
import numpy as np
from numpy import atleast_2d
from sklearn.decomposition import PCA
from sklearn.mixture import GaussianMixture
from sklearn.metrics import adjusted_mutual_info_score
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
from mpl_toolkits.mplot3d import Axes3D
# -

cmap = cm.get_cmap('viridis')
pd.options.display.float_format = '{:,.2f}'.format

# + [markdown] slideshow={"slide_type": "slide"}
# ### Load Iris Data

# + slideshow={"slide_type": "fragment"}
iris = load_iris()
iris.keys()

# + [markdown] slideshow={"slide_type": "slide"}
# ### Create DataFrame

# + slideshow={"slide_type": "fragment"}
features = iris.feature_names
data = pd.DataFrame(data=np.column_stack([iris.data, iris.target]), 
                    columns=features + ['label'])
data.label = data.label.astype(int)
data.info()

# + [markdown] slideshow={"slide_type": "skip"}
# ### Standardize Data

# + slideshow={"slide_type": "skip"}
scaler = StandardScaler()
features_standardized = scaler.fit_transform(data[features])
n = len(data)

# + [markdown] slideshow={"slide_type": "skip"}
# ### Reduce Dimensionality to visualize clusters

# + slideshow={"slide_type": "skip"}
pca = PCA(n_components=2)
features_2D = pca.fit_transform(features_standardized)

# + hide_input=false slideshow={"slide_type": "slide"}
ev1, ev2 = pca.explained_variance_ratio_
ax = plt.figure().gca(title='2D Projection', 
                      xlabel='Explained Variance: {:.2%}'.format(ev1), 
                      ylabel='Explained Variance: {:.2%}'.format(ev2))
ax.scatter(*features_2D.T, c=data.label, s=10);

# + [markdown] slideshow={"slide_type": "slide"}
# ### Perform GMM clustering

# + slideshow={"slide_type": "fragment"}
n_components = 3
gmm = GaussianMixture(n_components=n_components)
gmm.fit(features_standardized)
data['clusters'] = gmm.predict(features_standardized)
fig, axes = plt.subplots(ncols=2)
labels, clusters = data.label, data.clusters
mi = adjusted_mutual_info_score(labels, clusters)
axes[0].scatter(*features_2D.T, c=data.label, s=10)
axes[0].set_title('Original Data')
axes[1].scatter(*features_2D.T, c=data.clusters, s=10)
axes[1].set_title('Clusters | MI={:.2f}'.format(mi))

# + [markdown] slideshow={"slide_type": "slide"}
# ### Visualized Gaussian Distributions

# + slideshow={"slide_type": "fragment"}
xmin, ymin = features_2D.min(axis=0)
xmax, ymax = features_2D.max(axis=0)

x = np.linspace(xmin, xmax, 500)
y = np.linspace(ymin, ymax, 500)
X, Y = np.meshgrid(x, y)

simulated_2D = np.column_stack([np.ravel(X), np.ravel(Y)])
simulated_4D = pca.inverse_transform(simulated_2D)
Z = atleast_2d(np.clip(np.exp(gmm.score_samples(simulated_4D)), a_min=0, a_max=1)).reshape(X.shape)

# + slideshow={"slide_type": "slide"}
fig, ax = plt.subplots()
ax.set_aspect('equal')
CS = ax.contour(X, Y, Z, cmap='Greens', alpha=.5)
CB = plt.colorbar(CS, shrink=0.8)
ax.scatter(*features_2D.T, c=data.label, s=15)
fig.tight_layout();

# + slideshow={"slide_type": "slide"}
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')
CS = ax.contourf3D(X, Y, Z, cmap='RdBu_r', alpha=.5)
CB = plt.colorbar(CS, shrink=0.8)
ax.scatter(*features_2D.T, c=data.label, s=15)
fig.tight_layout()
path = '/Users/Stefan/Dropbox (Personal)/Data Science/AI & ML/Algorithmic Trading/12 Unsupervised Learning/figures/gaussian3D.png'
fig.savefig(path, dpi=300)

# + [markdown] slideshow={"slide_type": "slide"}
# ### Bayesian Information Criterion 

# + slideshow={"slide_type": "fragment"}
bic = {}
for n_components in range(2, 8):
    gmm = GaussianMixture(n_components=n_components)
    gmm.fit(features_standardized)
    bic[n_components] = gmm.bic(features_standardized)
pd.Series(bic)

StarcoderdataJupyterScriptsDedupFiltered