Análisis de supervivencia en el RMS Titanic: Proyecto S-Titanic
Análisis de supervivencia en el RMS Titanic:
Conjuntos de datos:
- train.csv (https://github.com/LuisAlejandroSalcedo/Proyecto-S-Titanic/blob/master/train.csv): En este conjunto de datos, se encuentran la lista de pasajeros a los cuales analizaremos gráficamente. Y al final, lo utilizaremos para entrenar un modelo de aprendizaje.
- test.csv (https://github.com/LuisAlejandroSalcedo/Proyecto-S-Titanic/blob/master/test.csv): Este conjunto de datos, contiene una lista de pasajeros, a los cuales no se les a clasificado su supervivencia. Esta lista, la utilizaremos al final para determinar la supervivencia de dichos pasajeros según sus ciertas características (Sexo, edad, cabina, embarcación, entre otras) .
Representación gráfica de los datos:
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline
data_train = pd.read_csv('train.csv') # Datos de entrenamiento data_test = pd.read_csv('test.csv') # Datos de Prueba
data_train.sample(3)
Perfecto, tenemos la información ordenada en una tabla la cual nos facilitara su manipulación. Como podemos observar, a cada pasajero se le asignan ciertas características: Su respectivo ID, sobrevivió (0 para los que no, y 1 para los que sí), clase, nombre del pasajero, sexo, edad (en numero con punto decimal), entre otros.
Con estos datos, podemos representar de forma gráfica el numero de sobrevivientes según ciertas características. En este caso, las características que usare, sera el sexo y la embarcación.
Para representar de forma grafico estos datos, podemos usar librerías como matplotlib. Pero en este caso, utilizaremos una librería llamada "seaborn", la cual es muy sencilla de utilizar. Pero queda de tu parte escoger tu librería de preferencia.
Para representar datos gráficamente, existen distintas formas. Una de ellas es el diagrama de barras. La cual podemos generar con "seaborn" con un solo método:
sns.barplot(x="Embarked", y="Survived", hue="Sex", data=data_train)
Como podemos ver en el diagrama, la mayoría de pasajeros que sobrevivieron eran mujeres.
sns.pointplot(x="Pclass", y="Survived", hue="Sex", data=data_train,
palette={"male": "blue", "female": "pink"},
markers=["*", "o"], linestyles=["-", "--"])
Transformando Características:
Estas características podemos simplificarlas. Vemos que en edad hay mucha variedad. Simplificar este tipo de características nos ayudara, por ejemplo a analizar los sobreviviente menores de edad.
Para la simplificación de las características (ages, cabins, fares y name), escribiremos una función por cada simplificación. Todo nos quedaría algo así:
def simplify_ages(df): df.Age = df.Age.fillna(-0.5) bins = (-1, 0, 5, 12, 18, 25, 35, 60, 120) group_names = ['Unknown', 'Baby', 'Child', 'Teenager', 'Student', 'Young Adult', 'Adult', 'Senior'] categories = pd.cut(df.Age, bins, labels=group_names) df.Age = categories return df def simplify_cabins(df): df.Cabin = df.Cabin.fillna('N') df.Cabin = df.Cabin.apply(lambda x: x[0]) return df def simplify_fares(df): df.Fare = df.Fare.fillna(-0.5) bins = (-1, 0, 8, 15, 31, 1000) group_names = ['Unknown', '1_quartile', '2_quartile', '3_quartile', '4_quartile'] categories = pd.cut(df.Fare, bins, labels=group_names) df.Fare = categories return df def format_name(df): df['Lname'] = df.Name.apply(lambda x: x.split(' ')[0]) df['NamePrefix'] = df.Name.apply(lambda x: x.split(' ')[1]) return df def drop_features(df): return df.drop(['Ticket', 'Name', 'Embarked'], axis=1) def transform_features(df): df = simplify_ages(df) df = simplify_cabins(df) df = simplify_fares(df) df = format_name(df) df = drop_features(df) return df data_train = transform_features(data_train) data_test = transform_features(data_test) data_train.head()
Muy bien, los nombres de la funciones son muy obvias y muy predecibles. En la primera ("simplify_ages") simplificamos las edades, sustituimos números por texto. Cuando la edad es "-1" decimos que es "Unknown" (desconocido), cundo es 0 decimos que es un "baby" (un bebe), cuando es 5 decimos que es un "child" (un niño) y así sucesivamente. Las simplificaciones las he escrito en ingles por la costumbre, pero no hay problema en colocarlas en español.
Luego de crear una función para cada simplificación, declaramos la función "transform_features" la cual llama a todas las funciones anteriores y nos devuelve los datos simplificados. Al final asignamos nuevos valores a las variables "data_train" y "data_test" llamando a la función "transform_features".
Con la función "head", pandas nos mostrara las primeras columnas de los datos simplificados. Al ejecutar el código anterior, nos devolverá algo así:
La diferencia es notoria. Ahora podemos graficar estos datos simplificados. Podemos utilizar el diagrama de barras utilizado anteriormente:
sns.barplot(x="Age", y="Survived", hue="Sex", data=data_train)
De esta forma, vemos los sobrevivientes según su edad.
También podemos ver los sobrevivientes, basados en las otras características simplificadas:
sns.barplot(x="Cabin", y="Survived", hue="Sex", data=data_train)
sns.barplot(x="Fare", y="Survived", hue="Sex",data=data_train)
Preprocesamineto de datos:
from sklearn import preprocessing def encode_features(df_train, df_test): features = ['Fare', 'Cabin', 'Age', 'Sex', 'Lname', 'NamePrefix'] df_combined = pd.concat([df_train[features], df_test[features]]) for feature in features: le = preprocessing.LabelEncoder() le = le.fit(df_combined[feature]) df_train[feature] = le.transform(df_train[feature]) df_test[feature] = le.transform(df_test[feature]) return df_train, df_test data_train, data_test = encode_features(data_train, data_test) data_train.head()
El resultado del código anterior es:
Como podemos observar, todo texto ahora sera representado por números.
Perfecto, ahora lo que haremos sera dividir los datos en: Conjunto de entrenamiento y Conjunto de prueba.
En la variable x_all almacenare todas las características, menos la que queremos predecir (Si sobrevivió).
En la variable y_all almacenare la característica que queremos predecir.
from sklearn.model_selection import train_test_split X_all = data_train.drop(['Survived', 'PassengerId'], axis=1) y_all = data_train['Survived'] num_test = 0.20 X_train, X_test, y_train, y_test = train_test_split(X_all, y_all, test_size=num_test, random_state=23)
Muy bien, luego de tener nuestros datos bien distribuidos, ya podemos empezar a entrenar al algoritmo en este caso un clasificador. El clasificador que utilizaremos para este ejercicio es "RandomForest". A continuación, declarare al clasificador para luego entrenarlo:
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import make_scorer, accuracy_score
from sklearn.model_selection import GridSearchCV
# Choose the type of classifier.
clf = RandomForestClassifier()
# Choose some parameter combinations to try
parameters = {'n_estimators': [4, 6, 9],
'max_features': ['log2', 'sqrt','auto'],
'criterion': ['entropy', 'gini'],
'max_depth': [2, 3, 5, 10],
'min_samples_split': [2, 3, 5],
'min_samples_leaf': [1,5,8]
}
# Type of scoring used to compare parameter combinations
acc_scorer = make_scorer(accuracy_score)
# Run the grid search
grid_obj = GridSearchCV(clf, parameters, scoring=acc_scorer)
grid_obj = grid_obj.fit(X_train, y_train)
# Set the clf to the best combination of parameters
clf = grid_obj.best_estimator_
# Fit the best algorithm to the data.
clf.fit(X_train, y_train)
Luego, podemos que tan bien aprendio nuestro algoritmo:
predicton = clf.predict(X_test)
accuracy_score(y_test ,predicton)
Esto nos devolverá el porcentaje de las veces en las que el algoritmo acertó en sus predicciones. En este caso fue del 79%. Este numero podemos subirlo cambiando algunos valores de los parámetros del clasificador.
Por ultimo, hacemos las predicciones las cuales guardare en un archivo llamado "titanic-predictions.csv".
ids = data_test['PassengerId'] predictions = clf.predict(data_test.drop('PassengerId', axis=1)) output = pd.DataFrame({ 'PassengerId' : ids, 'Survived': predictions }) output.to_csv('titanic-predictions.csv', index = False) output.head(10)
El resultado seria algo así:
Ademas del archivo generado con todas las predicciones.
Todos los archivos mostrados en este articulo puedes encontrarlos en mi repositorio: https://github.com/LuisAlejandroSalcedo/Proyecto-S-Titanic.
Este ejercicio los hago con motivos educativos. Pero no debemos olvidar que esta tragedia, se cobra mas de mil vidas.
Mi nombre es Luis, y fue un placer compartir mis conocimientos con todos ustedes 😀
-
-
Pudiste solucionarlo?
-
Deja una respuesta
Hola, estoy aprendiendo python y he encontrado tu blog, y me ha gustado mucho. Una pregunta. Estoy intentando repetir el ejercicio tal y como lo propones y tengo dos problemas,
En primer lugar, la linea %matplotlib inline me da error.
Si comento la línea, las sentencias barplot y pointplot no producen error, pero en la salida no se ve nada.
Estoy usando python 3.6 desde sublime text y el sublime repl.
Muchas gracias y enhorabuena por tu blog.