Herramientas de usuario

Herramientas del sitio


es:manual:items:generativos:web-semantica

Uso de la web semántica

Una opcion especialmente interesante, mas allá del uso de bases de datos locales, es la construccion de preguntas mediante bases de datos en repositorios de la denominada web semántica.

Para ello se ha definido la clase siette.util.corpus.WebTable con funciones especificas para construir tablas a partir de consultas SPARQL.

El mayor problema que se afronta al crear una consulta a una base de datos externa es la consistenacia de la información. No siempre se encuentran bases de datos apropiadas para su uso como preguntas. En muchos casos la información es incompleta, y en otros excesiva, dando lugar a preguntas demasiado detalladas que no es lo que se desea para la evaluación. A lo largo de los ejemplos se expondran los problemas mas frecuentes que se encuentran.

El uso de la web semantica y en general de preguntas o instancias que no son completamente fiables al 100% no siempre es adecuado, pero hay muchas aplicaciones que si lo son. En este artículo se estudia en mayor detalle las limitaciones de esta estrategia, se acotan los posibles errores en la evaluación y se establcen criterios de control de calidad.

Ejemplo 1

El siguiente código corresponde al enunciado de una pregunta generada a partir de una consulta a la Wikidata para identificar las banderas de distintos paises.

<%
String queryString = ""
+"PREFIX wd: <http://www.wikidata.org/entity/>"
+"PREFIX bd: <http://www.bigdata.com/rdf#>"
+"PREFIX wikibase: <http://wikiba.se/ontology#>"
+"PREFIX wdt: <http://www.wikidata.org/prop/direct/>"
+"select distinct ?img ?country ?countryLabel where { "
+"?country wdt:P31 wd:Q6256 . "
+"?country wdt:P41 ?img . "
+"?country wdt:P463 wd:Q1065 . " // Miembro ONU
+"SERVICE wikibase:label { bd:serviceParam wikibase:language \"es\" } ."
+"} ORDER BY ?countryLabel "
;
WebTable table = new WebTable("https://query.wikidata.org/sparql",queryString);
String[] pais = table.select();
String nombre = table.get(pais, "countryLabel" );
String img = table.get(pais, "img" );
String pattern = Table.toPattern(nombre, true, Table.LEFT) +"|"+  table.toPattern(nombre, true, Table.RIGHT);
%>
<center>
&iquest;De qu&eacute; pa&iacute;s es esta bandera? <br/>
<IMG src="<%= img %>" width='250' /><br/>
</center>

A partir de esta plantilla se obtienen preguntas como ésta:

La variable queryString contiene una cadena de caracteres con la consulta en el lenguaje SPARQL. La consulta selecciona un número indeterminado de filas con tres columnas que corresponden a los campos de la tabla, que son img, country countryLabel. La consulta se efectúa llamando al servicio de consultas de Wikidata, usando la instrucción:

 WebTable table = new WebTable("https://query.wikidata.org/sparql",queryString);

Al igual que en caso de otras tablas el método select selecciona un elemento al azar. Las variables nombre y img recogen respectivamente el nombre y la imagen de la bandera, que se ha obtenido mediante la consulta en los campos countryLabele img respectivamente.

A partir del nombre se obtiene un patrón de respuesta llamando al método toPattern. Esto es necesario porque la consulta a veces devuelve valores nominales como Republica Popular China, que requieren del patrón de respuesta {{Republica} Popular} China para poder aceptar respuestas simples como China.

La construcción de la consulta es sin duda el problema mas complejo. Si no se impone ninguna restricción la consulta de paises y banderas daria como resultado en algunos casos, paises que ya no existen (por ejemplo la Unión Sovietica), o quizás paises pequeños, en conflicto, o no reconocidos por la comunidad internacional. Para ello se debe intentar restringir la consulta, por ejemplo en esta caso se restringe a paises que sean miembros de Naciones Unidas. Si se quiere que la pregunta sea mas fácil, se puede restringir a paises con mator población, etc.

Ejemplo 2

En casos mas complejos puede combianarse la consulta a diversas funetes, de manera que se puedan construir patrones de respuesta mas completos. El siguiente código realiza tres consultas, combinando datos de DBpedia y Wikidata.

