<jupyter_start><jupyter_text>MAT281 - Laboratorio N°04 Objetivos del laboratorio* Reforzar conceptos básicos de reducción de dimensionalidad.  Contenidos* [Problema 01](p1)  I.- Problema 01El **cáncer de mama**  es una proliferación maligna de las células epiteliales que revisten los conductos o lobulillos mamarios. Es una enfermedad clonal; donde una célula individual producto de una serie de mutaciones somáticas o de línea germinal adquiere la capacidad de dividirse sin control ni orden, haciendo que se reproduzca hasta formar un tumor. El tumor resultante, que comienza como anomalía leve, pasa a ser grave, invade tejidos vecinos y, finalmente, se propaga a otras partes del cuerpo.El conjunto de datos se denomina `BC.csv`, el cual contine la información de distintos pacientes con tumosres (benignos o malignos) y algunas características del mismo.Las características se calculan a partir de una imagen digitalizada de un aspirado con aguja fina (FNA) de una masa mamaria. Describen las características de los núcleos celulares presentes en la imagen.Los detalles se puede encontrar en [<NAME> and <NAME>: "Robust Linear Programming Discrimination of Two Linearly Inseparable Sets", Optimization Methods and Software 1, 1992, 23-34].Lo primero será cargar el conjunto de datos:<jupyter_code>import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA


%matplotlib inline
sns.set_palette("deep", desat=.6)
sns.set(rc={'figure.figsize':(11.7,8.27)})
# cargar datos
df = pd.read_csv(os.path.join("data","BC.csv"), sep=",")
df['diagnosis'] = df['diagnosis'] .replace({'M':1,'B':0})
df.head()<jupyter_output><empty_output><jupyter_text>Basado en la información presentada responda las siguientes preguntas:1. Normalizar para las columnas numéricas con procesamiento **StandardScaler**.2. Realice un gráfico de correlación. Identifique la existencia de colinealidad.3. Realizar un ajuste PCA con **n_components = 10**. Realice un gráfico de la varianza y varianza acumulada. Interprete.4. Devuelva un dataframe con las componentes principales.5. Aplique al menos tres modelos de clasificación. Para cada modelo, calule el valor de sus métricas.<jupyter_code>#Hay que revisar que no hayan elementos NAN
df.isna().all().unique()<jupyter_output><empty_output><jupyter_text>Desde el dataset, debido a que es un *conjunto supervisado*, se deben crear los conjuntos de atributos y características, y el conjunto de las etiquetas.<jupyter_code>X = df.loc[:, df.columns[2:]].values
y = df.loc[:, ['diagnosis']].values
#Se normaliza con Standard Scaler
X = StandardScaler().fit_transform(X)<jupyter_output><empty_output><jupyter_text>Se debe realizar un análisis exploratorio de los datos<jupyter_code>predictor_names = df.columns[2:]
n_show = min(len(predictor_names),50)

corrmat = df[predictor_names[:n_show]].corr() #Correlación de las variables
fig, ax = plt.subplots(figsize=(8, 8)) 
sns.heatmap(corrmat, vmax=.9, square=True, ax=ax,cmap="PuBuGn") #Mapa de calor
ax.set_title("Correlación Lineal Predictores vs Predictores")
plt.show()<jupyter_output><empty_output><jupyter_text>Es sabido que, las áreas donde se tiene zonas más oscuras, indican una mayor correlación de las variables. Esto es malo a la hora de entrenar el modelo. Siempre se trata de que las variables sean lo más linealmente independientes entre sí para no caer en el overfitting. Para lidiar con esto, se realizará una reducción de la dimensionalidad.<jupyter_code>pca = PCA(n_components=10) #Modelo, se tomarán 10 n-componentes, es decir, se tomarán 10 variables para reducir la dimensión
principalComponents = pca.fit_transform(X) #fit del modelo
#Varianzas por n-componentes
percent_variance = np.round(pca.explained_variance_ratio_, decimals =3)
columns = ['PC1', 'PC2', 'PC3', 'PC4', 'PC5', 'PC6', 'PC7', 'PC8', 'PC9', 'PC10']

plt.figure(figsize=(15,7))
plt.bar(x= range(1,11), height=percent_variance, tick_label=columns)
plt.ylabel('Percentate of Variance Explained')
plt.xlabel('Principal Component')
plt.title('PCA Scree Plot')
plt.show()
# Gráfico de Varianza acumulada entre las n-componentes
percent_variance_cum = np.cumsum(percent_variance)
columns = ['PC1', 
           'PC1+PC2', 
           'PC1+PC2+PC3', 
           'PC1+PC2+PC3+PC4', 
           'PC1+PC2+PC3+PC4+PC5', 
           'PC1+PC2+PC3+PC4+PC5+PC6',
           'PC1+PC2+PC3+PC4+PC5+PC6+PC7',
           'PC1+PC2+PC3+PC4+PC5+PC6+PC7+PC8',
           'PC1+PC2+PC3+PC4+PC5+PC6+PC7+PC8+PC9',
           'PC1+PC2+PC3+PC4+PC5+PC6+PC7+PC8+PC9+PC10']

