<jupyter_start><jupyter_text>ClusterAI 2020 Ciencia de Datos - Ingeniería Industrial - UTN BA clase_07: Practica Clustering: Wine Data Set Elaborado por: <NAME>  Importamos Librerias<jupyter_code># importamos las librerías necesarias para trabajar.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import seaborn as sns
from sklearn import preprocessing
# Importamos librerias de PCA y silhouette_score
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
# Importamos librerias de Clustering
from sklearn.cluster import KMeans
from scipy.cluster.hierarchy import dendrogram, linkage 
from sklearn.cluster import AgglomerativeClustering<jupyter_output><empty_output><jupyter_text>Repositorio del Dataset Wine Data Set:https://archive.ics.uci.edu/ml/datasets/Wine  Importamos Dataset<jupyter_code>names_col = ['G','Alcohol','Malic acid','Ash','Alcalinity of ash','Magnesium','Total phenols',
             'Flavanoids','Nonflavanoid phenols','Proanthocyanins','Color intensity','Hue',
             'OD280/OD315 of diluted wines','Proline']

wine_df = pd.read_csv('../../datasets/vinos/clusterai2020_clase07_wine.data', delimiter=',', names=names_col)
wine_df.head()
wine_df.shape
wine_df.isnull().sum()
# Definimos nuestro X
x = wine_df.iloc[:,1:]
display(x.head())
print(x.shape)
# Vamos a crear un dataframe para guardar los resultados
results_df = pd.DataFrame(columns=['Cluster','Acc','Sill'])<jupyter_output><empty_output><jupyter_text>Auto-Scaling<jupyter_code># Realizamos un autoscaling con los datos, para todas las features
scaler = preprocessing.StandardScaler().fit(x)
xscal = scaler.transform(x)
xscal<jupyter_output><empty_output><jupyter_text>K-MEANS<jupyter_code>dist_cent = []
sill_list = []
for k in range(2, 10):
    kmeans = KMeans(n_clusters=k, random_state=1).fit(xscal)
    sill_score = silhouette_score(xscal,kmeans.labels_)
    sill_list.append(sill_score)
    dist_cent.append(kmeans.inertia_)
plt.plot(range(2, 10), dist_cent, marker='s');
plt.xlabel('N° K')
plt.ylabel('Sum of squared distances')
plt.show()
plt.plot(range(2, 10), sill_list, marker='s');
plt.xlabel('N° K')
plt.ylabel('Silhouette')
plt.show()

# Generamos un PCA con los datos luego del autoscaling
import matplotlib.cm as cm
from sklearn import decomposition

# Usamos el objeto PCA de la libreria 'decomposition'
# Definimos la cantidad de componentes
n_comps = 13
components = range(1,n_comps + 1) 
pca = decomposition.PCA(n_components=n_comps)

# Ajustamos
pca.fit(xscal)

# Transformamos
xpca = pca.transform(xscal)

# Porcentaje de la varianza explicada por cada PC
eigenvalues = pca.explained_variance_ratio_

# Suma acumulada
eigenvalues_acum = pca.explained_variance_ratio_.cumsum() 

# Graficamos
# Eje Izquierdo
fig, ax1 = plt.subplots(figsize=(9,6))
ax1.set_xlabel('Top PC')
ax1.set_ylabel('Varianza Explicada', color='k')
ax1.bar(components, eigenvalues, color='blue')
ax1.tick_params(axis='y', labelcolor='blue')

# Eje derecho
ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('Varianza Acumulada', color='k') 
ax2.plot(components, eigenvalues_acum, color='red') 
ax2.tick_params(axis='y', labelcolor='red')

fig.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()
# De la libreria:
# 'Principal axes in feature space, representing the directions of maximum variance in the data'
# The components are sorted by explained_variance_
pd.DataFrame(pca.components_[0:n_comps,:],columns=x.columns)

