Los datos abiertos de la Biblioteca Virtual Miguel de Cervantes federados en Wikidata

http://data.cervantesvirtual.com nació en el año 2015. Desde entonces hemos tenido la oportunidad de difundir nuestros avances en diferentes congresos y eventos en un contexto internacional como por ejemplo TPDL, IODC y DATeCH. También nos hemos centrado en incluir los contenidos como charlas de iniciación en diferentes instituciones con todo tipo de público, ya sea tecnológico o más enfocado a la literatura y autores clásicos.

Uno de los objetivos principales ha sido enriquecer nuestro repositorio con otras bases de datos como por ejemplo VIAF, DBpedia, Geonames y Wikidata. Paso a paso hemos ido mejorando nuestra forma de trabajo para poder ampliar los enlaces y enriquecer nuestro repositorio, de forma que facilitemos la reutilización y ampliemos el abanico de usuarios de nuestra biblioteca.

Recientemente, Wikidata incluyó nuestro http://data.cervantesvirtual.com/bvmc-lod/repositories/data en sus sistemas. Este hecho se denomina en el mundo tecnológico con el término “federado”, por lo que se suele decir que Wikidata ha federado el punto de servicio SPARQL de la Biblioteca Virtual Miguel de Cervantes (BVMC). Desde su página de puntos de acceso federados podemos comprobar cómo es posible realizar sentencias SPARQL desde Wikidata hacia la BVMC sin pasar por nuestra web.

Por ejemplo, si queremos obtener las obras de Lope de Vega debemos ejecutar una sentencia como la siguiente:

SELECT ?workLabel WHERE {
wd:Q165257 wdt:P2799 ?id
BIND(uri(concat("http://data.cervantesvirtual.com/person/", ?id)) as ?bvmcID)
SERVICE <http://data.cervantesvirtual.com/openrdf-sesame/repositories/data> {
?bvmcID <http://rdaregistry.info/Elements/a/authorOf> ?work .
?work rdfs:label ?workLabel
}
}

Os dejo el enlace para que lo podáis ejecutar el ejemplo de consulta federada directamente desde Wikidata. El identificador wd:Q165257 corresponde a Lope de Vega en Wikidata. Si queremos obtener las obras de Miguel de Cervantes tendremos que cambiar el idenficador por wd:Q5682.

Gracias a que Wikidata nos ha federado, nuestro catálogo tiene la posibilidad de ser consultado por una fuente inagotable de usuarios y aplicaciones. El origen de la BVMC no es otro que el de fomentar y facilitar el conocimiento de forma libre y para todos, que es similar al objetivo de Wikidata y su hermano Wikipedia.

¡Espero que os haya gustado y os animo a que creéis vuestras propias consultas SPARQL federadas!

 

geonames

¿Cómo usar la API de Geonames?

Si te mueves en el mundo de los datos abiertos habrás tenido que utilizar diferentes fuentes de datos para enriquecer tus información. Si es así, te sugiero que revises el repositorio geográfico de libre acceso Geonames. Como otros repositorios, dispone de diferentes librerías en diferentes lenguajes de programación para poder realizar búsquedas y trabajar con los resultados. En particular, en este artículo se utilizará la librería de Java.

En primer lugar debes crearte una cuenta y habilitar el uso de los servicios web. Geonames no permite el uso ilimitado de sus servicios y tu usuario sera indispensable para poder realizar hasta 2000 peticiones al día. En caso contrario, el servicio no funcionará.

Una vez tenemos el usuario creado, debemos crear un proyecto Java que incluya la librería. Me gusta la estructura de los proyectos Maven, pero no he conseguido localizar la librería en ningún repositorio y al final he optado por instalarla de forma local de la siguiente forma. Creamos en primer lugar la carpeta /lib/org/geonames/1.1.13/ y dentro copiamos el fichero geonames-1.1.13.jar (en su última versión) que descargaremos de la página de descargas de Geonames. A continuación añadimos el siguiente código a nuestro fichero pom.xml:

<dependency>
     <groupId>bvmc</groupId>
     <artifactId>geonames</artifactId>
     <scope>system</scope>
     <version>1.1.13</version>
     <systemPath>${basedir}/lib/org/geonames/1.1.13/geonames-1.1.13.jar</systemPath>
</dependency>

Ya tenemos disponible la librería en nuestro proyecto para poder utilizarla. A continuación simplemente tenemos que crear una clase que incluya el siguiente código:

public class GeonameService
{
private static String username = "usuario";
private static int maxResults = 5;
public ToponymSearchResult search(String query){
WebService.setUserName(username);
ToponymSearchResult searchResult = null;
if(!query.isEmpty()){
ToponymSearchCriteria searchCriteria = new ToponymSearchCriteria();
searchCriteria.setQ(query);
// configurar el tipo de resultado
//searchCriteria.setFeatureClass(FeatureClass.P);
searchCriteria.setMaxRows(maxResults);
searchCriteria.setFeatureClass(FeatureClass.P);
try {
searchResult = WebService.search(searchCriteria);
for(Toponym t: searchResult.getToponyms()){
System.out.println("PLACE matching IdGeonames: " + t.getGeoNameId() + 
" " + t.getName() + " country: " + t.getCountryName());
}
} catch (Exception e) {
System.out.println("Error Geonames webservice." + e.getMessage());
}
}
return searchResult;
}
}

La variable username debe contener el valor de vuestro usuario y simplemente es necesario crear un objeto de tipo GeonameService y llamar al método search con el valor del texto de búsqueda.

Como podéis comprobar es muy sencillo y así podéis tener un primer ejemplo de programa para detectar lugares en vuestra base de datos 🙂

¡Espero que os haya gustado!

Wikimedia_Foundation_RGB_logo_with_text.svg

¿Cuáles son las diferencias entre Wikipedia, Wikimedia y Wikidata?

Wikipedia-es-logo-black-on-white

Seguramente habéis consultado más de una vez información de la Wikipedia. En general, la mayoría de los usuarios de Internet conoce este ambicioso proyecto enfocado al conocimiento libre y público. La Wikipedia se financia únicamente con donaciones y si has entrado recientemente te habrás dado cuenta que muestran un pequeño formulario desde el cual puedes realizar pequeñas donaciones. Wikipedia no solo permite consultar, también permite a cualquier usuario crear nuevas entradas y modificar las existentes. Sin embargo, si añades información incorrecta, uno de los miles de revisores te enviará una notificación y revertirá los cambios.

Hoy en día, si tu página web aparece en la Wikipedia significa que tienes una fuente infinita de visitas y para el posicionamiento en buscadores o SEO (Search Engine Optimization) es muy importante. La Biblioteca Virtual Miguel de Cervantes es muy afortunada en este aspecto puesto que desde el inicio cuenta con numerosos enlaces que han sido añadidos por miles de usuarios y han ayudado a que nuestro proyecto reciba muchas visitas desde Wikipedia.

Llegados a este punto, ¿qué es Wikimedia? Es una fundación sin ánimo de lucro que incluye los proyectos Wikipedia, Wikcionario, Wikiquote, Wikilibros, Wikisource, Wikimedia Commons, Wikiespecies, Wikinoticias, Wikiversidad y, el más reciente, Wikidata. Os adjunto un enlace con más información que podéis consultar para conocer a fondo la Fundación Wikimedia. En particular, Wikimedia España se aloja en Valladolid, en la Agencia de Innovación y Desarrollo del Ayuntamiento, en Parque Alameda.

Wikidata logo

Recientemente la Fundación Wikimedia creó el proyecto Wikidata que es actualmente, desde nuestro punto de vista, uno de los proyectos más ambiciosos e innovadores que podemos encontrar en el mundo de los datos abiertos. Wikidata es un repositorio que almacena información estructurada y es alimentadada de forma colaborativa por usuarios y por los llamados bots o robots. La Biblioteca Virtual Miguel de Cervantes está desarrollando un papel importante en este proyecto proporcionando su repositorio semántico con miles de autores y obras. Wikidata permite realizar consultas federadas desde su punto de acceso SPARQL hacia nuestro respositorio, lo que nos da mucha fuerza para continuar con nuestros desarrollos en el mundo de los datos abiertos. Os adjunto una entrada donde se explica más en detalle este proyecto.

¡Espero que os haya gustado y ya no tengáis problemas a la hora de diferenciar cada uno de los proyectos y os animo a participar en la Wikipedia y Wikidata para ampliar el conocimiento de forma colaborativa!

 

corenlp-stanford

¿Conoces la librería CoreNLP de Stanford de procesamiento de lenguaje natural?

Desde hace unos años Stanford ha liderado el procesamiento del lenguaje natural. La BVMC se ha interesado desde siempre por esta librería y la ha puesto en práctica, por ejemplo, en el analizador sintáctico. Sin embargo, deseábamos adentrarnos un poco más en su funcionamiento y ha llegado el momento 🙂

La aplicación geosearch que algunos de vosotros conoceréis incluye enlaces a Geonames que se crearon de forma automática y la investigación fue presentada en el congreso DATeCH 2017. La desambiguación de lugares como Guadalajara en México y en España o Córdoba en Argentina y España es un claro ejemplo del procesamiento del lenguaje natural. En la investigación presentada en el congreso no se tuvo en cuenta la desambiguación y se solucionó de forma manual para no retrasarnos en la entrega del artículo. Sin embargo, ahora es el momento de detectar esas localizaciones y analizarlas más profundamente para comprobar si realmente podemos realizar una aplicación automática que funcione en un rango aceptable de acierto.

En primer lugar,  CoreNLP permite detectar localizaciones en la mención de la publicación original de nuestras obras, por ejemplo:

Madrid, por Iuan de la Cuesta, 1605

El apartado que nos interesa es el reconocedor de entidades de CoreNLP y aquí os dejo la documentación en inglés. Al empezar a revisar la documentación no encontré demasiada información al respecto y por eso hemos decidido crear este pequeño manual. En primer lugar, nos creamos un proyecto Java Maven en nuestro caso e incorporamos al fichero pom.xml las librerías correspondientes en su última versión, junto con los modelos en español:

<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.8.0</version>
<classifier>models-spanish</classifier>
</dependency>

CoreNLP nos permite configurar el idioma con el que vamos a trabajar y lo podemos configurar de la siguiente forma:

Properties props = new Properties();
props.put("annotators", "tokenize, ssplit, pos, lemma, ner");
props.setProperty("tokenize.language", "es");
props.setProperty("pos.model", "edu/stanford/nlp/models/pos-tagger/spanish/spanish-distsim.tagger");
props.setProperty("ner.model", "edu/stanford/nlp/models/ner/spanish.ancora.distsim.s512.crf.ser.gz");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);

Por defecto, CoreNLP utiliza el modelo de reconocimiento de entidades del corpus Ancora para el idioma español. Sin embargo, al hacer pruebas probablemente no obtendréis los resultados esperados porque el corpus no contempla todos los casos para vuestro contexto. Por ello, CoreNLP permite crear nuevos modelos de una forma flexible y sencilla para que puedan ser entrenados con contenido propio.

En primer lugar, debemos filtrar la información con la que queremos trabajar. En nuestro caso, utilizaremos la información en el campo lugar publicación original que podemos recoger desde nuestro punto de acceso SPARQL con el endpoint de geosearch:

SELECT DISTINCT ?p
WHERE { ?s &lt;http://data.cervantesvirtual.com/publicationStatement/#hasDescription&gt; ?p}

Obtendremos como resultado un fichero descriptions-ps-bvmc.txt con sentencias del tipo:

...
Palma de Mallorca, Hijas de Colomar, 1901
Palma de Mallorca, Hijas de Colomar, 1901
Palma de Mallorca, Hijas de Colomar, 1901
París, Librería Garnier Hermanos, 1883.
Leipzig, Romanische Studien, 1895.
Barcelona, Llibreria Millà, 1933.
Barcelona, Imprempta de Salvador Bonavía, 1908..
Barcelona, Biblioteca deLo Teatro Regional", 1898.
Barcelona, Llibrería D' Eudalt Puig, 1885.
Barcelona, Impremta de Salvador Bonavía, 1907.
México, Henrico Martínez, 1606
Barcelona, Impremta de Salvador Bonavía, 1911.
Barcelona, Antoni López ; Llibrería Espanyola, ca. 1864-1866.
Barcelona, Llibreria Espanyola de López, ca.1890.
Barcelona, Llibreria Espanyola de López, [ca. 1890].
Barcelona, Impremta de Salvador Bonavía, 1908.
...

CoreNLP además de facilitar el reconocimiento de entidades, también provee muchas más funcionalidades que nos pueden ayudar en nuestro trabajo como por ejemplo el tokenizador. Trabajar con las frases directamente es extremadamente complicado, y por ello la primera operación que debemos realizar es la tokenización y anotado de cada uno de los tokens. En primer lugar, descargamos la librería a nuestro ordenador. La descomprimimos y accedemos por consola a la ruta donde lo hemos descomprimido. A continuación, debemos tokenizar (convertir a tokens) cada una de las sentencias recogidas en el fichero descriptions-ps-bvmc.txt con el siguiente comando:

java -cp stanford-ner.jar edu.stanford.nlp.process.PTBTokenizer descriptions-ps-bvmc.txt > descriptions-ps-bvmc.tok

CoreNLP nos permite marcar cada uno de los tokens con unos valores predefinidos PERS (persona), LOC (Lugar), ORG (Organización) y O (Otro). A continuación marcamos cada uno los tokens con estos valores. Este proceso puede llevar mucho tiempo, pero para que CoreNLP funcione correctamente debemos proporcionarle una cantidad suficiente de tokens anotados. Os podéis ayudar de cualquier editor de texto y de las funciones buscar y reemplazar para trabajar más rápido. Los tokens y los valores predefinidos deben estar separados por un tabulador, en caso contrario CoreNLP no funcionará correctamente. El resultado lo almacenamos en un nuevo fichero con el nombre descriptions-ps-bvmc.tsv dentro de la carpeta de CoreNLP. Nos debe quedar algo parecido al siguiente ejemplo:

...
Impressa	O
en	O
Valencia	LOC
:	O
por	O
Gabriel	PERS
Ribas	PERS
...	O
,	O
1594	O
...

Una vez generado el fichero de tokens anotado, es necesario crear el modelo y para ello ejecutamos el siguiente comando:
java -cp stanford-ner.jar edu.stanford.nlp.ie.crf.CRFClassifier -prop locations-bvmc.prop

Donde locations-bvmc.prop es el fichero de configuración para crear el modelo:

#location of the training file
trainFile = descriptions-ps-bvmc.tsv 
#location where you would like to save (serialize to) your
#classifier; adding .gz at the end automatically gzips the file,
#making it faster and smaller
serializeTo = ner-model.ser.gz
#structure of your training file; this tells the classifier
#that the word is in column 0 and the correct answer is in
#column 1
map = word=0,answer=1
#these are the features we'd like to train with
#some are discussed below, the rest can be
#understood by looking at NERFeatureFactory
useClassFeature=true
useWord=true
useNGrams=true
#no ngrams will be included that do not contain either the
#beginning or end of the word
noMidNGrams=true
useDisjunctive=true
maxNGramLeng=6
usePrev=true
useNext=true
useSequences=true
usePrevSequences=true
maxLeft=1
#the next 4 deal with word shape features
useTypeSeqs=true
useTypeSeqs2=true
useTypeySequences=true
wordShape=chris2useLC

Tras un período de tiempo que dependerá del tamaño del fichero tsv y de las anotaciones realizadas, el modelo se habrá generado en la carpeta de CoreNLP con el nombre ner-model.ser.gz. Para poder trabajar con este nuevo modelo debemos copiarlo a nuestro proyecto a la carpeta src/main/resources:

model-proyecto-maven
model-proyecto-maven

Y a continuación configuramos el código Java para que utilice el nuevo modelo en lugar del inicial que nos provee CoreNLP:

props.setProperty("ner.model", "src/main/resources/ner-model.ser.gz");

Finalmente el código nos debe quedar de la siguiente forma:

public class NLPTest {
@Test
public void basic() {
System.out.println("Starting Stanford NLP");
Properties props = new Properties();
props.put("annotators", "tokenize, ssplit, pos, lemma, ner");
props.setProperty("tokenize.language", "es");
props.setProperty("pos.model", "edu/stanford/nlp/models/pos-tagger/spanish/spanish-distsim.tagger");
props.setProperty("ner.model", "src/main/resources/ner-model.ser.gz");
props.setProperty("ner.applyNumericClassifiers", "false");
props.setProperty("ner.useSUTime", "false");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
String[] tests =
{
"Guadalajara : Imprenta Daniel Ramírez, [1900?]",
"Guadalajara : Imp. de Ramírez, 1909",
"Guadalajara",
"[Guadalaxara? : s.n., 1669?]",
"Guadalajara : Impr. Provincial, 1884",
"Guadalajara, Tipografía de Luis Pérez Verdía, 1883",
"Guadalajara : Imprenta y Encuadernacion Provincial, 1884",
"Impresso en Guadalajara : por Pedro de Robles y Francisco de Cormellas, 1564",
"Guadalajara [Jalisco] : en la Oficina de Don José Fruto Romero, Año de 1811",
"Guadalajara, Imprenta de J. Cabrera, 1895",
"Guadalajara : Imprenta del Gobierno, a cargo de J. Santos Orozco, 1848"
};
for (String s : tests) {
Annotation document = new Annotation(s);
pipeline.annotate(document);
List<CoreMap> sentences = document.get(SentencesAnnotation.class);
for(CoreMap sentence: sentences) {
for (CoreLabel token: sentence.get(TokensAnnotation.class)) {
String word = token.get(TextAnnotation.class);
String pos = token.get(PartOfSpeechAnnotation.class);
String ne = token.get(NamedEntityTagAnnotation.class);
if(ne.equals("LOC"))
System.out.println("Lugar: " + word + " pos: " + pos + " ne:" + ne);
}
}
}
}
}

Y como resultado obtendremos por pantalla las siguiente líneas que corresponden a localizaciones, en concreto a diferentes ejemplos de Guadalajara:

Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalaxara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Jalisco pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC
Lugar: Guadalajara pos: np00000 ne:LOC

¡Espero que os haya gustado y os animo a practicar con esta librería para vuestros futuros desarrollos!

imagen premio aporta

Participa en la primera edición de los Premios Aporta de red.es

Desde la Fundación de la Biblioteca Virtual Miguel de Cervantes os aninamos a presentar vuestras propuestas para la primera edición de los Premios Aporta 2017. Promovidos por la Secretaría de Estado para la Sociedad de la Información y la Agenda Digital, Red.es y la Secretaría General de Administración Digital, tienen como objetivo la dibulgación y reconocimiento de proyectos que se han convertido en casos de éxito que faciliten la reutilización de datos abiertos como motor de transformación digital e innovación.

¿data.cervantesvirtual.com podría ser un caso de éxito de publicación y reutilización de datos abiertos? 🙂

Tenéis hasta el hasta el 12 de septiembre podrán presentar vuestras candidaturas. Os adjunto el enlace para las bases de los Premios Aporta 2017.