Trabajo Práctico 2: Análisis con Voting - Organización de Datos

Alumnos y Padrón

  • Grassano, Bruno - 103855
  • Romero, Adrián - 103371

https://github.com/brunograssano/TP-Organizacion-de-datos

Importamos las bibiliotecas

In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
In [2]:
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve
from sklearn.model_selection import KFold, StratifiedKFold
In [3]:
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
from sklearn import tree
In [4]:
from preprocessing import prepararSetDeDatos
from preprocessing import prepararSetDeHoldout
from preprocessing import prepararSetDeValidacion
from preprocessing import conversionAVariablesNormalizadas
from preprocessing import expansionDelDataset
In [5]:
from funcionesAuxiliares import mostrarAUCScore
from funcionesAuxiliares import mostrarROCCurve
from funcionesAuxiliares import mostrarMatrizDeConfusion
from funcionesAuxiliares import escribirPrediccionesAArchivo
from funcionesAuxiliares import obtenerDatasets
from funcionesAuxiliares import obtenerHoldout

Importamos los datos y los procesamos

In [6]:
X,y = obtenerDatasets()
X = prepararSetDeDatos(X)
y = prepararSetDeValidacion(y)

Voting

Este modelo es un ensamble que consiste en la unión de varios modelos, los cuales votaran de que clase es una instancia. En este caso, decidimos armar el ensamble utilizando los modelos que mejores resultados (segun la metrica AUC-ROC) nos dieron en los otros notebooks. Los elegidos fueron:

  • Árbol de decisión
  • SVM
  • Random Forest
  • Regresion logística

Cada uno de estos modelos lo recreamos con los mejores hiperparámetros que se encontraron en su notebook.

Para el preprocesamiento probamos primero con el basico, el cual incluye a todas las columnas que vienen en el dataframe.

In [7]:
X_voting = conversionAVariablesNormalizadas(X) 

Dividimos el set de datos en sets de training y test.

In [8]:
X_train, X_test, y_train, y_test = train_test_split(X_voting, y, test_size=0.25, random_state=0)

Inicializamos los modelos que usara Voting, cada uno con sus mejores hiperparametros encontrados. En el caso de random forest se les redujo algo la profundidad.

In [9]:
regresion_logistica = LogisticRegression(penalty = 'none', solver = "saga",max_iter = 5000)
random_forest = RandomForestClassifier(n_estimators=100, random_state=0,criterion='entropy',max_depth=7)
svm = SVC(C=200, kernel='rbf', gamma=0.1,probability=True)
arbol = tree.DecisionTreeClassifier(random_state=117, max_depth=4, criterion = 'gini')

Creamos el modelo y lo entrenamos.

In [10]:
voting = VotingClassifier(estimators=[('lr', regresion_logistica), ('rf', random_forest),('svm',svm),('tree',arbol)], voting='soft')
In [11]:
voting.fit(X_train, y_train)
Out[11]:
VotingClassifier(estimators=[('lr',
                              LogisticRegression(max_iter=5000, penalty='none',
                                                 solver='saga')),
                             ('rf',
                              RandomForestClassifier(criterion='entropy',
                                                     max_depth=7,
                                                     random_state=0)),
                             ('svm', SVC(C=200, gamma=0.1, probability=True)),
                             ('tree',
                              DecisionTreeClassifier(max_depth=4,
                                                     random_state=117))],
                 voting='soft')

Evaluación de métricas

Ahora si, realizamos las predicciones y observamos las métricas.

In [12]:
y_pred = voting.predict(X_test)
In [13]:
print(classification_report(y_test, y_pred, target_names=['No vuelve','Vuelve']))
              precision    recall  f1-score   support

   No vuelve       0.83      0.91      0.87       121
      Vuelve       0.84      0.72      0.78        80

    accuracy                           0.84       201
   macro avg       0.84      0.82      0.82       201
weighted avg       0.84      0.84      0.83       201

In [14]:
mostrarMatrizDeConfusion(y_pred,y_test)
In [15]:
mostrarROCCurve(voting,"Voting",X_test,X_train,y_test,y_train)
In [16]:
mostrarAUCScore(voting,"Voting",X_test,y_test)
AUC para Voting: 0.890

Observamos que obtuvimos una mejora en comparación a los otros modelos en varias de las métricas, por no decir todas.

Con otro preprocesamiento

Vemos ahora si podemos mejorar este resultado utilizando el Dataframe expandido.

