<jupyter_start><jupyter_text>Solución TitanicIntroducciónEn este notebook se resuelve el problema del Titanic. En específicio, se desarrollarán las siguientes etapas:Análisis de datos            Preguntas        Data wrangling        Exploratory data analysis        Conclusiones    Clasificación con Machine Learning            Pre-procesamiento de variables        Train, validation y test sets        3 modelos para clasificación        Entrenamiento        Diagnóstico        Resultados<jupyter_code># Manipulacion de datos y tensores.
import numpy as np
import pandas as pd
# Aprendizaje automatico.
import sklearn
from sklearn.model_selection import train_test_split
# Visualizaciones.
import matplotlib.pyplot as plt
from matplotlib import style
style.use("ggplot")
import seaborn as sns
# Retina command that makes things look good
%config InlineBackend.figure_format = 'retina'<jupyter_output><empty_output><jupyter_text>1. Análisis de datos Antes de aplicar Inteligencia Artificial analizaremos los datos siguiendo el proceso descrito previamente. En la primera fase, leeremos los datos y los cargaremos a una estructura de datos. Seguidamente, limpiaremos los datos utilizando estadística descriptiva para encontrar outliers y missing values. Despues, aplicaremos análisis de datos uni-variables y multi-variables con el fin de responder preguntas sobre el dataset. Finalmente, presentaremos conclusiones sobre nuestras preguntas. A. PreguntasEn esta sección:    Propondemos preguntas sobre el dataset del Titanic.     Cual es el sexo que tuvo mayor opcion de sobrevivir?.    Cual es el rango de edad que tuvo mayor opcion de sobrevivir?    Que clase social tenia mas oportunidad de sobrevivir? B. Data wranglingEn esta sección:    Cargaremos los datos a una estructura de datos    Exploraremos cada variable del dataset    Limpiaremos las variables del dataset<jupyter_code># Cargar datos
df_original = pd.read_csv("data/train.csv")
# Leer datos
df_original.head(3)<jupyter_output><empty_output><jupyter_text>Las features PassengerId, Name, Cabin, Embarked, Parch no tienen relacion con la variable de salida. Es decir, el id de identificacion de cada pasajero no decidira la muerte de un pasajero. El nombre de un pasajero tampoco interferira con su posibilidad de supervivencia. Asimismo, el numero de cabina o el puerto de abordo al barco tampoco afectan la supervivencia del pasajero. Por tanto eliminamos estas variables.<jupyter_code>df_dropped_features = df_original.drop(["PassengerId", "Name", "Cabin", "Embarked", "Parch", "Ticket"], axis = 1)
df_dropped_features.head()<jupyter_output><empty_output><jupyter_text>Antes de seguir con el analisis de datos, debemos transformar las features con valores no numericos. Estas features son Sex y Ticket. Veamos las siguientes celdas para entender la situacion.Feature Sex<jupyter_code># Veamos las clases unicas de la variable Sex.
print("Clases unicas: ", df_dropped_features["Sex"].unique())
print("Cantidad de variables unicas: ", len(df_dropped_features["Sex"].unique()))<jupyter_output><empty_output><jupyter_text>Como se puede observar, la variable de sexo esta compuesta por dos categorias o clases: male y female. Asimismo, la variable ticket esta compuesta por 681 categorias (el tipo de ticket nos sirve porque tiene correlacion con la la clase social a la cual el pasajero pertenece).Categorizacion de feature sex<jupyter_code># Categorizamos las features con el metodo get_dummies
df_categorized = pd.get_dummies(df_dropped_features)
df_categorized.head()
# Cuantas features tenemos?
print("Features:", [i for i in df_categorized.columns], "\n")
print("Cantidad total de features: ", len(df_categorized.columns))<jupyter_output><empty_output><jupyter_text>Utilizemos variables descriptivas para analizar los datos:<jupyter_code>df_categorized.describe()<jupyter_output><empty_output><jupyter_text>Conclusiones sobre la tabla    Con respecto a la cantidad de datos por feature podemos concluir que la feature Age tiene una menor cantidad de datos. Por tanto, probablemente hay valores nan. Limpieza de datos EjercicioDebemos limpiar los valores nan en la feature edad de nuestros datos. Tenemos varias opciones:    OPCION 1 Rellenar los valores nan con la media de las edades.    OPCION 2 Rellenar los valores nan con la mediana de las edades.    OPCION 3 Eliminar las filas con los valores nan.Por el momento tu trabajo es escoger una de las estrategias. Mas adelante evaluaras tus resultados al aplicar un algoritmo de machine learning para predecir el test set.<jupyter_code># ESCOJE UNA OPCION.
opcion = # LLena la variable con uno de los siguientes numeros: 1, 2, 3