<%@page import="java.util.Set, java.util.TreeSet, siette.SIETTE, siette.util.corpus.WebTable, siette.util.Random"%>
 
<%
String text="";
String img="";
String itemLabel="";
String itemPattern="";
String labelPattern="";
String altPattern="";
 
do {
 
text="";
img="";
itemLabel="";
itemPattern="";
labelPattern="";
altPattern="";
 
 
String queryString = ""
+"PREFIX wikibase: <http://wikiba.se/ontology#> "
+"PREFIX wd: <http://www.wikidata.org/entity/> "
+"PREFIX wdt: <http://www.wikidata.org/prop/direct/> "
+"PREFIX bd: <http://www.bigdata.com/rdf#> "
+"PREFIX schema: <http://schema.org/> "
+"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
+"SELECT DISTINCT ?item ?itemLabel ?image "
+"WHERE { "
+"  ?item wdt:P106 wd:Q170790. "
+"  ?famousfor wdt:P138 ?item. "
+"  ?item wdt:P18 ?image. "
+"  ?item wdt:P570 ?date . "
+"  FILTER (?date < \"1960-2-11\"^^xsd:dateTime) "
+"  SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],es,en\"  } "
+"} "
+"ORDER BY ?item "
;
 
WebTable table = new WebTable("https://query.wikidata.org/sparql",queryString);
String[] registro = table.select();
String nombre = table.get(registro, "itemLabel");
img = table.get(registro, "image");
String item = table.get(registro, "item");
String id = item.substring(item.lastIndexOf("/")+1);
itemLabel = table.get(registro, "itemLabel");
 
 
queryString = ""
+"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
+"PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
+"PREFIX wd:   <http://www.wikidata.org/entity/> "
+"PREFIX owl:  <http://www.w3.org/2002/07/owl#> "
+"SELECT DISTINCT ?dbpediaID ?label ?depiction ?description "
+"WHERE { "
+" ?dbpediaID  owl:sameAs      wd:"+id+" ; "
+"             rdfs:label      ?label ; "
+"             rdfs:comment    ?description . "
+" FILTER ( LANG(?label) = \"es\" ) "
+" FILTER ( LANG(?description) = \"es\" ) "
+"} "
;
 
table = new WebTable("https://dbpedia.org/sparql",queryString);
registro = table.select();
String dbpediaID = table.get(registro, "dbpediaID");
String label = table.get(registro, "label");
String description = table.get(registro, "description");
 
queryString = ""
+"PREFIX wd: <http://www.wikidata.org/entity/> "
+"PREFIX skos: <http://www.w3.org/2004/02/skos/core#> "
+"SELECT DISTINCT ?altLabel "
+"WHERE { "
+" wd:"+id+" skos:altLabel ?altLabel . "
+" FILTER (lang(?altLabel) = \"en\" || lang(?altLabel) = \"es\")  "
+"} "
;
 
table = new WebTable("https://query.wikidata.org/sparql",queryString);
Set set =  table.getAlternativesSet("altLabel");
altPattern = WebTable.toPatternAny(set);
 
String[] split = itemLabel.split(" ");
for(int i=0; i<split.length-1; i++) {
    itemPattern = " {" + itemPattern + split[i] + "} "  ;
}
itemPattern += split[split.length-1]  ;
 
 
split = label.split(" ");
for(int i=0; i<split.length-1; i++) {
    labelPattern = " {" + labelPattern + split[i] + "} "  ;
}
labelPattern +=  split[split.length-1]  ;
 
description = description.replaceAll("\\([^\\(\\)]+\\)",""); // Eliminar datos de fecha, etc.
String[] d = description.split("\\.");
String primera = d[0];
int pos = primera.indexOf("fue");
if (d.length>1) { // decartar las descripciones demasiado breves
   if (pos>0) {
       text = "Fue " + primera.substring(pos+3,primera.length()) +". ";
   }
   for(int i=1; i<d.length; i++) {
       text += d[i]+". ";
   }
} 
 
Set set1 = new TreeSet();
for(String st : (Set<String>) set) {
    set1.add(WebTable.toPattern(st));
}
for(int i=0; i<itemLabel.split(" ").length; i++) {
    set1.add(itemLabel.split(" ")[i]);
}
for(int i=0; i<label.split(" ").length; i++) {
    set1.add(label.split(" ")[i]);
}
text = WebTable.toHint(text, set1, "___");
text = SIETTE.filterHTML(text);
 
 
} while ("".equals(text));
 
