En este tutorial vamos a trabajar con el dataset del Titanic, analizarlo y enviar los resultados a la competición real. Ya has aprendido a obtener los datos e importarlos en tu Notebook de Kaggle en este tutorial. Ahora usaremos DataLab como cuaderno de ciencia de datos. Verás cómo utilizar ambas herramientas en plataformas distintas para que elijas la que más te guste.
Primero, entra en la sección "Competitions" de Kaggle y busca Titanic (Figura 5.4). Antes de ir directo al notebook, conviene entender toda la información de las secciones "Description" y "Rules". También es importante revisar los notebooks de otras personas; pueden darte ideas para tu solución.

La competición consiste en usar machine learning para crear un modelo que prediga qué pasajeros habrían sobrevivido al naufragio del Titanic. Usaremos un dataset con información de los pasajeros como nombre, género, edad, etc. Trabajaremos con dos datasets. El primero es 'train.csv'. Además de la información de los pasajeros, incluye los valores reales, como 'survived' y 'not survived'. En el segundo, 'test.csv', no hay valores de ground truth, ya que debemos predecirlos y enviar nuestros resultados.
El archivo de envío tendrá solo 2 columnas: PassengerId y Survived. El sistema dará error si intentas subir un archivo con más de 2 columnas. Ten en cuenta que puedes realizar hasta 10 envíos al día.
Con la información de la sección "Competition Description", el siguiente paso es traer los datos a nuestro DataLab y analizarlos.
Para empezar, descarga el dataset desde Data Explorer entrando en la pestaña Data (Figura 5.5). Debes descargar tanto 'train.csv' como 'test.csv'.
Después de descargar los archivos, ve a DataLab. Recuerda que antes necesitas crear una cuenta. Crear una cuenta y usar DataLab es gratis.
Puedes arrastrar y soltar archivos fácilmente en el panel izquierdo del notebook (Figura 5.6).


El siguiente paso es consultar el diccionario de datos en la descripción del dataset. Te ayudará a decidir qué columnas visualizar.
- survival: Supervivencia
- pclass: Clase del billete
- sex: Sexo
- Age: Edad en años
- sibsp: Nº de hermanos/as o cónyuges a bordo del Titanic
- parch: Nº de padres/madres o hijos/as a bordo del Titanic
- ticket: Número de billete
- fare: Tarifa del pasajero
- cabin: Número de camarote
- embarked: Puerto de embarque
Importación de datos
En los notebooks de Jupyter puedes usar comandos de bash anteponiendo un signo de exclamación en la celda. Vamos a comprobar la ubicación de los archivos subidos con los comandos pwd y ls.
!pwd; ls
/work/files/workspace
notebook.ipynb test.csv train.csv
Pandas es una librería de Python para manipulación y análisis de datos. Ahora hemos eliminado las columnas Ticket, Name y PassengerId porque no aportan información numérica o categórica útil. Ya puedes ver el resto de variables que utilizaremos.
En las siguientes líneas se leen los archivos de entrenamiento y prueba con el método read_csv de Pandas. Fíjate en que las columnas Survived y PassengerId se añaden respectivamente a los dataframes de train y test. Alimentaremos el modelo por separado con las variables en columns_to_be_added_as_features y las etiquetas en la columna Survived. Pero, para simplificar el preprocesado, de momento podemos combinarlos. La variable test_df_matcher incluye también PassengerId. La usaremos para emparejar PassengerId con las predicciones del conjunto de test y generar el CSV que subiremos a Kaggle como resultado.
import pandas as pd
columns_to_be_added_as_features = ['Sex','Age','SibSp','Parch','Pclass','Fare','Embarked']
train_df = pd.read_csv('train.csv', usecols=columns_to_be_added_as_features + ['Survived'])
test_df_matcher = pd.read_csv('test.csv', usecols=columns_to_be_added_as_features + ['PassengerId'])
test_df = test_df[columns_to_be_added_as_features]
Con el método head() podemos ver las primeras 5 filas con sus nombres de columna. Puedes indicar cuántas filas iniciales quieres mostrar pasándolo como parámetro a head(). En la siguiente celda se imprime el número de filas del conjunto de entrenamiento y del de prueba, respectivamente.
print(train_df.head())

print("Number of rows in training set: {}".format(len(train_df)))
print("Number of rows in test set: {}".format(len(test_df)))
Number of rows in training set: 891 Number of rows in test set: 418
Preprocesado
Debemos convertir a tipo float los valores que usaremos como variables del modelo. Esta conversión nos permitirá realizar operaciones numéricas al normalizar los datos.
for column_title in columns_to_be_added_as_features:
if column_title in ['Embarked', "Sex"]:
continue
train_df[column_title] = pd.to_numeric(train_df[column_title], downcast="float")
test_df[column_title] = pd.to_numeric(test_df[column_title], downcast="float")
train_df["Survived"] = pd.to_numeric(train_df["Survived"], downcast="float")
El modelo necesita valores numéricos. En el siguiente fragmento convertimos cadenas en números.
train_df['Embarked'].replace('Q', 0,inplace=True)
train_df['Embarked'].replace('S', 1,inplace=True)
train_df['Embarked'].replace('C', 2,inplace=True)
test_df['Embarked'].replace('Q', 0,inplace=True)
test_df['Embarked'].replace('S', 1,inplace=True)
test_df['Embarked'].replace('C', 2,inplace=True)
train_df['Sex'].replace('male', 0,inplace=True)
train_df['Sex'].replace('female', 1,inplace=True)
test_df['Sex'].replace('male', 0,inplace=True)
test_df['Sex'].replace('female', 1,inplace=True)
print(train_df.head())