In [17]:
X = expansionDelDataset(X)
In [18]:
X.head()
Out[18]:
sufijo tipo_de_sala genero edad amigos parientes precio_ticket fila nombre_sede autocompletamos_edad 2_clusters 4_clusters 10_clusters cantidad_total_invitados total_pagado pago_categorizado edades_estratificadas categoria_invitados
0 Señor 4d hombre 73.0 0 0 1 No responde fiumark_quilmes False 1 1 4 0 1 Pago poco mayor Fue solo
1 Señora 4d mujer 35.0 1 1 2 No responde fiumark_quilmes False 0 2 0 2 6 Pago normal adulto Fue en grupo
2 Señor normal hombre 32.0 0 0 3 No responde fiumark_chacarita True 0 2 0 0 3 Pago normal adulto Fue solo
3 Señor 4d hombre 32.0 0 0 1 No responde fiumark_palermo True 0 2 0 0 1 Pago poco adulto Fue solo
4 Señorita 4d mujer 4.0 1 1 2 No responde fiumark_palermo False 0 3 3 2 6 Pago normal ninio Fue en grupo
In [19]:
columnas_codificables_extra = ['pago_categorizado','edades_estratificadas','categoria_invitados']
columnas_numericas_extra = ['2_clusters','4_clusters','10_clusters','cantidad_total_invitados','total_pagado']
X_voting_exp = conversionAVariablesNormalizadas(X,columnas_codificables_extra,columnas_numericas_extra) 
In [20]:
X_train, X_test, y_train, y_test = train_test_split(X_voting_exp, y, test_size=0.25, random_state=0)
In [21]:
voting_exp = VotingClassifier(estimators=[('lr', regresion_logistica), ('rf', random_forest),('svm',svm),('tree',arbol)], voting='soft')
In [22]:
voting_exp.fit(X_train, y_train)
Out[22]:
VotingClassifier(estimators=[('lr',
                              LogisticRegression(max_iter=5000, penalty='none',
                                                 solver='saga')),
                             ('rf',
                              RandomForestClassifier(criterion='entropy',
                                                     max_depth=7,
                                                     random_state=0)),
                             ('svm', SVC(C=200, gamma=0.1, probability=True)),
                             ('tree',
                              DecisionTreeClassifier(max_depth=4,
                                                     random_state=117))],
                 voting='soft')

Evaluamos

In [23]:
y_pred = voting_exp.predict(X_test)
In [24]:
print(classification_report(y_test, y_pred, target_names=['No vuelve','Vuelve']))
              precision    recall  f1-score   support

   No vuelve       0.82      0.88      0.85       121
      Vuelve       0.80      0.71      0.75        80

    accuracy                           0.82       201
   macro avg       0.81      0.80      0.80       201
weighted avg       0.82      0.82      0.81       201

In [25]:
mostrarROCCurve(voting_exp,"Voting",X_test,X_train,y_test,y_train)
In [26]:
mostrarAUCScore(voting_exp,"Voting",X_test,y_test)
AUC para Voting: 0.881

Vemos que empeoro probando con toda la informacion nueva.

Otro preprocesamiento mas

Vemos si cambia algo sacar algunas columnas. Sacamos la del resultado con 10 clusters y la de la cantidad total de invitados.

In [27]:
columnas_codificables_extra = ['pago_categorizado','edades_estratificadas','categoria_invitados']
columnas_numericas_extra = ['2_clusters','4_clusters','total_pagado']
X_voting_exp2 = conversionAVariablesNormalizadas(X,columnas_codificables_extra,columnas_numericas_extra) 
In [28]:
X_train, X_test, y_train, y_test = train_test_split(X_voting_exp2, y, test_size=0.25, random_state=0)
In [29]:
voting_exp2 = VotingClassifier(estimators=[('lr', regresion_logistica), ('rf', random_forest),('svm',svm),('tree',arbol)], voting='soft')
In [30]:
voting_exp2.fit(X_train, y_train)
Out[30]:
VotingClassifier(estimators=[('lr',
                              LogisticRegression(max_iter=5000, penalty='none',
                                                 solver='saga')),
                             ('rf',
                              RandomForestClassifier(criterion='entropy',
                                                     max_depth=7,
                                                     random_state=0)),
                             ('svm', SVC(C=200, gamma=0.1, probability=True)),
                             ('tree',
                              DecisionTreeClassifier(max_depth=4,
                                                     random_state=117))],
                 voting='soft')

Evaluamos este preprocesamiento

In [31]:
y_pred = voting_exp2.predict(X_test)
In [32]:
print(classification_report(y_test, y_pred, target_names=['No vuelve','Vuelve']))
              precision    recall  f1-score   support

   No vuelve       0.84      0.90      0.87       121
      Vuelve       0.83      0.74      0.78        80

    accuracy                           0.84       201
   macro avg       0.83      0.82      0.82       201
weighted avg       0.84      0.84      0.83       201

In [33]:
mostrarROCCurve(voting_exp2,"Voting",X_test,X_train,y_test,y_train)
In [34]:
mostrarAUCScore(voting_exp2,"Voting",X_test,y_test)
AUC para Voting: 0.888

Mejoro bastante respecto al anterior, pero no llego a superar la metrica del primero.

Predicciones sobre el nuevo archivo

Realizamos ahora las predicciones del nuevo archivo entregado.

In [35]:
holdout = obtenerHoldout()
ids_usuarios = np.array(holdout['id_usuario'])
holdout = prepararSetDeHoldout(holdout)
holdout_voting = conversionAVariablesNormalizadas(holdout)

Realizamos las predicciones y escribimos al archivo CSV.

In [36]:
predicciones_holdout = voting.predict(holdout_voting)
In [37]:
escribirPrediccionesAArchivo(predicciones_holdout,"Voting",ids_usuarios)