%>
<center> &iquest;De qu&eacute; matem&aacute;tico se trata? <br/><br/></center>
<div class="texto">
<div><img src="<%= img %>" max-width='250' style='max-width:250; width:50%; float:left; padding-right:10px; "padding-bottom:10px; '></div>
<div><%= text %></div>
</div>

Entre otras, esta plantilla gnera la siguiente instancia:

Las tres consultas permiten construir patrones diferentes, ya que hay multiples formas de escribir los nombres porpios. En el caso anterior se han construido estos tres patrones mediante el método toPattern:

{Georgi} Voronói

 {Gueorgui} Voronói
 Georgi Voronoi

El texto que describe al personaje procede de la Wikipedia pero en ocasiones contiene el nombre del personaje para hacer referencia a él. Usando el método toHint, que elimina del texto el nombre del personaje, sustituyendolo por ___

Los resultados de instanciar esta plantilla no siempre son apropiados para construir una pregunta. Un problema común por ejemplo es que la imagen no aparezca, o que no sea adecuada. En esos casos se debe recurrir al mecanismo de control de instancias.

La figura anterior muestra una instancia de la plantilla que ha sido descartada con la ayuda de la opción Previsualizar del menú de preguntas. Como puede verse la imagen seleccionada incluye ya el nombre del personaje, por lo que esta instancia no es válida. El control que aparece en la parte superior derecha se ha activado indicando que esa instancia no debe usarse. El generador de preguntas de Siette al instanciar la plantilla comprobará que no coincide con esta instancia, ni con otras que esten igualmente descartadas y procederá a generar ottra instancia.

Solución de problemas

La consulta no genera ningun registro

Uno de los problemas mas frecuentes que ocurren al utilizar este tipo de preguntas es que se realicen cambios en el otro extremo de la consulta. Por ejemplo, ciertas preguntas que se habian desarrollado en función de la DBpedia simplementa han dejado de funcionar, como ésta:

Al parecer la consulta funciona, y no da error al construir la plantilla, pero probablemente la consulta ya no devuelve ningun resultado. La solución pasa por rehacer la consulta.

Fallo al instanciar la plantilla

Otro problema típico de las consultas a la web semántica es que no se llegue a construir la plantilla, dando en la pestaña Previsualizar un error de instanciación como este:

Puede deberse a varias causas, pero un problema común es el tiempo de respuesta. Si la pregunta es compleja, o si en ese momento la conexión con el servidor no es todo lo rápida que debiera, se puede producir un error al instanciar la pregunta. En muchos casos basta con reintentar para que problema se solucione por si solo. Otra posible acción es incrementar el valor de Limite de tiempo (en segundos), que por defecto es 10, de manera que aunque la plnatilla tarde mas en instanciarse el sistema permanezca a la espera.

En el entorno de aplicación de las evaluaciones, cuando se selecciona una plantilla, lo primero que hay que hacer es instanciarla, y posteriormente se verifica que ha habido exito en esta operación, repitiendo la operación hasta 10 veces si no se consigue. Hay varios motivos por los que una pregunta puede no poderse instanciar, o instanciarse a una opción incorrecta: Por ejemplo, si la instancia ya ha aparecido anteriormente en la misma sesion, o si la instancia ha sido anulada mediante el control de instancias, o simplemente porque no se ha conseguido en el límite temporal. Si tras 10 intentos no se consigue instanciar la plantilla, se descarta, ignorando la opciónque marca el número máximo de veces que puede emplearse en una misma sesión. En ocasiones un test se basa exclusivamente en una única plantilla, si esto ocurre y la plantilla no se puede instanciar, el test dará el mensaje de No hay preguntas disponibles

es/manual/items/generativos/web-semantica.txt · Última modificación: 2021/05/27 19:20 por root

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki