Nuevos proyectos y Python Toolbox 1

Hace ya unas semanas que no escribo nada y no me gusta. Este blog me permite poner en orden mis ideas y nuevos conocimientos y, la verdad, creo que me resultaba super útil, así que voy a intentar volver a escribir con regularidad. La razón por la que he dejado de escribir estas últimas semanas ha sido que en el trabajo me han asignado un nuevo proyecto y estaba a tope.

Nuevo proyecto: creación de datasets

En este nuevo proyecto que me han asignado estoy creando automáticamente datasets para lueg entrenar un sistema de extracción de intenciones. El objetivo es saber qué está pidiendo el usuario. En concreto, me centro en intenciones en el dominio de soporte informático (IT). Por ejemplo: ¿Quiere que le cambien el portátil? ¿No puede conectarse a internet? ¿Tiene un problema con su teclado?

Pero, antes de entrenar, lo que estamos haciendo es crear un dataset de posibles preguntas que puede hacer el usuario para pedir/preguntar todas esas cosas. Para crearlo estoy usando Chatito, una herramienta de código abierto, que genera conjuntos de datos (datasets) que luego podremos usar para entrenar el sistema.

El input de Chatito son nuestros posibles patrones, es decir, las posibles frases que el usuario puede usar para plantear esos problemas/peticiones al servicio técnico. El output son una serie de documentos JSON que pueden estar en formato RASA NLU, Flair, LUIS o snips NLU. En nuestro caso, vamos a trabajar con RASA NLU, así que cacharrear con este framework está ya entre mis deberes.

Python toolbox 1

Aparte del proyecto que comento, hoy continúo mi proceso de aprendizaje con DataCamp, con el curso de Python toolbox 1. Mi objetivo es completar los 4 cursos de Python que eran requisito del curso Natural Language Processing Fundamentals with Python, también de esta misma plataforma.

Este curso está compuesto de 3 módulos. El primero está dedicado a escribir tus propias funciones. Como antes, en algunos de los módulos de los cursos anteriores, ya sé cómo se hace, pero siempre aprendo algo nuevo y más dirigido a la ciencia de datos, no en general como en otros cursos que hice en el pasado.

Qué he aprendido hoy
  • Definir una función propia con un parámetro y devolver (return) un valor (vídeo 1)
def square(value) # function header with a parameter "value". Signature of the function
    new_value = value ** 2    
    return(new_value)

valor = square(4)  ## así llamamos a la función, usando un argumento concreto, en este caso 4.
print(valor)
  • Definir una función propia con más de un parámetro (vídeo 2)
def square(value1, value2)
    new_value = value1 ** value2
    return(new_value)

valor = square(4, 2)
print(valor)
  • Primeras nociones de tuplas: Son similares a las listas ya que pueden contener distintos valores, pero son inmutables, es decir, una vez creadas no podremos cambiar sus valores. Las tuplas se construyen con los paréntesis. (Recuerdo: los diccionarios los creábamos con {} y las listas con [] )
numeros_pares = (2, 4, 6) ## creamos una tupla

a, b, c = numeros_pares ## empaquetamos cada elemento en una variable

numeros_pares[1]  ## accede al segundo elemento de la tupla
print(numeros_pares) ## los imprimirá todos en pantalla

Y, hasta aquí llegamos por hoy (50% del primer módulo hecho), que tengo que volver al proyecto!

Introduction to Python (Data Science)

He acabado el curso de Introducción a Python de Data Camp, así que voy a hacer un resumen de lo que he aprendido para poner un poco en orden mis ideas.

El curso en cuestión está dividido en cuatro módulos:

  1. Python Basics
  2. Pythons Lists
  3. Functions & Packages
  4. NumPy

Python Basics

Para empezar, nos explican cómo instalar Python en nuestro equipo y que los ficheros de Python tendrán la extensión .py

Luego, pasan ya a revisar cómo instanciar las variables (case-sensitive) y nos hablan de los tipos de datos con los que podemos trabajar: float, integer, string, boolean.

Python Lists

En este módulo entramos un poco más en detalle en los tipo de datos y cómo estos se pueden usar para crear listas, que no serían otra cosa que colecciones de valores (o datos). Una lista en Python puede contener distintos tipos de datos, no es necesario que todos sus elementos sean del mismo tipo. Un ejemplo de lista:

fam = ["liz", 1.73, "emma", 1.68]

En Python también se pueden crear listas de listas, como por ejemplo:

fam = [["liz", 1.73], 
["emma", 1.68]]

Las listas son un tipo de dato en sí mismas, así que si le preguntamos a Python, nos lo dirá:

type(fam)
>> list

Los elementos de una lista están ordenados, desde el elemento 0 (el primero) hasta el último. Para acceder a los distintos elementos usaremos los corchetes:

fam[3]
>> "emma" 
# usando la primera definición de fam, no la lista de listas
fam[-1]
>> 1.68
# si usamos un número negativo empezará por detrás

También podemos partir una lista y seleccionar sólo una parte de los elementos (slicing):

fam[1:3]
>> [1.73, "emma"]
# el último elemento no se incluye
fam[:3]
>> ["liz", 1.73, "emma"]
# desde el primer elemento hasta el tercero, no incluido
fam[1:]
>> [1.73, "emma", 1.68]
# desde el elemento con índice 1 hasta el final, último elemento incluido

Las listas se pueden manipular con algunas funciones propias. Por ejemplo, podemos cambiar uno o varios datos:

fam[2] = "maria"
fam
>> ["liz", 1.73, "maria", 1.68]
fam[:2] = ["luisa", 1.56]
fam
>> ["luisa", 1.56, "maria", 1.68]