# Assertions.
assert (type(opcion) == int), "La variable opcion debe ser un entero."
assert ((opcion in [1,2,3]) == True), "opcion debe tener un valor entre [1, 2, 3]"

# Local variables
df_cleaned = df_categorized.copy()

# Opciones de limpieza para valores nan.
if (opcion == 1):
    media_edad = df_categorized["Age"].mean()
    df_cleaned["Age"] = df_categorized["Age"].fillna(media_edad)
elif (opcion == 2):
    mediana_edad = df_categorized["Age"].median()
    df_cleaned["Age"] = df_categorized["Age"].fillna(mediana_edad)
elif (opcion == 3):
    df_cleaned["Age"] = df_categorized.dropna(axis = 1)<jupyter_output><empty_output><jupyter_text>C. Exploratory data analysisEn esta sección:    Responderemos a las preguntas formuladas previamente Cual es el sexo que tuvo mayor opcion de sobrevivir?La siguiente celda tiene codigo que te ayudara a graficar mas sencillamente.<jupyter_code>def plot_with_bar(values = None, title = None, xticks = None):
    # Assertions
    if (values == None):
        raise ValueError("Values no puede estar vacio.")
    if (type(values) == list) or (type(values) == tuple):
        pass
    else:
        raise TypeError("Values debe ser una lista o tupla.")
    ind = [i for i in range(len(values))]
    plt.bar(ind, values)
    plt.title(title)
    plt.xticks(ind, xticks)
    plt.show()
# Cuantos hombres y mujeres habian entre pasajeros.
male = df_cleaned.query("Sex_male == 1")
female = df_cleaned.query("Sex_female == 1")
print("Cantidad de hombres: ", male.shape[0])
print("Cantidad de mujeres: ", female.shape[0])
print("Cantidad total de pasajeros: ", df_original.shape[0])
# Plot a bar
plot_with_bar(values = [male.shape[0], female.shape[0]], 
              title = "Cantidad de pasajeros en el barco por sexo", 
              xticks = ["Hombres", "Mujeres"])
# Del numero total de mujeres, cuantas sobrevivieron y cuantas no.
females_survived = df_cleaned.query("Survived == 1 and Sex_female == 1")
females_not_survived = df_cleaned.query("Survived == 0 and Sex_female == 1")
# Del numero total de hombres, cuantos sobrevivieron y cuantos no.
males_survived = df_cleaned.query("Survived == 1 and Sex_male == 1")
males_not_survived = df_cleaned.query("Survived == 0 and Sex_male == 1")
# Print
print("Mujeres")
print("Mujeres sobrevivieron: ", females_survived.shape[0])
print("Mujeres no sobrevivieron: ", females_not_survived.shape[0])
plot_with_bar(values = [females_survived.shape[0], females_not_survived.shape[0]], 
              title = "Supervivencia de mujeres", 
              xticks = ["Sobrevivieron", "No sobrevivieron"])
print("\nHombres")
print("Hombres sobrevivieron: ", males_survived.shape[0])
print("Hombres no sobrevivieron: ", males_not_survived.shape[0])
plot_with_bar(values = [males_survived.shape[0], males_not_survived.shape[0]], 
              title = "Supervivencia de hombres", 
              xticks = ["Sobrevivieron", "No sobrevivieron"])<jupyter_output><empty_output><jupyter_text>Respuesta    Determinar la cantidad de pasajeros nos permitio concluir que hubo una mayor cantidad de hombres con respecto a mujeres en el barco.    Seguidamente obtuvimos una cantidad de 233 de 314 mujeres que sobrevivieron. Por tanto, si eras mujer tenias un 74% de probabilidad de sobrevivir.    Despues obtuvimos una cantidad de 109 de 577 hombres que sobrevivieron. Por tanto, si eras hombre tenias un 18% de probabilidad de sobrevivir.    Ademas, podemos agregar estos datos y determinar que 341 de 891 pasajeros sobrevivieron al accidente. Esto representa 38% del total de personas en el barco, menos de la mitad.  Cual es el rango de edad que tuvo mayor opcion de sobrevivir?<jupyter_code># Primero veamos el rango de edades.
df_cleaned["Age"].describe()
# Podemos observar que la edad minima es 0.42 y la edad maxima es 80. 
# Crearemos tres categorias para segmentar los pasajeros.
children = df_cleaned.query("Age < 18")
adults = df_cleaned.query("Age >= 18 and Age <= 55")
elder = df_cleaned.query("Age > 55 and Age <= 80")
# Grafiquemos los datos.
plot_with_bar(values = [children.shape[0], adults.shape[0], elder.shape[0]],
              title = "Edades por categorias",
              xticks = ["Niños", "Adultos", "3ra edad"])
# Ahora veamos la cantidad de ninos, adultos y 3ra edad que sobrevivieron.
children_survived = children.query("Survived == 1")
children_not_survived = children.query("Survived == 0")
adults_survived = adults.query("Survived == 1")
adults_not_survived = adults.query("Survived == 0")
elder_survived = elder.query("Survived == 1")
elder_not_survived = elder.query("Survived == 0")
per_ch_surv = (children_survived.shape[0] / (children_survived.shape[0] + children_not_survived.shape[0]))*100
per_ad_surv = (adults_survived.shape[0] / (adults_survived.shape[0] + adults_not_survived.shape[0]))*100
per_el_surv = (elder_survived.shape[0] / (elder_survived.shape[0] + elder_not_survived.shape[0]))*100
# Grafiquemos los datos
plot_with_bar(values = [children_survived.shape[0], children_not_survived.shape[0]],
              title = "Supervivencia de niños",
              xticks = ["Sobrevivieron", "No sobrevivieron"])
plot_with_bar(values = [adults_survived.shape[0], adults_not_survived.shape[0]],
              title = "Supervivencia de adultos",
              xticks = ["Sobrevivieron", "No sobrevivieron"])
plot_with_bar(values = [elder_survived.shape[0], elder_not_survived.shape[0]],
              title = "Supervivencia de 3ra edad",
              xticks = ["Sobrevivieron", "No sobrevivieron"])
print("Supervivencia niños: ", str(per_ch_surv)[:6])
print("Supervivencia adultos: ", str(per_ad_surv)[:6])
print("Supervivencia 3ra edad: ", per_el_surv)<jupyter_output><empty_output><jupyter_text>Respuesta    Los niños tenian un 53% porcentaje de supervivencia.    Los adultos tenian un 36% porcentaje de supervivencia.    Los 3ra eda tenian un 30% porcentaje de supervivencia.    En conclusion, los niños tenian una mayor ventaja en supervivencia.  Que clase social tenia una mayor posibilidad de supervivencia?<jupyter_code># Veamos lost tipos de clases sociales.
print("Tres tipos de clases: ", df_cleaned["Pclass"].unique())
# Veamos la distribucion de clases en el barco.
first_class = df_cleaned.query("Pclass == 1")
second_class = df_cleaned.query("Pclass == 2")
third_class = df_cleaned.query("Pclass == 3")
# Plots.
plot_with_bar(values = [first_class.shape[0], second_class.shape[0], third_class.shape[0]],
              title = "Distribucion clases sociales en los pasajeros",
              xticks = ["1ra", "2da", "3ra"])
