Google+ Seguidores

domingo, 18 de febrero de 2018

StringTagger: Clasificación de Texto con Python

Hola a todos, les doy la bienvenida nuevamente a "Mi Diario Python". Mi nombre es Luis y te agradezco por estar leyendo esto :D.

En el articulo de hoy, quisiera mostrarles un proyecto en el que he estado trabajando. Lo he hecho con motivos educativos, con lo cual podremos ver las maravillas que se pueden lograr con una formula matemática y un lenguaje de programación.

StringTagger - Etiquetador de Texto:

"StringTagger" es el nombre que le he dado a este proyecto. Se trata de un modulo que implementa un clasificador bayesiano simple para la clasificación de cadenas de textos.


La analogía es muy simple, el clasificador clasificara las cadenas de texto según el numero de las palabras más frecuentes.  Lo primero que debemos hacer para poner en funcionamiento el clasificador, es entrenarlo. La forma en la que entrenamos al clasificador es dándole largos contenidos de texto, luego este los dividirá en palabras para saber cuales son las palabras más frecuentes, de esta manera a las nuevas cadenas de texto podrá clasificarlas según la frecuencia de palabras.

¿Un ejemplo? Claro, aquí lo tenemos: (clasificador_de_texto_ejemplo.py)

"""
Uso sencillo de "StringTagger" para el etiquetado (clasificación) de texto.
"""

__author__ = "Luis Salcedo" 

from StringTagger.StringClf import Classifier
from StringTagger.getPage import getTextPage

training_data = { # Datos para entrenar al clasificador
 "Ciencia":[
  'https://es.wikipedia.org/wiki/Ciencia', # Entrenamos al clasificador con paginas de wikipedia.
  'https://es.wikipedia.org/wiki/Qu%C3%ADmica'
 ],
 "Deportes":[
  'https://es.wikipedia.org/wiki/Deporte',
  'https://es.wikipedia.org/wiki/Deportes_ol%C3%ADmpicos'
 ],
 "Tecnologia":[
  'https://es.wikipedia.org/wiki/Tecnolog%C3%ADa',
  'https://es.wikipedia.org/wiki/Rob%C3%B3tica'
 ],
 
}

clf = Classifier() # Instancia del clasificador

for category,urls in training_data.items(): # Entrenamos al clasificador con el contenido de cada pagina
 for url in urls:
  clf.train(getTextPage(url),category) # El metodo "getTextPage", recive como argumento una url para extraer su texto

# Iniciamos el proceso de clasificación con el metodo "String"
# Solo le pasamos como argumento el texto que deseamos etiquetar (clasificar)
string = "Molécula de agua, dos átomos de hidrógeno unidos a uno de oxígeno."
clas = clf.String(string)
print('\n')
print("Texto: %s " % string)
print("Etiqueta del Texto: %s" % clas)


El código anterior nos muestro el uso básico de "StringTagger", como se puede apreciar, lo primero que se hace es crear un diccionario, el cual contiene el nombre de todas las categorías. Cada categoría contiene un par de url, a las cuales el método "getTextPage" extrae todo su texto y lo usa para el entrenamiento del clasificador. 

Luego de entrenar al clasificador, utilizamos el método "String" para clasificar el texto que ingrese el usuario. El método "String" de la clase "Classifier" nos devolverá el nombre de la categoría a la cual pertenezca el texto.

El resultado del ejemplo anterior seria:


Puedes descargar StringTagger y el ejemplo anterior ingresando al siguiente enlace: https://github.com/LuisAlejandroSalcedo/StringTagger-Clasificador-de-Texto.

Como se puede observar en la imagen, el script extrae todo el texto de las paginas web que les proporcionamos, para que luego este aprenda de los textos.  Luego le pasamos una cadenas de texto, para luego obtener el resultado que este caso es "Ciencia".

(Si se preguntan porque el nombre del usuario es PILAR, es por que esta no es mi PC :D)

Entre más datos, mejor. Entre más contenido podamos administrarle al clasificador, este sera más eficaz en sus clasificaciones. 

Este método puede ser usado para muchos propósitos: Clasificador de noticias, clasificador de tweets, hackeo de la CIA y del pentágono, entre otros. (Las ultimas 2 no están confirmadas, pero no perdemos nada intentándolo).

Bueno, eso es todo, creo que al mirar y experimentar con esto, podremos aprender mucho.

¿Quieres que explique la creación de StringTagger? Deja un comentario y déjamelo saber.