También podemos añadir o borrar elementos:

fam + ["silvia", 1.60]
fam
>> ["luisa", 1.56, "maria", 1.68, "silvia", 1.60]
# los nuevos elementos se añadirán al final
del(fam[0])
fam
>> [1.56, "maria", 1.68, "silvia", 1.60]
# hay que tener cuidado al borrar elementos, ya que luego cambiarán los índices de los elementos que estaban en la lista.

Finalmente, nos advierten del cambio de nombre de las listas, ya que podemos liarla. Veamos el siguiente código:

x = ['a', 'b', 'c']
y = x
y[1] = 'z'
y
>> ['a', 'z', 'c'] #se ha añadido la z tal y como queríamos
x
>> ['a', 'z', 'c'] # pero cuidado, x también ha cambiado!!

# para evitar esto tendremos que hacer lo siguiente

x = ['a', 'b', 'c']
y = list(x)
y = x[:]
y[1] = 'z'
y
>> ['a', 'z', 'c']
x
>> ['a', 'b', 'c']

Functions & Packages

Una función no es más que un trozo de código que podemos reusar, normalmente para resolver una tarea concreta. Los distintos tipos de datos tienen distintas funciones predefinidas en Python.

Algunos ejemplos:

  • type() es una función predefinida que nos dará el tipo de dato de lo que esté entre paréntesis.
  • max() es una función que nos decuelve el número más alto de una lista.
  • round() es una función que redondeará un número float.

Todas las funciones nos devolverán algo cuando las llamemos y les pasemos los correspondientes argumentos (lo que va entre paréntesis), que pueden ser uno o varios. Además algunos argumentos pueden ser opcionales. Podemos ver esto en la documentación de round(), por ejemplo. Aquí vemos que, el número de dígitos será un argumento opcional.

Un método no es más que una función de un objeto concreto. Cada tipo de dato es, a su vez, un objeto de Python, por lo que cada tipo de dato tendrá métodos propios. Por ejemplo:

  • El objeto/tipo de dato string tiene asociados (entre otros muchos) los métodos capitalize() (para convertirlo a mayúsculas) o replace().
  • El objeto/tipo de dato lista tiene asociados (entre otros) los métodos index() o count().

Los paquetes o librerías es un archivo o conjuntos de archivos que se pueden utilizar para hacer una determinada tarea, más compleja que la que podemos realizar con un simple método. Normalmente, cada librería está asociada a un tipo de tarea. Por ejemplo: NLTK es una librería para tareas de procesamiento del lenguaje natural, MatPotLib es una librería para tareas de visualización, etc. Existen miles de librerías o paquetes disponibles. Mejor buscar si ya existe algo disponible antes de ponernos a picar código sin sentido!

Cada script dentro de una librería se llama módulo.

Para instalar una librería o paquete simplemente podemos utilizar «pip» desde la terminal. Una vez instalado, si lo queremos usar en nuestro programa, tendremos que importarlo:

import numpy as np 
# normalmente le pondremos un nombre más corto, para eso usamos el as np

from numpy import array

# usaremos from.. import para importaciones parciales, de solo algún módulo dentro de la librería.

# ejemplos de uso
 np.array([1, 2])

NumPy

Uno de los problemas que presentan las listas es que no se pueden hacer operaciones matemáticas con sus elementos. Esto, y el tiempo de procesamiento, nos lo soluciona la librería NumPy.

En el ejemplo vemos que si definimos la altura y el peso como simples listas y queremos operar con los distintos valores, nos dará error. Esto no ocurre si creamos unos arrays de NumPy a partir de ellas. Una ve creados los arrays de NumPy, estas listas se entederán como vectores y, por tanto, será posible operar con los distintos elementos.

In [13]: height = [1.73, 1.68, 1.71, 1.89, 1.79]
In [14]: weight = [65.4, 59.2, 63.6, 88.4, 68.7]
In [15]: weight / height ** 2
TypeError: unsupported operand type(s) for **: 'list' and 'int'

In [16]: np_height = np.array(height)
In [17]: np_weight = np.array(weight)
In [18]: np_weight / np_height ** 2
Out[18]: array([ 21.852, 20.975, 21.75 , 24.747, 21.441])

Otra diferencia con respecto a las listas es que los arrays de NumPy solo pueden contener elementos de un mismo tipo. Las listas podían estar formadas por datos de distintos tipos (strings, float, boolean…).

Al igual que las listas, los arrays de NumPy pueden ser listas de listas. Para saber qué tipo de matriz tenemos podemos usar la siguiente función:

np_array.shape
>> (2, 5)
# en este caso nos dice que nuestra matriz tendrá dos file y 5 columnas. O, lo que es lo mismo, dos vectores con 5 elementos cada uno.

Para acceder a los elementos de un array de NumPy lo tendremos más fácil que con las listas.

np_2d = np.array([[1.73, 1.68, 1.71, 1.89, 1.79],
[65.4, 59.2, 63.6, 88.4, 68.7]])

np_2d[0]
>> array([ 1.73, 1.68, 1.71, 1.89, 1.79])

np_2d[0][2]
>> 1.71

np_2d[0,2] # fila 0, columna 2
>> 1.71

np_2d[:,1:3] # todas las filas, de la columna 1 a la 3
>> array([[ 1.68, 1.71],
[ 59.2 , 63.6 ]])

np_2d[1,:] # file 1, todas las columnas
>> array([ 65.4, 59.2, 63.6, 88.4, 68.7])

Algunos cálculos de estadística básica que podremos hacer con NumPy son:

  • Media: np.mean()
  • Mediana: np.median()
  • Correlación de coeficientes (?¿): np.corrcoef()
  • Desviación estándar: np.std()