<jupyter_start><jupyter_text>Trabajo Práctico 2: Análisis con Voting - Organización de Datos **Alumnos y Padrón**+ <NAME>, <NAME> - 106255 + <NAME> - 103735https://github.com/joaqogomez/Organizacion-de-datos-fiuba  Configuraciones InicialesPrimero, importamos las bibliotecas que vamos a utilizar:<jupyter_code>import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.model_selection import KFold, StratifiedKFold
from sklearn.metrics import roc_auc_score
from sklearn.ensemble import VotingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from preprocessing import dividir_dataset
from preprocessing import preparar_dataset
from preprocessing import normalizar_datos
from preprocessing import aplicar_one_hot_encoding
from funciones_auxiliares import graficar_auc_roc
from funciones_auxiliares import traer_df<jupyter_output><empty_output><jupyter_text>Carga del set de datosCargamos el dataset y aplicamos las funciones necesarias para adecuarlo al modelo. También segmentamos el dataset en X e y (target):<jupyter_code>df = traer_df()
df = preparar_dataset(df)<jupyter_output><empty_output><jupyter_text>También segmentamos el dataset en X e y (target), y luego lo dividimos en subsets de entrenamiento y test.<jupyter_code>X, y = dividir_dataset(df)
X = aplicar_one_hot_encoding(X)
X_train_original, X_test_original, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0, stratify=y)<jupyter_output><empty_output><jupyter_text>Asignamos los clasificadores a ser utilizados para realizar el ensamble. En este caso, utilizamos los que mejor ROC-AUC score proporcionaron: KNN, SVM y Random Forest, cada uno con sus mejores hiperparámetros.<jupyter_code>clf_1 = KNeighborsClassifier(n_neighbors = 40, weights = 'uniform', metric = 'cosine')
clf_2 = SVC(kernel = 'rbf', C = 0.1, degree = 2, gamma = 0.01, probability = True)
clf_3 = RandomForestClassifier(max_depth = 16, n_estimators = 500, criterion = 'entropy')<jupyter_output><empty_output><jupyter_text>Generamos el ensamble con los modelos anteriormente mencionados:<jupyter_code>voting = VotingClassifier(
    estimators=[('clf_1', clf_1), ('clf_2', clf_2), ('clf_3', clf_3)], voting='soft', n_jobs = -1
)<jupyter_output><empty_output><jupyter_text>Entrenamiento y predicción con el dataset original Normalizamos los datos del dataset original y entrenamos el modelo:<jupyter_code>X_train, X_test = normalizar_datos(X_train_original, X_test_original)
voting.fit(X_train, y_train)<jupyter_output><empty_output><jupyter_text>Ahora hacemos que este prediga sobre el subset de validation:<jupyter_code>y_pred = voting.predict(X_test)
y_pred_proba = voting.predict_proba(X_test)[:,1]
graficar_auc_roc(y_test, y_pred_proba)<jupyter_output><empty_output><jupyter_text>Se puede ver un AUC score muy elevado, que tiene sentido, ya que realizamos una votación entre los modelos con mejor rendimiento.A continuación, se muestra el classification report, que muestra otras métricas como precision, recall, accuracy, etc.<jupyter_code>print(classification_report(y_test, y_pred, target_names=['No Tiene Alto Valor Adquisitivo', 'Tiene Alto Valor Adquisitivo'], digits = 3))<jupyter_output>precision    recall  f1-score   support

No Tiene Alto Valor Adquisitivo      0.866     0.937     0.900      6181
   Tiene Alto Valor Adquisitivo      0.732     0.541     0.622      1960

                       accuracy                          0.842      8141
                      macro avg      0.799     0.739     0.761      8141
                   weighted avg      0.834     0.842     0.833      8141<jupyter_text>Observamos una alta precision y recall para las instancias con bajo valor adquisitivo. Sin embargo, las instancias con alto valor adquisitivo tienen un recall regular, a pesar de tener una alta precision. Esto se ve más claramente en la matriz de confusión, donde se ve que Voting clasifica muy bien a los ceros, y decentemente a los unos.<jupyter_code>from funciones_auxiliares import graficar_matriz_confusion
