import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('seaborn')

from jupyterworkflow.data import get_fremont_data
from sklearn.decomposition import PCA
from sklearn.mixture import GaussianMixture

"""
Explanation: Unsupervised Analysis of Fremont Bridge Data
Codealong from Jake Vanderplas Youtube video
<pre>Must use Python 3 because of the urllib package only available in Python 3
Treating bridge crossings for each day as features to understand relationships between various days.
</pre>
End of explanation
"""


data = get_fremont_data()

pivoted = data.pivot_table('Total', index=data.index.time, columns=data.index.date)
pivoted.plot(legend=False, alpha=0.01)

np.unique(data.index.time)

pivoted.shape

# if we transpose it, the days become observations and hours become columns
pivoted.T.shape

"""
Explanation: Get Data
End of explanation
"""


X = pivoted.fillna(0).T.values
X.shape

PCA(2).fit(X)

# transforming X into 2 dimensions (features) using PCA
X2 = PCA(2, svd_solver='full').fit_transform(X)

X2.shape

plt.scatter(X2[:, 0], X2[:,1])
plt.title('Pivoted Transposed Fremont Data with PCA/full SVD')

# 2 clusters
# use guassian mixture to classify each observation into 2 groups

# what would it look like if we did with 'auto' svd_solver?

X2_auto = PCA(2).fit_transform(X)
X2_auto.shape

plt.scatter(X2_auto[:, 0], X2_auto[:,1])
plt.title('Pivoted Transposed Fremont Data with PCA/auto SVD')

# looks to be no difference.

"""
Explanation: Principal Component Analysis
End of explanation
"""


gmm = GaussianMixture(2).fit(X)
labels = gmm.predict(X)

plt.scatter(X2[:, 0], X2[:,1], c=labels, cmap='rainbow')
plt.title('Pivoted Transposed Fremont Data with PCA/full SVD and Gaussian Mixture Labels')
plt.colorbar();

fig, ax = plt.subplots(1, 2, figsize=(14,6))
pivoted.T[labels == 0].T.plot(legend=False, alpha=0.1, ax=ax[0])
pivoted.T[labels == 1].T.plot(legend=False, alpha=0.1, ax=ax[1])

ax[0].set_title('Purple Cluster - Weekday Pattern')
ax[1].set_title('Red Cluster - Weekend Pattern')

"""
Explanation: Unsupervised Clustering - Gaussian Mixture
End of explanation
"""


dayofweek = pd.DatetimeIndex(pivoted.columns).dayofweek

plt.scatter(X2[:, 0], X2[:,1], c=dayofweek, cmap='rainbow')
plt.title('Pivoted Transposed Fremont Data with PCA/full SVD and DayOfWeek Labels')
plt.colorbar();

"""
Explanation: Comparing with Day of Week
Looking at clusters with labels as day of the week
End of explanation
"""


dates = pd.DatetimeIndex(pivoted.columns)
dates[(labels == 1) & (dayofweek<5)]

# cluster [1] with weekday labels

# look up date 2017-02-06 reason why this weekday shows up in the 'weekend' cluster
# This has shown to be the snow day, one of the worst weathers in Seattle.
# All other dates are related to holidays

"""
Explanation: Analyzing Outliers
End of explanation
"""


# checking versions
# import sklearn
# sklearn.__version__

"""
Explanation: Thank you Jake Vanderplas for this wonderful tutorial!
End of explanation
"""