# En criollo:
# Es la direccion de los ejes de cada componente (autovectores)
# scatter plot de los datos, solamente con 2 PC
plt.figure(figsize=(9,6))
plt.scatter(xpca[:,0],xpca[:,1])    
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('Figura de PC1 y PC2')
plt.show()
# Generamos un modelo de K means con 3 clusters con los datos autoscalados
kmeans = KMeans(n_clusters=3, random_state=10).fit(xscal)<jupyter_output><empty_output><jupyter_text>**Pregunta: Como se define el numero de cluster del Kmean?**<jupyter_code># una vez realizado el clusering, observamos los labels de cluster asignadas a cada muestra
kmeans.labels_ = kmeans.labels_+1
kmeans.labels_
# visualizamos los centroides finales de cada cluster
centers = kmeans.cluster_centers_
centers
# Scatter plot de muestras y centroides con 2 PC: segun Cluster verdadero vs Clustering con K-Means

#Verdadero
plt.figure(figsize=(9,6))
plt.scatter(xpca[:,0],xpca[:,1],c=wine_df['G'].astype(float))    
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('Clustering Verdadero')
# K-Means
plt.figure(figsize=(9,6))
plt.scatter(xpca[:,0],xpca[:,1],c=kmeans.labels_.astype(float))
plt.scatter(centers[:,0], centers[:,1], marker="x", color='r',s=150)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('Clustering K-Means')
plt.show()<jupyter_output><empty_output><jupyter_text>**PREGUNTA:****¿Son correctos los centroides?**  Metricas del Kmeans<jupyter_code># Metricas
# Cantidad de errores
q_wrong = kmeans.labels_ - wine_df['G']
q_wrong = (q_wrong!=0).sum()
print(q_wrong)
#Accuracy
acc = ( x.shape[0] - q_wrong ) / x.shape[0]
#Sill. score
sill_score = silhouette_score(xscal,kmeans.labels_)
print(acc)
print(sill_score)
#Guardamos los resultados
results_df = results_df.append({'Cluster':'Kmeans',
                                'Acc':acc,
                                'Sill':sill_score},ignore_index=True)<jupyter_output><empty_output><jupyter_text>Reduccion de Dimensionalidad (RD) + K-Means Ahora vamos dejar de usar las 13 variables originales.Vamos a clusterizar con lo que nos puedan explicar UNICAMENTE los primeros 2 PC, y compararemos los resultados.<jupyter_code>reduced_dim = 2
xpca_rd = xpca[:,0:reduced_dim]
# Generamos el modelo K-means + RD
kmeans_rd = KMeans(n_clusters=3, random_state=10).fit(xpca_rd)
# una vez realizado el clusering, observamos las labels de cluster asignadas a cada muestra
kmeans_rd.labels_ = kmeans_rd.labels_ +1
kmeans_rd.labels_
# visualizamos los centroides finales de cada cluster
centers_rd = kmeans_rd.cluster_centers_
centers_rd
# Scatter plot con 2 PC: segun Cluster verdadero vs Clustering con K-Means+RD

#Verdadero
plt.figure(figsize=(9,6))
plt.scatter(xpca[:,0],xpca[:,1],c=wine_df['G'].astype(float))    
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('Clustering Verdadero')
# K-Means + RD
plt.figure(figsize=(9,6))
plt.scatter(xpca_rd[:,0],xpca_rd[:,1],c=kmeans_rd.labels_.astype(float))
plt.scatter(centers_rd[:,0], centers_rd[:,1], marker="x", color='r',s=150)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('Clustering K-means+RD')
plt.show()<jupyter_output><empty_output><jupyter_text>**PREGUNTA:****¿Y aca que sucedió?**  Metricas RD + K-Means<jupyter_code># Metricas
q_wrong = kmeans_rd.labels_ - wine_df['G']
q_wrong = (q_wrong!=0).sum()
print(q_wrong)
acc_rd = ( x.shape[0] - q_wrong ) / x.shape[0]

sill_score_rd = silhouette_score(xpca_rd,kmeans_rd.labels_)

