Linked Data: RDF, SPARQL y Question Answering systems (1)

Hoy voy a hacer un alto en el curso y voy a prepararme un poco el tema de los sistemas de pregunta respuesta y su relación con el linked data. He estado leyendo el siguiente artículo: An Introduction to Question Answering over Linked Data

Las principales diferencias entre estos sistemas de pregunta-respuesta y los buscadores clásicos tipo Google:

  • los buscadores clásicos se basan en palabras clase, mientras que los sistemas de pregunta respuesta son capaces de «entender» preguntas con estructuras lingüísticas complejas.
  • el resultado de los buscadores clásicos son un conjunto de documentos, mientras que los sistemas de pregunta-respuesta nos darán directamente la respuesta.

Algunos ejemplos de sistemas de pregunta-respuesta son Wolfram Alpha o IBM Watson (ya hablé un poquito de este sistema aquí).

El mayor escollo que tienen que salvar los sistemas de pregunta-respuesta es traducir el lenguaje natural en el que se hace la pregunta al lenguaje SPARQL, el lenguaje que se usa para acceder a los datos de los documentos RDF (los documentos en los que se basa la Web Semántica o «linked data»). En muchos casos esta traducción implica:

  • mapear las expresiones de lenguaje natural con el vocabulario que tenemos en los datos, teniendo en cuenta los errores que pueda acarrear ese mapeo
  • manejar variaciones de significado, ambigüedades, expresiones demasiado vagas, expresiones anafóricas, etc.

¿Qué es RDF (Resource Description Framework)?

Es un standard para modelar datos. Tiene 3 componentes principales: sujeto, predicado y objeto (RDF Triples). Un sujeto se relacionará con un objeto a través de un predicado. Los predicados pueden ser de muchos tipos: «is in», «lives in», «is a»… Estas relaciones forman grafos enormes con un montón de información relacionada. Esta red de nodos relacionados unos con otros por distintos tipos de predicados es lo que se conoce como ontologías.

¿De dónde vienen esos RDF triples? De la web semántica o Linked Open Data, con sitios como DBpedia (datos de la Wikipedia), GeoNames, FOAF (Firend of a Friend, para describir personas) o Dublin Core entre otros. Se estima que en el Linked Open Data Cloud existen unos 3000 repositorios con 150 billones de datos.

Los sujetos y predicados de los RDF tienen que ser URIs o IRIs ( International Resource Identifier). Estos últimos son similares a los URIs pero incluyen caracteres no sólo de ASCII.

Los grafos RDF podemos crearlos en documentos JSON o XML. También TTL.

SPARQL es el lenguaje en el que consultaremos los grafos RDF. Es un lenguaje similar a SQL

Deberes:

  • Tom Grube: fundador de Siri.inc

Día 9: Pandas

Continúo con el curso de Python intermedio para Ciencia de Datos.

DataFrame es uno de las estrucutras de datos más populares dentro de Pandas. Se trata, básicamente, de una tabla donde podemos indicar el nombre de las columnas y las filas y, si queremos, podemos importarla desde un documento CSV (comma separated values). Para importar los datos desde un CSV:

pd.read_csv('path to the file')

Al igual que las arrays de Numpy, los datos de una estructura de datos de Pandas, pueden contener elementos de distintos tipos (string, bool, etc.). Para acceder a los distintos elementos usaremos también los corchetes [].

iloc() accederá a las filas o las columnas del documento especificando el índice de esa fila o columna.

loc() accederá a las filas o las columnas del documento especificando la etiqueta de esa fila o columna.

¡Hoy he acabado este módulo! Sólo me quedan 3 más y acabo el curso!! 😀

Día 8: MatPlotLib

Ayer empecé un poquito con el curso intermedio de Python para Ciencia de Datos de DataCamp y hoy he continuado.

He acabado el primer módulo, que habla de la librería MatPlotLib. Con ella podemos crear diferentes tipos de gráficos: histogramas, scatterplot, etc. También nos enseñan cómo ponerlo bonito, cambiando los colores, los tamaños, poniendo rótulos, etc.

Continúo con el módulo dos, dedicado a los diccionarios y la librería Pandas (otra de las que están pidiendo actualmente en casi todos los puestos a los que aplico!). Básicamente, lo que hace Pandas es crear documentos tabulares con datos. Incluso podemos importarlos de un documento CSV. Creo que esto funcionará bien para hacer algunas pruebas con word2vec (creo que probaré este tutorial)

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()

Día 7: Numpy y Machine Learning

Continuamos con el último módulo de Introduction to Python, de Data Camp. Este módulo está dedicado exclusivamente a la librería de NumPy.