Te reto a mejorar esto, a que le agregues más funcionalidades y las compartas con nosotros.

Mi nombre es Luis, y fue un placer compartir mis conocimientos con todos ustedes :D.

Seguir Leyendo

viernes, 16 de febrero de 2018

Generar Tablas de Logaritmos - Matemáticas con Python

Saludos, en el presente artículo vamos a realizar un ejercicio con tablas. Concretamente vamos a crear un programa que nos genere una tabla de logaritmos, a partir de la información referente al rango numérico sobre el que queremos realizarlos y la base de tales logaritmos. Un ejemplo de ejecución de nuestro programa sería el siguiente:
En el ejemplo tenemos como nuestro programa, después de habernos dado a elegir si mostrar resultados desde el número 1 (método “A”) o mostrar los resultados correspondientes a un rango escogido por nosotros (método “B”) y de pedirnos la base de nuestros logaritmos, nos mostrará una tabla en la que en la columna izquierda, se nos muestran los números sobre los que vamos a hacer el cálculo y en la columna de la derecha el resultado de calcula sus correspondientes logaritmos.
Como es habitual, empezaremos importando los módulos y funciones que vamos a necesitar para crear nuestro programa:
Ya que de lo que se trata es de calcular logaritmos, lo primero que vamos a importar es el modulo “math”, del que, a su vez, importaremos la función existente para el cálculo de logaritmos (función “log”). Por su parte, de nuestro módulo “VALID” (del cual, hablo en este enlace: http://www.pythondiario.com/2018/01/creando-calculadoras-del-tiempo-2-el.html)
Importaremos las funciones “OK” y “ns”, que como recordaremos son las siguientes:
Finalmente importaremos “subprocess” para efectuar la habitual limpieza de pantalla tras cada ejecución.
Como ya hemos señalado, lo primero que va a hacer nuestro programa es dar al usuario la posibilidad de escoger entre ver los logaritmos correspondientes a un conjunto de números empezando por el número 1, o ver tales cálculos referidos a un rango numérico determinado por el mismo usuario. Para ello, empezaremos mostrando en pantalla, ambas posibilidades:
De ese modo, tras mostrar las dos posibilidades, (a las que a efectos de definirlas, llamaremos “A” y “B”) mostraremos un input en el que el usuario tendrá que indicar una de tales opciones, almacenándose la opción en la variable “met”. Debido a que solo queremos que la respuesta sea “A” o “B” (y ninguna otra), aplicaremos sobre este input una función (a la que hemos llamado “AB”) que asegure que la respuesta introducida sea únicamente una de las indicadas. Dicha función la habremos definido con anterioridad y será la siguiente:
Una vez establecido el modo de seleccionar los números que conformarán nuestra tabla, lo siguiente que vamos a pedirle al usuario (al ser un dato necesario para calcular nuestros logaritmos) es que nos indique la base de tal logaritmo. Dicho dato lo almacenaremos en otra variable a la que llamaremos “B”.


Pero hemos de recordar aquí, que lo que queremos es una base para el logaritmo. Esto implica que no nos vale cualquier número, ya que dicha base habrá de ser mayor de 1, ya que si intentáramos calcular el logaritmo de un número tomando como base un número igual o inferior a 1, obtendríamos errores como los que se muestran en la imagen:
Por ello, es conveniente diseñar nuestro programa de tal forma que no se pueda dar lugar a que se produzcan este tipo de errores. Por ello haremos uso de una función (a la que hemos llamado “op_val”) que se aplicará sobre el input introducido para la variable “B”. Esta función deberá verificar la idoneidad de la base introducida.
Pero junto a los logaritmos con base a un número (mayor de 1) vamos a crear nuestro programa de tal forma que pueda crear tablas de “logaritmos naturales”, los cuales, toman como base el número “e” (cuyo valor aproximado es de 271828). Para ello vamos a diseñar nuestra función verificadora (“op_val”) de modo que admita como input válido, la letra “e”. De ese modo pasamos a explicar dicha función que habremos definido con anterioridad:
Tenemos, así, una función que tomando como argumento el dato introducido para la base (“B”) empieza comprobando si el carácter introducido es “e” (en cuyo caso, devolverá dicho resultado, sin realizar ninguna comprobación más). No obstante, en el caso de que el dato introducido sea distinto de “e” (número “e”), mediante “try” intentará convertir el dato al formato de número entero (de modo de que en el caso de que no lo consiga será debido a que no se ha introducido un dato numérico, produciéndose una excepción que mostrará en pantalla un texto pidiendo la introducción de un dato adecuado (un valor numérico o el número “e”) sobre el que se volverá a aplicar la función integra desde el principio. En el caso de que la conversión haya podido realizarse con éxito (por tratarse de un valor numérico), el siguiente paso será constatar si dicho número es menor de 1 (porque aquí lo que interesa es que sea mayor que la unidad), en cuyo caso aparecerá un texto en el que se advertirá de que dicho número ha de ser mayor de 1 (aplicándose de nuevo la función desde el principio, sobre el resultado introducido en tal caso). Finalizado el proceso de verificación (habiéndose constatado que el dato introducido es mayor de 1 o “e”) el programa devolverá el dato que quedará almacenado en la variable “B” (base).
A partir de este punto empezaremos a crear la nuestra tabla. El modo en el que nuestro programa va a mostrar los resultados dependerá del método previamente escogido por el usuario (que como recordaremos se almacenaba en la variable “met”). Empezaremos introduciendo las instrucciones a ejecutar por el programa para el supuesto de que la elección hubiese sido la “A” (método “lista”):
Puesto que en este caso vamos a mostrar los resultados desde 1, lo primero que haremos será crear un variable “x” que será igual a la unidad. Por su parte, crearemos otra variable (que recibirá el nombre de “top”) la cual representará el número hasta el que queremos que se extienda la tabla (la función “OK” se encargará de verificar de que se trata, efectivamente, de un carácter numérico). A partir de este punto (y conociendo el primer y último número cuyo logaritmo se mostrará en la tabla) crearemos un ciclo el cual se irá desarrollando mientras que la variable “x” sea menor o igual al número introducido para la variable “top” (para lo que en cada ejecución del ciclo el valor de “x” tendrá que aumentar en 1). Pero, a su vez, el calculo que se va a efectuar en cada ejecución del ciclo, va a depender de la opción introducida para la base (concretamente, diferenciaremos el caso en el que la base sea el numero “e” de aquellos en que la base sea cualquier número mayor de 1).


Así, para el caso en el que se haya optado por el “logaritmo natural”, para cada ejecución del ciclo visualizaremos el valor actual de “x” (que irá cambiando con cada ejecución) y el resultado de calcular sobre dicho valor, su correspondiente logaritmo (ambos números, los separaremos mediante una secuencia de escape y un carácter de tabulación (‘\t’)):
Por su parte, para el caso del logaritmo con base en un número natural:
En este caso prácticamente lo mismo que en el caso anterior, con la salvedad que a la hora de calcular el logaritmo tendremos que dividir el logaritmo (natural) del valor actual de “x”, por el logaritmo de “B” (que como recordamos, es la base que establecimos con anterioridad).
Finalmente, habrá que hacer que “x” vaya aumentando en una unidad en cada ejecución del ciclo (y evitar caer en un bucle infinito y para ir visualizando el logaritmo de los sucesivos números). Para ello escribiremos:
Hasta aquí hemos visto el modo de generar nuestra tabla, para el supuesto en que el método de visualización escogido (“met”) fuera el de lista (empezando siempre por el 1 y hasta el límite marcado por el usuario). Pero puede suceder que deseemos establecer un rango personalizado (que no empiece necesariamente por 1).
El método que vamos a emplear para definir el rango que queremos, es el de pedir a nuestro usuario potencial, que introduzca los dos números que acotan dicho rango, separados por una coma. De ese modo, creamos una variable (a la que denominaremos “nums”) que almacenará dicho rango mediante el correspondiente input:
Sin embargo, al igual de lo que nos sucedía cuando establecíamos la base del logaritmo, no nos vale cualquier rango numérico, ya que necesitamos que dicho input cumpla tres requisitos: 1) Que se trate de valores numéricos, para que la computadora pueda trabajar con ellos. 2) Que el número de elementos introducido sea 2 (un valor de inicio y un valor final) y 3) Que ninguno de los valores sea menor de 1.
Para ello tenemos que crear una función que verifique que nuestro input cumpla esos tres requerimientos. A esta función la hemos llamado (como se ve arriba) “ran_val” la cual aplicaremos sobre el input introducido para la variable “nums”. Dicha función la habremos definido con anterioridad y será la siguiente:
Así nuestra función “ran_val” va a efectuar la comprobación del input mediante tres grandes pasos: Lo primero que hará será tomar el input (“nums”) y hacer una separación de sus elementos tomando la coma como criterio separador. De modo que mientras que la cantidad de elementos sea distinta de 2 nos aparecerá un mensaje instándonos a introducir los dos valores separados por una coma. Así, esta primera fase tiene la doble misión de comprobar si el número de valores introducidos es 2 y si el elemento separador es una coma, ya que si se usase otro elemento separador (para este caso concreto), la longitud de la lista “nums” sería 1, tal y como se ve en este ejemplo:
En la segunda fase de nuestra función “ran_val”, empleamos un ciclo “for” mediante el cual la variable “i” va tomando el valor de cada uno de los dos elementos de la lista, con los que haciendo uso de “try” va “intentando” convertirlos al formato entero de modo que si con alguno de dichos valores no consigue completar tal operación (por no ser datos numéricos) se generará un excepción que devolverá un mensaje instando a introducir solo valores numéricos.
La última fase del proceso de comprobación, es la empleada para detectar si ambos valores introducidos son mayores o iguales a 1, de modo que mientras (“while”) no se de esta condición nos aparecerá un mensaje diciendo “rango no válido”.
Nótese que cada vez que instamos al usuario a corregir su input, aplicamos sobre este, la función “ran_val”  desde el principio.
Finalmente, una vez completados todos pasos en la verificación (sin que se detecte ningún fallo en el input) la función devolverá el rango establecido.
Una vez que tenemos el rango establecido (en formato cadena) lo que haremos es pasar sus dos elementos (el situado en la posición 0 y el situado en la posición 1) al formato entero. Lo que haremos del siguiente modo:
Después de lo cual, usaremos la función “.sort()” para ordenar los valores del rango de menor a mayor. Esto último lo haremos de cara a que, nuestro programa, genere la misma lista, indistintamente de si el usuario introduce como rango (por ejemplo) “2,10” o “10,2”.
Finalmente, una vez que tenemos nuestro rango establecido correctamente, emplearemos un ciclo (“for”) en el que una variable “i” irá tomando los distintos valores existentes entre ambos valores y sobre los que se irán calculando los correspondientes logaritmos en función de la base escogida, del mismo modo que veíamos para el método “A” (en lista):
Cabe señalar que, debido a que el recorrido en el rango, excluye el último valor (tal y como se aprecia en el ejemplo siguiente), para conseguir que nuestro valor último se incluya, lo que haremos es establecer como final del rango, ese mismo valor más 1.
Y con esto ya tendríamos nuestro programa generador de tablas logarítmicas para cualquier base que queramos. Lo último que haremos será preguntar (haciendo uso de la función “ns” y la variable “conti”) si quiere crear más tablas. De modo que en el caso de que la respuesta sea negativa, finalice nuestro programa mediante la sentencia “break”. Y en caso afirmativo, se haga uso de la función “subprocess.call” que efectuará una limpieza de pantalla, dejándola lista para crear una nueva tabla logarítmica.
El código completo de este programa (“tabla_loga.py”) y del modulo “VALID”, puede verse integro en el siguiente enlace de github: https://github.com/antonioam82/Tablas.
Escrito por: Antonio Alfonso Martinez.
Seguir Leyendo

martes, 13 de febrero de 2018

Análisis de supervivencia en el RMS Titanic: Proyecto S-Titanic

Análisis de supervivencia en el RMS Titanic:

El RMS Titanic 1 fue un transatlántico británico, el mayor barco del mundo al finalizar su construcción, que se hundió en la noche del 14 a la madrugada del 15 de abril de 1912 durante su viaje inaugural desde Southampton a Nueva York. En el hundimiento del Titanic murieron 1514 personas de las 2223 que iban a bordo, lo que convierte a esta tragedia en uno de los mayores naufragios de la historia ocurridos en tiempo de paz. Construido entre 1909 y 1912 en el astillero Harland and Wolff de Belfast, el Titanic era el segundo de los tres transatlánticos que formaban la clase Olympic, propiedad de la naviera White Star Line, junto al RMS Olympic y, posteriormente, el HMHS Britannic.
A continuación, se utilizara un set de datos (train.csv y test.csv) el cual contiene un listado de los pasajeros que estuvieron abordo del Titanic para anlizar la supervivenvia de los pasajeros segun ciertas caracteristicas (Sexo, edad, cabina, embarcación, entre otras).

Ademas, utilizaremos la librería Scikit-Learn para el procesamiento de datos, y la predicción de nuevos datos sin etiquetar (Determinar la probabilidad de supervivencia de un nuevo pasajero, según nuevas categorías ingresadas) los cuales se encuentran en el conjunto de datos de prueba.
Para este ejercicio, es necesario que el lector tengo conocimientos básicos sobre el Machine learning. En el blog, pueden encontrar una serie de artículos enfocados al Machine Learning y sus fundamentos. 
Las librerias que se utilizaran a lo largo del ejercicio son: Skcikit-Learn, Numpy, Pandas y Seaborn.