print(acc_rd)
print(sill_score_rd)
#Guardamos los resultados
results_df = results_df.append({'Cluster':'PCA + Kmeans',
                                'Acc':acc_rd,
                                'Sill':sill_score_rd},ignore_index=True)
pd.DataFrame(pca.components_[0:reduced_dim,:],columns=x.columns)<jupyter_output><empty_output><jupyter_text>Recontrusccion **Si quisieramos volver a nuestro espacio original, consideremos que:**X = PCAvalores * PCAdireccionesX = PCAscores * PCAcomponents X = Autovalores * AutovectoresSolo nos quedaria un detalle. Sumar la media de X.**¿POR QUE?**X = Autovalores * Autovectores + Xmedia**Entonces:**X_reconstruida = Autovalores(n_componentes) * Autovectores(n_componentes) + Xmedia<jupyter_code>mu = np.mean(x, axis=0)
# 2 PCA
xpca_rd = xpca[:,0:reduced_dim]
x_reconstruido = np.dot(xpca_rd, pca.components_[0:reduced_dim,:])
x_reconstruido += mu
x_reconstruido_df = pd.DataFrame(x_reconstruido,columns=x.columns)

# Muestramos la reconstruccion
sample = np.random.randint(0,high=x.shape[0])
display(x.iloc[sample,:].to_frame().transpose())
display(x_reconstruido_df.iloc[sample,:].to_frame().transpose())<jupyter_output><empty_output><jupyter_text>Consultas?  Clustering Jerárquico<jupyter_code># Definimos el linkage
Z = linkage(xscal, 'ward')
# Threshold (Similaridad)
dist_cluster = 4
plt.figure(figsize=(25, 10))
dendrogram(Z,color_threshold=dist_cluster)
plt.axhline(c='k',linestyle='--', y=dist_cluster)
plt.show()
#dist_cluster = ?
#q_clusters = 5

dist_cluster = 20
plt.figure(figsize=(25, 10))
dendrogram(Z,color_threshold=dist_cluster)
plt.axhline(c='k',linestyle='--', y=dist_cluster)
plt.show()

cluster = AgglomerativeClustering(n_clusters=None, distance_threshold =dist_cluster,
                                  affinity='euclidean',
                                  linkage='ward')
cluster.fit_predict(xscal)
cluster.labels_= cluster.labels_+1
cluster.labels_<jupyter_output><empty_output><jupyter_text>SOLO PORQUE SABEMOS EL GROUND TRUE DE LOS CLUSTERS LOS AJUSTO MANUALENTE PARA CALCULAR EL ACCURACY ! !<jupyter_code>for i in np.arange(0,x.shape[0]):
    if cluster.labels_[i]==3:
        cluster.labels_[i]=1
    elif cluster.labels_[i]==2:
        cluster.labels_[i]=3
    elif cluster.labels_[i]==1:
        cluster.labels_[i]=2
cluster.labels_
plt.figure(figsize=(9, 6))
plt.scatter(xpca[:,0], xpca[:,1], c=cluster.labels_,)
plt.show()
# Metricas
q_wrong = cluster.labels_ - wine_df['G']
q_wrong = (q_wrong!=0).sum()
print(q_wrong)
acc3 = ( x.shape[0] - q_wrong ) / x.shape[0]
sill_score_h = silhouette_score(xscal,cluster.labels_)

print(acc3)
print(sill_score_h)
#Guardamos los resultados
results_df = results_df.append({'Cluster':'Hierarchy',
                                'Acc':acc3,
                                'Sill':sill_score_h},ignore_index=True)<jupyter_output><empty_output><jupyter_text>Resultados<jupyter_code>display(results_df)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1321309149863208, 'fraction_numerical': 0.015097780930185429, 'mean_word_length': 5.769547325102881, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 50, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '599329', 'license': 'Apache-2.0', 'n_tokens_mistral': 3890, 'n_tokens_neox': 3669, 'n_words': 739, 'path': 'clases/clase_07/clusterai_2020_clase07_clustering_vinos.ipynb', 'repo_name': 'nmirson-ml/clusterai_2020', 'size': '9878'}