# Ahora veamos el porcentaje de supervivencia de cada clase.
first_class_survived = first_class.query("Survived == 1")
first_class_not_survived = first_class.query("Survived == 0")
second_class_survived = second_class.query("Survived == 1")
second_class_not_survived = second_class.query("Survived == 0")
third_class_survived = third_class.query("Survived == 1")
third_class_not_survived = third_class.query("Survived == 0")
print("Supervivencia 1ra clase: ", (first_class_survived.shape[0] / (first_class_survived.shape[0] + first_class_not_survived.shape[0])))
print("Supervivencia 2da clase: ", (second_class_survived.shape[0] / (second_class_survived.shape[0] + second_class_not_survived.shape[0])))
print("Supervivencia 3ra clase: ", (third_class_survived.shape[0] / (third_class_survived.shape[0] + third_class_not_survived.shape[0])))
# Grafiquemos.
survived = (first_class_survived.shape[0], second_class_survived.shape[0], third_class_survived.shape[0])
not_survived = (first_class_not_survived.shape[0], second_class_not_survived.shape[0], third_class_not_survived.shape[0])
ind = np.arange(3)    # the x locations for the groups
width = 0.35       # the width of the bars: can also be len(x) sequence
p1 = plt.bar(ind, survived, width)
p2 = plt.bar(ind, not_survived, width, bottom=survived)
plt.ylabel("Cantidad")
plt.title("Supervivencia por clase social")
plt.xticks(ind, ("1ra clase", "2da clase", "3ra clase"))
# plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ("Sobrevivieron", "No sobrevivieron"))
plt.show()<jupyter_output><empty_output><jupyter_text>Respuesta    La tercera clase doblaba a la 2da y 1ra clase en cantidad de pasajeros.    Si eras de 1ra clase tenias un 62% de supervivencia.    Si eras de 2da clase tenias un 47% de supervivencia.    Si eras de 3ra clase tenias un 24% de supervivencia.    D. ConclusionesEn esta sección:    Presentaremos las conclusiones de nuestro estudio Las conclusiones son las respuestas a las preguntas previas.Puedes agregar mas conclusiones?     Agrega aqui tus conclusiones. 2. Clasificación con Machine Learning A. Pre-procesamiento de variables<jupyter_code># Dividimos la matriz en X y Y.
Y = df_cleaned["Survived"]
X = df_cleaned.drop("Survived", axis = 1)
print(X.shape, Y.shape)<jupyter_output><empty_output><jupyter_text>B. Train, validation y test setsEJERCICIODebes escoger el porcentaje de datos que ocupara el training set y lo mismo para el validation set. Recuerda los valores que vimos en clase.Nota: En esta ocacion solo necesitamos un train set y un validation set. El test set lo provee Kaggle.<jupyter_code># TRAIN SIZE Y VALIDATION SIZE deben sumar 1.0. 
# Por ejemplo: TRAIN_SIZE = 0.5 y VALIDATION_SIZE = 0.5
TRAIN_SIZE = # ESCOJE EL VALOR DEL TRAINING SET
VALIDATION_SIZE = # ESCOJE EL VALOR DEL VALIDATION SET
assert TRAIN_SIZE+VALIDATION_SIZE==1.0, "TRAIN SIZE y VALIDATION SIZE deben sumar 1.00"
# Training y validation set.
x_train, x_validation, y_train, y_validation = train_test_split(X, Y, test_size=TEST_SIZE, random_state=42)
print("Tamaños train set: ", x_train.shape, y_train.shape)
print("Tamaños validation set: ", x_validation.shape, y_validation.shape)<jupyter_output><empty_output><jupyter_text>C. Modelos para clasificaciónEjerciciosTu trabajo es entrenar los modelos de aprendizaje automatico evitando el overfitting y underfitting. Para lo cual analizaras la precision de tu modelo utilizando el train y el validation set. Recuerda que ambas precisiones deben estar lo mas cerca posible entre ellas para obtener un buen resultado. Random forestUtiliza la documentacion en el siguiente link para tunear los parametros de un random forest: Random forest<jupyter_code># Random forest
from sklearn.ensemble import RandomForestClassifier
randForClf = RandomForestClassifier(n_estimators = , # CAMBIA EL VALOR DE ESTE PARAMETRO
                             max_features = , # CAMBIA EL VALOR DE ESTE PARAMETRO
                             max_depth = , # CAMBIA EL VALOR DE ESTE PARAMETRO
                             min_samples_leaf = , # CAMBIA EL VALOR DE ESTE PARAMETRO
                             min_samples_split = ) # CAMBIA EL VALOR DE ESTE PARAMETRO