¿Qué he aprendido?

  • import numpy as np
  • np.array(lista) -> convertimos una lista en un array de numpy, lo que nos permitirá manipular los elementos como queramos. Vector arithmetic.
  • Ojo!
    • un array de numpy no puede contener elementos de distintos tipos (como sí pasaba con las listas)
    • los símbolos aritméticos (+, / , -, *) funcionan de manera diferente en las listas y los arrays de numpy (vectores).
      • Ej.: np.array([True, 1, 2]) + np.array([3, 4, False]) >> array([4, 5, 2])
  • Acceder a los elementos de un array de Numpy es mucho más fácil que con listas de listas en Python. Veamos cómo acceder a los elementos «a» y «c»:
# regular list of lists
x = [["a", "b"], ["c", "d"]]
[x[0][0], x[1][0]]

# numpy
import numpy as np
np_x = np.array(x)
np_x[:,0]
  • Los índices de antes de la coma, se refieren a las filas y los de después de la coma a las columnas. El «:» del ejemplo es para hacer slicing y le dice que se incluyan todas las filas.
  • Numpy nos permite realizar cálculos de estadística básicos de manera muy simple. Por ejemplo:
    • np.mean
    • np.median
    • np.corrcoef
    • np.std
import numpy as np
x = [1, 4, 8, 10, 12]
np.mean(x)
np.median(x)

Día 6: funciones, métodos y librerías en Python

Hoy voy a continuar con el módulo 3 de Introduction to Python, de DataCamp.

¿Qué he aprendido hoy?

  • Funciones: trocitos de código reusables que solucionan un problema particular. Ej.: print(), type(), max(), round(), len()…
    • sorted(lista, reverse=False): esto nos ordena los elementos de una lista. Por defecto, estarán en order normal, si los queremos al revés pondremos «reverse=True»
  • Métodos: funciones que pertenecen a un objeto (string, lista, float…).
    • métodos de strings: capitalize(), replace()…
    • métodos de floats: bit_length(), conjugate()…
    • métodos de listas: index(), count()…
fam = ['liz', 1.73, 'emma', 1.68, 'mom', 1.71, 'dad', 1.89]
fam.index('mom') # index de 'mom'
>> 4
fam.count(1.73) # cuántas veces aparece 1.73 en la lista fam
>> 1
  • Paquetes/librerías: algunas librerías útiles para Data Science son: NumPy, MatpotLib, Scikit-learn.
    • No todas las librerías están preintaladas en Python por defecto, así que tendremos que instalarlas si las queremos usar. Usaremos «pip».Una vez intalado el paquete que necesitamos, tendremos que importarlo si queremos usarlo. Ej.: import numpy / import numpy as np (simplemente para simplificar su nombre).Si solo necesitamos una función en concreto, lo explicitaremos en el código. Ej.: from numpy import array.

Hoy he tenido también una entrevista de trabajo, así que no me da tiempo a acabar los dos módulos que me quedan.

Deberes

Acabar el módulo de NumPy, que es el último, para acabar el curso de Introduction to Python.

Día 5: vuelta a los básicos

Hoy tenía muchas ganas de continuar con el siguiente módulo de «NLP fundamentals with Python«. Sin embargo, he visto que en la descripción de este curso dicen que deberías haber hecho los siguientes cursos como prerequisitos:

  • Introducción a Python
  • Python intermedio para Data Science
  • Python Data Science Toolbox 1
  • Python Data Science Toolbox 2

Vamos, que te empapes de Python y luego hagas cosas más específicas. Es cierto, que ya conozco Python (de hecho, he podido seguir bien el primer módulo), pero he decidido que esta vez voy a hacerlo bien y en orden, así que esta tarde me he puesto a hacer los cursos que son prerequisitos de este otro.