Conjuntos de datos:

En el repositorio en el cual se encuentra este pequeño ejercicio (https://github.com/LuisAlejandroSalcedo/Proyecto-S-Titanic/), se encuentran dos archivos de formato CSV (Valores Separados por Coma) los cuales contienen los datos que utilizaremos en este ejercicio. Los dos archivos que contiene los datos son:

  1. 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.
  2. 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:

Perfecto, una vez que tengamos todo lo necesario, podemos comenzar.

Comencemos por importar las librerías necesarias:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

Luego de esto, procedemos a cargar nuestros datos de los archivos descargados anteriormente. Esto lo lograremos con el método "read_csv", el cual nos proporciona "pandas":

data_train = pd.read_csv('train.csv') # Datos de entrenamiento
data_test = pd.read_csv('test.csv') # Datos de Prueba

De esta manera, en las variables "data_train" y "data_test" se encontraran los datos de los respectivos archivos.

"Pandas" guarda la información de los datos csv en forma de tabla. Podemos ver un pequeño vistazo de su contenido usando el método "sample" y pasando le como argumento la cantidad de ejemplos que queremos visualizar:


data_train.sample(3)


El resultado seria:




Muy bien. También debemos tener en cuenta de que cada vez que se llama al metodo "samples", nos devolverá datos aleatorios, por ende existen pocas posibilidades de que les muestra la tabla que me dio como resultado.

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)

Out[36]:
<matplotlib.axes._subplots.AxesSubplot at 0xc12f350>



Como podemos ver en el diagrama, la mayoría de pasajeros que sobrevivieron eran mujeres.

Para generar este diagrama con "seaborn", solo debemos llamar al método "borplot" y pasarle como argumentos la información que queremos graficar.

A parte de los diagramas de barras, podemos generar otros tipos de diagramas, como el que les muestro a continuación:


sns.pointplot(x="Pclass", y="Survived", hue="Sex", data=data_train,
                 palette={"male": "blue", "female": "pink"},
                  markers=["*", "o"], linestyles=["-", "--"])

Out[37]:
<matplotlib.axes._subplots.AxesSubplot at 0xc1ce210>

Transformando Características:

Perfecto, ya hemos visto datos graficados según sus 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)

Out[39]:
<matplotlib.axes._subplots.AxesSubplot at 0xc219350>
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)

Out[40]:
<matplotlib.axes._subplots.AxesSubplot at 0xc285310>


sns.barplot(x="Fare", y="Survived", hue="Sex",data=data_train)

Out[41]:
<matplotlib.axes._subplots.AxesSubplot at 0xc2f8090>


Preprocesamineto de datos:

Muy bien, con las simplificaciones de los datos se nos hace mejor trabajar con ellos. Ye hemos graficado suficientes datos ¿No?. Los invito a que no se limiten y utilizan las otras características.

Llegamos a la parte final. Como menciona al principio, en esta parte utilizaremos el set de datos "test.csv" el cual tiene una lista de pasajeros a los cuales no se les a clasificado como vivos o muertos. Lo que haremos sera entrenar a un clasificador que mediante ciertas características de estos pasajeros, pueda determinar la posibilidad de que estos pasajeros sobrevivieran o no.

Muy bien, en esta parte estaremos utilizando métodos de Aprendizaje Automático. Sabemos que estos métodos son matemáticos y analíticos, por lo cual solo se manejan con números. Para ello usaremos métodos de preprocesamiento de datos para transformar las características de los pasajeros, a numero. Como la característica survived, la cual nos indica si un pasajero sobrevivió mediante 0 (no sobrevivió) y 1 (sí sobrevivió). Esto lo haremos con las características como: Sex, Age, LName, etc.

El preprocesamiento lo podemos lograr con la libreria scikit-learn. Lo podemos hacer de la siguiente manera:

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)

Out[29]:
0.79329608938547491

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 :D
Seguir Leyendo

Entradas más recientes

Powered by Blogger .