randForClf.fit(x_train, y_train)<jupyter_output><empty_output><jupyter_text>Utiliza la siguiente celda para debugear tu entrenamiento. Recuerda que el score del training y el validation deben estar lo mas cerca posible.<jupyter_code>print("Score en training set: ", randForClf.score(x_train, y_train))
print("Score en validation set: ", randForClf.score(x_validation, y_validation))<jupyter_output><empty_output><jupyter_text>SVMUtiliza la documentacion en el siguiente link para tunear los parametros de un SVM: SVMPuedes escoger entre los siguientes tipos de kernel:     "linear"    "rbf"    "sigmoid"<jupyter_code># SVM
from sklearn.svm import SVC
svcclf = SVC(kernel = "sigmoid") # ESCOJE EL TIPO DE KERNEL DE EN ESTE PARAMETRO
svcclf.fit(x_train, y_train)
print("Score en training set: ", svcclf.score(x_train, y_train))
print("Score en validation set: ", svcclf.score(x_validation, y_validation))<jupyter_output><empty_output><jupyter_text>AdaboostUtiliza la documentacion en el siguiente link para tunear los parametros de un Adaboost: Adaboost<jupyter_code># Adaboost
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import zero_one_loss
from sklearn.ensemble import AdaBoostClassifier
# Clasifier
treeclf = DecisionTreeClassifier(max_depth= , # ESCOJE EL MAX DEPTH
                                 min_samples_leaf= ) # ESCOJE EL MIN SAMPLES LEAF
treeclf.fit(x_train, y_train)
adareal = AdaBoostClassifier(
    base_estimator=treeclf,
    learning_rate = , # ESCOJE UNA TASA DE APRENDIZAJE
    n_estimators = , # ESCOJE UN NUMERO DE ESTIMADORES
    algorithm="SAMME.R")
adareal.fit(x_train, y_train)
print("Score en training set: ", adareal.score(x_train, y_train))
print("Score en validation set: ", adareal.score(x_validation, y_validation))<jupyter_output><empty_output><jupyter_text>F. ResultadosCuando creas que tus resultados son correctos. Prueba con el test set provisto por Kaggle. Para esto corre el codigo de las siguientes celdas. EJERCICIOEscribe tu nombre y la version de tu archivo en las siguientes variables.<jupyter_code>your_name = "Rodrigo" # ESCRIBE TU NOMBRE AQUI
your_version = "1" # ESCRIBE LA VERSION DE TU ARHIVO
# Leer datos de entrada.
df_test_set = pd.read_csv("data/test.csv")
df_passenger_id = df_test_set["PassengerId"]
# Eliminar features que no usamos.
df_test_set = df_test_set.drop(["PassengerId", "Name", "Cabin", "Embarked", "Parch", "Ticket"], axis = 1)
# Limpiar datos.
if (opcion == 1):
    df_test_set["Age"] = df_test_set["Age"].fillna(df_test_set["Age"].mean())
    df_test_set["Fare"] = df_test_set["Fare"].fillna(df_test_set["Fare"].mean())
elif (opcion == 2):
    df_test_set["Age"] = df_test_set["Age"].fillna(df_test_set["Age"].median())
    df_test_set["Fare"] = df_test_set["Fare"].fillna(df_test_set["Fare"].median())
elif (opcion == 3):
    df_test_set = df_test_set.dropna(axis = 1)
# Categorizar variables.
df_test_set = pd.get_dummies(df_test_set)
# Preprocesar datos.
x_test = df_test_set<jupyter_output><empty_output><jupyter_text>ESCRIBE EL NOMBRE DEL MODELO QUE ESCOJES PARA EL TEST SET EN LA SIGUIENTE CELDA.Opciones:    "Random forests"    "SVM"    "Adaboost"<jupyter_code># Escribe aqui el nombre de tu modelo.
MODELO_ESCOGIDO = # ESCRIBE EL MODELO EN UN STRING
# Procesar resultados del modelo
if (MODELO_ESCOGIDO == "Random forests"):
    resultados = randForClf.predict(x_test)
elif (MODELO_ESCOGIDO == "SVM"):
    resultados = svcclf.predict(x_test)
elif (MODELO_ESCOGIDO == "Adaboost"):
    resultados = adareal.predict(x_test)
else:
    print("El nombre no es valido")
# Escribir archivo de salida.
file = open("data/enviar_archivo_" + your_name + "_" + your_version + "_kaggle.csv", "w")
file.write("PassengerId,Survived\n")
for i, j in zip(df_passenger_id, resultados):
    file.write(str(i) + "," + str(j) +"\n")
file.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09470288271412218, 'fraction_numerical': 0.01113539390155063, 'mean_word_length': 5.06468917639634, 'pattern_counts': {'":': 0, '<': 76, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '502691', 'license': 'Apache-2.0', 'n_tokens_mistral': 6844, 'n_tokens_neox': 6595, 'n_words': 1913, 'path': 'Proyecto de curso Titanic/Notebook_titanic.ipynb', 'repo_name': 'widslapaz/curso_data_science_version_2_emi', 'size': '19218'}