graficar_matriz_confusion(y_test, y_pred)<jupyter_output><empty_output><jupyter_text>Se puede observar que el ensamble tiene una clara tendencia a predecir instancias de bajo valor adquisitivo, ya que predijo un 46% de las instancias de alto valor adquisitivo como de bajos ingresos. Esto está relacionado con el recall regular para esas instancias mencionado anteriormente, de 0.541.  Entrenamiento y predicción con el dataset ampliadoComo otra técnica de preprocesamiento, decidimos expandir el dataset utilizando clustering para obtener cuatro nuevas columnas. Las columnas corresponden a la utilización de K-means con 2, 4, 6 y 10 como cantidad de clusters usados.<jupyter_code>from preprocessing import expandir_dataset<jupyter_output><empty_output><jupyter_text>Expandimos el dataset y realizamos el split del mismo en los subsets de entrenamiento y validación.<jupyter_code>X_exp = expandir_dataset(X)
X_exp_train_original, X_exp_test_original, y_exp_train, y_exp_test = train_test_split(X_exp, y, test_size=0.25, random_state=0, stratify=y)<jupyter_output><empty_output><jupyter_text>Generamos el ensamble para el dataset expandido con los modelos anteriormente mencionados:<jupyter_code>voting_expandido = VotingClassifier(
    estimators=[('clf_1', clf_1), ('clf_2', clf_2), ('clf_3', clf_3)], voting='soft', n_jobs = -1
)<jupyter_output><empty_output><jupyter_text>Normalizamos los datos del dataset ampliado y entrenamos el modelo:<jupyter_code>X_exp_train, X_exp_test = normalizar_datos(X_exp_train_original, X_exp_test_original)
voting_expandido.fit(X_exp_train, y_exp_train)<jupyter_output><empty_output><jupyter_text>Ahora hacemos que este prediga sobre el subset de validation:<jupyter_code>y_pred = voting_expandido.predict(X_exp_test)
y_pred_proba = voting_expandido.predict_proba(X_exp_test)[:,1]
graficar_auc_roc(y_exp_test, y_pred_proba)<jupyter_output><empty_output><jupyter_text>Podemos observar que el AUC score dio muy alto, incluso levemente mejor al del dataset original. Tiene sentido, ya que estamos haciendo una votación entre varios modelos que tuvieron un score alto.A continuación, se muestra el classification report, que muestra otras métricas como precision, recall, accuracy, etc.<jupyter_code>print(classification_report(y_test, y_pred, target_names=['No Tiene Alto Valor Adquisitivo', 'Tiene Alto Valor Adquisitivo'], digits = 3))<jupyter_output>precision    recall  f1-score   support

No Tiene Alto Valor Adquisitivo      0.871     0.938     0.903      6181
   Tiene Alto Valor Adquisitivo      0.742     0.560     0.638      1960

                       accuracy                          0.847      8141
                      macro avg      0.806     0.749     0.771      8141
                   weighted avg      0.840     0.847     0.839      8141<jupyter_text>Se puede ver una alta precision y recall para las instancias con bajos ingresos. Para los de altos ingresos, se ve una precision relativamente alta, y un recall regular. La predicción se ve más claramente en la siguiente matriz de confusión:<jupyter_code>from funciones_auxiliares import graficar_matriz_confusion
graficar_matriz_confusion(y_test, y_pred)<jupyter_output><empty_output><jupyter_text>La tendencia a predecir instancias de bajo valor adquisitivo persiste, pero se hace menos fuerte con el dataset expandido, mejorando levemente el recall.  Predicción con el dataset nuevoA continuación, realizamos la predicción con Voting con el dataset ampliado (ya que este tuvo una mejor performance según AUC-ROC) sobre el dataset de predicciones nuevo, y la escribimos al archivo 'Voting.csv'<jupyter_code>from funciones_auxiliares import traer_df_predicciones
from preprocessing import preparar_df_predicciones
from funciones_auxiliares import escribir_predicciones
df_predicciones = traer_df_predicciones()
ids, df_predicciones = preparar_df_predicciones(df_predicciones)
df_predicciones = aplicar_one_hot_encoding(df_predicciones)
df_predicciones = expandir_dataset(df_predicciones)
X_exp_train_normalizado, df_predicciones = normalizar_datos(X_exp_train_original, df_predicciones)
predicciones = voting_expandido.predict(df_predicciones)
escribir_predicciones(ids, predicciones, "Voting")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06318419800095193, 'fraction_numerical': 0.025226082817705855, 'mean_word_length': 5.551052221356197, 'pattern_counts': {'":': 0, '<': 70, '<?xml version=': 0, '>': 70, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '237775', 'license': 'MIT', 'n_tokens_mistral': 2923, 'n_tokens_neox': 2790, 'n_words': 790, 'path': 'TP2/Voting.ipynb', 'repo_name': 'MateoCraviotto/Organizacion-de-datos-fiuba-1', 'size': '8432'}