plt.figure(figsize=(15,7))
plt.bar(x= range(1,11), height=percent_variance_cum, tick_label=columns)
plt.xticks(x= range(1,11), rotation='vertical')
plt.ylabel('Percentate of Variance Explained')
plt.xlabel('Principal Component Cumsum')
plt.title('PCA Scree Plot')
plt.show()
#Veamos cuanto es el valor del acumulado al final
percent_variance_cum[9]<jupyter_output><empty_output><jupyter_text>Lo anterior nos indica que con solo 10 n-componentes se puede resumir la información del dataset en un 95.3%. Hemos de ver cuales son dichos componentes.<jupyter_code>principalDataframe = pd.DataFrame(data = principalComponents, 
                                  columns = ['PC1', 'PC2', 'PC3', 'PC4', 'PC5', 'PC6', 'PC7', 'PC8', 'PC9', 'PC10'])
targetDataframe = df[['diagnosis']]

df_reducido = pd.concat([principalDataframe, targetDataframe],axis = 1)
df_reducido.head()<jupyter_output><empty_output><jupyter_text>Y listo! Se redujo la dimensionalidad del problema a través del Principal Component Analisys. Se pasará ahora a hacer el ajuste de los modelos, y evaluar en base a las métricas que se impongan.<jupyter_code>from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier,DecisionTreeRegressor

#Se utilizan las componentes proyectadas
X = df_reducido[['PC1', 'PC2', 'PC3', 'PC4', 'PC5', 'PC6', 'PC7', 'PC8', 'PC9', 'PC10']]
Y = df_reducido['diagnosis']

#Se crean los conjuntos de entrenamiento y test desde los conjuntos definidos anteriormente
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33, random_state = 2)<jupyter_output><empty_output><jupyter_text>Se utilizarán como clasificadores **Support Vector Machine-C, Random Forest y OVO.**<jupyter_code>from sklearn.ensemble import RandomForestClassifier
from sklearn.multiclass import OneVsOneClassifier
from sklearn.svm import LinearSVC
from sklearn import svm

#Se crean los clasificadores
clf1 = svm.SVC(random_state=2) # Clasificador 1: SVM-C
clf2 = RandomForestClassifier(max_depth=2, random_state=2) # Clasificador 2: Random Forest
clf3 = OneVsOneClassifier(LinearSVC(random_state=2)) # Clasificador 3: OVO
#Se fittean los clasificadores a los conjuntos de entrenamiento
clf1.fit(X_train,Y_train)
clf2.fit(X_train,Y_train)
clf3.fit(X_train,Y_train)<jupyter_output>C:\Users\56982\Anaconda3\lib\site-packages\sklearn\svm\base.py:193: FutureWarning: The default value of gamma will change from 'auto' to 'scale' in version 0.22 to account better for unscaled features. Set gamma explicitly to 'auto' or 'scale' to avoid this warning.
  "avoid this warning.", FutureWarning)
C:\Users\56982\Anaconda3\lib\site-packages\sklearn\ensemble\forest.py:245: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
  "10 in version 0.20 to 100 in 0.22.", FutureWarning)<jupyter_text>Se han de revisar los predictores.<jupyter_code>#Y_predict i _train/test representa la predicción del conjunto de train/test para el i-ésimo modelo
Y_predict1_train = clf1.predict(X_train)
Y_predict1_test = clf1.predict(X_test)

Y_predict2_train = clf2.predict(X_train)
Y_predict2_test = clf2.predict(X_test)

Y_predict3_train = clf3.predict(X_train)
Y_predict3_test = clf3.predict(X_test)<jupyter_output><empty_output><jupyter_text>Se utilizará la **accuracy** como métrica para evaluar.<jupyter_code>from sklearn import metrics 
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import roc_auc_score
print('Accuracy Score sobre train_set - SVM-C: ', metrics.accuracy_score(Y_train, Y_predict1_train))
print('Accuracy Score sobre test_set - SVM-C: ', metrics.accuracy_score(Y_test, Y_predict1_test)) 
print('')
print('Accuracy Score sobre train_set - Random Forest: ', metrics.accuracy_score(Y_train, Y_predict2_train))
print('Accuracy Score sobre test_set - Random Forest: ', metrics.accuracy_score(Y_test, Y_predict2_test)) 
print('')
print('Accuracy Score sobre train_set - OVO: ', metrics.accuracy_score(Y_train, Y_predict3_train))
print('Accuracy Score sobre test_set - OVO: ', metrics.accuracy_score(Y_test, Y_predict3_test))<jupyter_output>Accuracy Score sobre train_set - SVM-C:  0.9921259842519685
Accuracy Score sobre test_set - SVM-C:  0.9521276595744681

Accuracy Score sobre train_set - Random Forest:  0.9212598425196851
Accuracy Score sobre test_set - Random Forest:  0.9202127659574468

Accuracy Score sobre train_set - OVO:  0.9868766404199475
Accuracy Score sobre test_set - OVO:  0.973404255319149<jupyter_text>Se tienen buenos resultados. La accuracy de los conjuntos de testeo y training son muy parecidos. Lo anterior indica que probablemente **no hay overfitting**. PCA ayuda a hacer linealmente independiente los datos.Sin embargo, existe un problema. Puede que no se esté considerando algo, para ello, se verán como rinden las otras métricas. Es de destacar que se utilizará el promedio con pesos.<jupyter_code>print('Métricas SVM:')
print('')

print('SUPPORT VECTOR MACHINE-C Train')
print('Accuracy Score - SVM - Train:', metrics.accuracy_score(Y_train, Y_predict1_train))
print('F1 Score - SVM - Train:', metrics.f1_score(Y_train, Y_predict1_train,average='weighted'))
class_report_RF_1 = classification_report(Y_train, Y_predict1_train) #classification report
print(class_report_RF_1)
print('')
print('')


print('SUPPORT VECTOR MACHINE-C Test')
print('Accuracy Score - SVM - Test:', metrics.accuracy_score(Y_test, Y_predict1_test))
print('F1 Score - SVM - Test:', metrics.f1_score(Y_test, Y_predict1_test,average='weighted'))
class_report_RF_2 = classification_report(Y_test, Y_predict1_test)
print(class_report_RF_2)
print('')
print('')
print('Métricas Random Forest:')
print('')

print('RANDOM FOREST Train')
print('Accuracy Score - RFC - Train:', metrics.accuracy_score(Y_train, Y_predict2_train))
print('F1 Score - RFC - Train:', metrics.f1_score(Y_train, Y_predict2_train,average='weighted'))
class_report_RF_3 = classification_report(Y_train, Y_predict2_train) #classification report
print(class_report_RF_3)
print('')
print('')


print('RANDOM FOREST Test')
print('Accuracy Score - RFC - Test:', metrics.accuracy_score(Y_test, Y_predict2_test))
print('F1 Score - RFC - Test:', metrics.f1_score(Y_test, Y_predict2_test,average='weighted'))
class_report_RF_4 = classification_report(Y_test, Y_predict2_test)
print(class_report_RF_4)
print('')
print('')
print('Métricas One Vs One:')
print('')
print('ONE VS ONE Train')
print('Accuracy Score - OVO - Train:', metrics.accuracy_score(Y_train, Y_predict3_train))
print('F1 Score - OVO - Train:', metrics.f1_score(Y_train, Y_predict3_train,average='weighted'))
class_report_RF_5 = classification_report(Y_train, Y_predict3_train) #classification report
print(class_report_RF_5)
print('')
print('')


print('ONE VS ONE Test')
print('Accuracy Score - OVO - Test:', metrics.accuracy_score(Y_test, Y_predict3_test))
print('F1 Score - OVO - Test:', metrics.f1_score(Y_test, Y_predict3_test,average='weighted'))
class_report_RF_6 = classification_report(Y_test, Y_predict3_test)
print(class_report_RF_6)
print('')
print('')<jupyter_output>Métricas One Vs One:

ONE VS ONE Train
Accuracy Score - OVO - Train: 0.9868766404199475
F1 Score - OVO - Train: 0.9868454794840024
              precision    recall  f1-score   support

           0       0.98      1.00      0.99       242
           1       0.99      0.97      0.98       139

    accuracy                           0.99       381
   macro avg       0.99      0.98      0.99       381
weighted avg       0.99      0.99      0.99       381



ONE VS ONE Test
Accuracy Score - OVO - Test: 0.973404255319149
F1 Score - OVO - Test: 0.9733701124016605
              precision    recall  f1-score   support

           0       0.97      0.98      0.98       115
           1       0.97      0.96      0.97        73

    accuracy                           0.97       188
   macro avg       0.97      0.97      0.97       188
weighted avg       0.97      0.97      0.97       188
{'fraction_non_alphanumeric': 0.10141267461131719, 'fraction_numerical': 0.04443216794254597, 'mean_word_length': 5.051575931232092, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '225694', 'license': 'MIT', 'n_tokens_mistral': 4745, 'n_tokens_neox': 4395, 'n_words': 1209, 'path': 'labs/10_overfitting/laboratorio_10.ipynb', 'repo_name': 'gonzalogacitua/MAT281_Portafolio', 'size': '12689'}