He empezado con Introduction to Python, que tiene 4 módulos:

  • Python Basics: completado. Muy muy básico, lo he hecho en unos 20 minutos. Generalidades, variables, print, tipos de datos.
  • Python Lists: completado. colecciones de valores de distintos tipos.
    • lista = [dato, dato, dato…].
    • Listas de listas.
    • Las listas en sí mismas son un tipo de dato (podemos acceder a él con type(list’s name), en concreto un compound data type.
    • Cómo acceder a los elementos de una lista: index (lista[index]) o slicing (list[start index:end index]). Ojo, el start index está incluido, pero el end index no. Si no añadimos un index de inicio, se sobreentiende que empieza desde cero. Si no añadimos el index de final, se sobreentiende que llega hasta el final (incluido).
    • Manipulación de listas (añadir, cambiar o eliminar elementos)
  • Functions and Packages
  • NumPy

La verdad es que, aunque muchas cosas ya las conocía (al menos del curso básico), está bien porque está muy orientado a Data Science, en concreto. He tardado 1 hora aprox. en completar los dos primeros módulos de Introduction to Python.

Finalmente, cotilleando un poco la web de Data Camp, he visto que en el área de community tienen también un montón de tutoriales. Además, aparte de los cursos hay también una serie de proyectos

Deberes

Acabar los módulos que me quedan de Introduction to Python para poder continuar con los otros tres también. ¡Me lo estoy pasando pipa, la verdad! 😀

Día 4: Regex y Matpotlib

Continuamos con el primer módulo del curso de NLP Fundamentals with Python de DataCamp. Primer módulo acabado! 😀

¿Qué he aprendido hoy?

  • Un poco de práctica con Regex en Python:
    • | = Or
    • () = define a group
    • [] = define specific character ranges
    • Example: (\d+|\w+) –> patrón para encontrar dígitos y palabras
    • [A-Za-z]+ = upper and lowercase English alphabet
    • [0-9] = numbers from 0 to 9
    • [A-Za-z-.]+ = upper and lowercase English alphabet, – and .
    • (a-z) = a, – and z
    • (\s+l,) = spaces or a comma
  • MATPOTLIB: es una libraría de Python que nos permite crear gráficos de distintos tipos (e incluso gráficos en 3D y animaciones).

Aquí un ejemplo:

In [1]: from matplotlib import pyplot as plt
In [2]: plt.hist([1, 5, 5, 7, 7, 7, 9])
Out[2]: (array([ 1., 0., 0., 0., 0., 2., 0., 3., 0., 1.]),
array([ 1. , 1.8, 2.6, 3.4, 4.2, 5. , 5.8, 6.6,
7.4, 8.2, 9. ]),)
In [3]: plt.show()
Este sería el gráfico que generaríamos con el código anterior. Este es el gráfico más básico, pero se podría poner mucho más bonito añadiendo algunas librerías y funcionalidades.

Otro ejemplo mezclando datos de NLP con gráficos:

In [1]: from matplotlib import pyplot as plt
In [2]: from nltk.tokenize import word_tokenize
In [3]: words = word_tokenize("This is a pretty cool tool!")
In [4]: word_lengths = [len(w) for w in words]
In [5]: plt.hist(word_lengths)
Out[5]: (array([ 2.,  0.,  1.,  0.,  0.,  0.,  3.,  0.,  0.,  1.]),
        array([ 1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5,  5. ,  5.5, 6. ]),
        <a list of 10 Patch objects>)
In [6]: plt.show()
Este el el histograma del número de palabras y letras.

Día 3: Regular Expressions & Word Tokenization

Hoy me he inscrito en Data Camp. He visto que hay algunos cursos específicos de Python con NLP. Justo lo que necesito ahora mismo. La suscripción a los cursos es de unos 33$ al mes, así que me parece razonable también.

He empezado el curso «Natural Language Processing Fundamentals with Python«. Estoy con el módulo 1, que es gratuito: Regular expressions & word tokenization. Algunas de estas cosas ya las sé, pero me ha obligado a crearme un Jupyter Notebook nuevo y empezar a trastear. Ya vale de lecturas y podcasts!

¿Qué he aprendido hoy?

REGEX con Python (siempre había trabajado con Regex en Perl)

  • El módulo de Python para expresiones regulares es «re»: import re
  • re.split: nos permite usar la expresión en REGEX como separador. Lo más común es usar el espacio como separador. Por tanto,
    • re.split(‘\s+’, ‘Split on spaces.’) => [‘Split’, ‘on’, ‘spaces.’]
  • re.findall(regex, string) => encuentra todos los casos de esa regex en el texto o string dada.
  • re.search(): el patrón que busquemos puede estar en cualquier parte del string/documento.
  • re.match(): el patrón que busquemos tiene que estar al principio del string.
    • if you need to match at the beginning of the string, or to match the entire string use match. It is faster. Otherwise use search.

TOKENIZATION con Python

  • Un módulo que podemos usar para tokenizar es NLTK.
  • Simplemente lo importamos en Python (import nltk) y dentro de él, usaremos el tokenizador: from nltk import word_tokenize
  • Lo usaremos así: word_tokenize(«Hi there!»)
  • Otros módulos de NLTK que podemos usar para tokenizar el texto:
    • sent_tokenize: separa todo el texto en frases.
    • regexp_tokenize: separa un texto o un string en base a una Regex que le indiquemos.
    • TweetTokenizer: especial para tokenizar tweets (hashtags, menciones, etc.)

Otras notas:

  • Buscar el tutorial de cómo crear un chatbot usando RASA NLU: te dice paso a paso cómo crear y entrenar tu chatbot usando Spacy así que me parece muy interesante para hacerlo como ejercicio.