A continuación, normalizamos todas las variables, es decir, las escalamos entre 0 y 1 en este caso.
#Credit: Michael Aquilina,
#https://stackoverflow.com/questions/26414913/normalize-columns-of-pandas-data-frame
def normalize(df):
result = df.copy()
for feature_name in df.columns:
max_value = df[feature_name].max()
min_value = df[feature_name].min()
result[feature_name] = (df[feature_name] - min_value) / (max_value - min_value)
return result
train_df = normalize(train_df)
test_df = normalize(test_df)
print(train_df.head())

Como vamos a dividir el dataset en entrenamiento y validación, primero barajamos las filas para evitar agrupamientos en un solo conjunto.
#Credit: Kris, https://stackoverflow.com/questions/29576430/shuffle-dataframe-rows
train_df = train_df.sample(frac=1).reset_index(drop=True)
Todos los valores vacíos se reemplazarán por 0; elegimos esta opción para ahorrar tiempo. Aun así, puedes leer este tutorial para aprender a tratar los valores faltantes en machine learning.
train_df = train_df.fillna(0)
test_df = test_df.fillna(0)
Abajo fijamos la proporción de validación en 0.2, es decir, el 20% de los datos se usará para validar. Para dividir el dataset en entrenamiento y validación utilizamos train_test_split de Sklearn. Luego separamos variables y etiquetas como ves en las últimas 4 líneas.
validation_set_ratio = 0.2
validation_set_size = int(len(train_df)*validation_set_ratio)
training_set_size = len(train_df) - validation_set_size
print("Total set size: {}".format(len(train_df)))
print("Training set size: {}".format(training_set_size))
print("Validation set size: {}".format(validation_set_size))
from sklearn.model_selection import train_test_split
train, val = train_test_split(train_df, test_size=validation_set_ratio)
train_X = train[columns_to_be_added_as_features]
train_Label = train[['Survived']]
val_X = val[columns_to_be_added_as_features]
val_Label = val[['Survived']]
Entrenamiento
Las máquinas de vectores de soporte son modelos de aprendizaje supervisado usados para clasificación y regresión. Hemos elegido este modelo con los parámetros de abajo. Deberías probar otros modelos con distintas combinaciones de parámetros. No hace falta arrancar y parar el código cada vez que quieras modificar un parámetro o probar otro modelo; puedes automatizar el proceso. Si te interesan las Support Vector Machines, echa un vistazo al tutorial Support Vector Machines with Scikit-learn en DataCamp.
from sklearn.svm import SVC
SVM_KERNEL = "linear"
SVM_C = 10
SVM_GAMMA = 0.00001
svm_model = SVC(kernel = SVM_KERNEL, C = SVM_C, gamma = SVM_GAMMA)
svm_model.fit(train_X, train_Label)
Obtener las predicciones del conjunto de validación
En esta parte, alimentamos el modelo con las variables de validación y obtenemos las predicciones. Luego las comparamos con los valores reales. Usamos metrics.accuracy_score de Sklearn para facilitar el cálculo de la precisión. La precisión en validación es 0.799, un buen punto de partida.
from sklearn import metrics
y_pred = svm_model.predict(val_X)
print("Accuracy:",metrics.accuracy_score(val_Label, y_pred))
Accuracy: 0.7988826815642458
Obtener las predicciones del conjunto de test
Ahora pasamos a obtener las predicciones del conjunto de test real. Como no hay valores reales para test, solo conoceremos la precisión después de subir el archivo de predicciones a Kaggle.
test_pred = svm_model.predict(test_df)
Generar el DataFrame de salida
La columna PassengerId se toma del dataframe test_df_matcher. Si la devolvemos directamente, el tipo será Series. Por eso la convertimos a tipo DataFrame de Pandas. Después insertamos las predicciones del conjunto de test como segunda columna.
result = pd.DataFrame(test_df_matcher['PassengerId'])
print(result.head(10))

result.insert(1, "Survived", test_pred, True)
result["Survived"] = pd.to_numeric(result["Survived"], downcast="integer")
print(result.head(10))

Generar el archivo de salida
Por fin, ya tenemos el formato de salida listo. Como último paso, eliminamos los valores del índice pasando False al parámetro index. Ya puedes descargar el archivo generado y subirlo a Kaggle. Así conocerás la precisión en test y aparecerás en el leaderboard.
result.to_csv("out.csv", index=False)
Ahora volvemos a la página de la competición, hacemos clic en "Submit Predictions" y subimos el archivo de predicciones. A los pocos segundos obtendrás tu precisión en test (Figura 5.12).

Conclusión
En este tutorial has aprendido a analizar un dataset y a enviar tus resultados a una competición de Kaggle. Si te gustan las competiciones de ciencia de datos, puedes saber más sobre DataCamp Competitions aquí.


