Autor: javiermurcia

  • Razonamiento sobre Datos: Transformando Información Cruda en Conocimiento Inteligente

    Vivimos en la era del Big Data. Las empresas y organizaciones acumulan millones de registros diarios, pero tener datos guardados en una base de datos no es sinónimo de tener respuestas. Para dar el salto de la simple acumulación a la verdadera inteligencia, necesitamos aplicar el razonamiento sobre datos.

    Pero, ¿qué significa exactamente este concepto y cómo puede revolucionar la forma en que extraemos valor de nuestra información?

    ¿Qué es el Razonamiento sobre Datos?

    El razonamiento sobre datos (o inferencia semántica) es el proceso mediante el cual un sistema informático utiliza reglas lógicas y ontologías para descubrir nueva información que no estaba explícitamente guardada en la base de datos original.

    En bases de datos relacionales tradicionales (SQL), si haces una consulta, solo obtienes lo que alguien escribió previamente. Con el razonamiento lógico sobre datos estructurados en grafos de conocimiento, el sistema es capaz de deducir nuevas verdades. Es decir, por cada dato que introduces, el motor de inferencia puede generar automáticamente decenas de datos implícitos.

    Para entender el verdadero poder de esta tecnología, veamos un ejemplo a gran escala.

    De la Teoría a la Práctica: Infiriendo 14 Millones de Relaciones

    Para demostrar la capacidad del razonamiento lógico sobre datos, diseñé un proyecto de Ingeniería de Conocimiento a Gran Escala utilizando información de Wikidata.

    El objetivo no era consultar un árbol genealógico existente, sino construir una genealogía ampliada partiendo de un conjunto mínimo de datos.

    El Punto de Partida: Datos Explícitos

    Tomé una muestra de casi un millón de personas en Wikidata. La única relación de parentesco directa que utilicé fue la propiedad básica: hijo/a de.

    Un sistema tradicional se quedaría ahí. Sabría quién es el padre y quién es el hijo, pero no sabría responder a la pregunta: «¿Quiénes son primos terceros en esta base de datos?».

    La Inferencia Semántica en Acción

    Diseñé una ontología ligera y un motor de inferencia basado en cláusulas lógicas. A través de operaciones de materialización de conocimiento (usando inserciones SPARQL en cascada), enseñé al sistema a razonar.

    La lógica subyacente es sencilla para un humano, pero procesarla a esta escala requiere una arquitectura robusta:

    Si A es mujer, y A es hermana de B, y B es madre de C; entonces el sistema deduce automáticamente que A es tía de C.

    Los Resultados del Razonamiento

    Gestionando la explosión combinatoria para no saturar la memoria del servidor, el motor procesó ese millón de entidades iniciales. ¿El resultado?

    • 14.647.450 de nuevas relaciones semánticas generadas.
    • Por cada dato explícito original, el sistema infirió 14 datos implícitos.
    • Logramos deducir relaciones lejanas de hasta tercer grado de consanguinidad (más de 1.3 millones de relaciones de «primos terceros»).
    Tipo de DatoCantidad OriginalConocimiento Inferido
    Nodos (Personas)~ 1.000.000
    Relaciones Explícitas3.275.201
    Nuevas Relaciones Deducidas14.647.450
    Total de Triples en el Grafo> 40.500.000


    Pasamos de un listado plano de nacimientos a una red semántica viva y explorable.

    ¿Por qué importa el Razonamiento sobre Datos en el mundo empresarial?

    La capacidad de modelar ontologías y aplicar deducción lógica no es un mero ejercicio académico. Es una ventaja competitiva crítica para múltiples sectores:

    • Sector Legal y Financiero: Detección de conflictos de intereses corporativos, rastreo de beneficiarios reales y prevención de fraude conectando puntos que aparentemente no estaban relacionados.
    • Investigación Biomédica: Descubrimiento de relaciones ocultas entre genes, proteínas y enfermedades a partir de literatura médica dispersa.
    • Gestión de Recursos Humanos y Redes: Análisis de influencia y liderazgo dentro de grandes organizaciones corporativas.

    Los grafos de conocimiento equipados con motores de razonamiento no solo almacenan información; la entienden, la expanden y generan inteligencia estructurada.

    Lleva tus datos al siguiente nivel

    Si tu organización maneja grandes volúmenes de información fragmentada y necesitas transformar tus bases de datos estáticas en grafos de conocimiento vivos, puedo ayudarte.

    Diseño ontologías a medida, implemento modelos de inferencia escalables y desarrollo infraestructuras técnicas basadas en Inteligencia Artificial Simbólica para que tus datos empiecen a trabajar para ti.

  • RAG Semántico: Conectando Modelos de Lenguaje (LLMs) con Grafos de Conocimiento.

    La Inteligencia Artificial Generativa ha prometido revolucionar la forma en que las empresas interactúan con su información. Sin embargo, cuando las organizaciones conectan modelos como ChatGPT o Gemini a sus documentos corporativos, tropiezan con un muro peligroso: las alucinaciones.

    Si le pides a una IA estándar que cruce la normativa legal de tu empresa con el historial de un cliente, es muy probable que invente datos, mezcle conceptos o dé respuestas plausibles pero falsas. En sectores como el legal, el farmacéutico o la administración pública, un error del 5% no es un margen de mejora; es un riesgo inasumible.

    La solución a este problema no es entrenar modelos más grandes, sino cambiar la arquitectura de datos subyacente. La respuesta se llama RAG Semántico impulsado por Grafos de Conocimiento.

    ¿Qué es RAG y por qué el enfoque tradicional se queda corto?

    RAG (Retrieval-Augmented Generation o Generación Aumentada por Recuperación) es una técnica que permite a una IA buscar información en tus bases de datos privadas antes de responder.

    En el RAG tradicional, los documentos se cortan en pedazos y se guardan como «vectores» (números). Cuando el usuario hace una pregunta, el sistema busca los fragmentos de texto que más se parecen estadísticamente a la pregunta y se los da a la IA para que redacte la respuesta.

    ¿El problema? La similitud estadística no es comprensión lógica. Si le preguntas a un RAG tradicional: «¿Qué medicamentos de nuestro catálogo interactúan negativamente con el ibuprofeno?», el sistema buscará textos donde las palabras «ibuprofeno» e «interacción» estén cerca. Si el catálogo es complejo, omitirá relaciones indirectas o inventará conexiones, porque no entiende qué es un medicamento ni cómo funciona la química.

    La solución: RAG Semántico y la IA Neuro-Simbólica

    Para que una IA deje de adivinar, necesitamos darle un «cerebro lógico». Aquí es donde entran los Grafos de Conocimiento y la Web Semántica.

    En un RAG Semántico (a menudo llamado GraphRAG), no cortamos los textos a ciegas. Primero, estructuramos la información de la empresa en una ontología. Modelamos las entidades (Pacientes, Contratos, Fármacos) y sus relaciones lógicas exactas.

    De este modo, creamos un sistema de IA Neuro-Simbólica:

    1. La parte Simbólica (El Grafo): Aporta lógica estricta, determinismo y hechos comprobables mediante consultas precisas (SPARQL).
    2. La parte Neuronal (El LLM): Aporta la comprensión del lenguaje natural para interactuar con el usuario de forma fluida.

    Cuando el usuario hace la misma pregunta sobre el ibuprofeno, el LLM no busca similitudes de texto; traduce la pregunta a una consulta lógica al grafo. El grafo devuelve hechos y relaciones exactas, y el LLM simplemente los traduce de vuelta a lenguaje humano. Cero alucinaciones. Trazabilidad absoluta.

    Caso de Uso Práctico: Datos Farmacéuticos (HealthKG)

    Un ejemplo claro de la necesidad de esta precisión es mi proyecto HealthKG, un grafo del ecosistema farmacéutico español.

    En este sector, cruzar datos de la Agencia Española de Medicamentos (AEMPS) con bases de datos globales (Wikidata, DBpedia) y ontologías médicas (como ATC o DOID) es un desafío monumental si se usan bases de datos relacionales.

    Al modelar este ecosistema como un Grafo de Conocimiento, un sistema RAG semántico puede navegar por las relaciones estructuradas para inferir de forma 100% precisa interacciones, duplicidades terapéuticas y vincular fármacos con biomarcadores, respondiendo a preguntas complejas con referencias exactas a las normativas vigentes. Puedes explorar la visualización y el modelado de este ecosistema en el caso de estudio de HealthKG«).

    Beneficios del RAG Semántico para tu organización

    Implementar esta arquitectura supone un salto cualitativo enorme:

    • Trazabilidad total (Explicabilidad): Cada afirmación de la IA está vinculada a un nodo específico de tu base de datos. Si la IA afirma algo, puedes ver exactamente de qué documento y relación lógica partió.
    • Inferencia de nuevo conocimiento: El grafo puede deducir relaciones implícitas gracias a la lógica de su ontología (algo que los vectores simples no pueden hacer).
    • Actualización en tiempo real: Si cambias un dato en el grafo (ej. una ley o el precio de un producto), la IA lo asimila instantáneamente, sin necesidad de ser re-entrenada.

    Conclusión

    El futuro de la IA empresarial no pasa por modelos de lenguaje que actúen como enciclopedias que memorizan textos, sino como interfaces inteligentes que consultan Grafos de Conocimiento rigurosos. Modelar la realidad de tu empresa de forma lógica es el único camino hacia una automatización segura y fiable.

    ¿Quieres implementar un sistema de IA que entienda tus datos sin inventar respuestas? Hablemos de la arquitectura semántica de tu proyecto.

  • SPARQL explicado con ejemplos reales (y ejecutables)

    SPARQL explicado con ejemplos reales (y ejecutables)

    Si trabajas con grafos de conocimiento, sabes que SPARQL no se aprende leyendo teoría, sino viendo cómo se resuelven problemas reales.

    En este artículo voy a explicarlo con ejemplos que uso en producción sobre:

    • Wikidata.
    • Grafos propios (patrimonio, lugares, genealogías)
    • Consultas federadas reales.
    • Casos complejos (inferencias, agregaciones, grafos distribuidos)

    Además, podrás ejecutar las consultas en vivo gracias a endpoints propios basados en Apache Fuseki + YASGUI.

    ¿Qué es SPARQL (en 30 segundos)?

    SPARQL es el lenguaje de consulta para RDF, equivalente a SQL en bases de datos relacionales, pero pensado para grafos.

    La idea clave:
    No consultas tablas → consultas relaciones (tripletas)

    1. Primer ejemplo real: consultar un grafo propio

    Vamos a empezar con algo sencillo: obtener monumentos y su municipio desde un grafo de patrimonio.

    
    PREFIX monu:  <http://www.monumentos.es/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    
    SELECT DISTINCT *
    WHERE {
      ?monumento a monu:Sitio_de_interés.
      ?monumento rdfs:label ?label.
      ?monumento monu:Está_en_Municipio  ?municipio.
      ?municipio rdfs:label ?municipiolabel.
    }
    LIMIT 25
    Lenguaje del código: SQL (Structured Query Language) (sql)

    Qué está pasando aquí

    • Filtramos por tipo
    • Navegamos relaciones
    • Recuperamos etiquetas

    Ejecutar consulta en vivo: Abrir en YASGUI

    2. Consultar Wikidata con grafos: descendientes de Alfonso X

    PREFIX bd: <http://www.bigdata.com/rdf#>
    PREFIX wikibase: <http://wikiba.se/ontology#>
    PREFIX schema: <http://schema.org/>
    PREFIX wdt: <http://www.wikidata.org/prop/direct/>
    PREFIX wd: <http://www.wikidata.org/entity/>
    PREFIX gas: <http://www.bigdata.com/rdf/gas#>
    SELECT ?item ?itemLabel ?linkTo ?depth ?comment (SAMPLE (?EjemfechaNaci) AS ?fechaNaci) (SAMPLE (?pic) AS ?unica_pic)
    WHERE
    {
    SERVICE gas:service {
      gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" ;
      gas:in wd:Q47595; #Alfonso X
      gas:traversalDirection "Forward";
      gas:out ?item;
      gas:out1 ?depth;
      gas:maxIterations 3;
      gas:linkType wdt:P40; #descendiente
    }
    OPTIONAL { ?item wdt:P40 ?linkTo.}
    OPTIONAL { ?item wdt:P18 ?pic.}
    OPTIONAL { ?item wdt:P569 ?EjemfechaNaci}
    OPTIONAL{?item schema:description ?comment.
    FILTER (lang(?comment) = 'es').}
    SERVICE wikibase:label { bd:serviceParam wikibase:language"[AUTO_LANGUAGE],es,en,ar,be,bg,bn,ca,cs,da,de,el,fr,et,fa,fi,he,hi,hu,hy,id,it,ja,jv,ko,nb,nl,eo,pa,pl,pt,ro,ru,sh,sk,sr,sv,sw,te,th,tr,uk,yue,vec,vi,zh".}
    }
    GROUP BY ?item ?itemLabel ?linkTo ?unica_pic ?depth ?comment ?fechaNaci
    ORDER BY ?depth
    LIMIT 200Lenguaje del código: PHP (php)

    Qué hace esto

    • Aplica Single Source Shortest Path (SSSP)
    • Parte de Alfonso X.
    • Recorre descendientes.

    Por qué es potente: estás haciendo análisis de grafos dentro de SPARQL.

    Ejecutar consulta en vivo: Abrir demo

    Consultas federadas: unir múltiples grafos

    PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix monu:  <http://www.monumentos.es/>
    prefix lugares: <http://www.monumentos.es/lugares/>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    select (sample (?EjemplolugarActual) as ?lugarActual) ?monu ?labelMonu ?lugarHist ?labelHis ?labelActual ?point ?pointMonu ?image ?definition
    WHERE {
    ?monu monu:Estuvo_situado_en ?lugarHist.
    ?lugarHist lugares:LugHistóricoÉpoca monu:Edad_Antigua. # monu:Edad_del_Hierro
    ?lugarHist lugares:Se_refiere_a_lugar_actual ?EjemplolugarActual
      service <https://javiermurcia.tech/fuseki/tesauros-mec/> {
      ?lugarHist skos:prefLabel ?labelHis.
      ?lugarHist skos:definition  ?definition.
      FILTER (LANG (?labelHis) = 'es')
      }
      service <https://javiermurcia.tech/fuseki/lugares-espana/> {
      ?EjemplolugarActual rdfs:label ?labelActual.
      FILTER (LANG (?labelActual) = 'es')
      ?EjemplolugarActual <http://www.wikidata.org/prop/direct/P625> ?point.
      }
      service <https://javiermurcia.tech/fuseki/monumentos-espana/> {
      ?monu rdfs:label ?labelMonu.
      FILTER (LANG (?labelMonu) = 'es')
      ?monu <http://www.wikidata.org/prop/direct/P625> ?pointMonu.
      ?monu monu:Imagen ?image.
      }
    }group by ?lugarActual ?monu ?labelMonu ?lugarHist ?labelHis ?labelActual ?point ?pointMonu ?image ?definition
    limit 35Lenguaje del código: PHP (php)

    Qué está pasando

    Estás consultando varios grafos a la vez y unificando resultados en una sola query. La consulta va saltando por varios grafos hasta unificar lugares, monumentos y toponimia histórica

    Ejecutar consulta en vivo: Abrir demo

    Agregaciones: análisis de datos (estilo barroco)

    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX monu:  <http://www.monumentos.es/>
    SELECT (COUNT (?subject) as ?monu) ?lugar ?label
    WHERE {
      {
        ?subject a monu:Sitio_de_interés.
        ?subject monu:Monumento_tiene_estilo monu:Barroco.
        ?subject  monu:Está_en_Provincia ?lugar.
      }
      service <https://javiermurcia.tech/fuseki/lugares-espana/> {
        ?lugar rdfs:label ?label
        filter (lang (?label) = 'es')
      }
    }
    GROUP BY
    ?monu ?lugar  ?label
    order by desc ( ?monu)
    LIMIT 100Lenguaje del código: PHP (php)

    Aquí estás contando, agrupando y ordenando resultados: SPARQL también sirve para analítica.

    Ejecutar consulta en vivo: Abrir demo

    5. CONSTRUCT: crear nuevo conocimiento

    PREFIX monu:  <http://www.monumentos.es/>
    PREFIX lugares: <http://www.monumentos.es/lugares/>
    CONSTRUCT {
      ?nomhisto lugares:LugHistóricoÉpoca ?epoca .
    }
    WHERE {
      ?a a monu:Sitio_de_interés ;
                monu:Esta_situado_en ?b ;
                monu:Monumento_tiene_epoca ?epoca .
      SERVICE <https://javiermurcia.tech/fuseki/Lugares-Historicos> {
        ?b lugares:Tiene_nombre_histórico ?nomhisto .
      }
    }limit 20Lenguaje del código: HTML, XML (xml)

    No estás consultando datos: estás creando nuevos triples.

    Este tipo de consultas permite inferir conocimiento sin necesidad de motores OWL complejos.

    6. Caso complejo: genealogías + DBpedia

    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
    PREFIX fami: <http://www.relacionesfamiliares/>
    SELECT  ?a  ?aLabel
    (SAMPLE (?pic) AS ?aejempic) (SAMPLE (?pic2) AS ?segudoejempic)(SAMPLE (?pic3) AS ?primoejempic) (SAMPLE (?pic4) AS ?PrimotercerPic) ?ParejaPrimo ?ParejaPrimolabel ?EjemfechaNacia  ?fechaNaciParjeaAfines
    ?ParejaPrimoSegundo ?ParejaPrimoSegundolabel ?ParejaPrimoTercero  ?ParejaPrimoTercero ?ParejaPrimoTercerolabel
    WHERE {
      {
        ?c <http://purl.org/dc/terms/subject>   <http://es.dbpedia.org/resource/Categoría:Casa_de_Austria>.
        ?c rdfs:label ?aLabel.
        service <https://javiermurcia.tech/fuseki/personas-con-hijos/> {
          ?a rdfs:label ?aLabel
          filter (lang (?aLabel) = 'es')
          optional {
            ?a <http://www.wikidata.org/prop/direct/P18> ?pic
          }
          OPTIONAL {
            ?a  <http://www.wikidata.org/prop/direct/P569> ?EjemfechaNacia.
          }
          ?a fami:esParejaDe  ?ParejaPrimo .
          ?a <http://www.relacionesfamiliares/esPrimoDe>  ?ParejaPrimo.
          ?ParejaPrimo   rdfs:label ?ParejaPrimolabel.
          filter (lang (?ParejaPrimolabel) = 'es')
          OPTIONAL {
            ?ParejaPrimo <http://www.wikidata.org/prop/direct/P569> ?fechaNaciParjeaAfines.
          }
          optional {
            ?ParejaPrimo <http://www.wikidata.org/prop/direct/P18> ?pic3
          }
        }
      }
      union {
        ?c <http://purl.org/dc/terms/subject>   <http://es.dbpedia.org/resource/Categoría:Casa_de_Austria>.
        ?c rdfs:label ?aLabel.
        service <https://javiermurcia.tech/fuseki/personas-con-hijos/> {
          ?a rdfs:label ?aLabel
          filter (lang (?aLabel) = 'es')
          optional {
            ?a <http://www.wikidata.org/prop/direct/P18> ?pic
          }
          OPTIONAL {
            ?a <http://www.wikidata.org/prop/direct/P569> ?EjemfechaNacia.
          }
          ?a  fami:esParejaDe ?ParejaPrimoSegundo .
          ?a  <http://www.relacionesfamiliares/esPrimoSegundoDe>  ?ParejaPrimoSegundo.
          ?ParejaPrimoSegundo   rdfs:label ?ParejaPrimoSegundolabel.
          filter (lang (?ParejaPrimoSegundolabel) = 'es')
          OPTIONAL {
            ?ParejaPrimoSegundo <http://www.wikidata.org/prop/direct/P569> ?fechaNaciParjeaAfines.
          }
          optional {
            ?ParejaPrimoSegundo <http://www.wikidata.org/prop/direct/P18> ?pic2
          }
        }
      }
      union {
        ?c <http://purl.org/dc/terms/subject>   <http://es.dbpedia.org/resource/Categoría:Casa_de_Austria>.
        ?c rdfs:label ?aLabel.
        service <https://javiermurcia.tech/fuseki/personas-con-hijos/> {
          ?a rdfs:label ?aLabel
          filter (lang (?aLabel) = 'es')
          optional {
            ?a <http://www.wikidata.org/prop/direct/P18> ?pic
          }
          OPTIONAL {
            ?a  <http://www.wikidata.org/prop/direct/P569> ?EjemfechaNacia.
          }
          ?a fami:esParejaDe ?ParejaPrimoTercero .
          ?a <http://www.relacionesfamiliares/esPrimoTerceroDe>  ?ParejaPrimoTercero.
          ?ParejaPrimoTercero   rdfs:label ?ParejaPrimoTercerolabel.
          filter (lang (?ParejaPrimoTercerolabel) = 'es')
          OPTIONAL {
            ?ParejaPrimoTercero <http://www.wikidata.org/prop/direct/P569> ?fechaNaciParjeaAfines.
          }
          optional {
            ?ParejaPrimoTercero <http://www.wikidata.org/prop/direct/P18> ?pic4
          }
        }
      }
    }group by ?a ?aLabel ?aejempic ?segudoejempic ?primoejempic ?PrimotercerPic ?ParejaPrimo ?ParejaPrimolabel ?EjemfechaNacia ?fechaNaciParjeaAfines
    ?ParejaPrimoSegundo ?ParejaPrimoSegundolabel ?ParejaPrimoTercero ?ParejaPrimoTercerolabel
    LIMIT 100
    Lenguaje del código: PHP (php)

    En este ejemplo combinamos:

    • DBpedia (categorías Wikipedia)
    • Un grafo propio de relaciones familiares

    Detectamos relaciones como:

    • Primos.
    • Primos segundos.
    • Primos terceros.

    Esto demuestra integración semántica real entre datasets.

    Ejecutar consulta en vivo: Abrir demo

    7. Caso avanzado: análisis geoespacial + demografía

    PREFIX monu:  <http://www.monumentos.es/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix lugares: <http://www.monumentos.es/lugares/>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    SELECT ?provincia ?provinciaLabel (COUNT (?hospital) as ?Hospitales) (SAMPLE (?Ejempoblación) AS ?población)  ?resultado ?point
    WHERE {
    {
        ?provincia a lugares:Provincia;
                   rdfs:label ?provinciaLabel;
                   <http://www.wikidata.org/prop/direct/P625> ?point.
        optional {
          ?provincia  <http://www.wikidata.org/prop/direct/P1082> ?Ejempoblación
        }
        filter(lang (?provinciaLabel) = 'es')
        ?hospital a lugares:Hospital;
                  <http://www.wikidata.org/prop/direct/P131>  ?municipio.
        ?municipio lugares:Contenida_en_entidades_mayores ?provincia.
        optional {
        ?provincia lugares:Contenida_en_entidades_mayores ?CCAA.
        }
        optional {
          ?CCAA  <http://www.wikidata.org/prop/direct/P1082> ?Ejempoblación
        }
      }
      union {
        ?provincia a lugares:Provincia;
                   rdfs:label ?provinciaLabel;
                   <http://www.wikidata.org/prop/direct/P625> ?point.
        optional {
          ?provincia  <http://www.wikidata.org/prop/direct/P1082> ?Ejempoblación
        }
        filter(lang (?provinciaLabel) = 'es')
        ?hospital a lugares:Hospital;
                  <http://www.wikidata.org/prop/direct/P131>  ?algo.
        ?algo lugares:Está_contenido_en_Municipio ?municipio.
        ?municipio lugares:Esta_contenido_en_Provincia ?provincia.
        optional {
          ?provincia lugares:Contenida_en_entidades_mayores ?CCAA.
        }
        optional {
          ?CCAA  <http://www.wikidata.org/prop/direct/P1082> ?Ejempoblación
        }
      }
      union {
        ?provincia a lugares:Provincia;
                   rdfs:label
    ?provinciaLabel;
                   <http://www.wikidata.org/prop/direct/P625> ?point.
        optional {
          ?provincia  <http://www.wikidata.org/prop/direct/P1082> ?Ejempoblación
        }
        filter(lang (?provinciaLabel) = 'es')
        ?hospital a lugares:Hospital;
                  <http://www.wikidata.org/prop/direct/P131>   ?provincia.
      }
      bind ((?Ejempoblación/100000) as ?resultado)
    }group by ?provincia ?provinciaLabel ?Hospitales ?población  ?resultado ?point
    LIMIT 100Lenguaje del código: PHP (php)

    Calculamos ratios de hospitales por población usando datos geográficos y demográficos.

    Esto es analítica avanzada sobre grafos.

    Ejecutar consulta en vivo: Abrir demo

    Conclusión

    SPARQL no es solo un lenguaje de consulta:

    • Análisis de grafos.
    • Integración de datos.
    • Construcción de conocimiento.
    • Analítica avanzada.

    Su valor real aparece con casos reales, no ejemplos teóricos.

    Sobre mí

    Trabajo en el desarrollo de grafos de conocimiento, integración semántica y análisis de datos RDF.

    Puedes explorar mis demos y sus interfaces de descubrimiento aquí: Ver demos SPARQL

  • Qué son los grafos de conocimiento y por qué son importantes

    Qué son los grafos de conocimiento y por qué son importantes

    Introducción

    Vivimos en una era en la que las organizaciones acumulan enormes cantidades de datos, pero tener datos no es lo mismo que tener conocimiento.

    Aquí es donde entran los grafos de conocimiento: una tecnología capaz de conectar información, revelar relaciones ocultas y permitir nuevas formas de análisis.

    En este artículo explico qué son, cómo funcionan y por qué se están convirtiendo en una pieza clave en inteligencia artificial, análisis de datos y sistemas empresariales. Además, mostraré un ejemplo real basado en un grafo de medicamentos desarrollado a partir de datos públicos.

    ¿Qué es un grafo de conocimiento?

    Un grafo de conocimiento es una estructura que representa información mediante:

    • Entidades (por ejemplo: medicamentos, enfermedades, genes)
    • Relaciones entre esas entidades.

    Por ejemplo:

    “metformina” → trata → “diabetes”

    A diferencia de una base de datos tradicional, donde los datos se organizan en tablas, un grafo permite modelar directamente las relaciones, que es donde reside gran parte del valor.

    ¿En qué se diferencia de una base de datos tradicional?

    Las bases de datos relacionales funcionan bien cuando:

    • Los datos están claramente estructurados.
    • Las consultas son previsibles.

    Pero presentan limitaciones cuando:

    • Las relaciones son complejas.
    • Los datos provienen de múltiples fuentes.
    • Se necesita flexibilidad.

    Los grafos de conocimiento permiten:

    • Integrar datos heterogéneos.
    • Adaptarse a nuevos requisitos.
    • Realizar consultas más cercanas a cómo pensamos.

    ¿Cómo funcionan?

    Los grafos de conocimiento suelen basarse en estándares como:

    • RDF (Resource Description Framework)
    • SPARQL (lenguaje de consulta)
    • OWL (ontologías)

    Estos estándares permiten:

    • Definir entidades de forma unívoca.
    • Establecer relaciones explícitas.
    • Realizar consultas complejas e inferencias.

    Ejemplo real: un grafo de medicamentos

    Para ilustrar estas ideas, he desarrollado un grafo de conocimiento en el ámbito sanitario a partir de datos públicos de la AEMPS.

    🔧 Construcción del grafo

    El proceso incluyó:

    • Transformación de archivos XML y CSV a RDF.
    • Diseño de una ontología específica del dominio.
    • Creación de entidades como:
      • medicamentos
      • principios activos
      • enfermedades
      • interacciones
      • biomarcadores

    Además, se añadieron relaciones que no existían explícitamente en los datos originales, mediante consultas SPARQL e inferencias.

    🔗 Enriquecimiento con datos externos

    Para aumentar el valor del grafo, se realizó una vinculación con fuentes externas:

    • Wikidata (información biológica y médica)
    • DBpedia (contexto adicional)
    • Ontologías biomédicas como ATC o Disease Ontology.

    Esto permitió conectar, por ejemplo:

    • un medicamento → su principio activo
    • el principio activo → enfermedades tratadas
    • las enfermedades → procesos biológicos o genes

    🧠 Descubrimiento de relaciones

    Uno de los puntos clave fue que muchas relaciones no estaban explícitas en los datos originales.

    Mediante consultas e inferencias se pudieron construir:

    • Relaciones entre enfermedades y tratamientos.
    • Interacciones entre principios activos.
    • Conexiones con biomarcadores y genes.

    Esto transforma un conjunto de datos estático en un sistema capaz de generar conocimiento nuevo.

    📊 Resultados

    El grafo resultante incluye:

    • Más de 25.000 medicamentos.
    • Más de 3.000 principios activos.
    • Más de 20.000 enfermedades.
    • Millones de triples RDF.

    Y lo más importante:

    Permite navegar y descubrir relaciones complejas entre todos estos elementos.

    🔍 ¿Qué permite hacer este grafo?

    Por ejemplo:

    • Identificar tratamientos relacionados con una enfermedad.
    • Analizar interacciones entre medicamentos.
    • Explorar conexiones entre fármacos y procesos biológicos.
    • Navegar desde un medicamento hasta genes asociados.

    Este tipo de exploración sería extremadamente compleja con modelos tradicionales.

    ¿Por qué son importantes hoy?

    1. Integración de datos

    Permiten unificar múltiples fuentes en un solo modelo coherente.

    2. Inteligencia Artificial y RAG

    Los grafos de conocimiento son fundamentales para mejorar sistemas de IA:

    • Aportan contexto estructurado.
    • Reducen ambigüedad.
    • Mejoran la calidad de las respuestas.

    3. Descubrimiento de conocimiento

    Permiten identificar relaciones que no eran evidentes:

    • Patrones ocultos.
    • Conexiones indirectas.
    • Inferencias automáticas.

    4. Toma de decisiones

    Transforman datos en conocimiento útil para:

    • Análisis.
    • Planificación.
    • Estrategia.

    Casos de uso

    • Sanidad (medicamentos, enfermedades, genética)
    • Cultura e historia.
    • Sistemas legales.
    • Integración de datos empresariales.

    Conclusión

    Los grafos de conocimiento permiten pasar de:

    👉 datos aislados
    a
    👉 conocimiento conectado

    Y eso cambia completamente cómo entendemos y utilizamos la información.

    Si estás explorando cómo aplicar grafos de conocimiento en tu organización —ya sea para integrar datos, mejorar sistemas de IA o descubrir nuevas relaciones— puedo ayudarte a diseñar la arquitectura, ontologías y procesos necesarios.

  • Por qué tu Inteligencia Artificial necesita leer a Borges

    John Wilkins y la lengua universal

    John Wilkins (14 de febrero de 1614-19 de noviembre de 1672) fue un religioso y naturalista inglés, además del primer secretario de la Royal Society y versátil ensayista.

    Tuvo muy en mente la creación de una lengua franca. Un problema típico de la “República de las letras” donde se alternaba el uso de Latín como lengua de intercambio intelectual y las lenguas vernáculas de cada erudito.

    Desarrolló así la posibilidad de construir un lenguaje mundial artificial, una lengua filosófica, aspecto en el que se insistiría hasta finales del siglo de las Luces. Como desarrollo de esta idea fue autor de la primera lengua sintética («lengua artificial filosófica de uso universal») que dio a conocer en varios de sus libros.

    Y aunque su nombre no ha pasado a los primeros puestos de la historia del pensamiento si que llamó la atención de otro autor muy interesado en el lenguaje, sus juegos y sus límites: el escritor argentino Jorge Luis Borges, que dedicó un ensayo a una de sus obras.

    El Emporio celestial de conocimientos benévolos

    Wilkins proponía un sistema en apariencia muy simple donde dividía el universo en cuarenta categorías divisibles a su vez en especies, asignando a cada género un monosílabo de dos letras; a cada diferencia, una consonante y a cada especie, una vocal.

    Y es en este contexto donde Borges ficciona su celebérrimoEl Emporio celestial de conocimientos benévolos” una cierta enciclopedia china donde los animales se clasificarían en:

    • (a) pertenecientes al Emperador,
    • (b) embalsamados,
    • (c) amaestrados,
    • (d) lechones,
    • (e) sirenas,
    • (f) fabulosos,
    • (g) perros sueltos,
    • (h) incluidos en esta clasificación,
    • (i) que se agitan como locos,
    • (j) innumerables
    • (k) dibujados con un pincel finísimo de pelo de camello,
    • (l) etcétera,
    • (m) que acaban de romper el jarrón,
    • (n) que de lejos parecen moscas.

    A Borges le debió parecer que las las taxonomías poseían una naturaleza arbitraria, ya sea que formen un lenguaje o simplemente compongan una forma de entender y ordenar el mundo. Concluyendo que a su entender no podría haber una clasificación del universo que no fuese arbitraria y llena de conjeturas.

    Dice Borges en dicho relato: «(…) notoriamente no hay clasificación del universo que no sea arbitraria y conjetural. La razón es muy simple: no sabemos qué cosa es el universo».

    Foucault y los límites de nuestro pensamiento

    No mucho tiempo después el filósofo francés Michael Foucault le dedicaría una reflexión en el prefacio de “Las palabras y las cosas”, confesando que leer ese texto de Borges le hizo reír, pero también rompió todas las familiaridades de su pensamiento.

    En efecto esta lista nos hace sonreír por su aparente absurdo e incoherencia lógica desde nuestra perspectiva occidental moderna.

    Pero lo que Foucault nos enseña es que toda clasificación es hija de su tiempo, su cultura y su propósito. Y no existe una forma «natural» u «objetiva» de dividir el mundo en categorías. Lo que a nosotros nos parece lógico (clasificar animales por vertebrados/invertebrados), a otra cultura (o a un sistema con otro propósito) le resultaría inútil.

    El Síndrome de la «Ontología Universal»

    Cuando una empresa u organización decide montar un Grafo de Conocimiento o un sistema RAG para su IA, el primer instinto del equipo técnico es intentar modelar «toda la realidad» de la empresa de forma exhaustiva y perfecta.

    Las posibilidades epistemológicas y de representación que nos ofrecen nuestros datos y el mundo en su conjunto son inagotables, los equipos pueden perder meses discutiendo filosóficamente: «¿Un paciente es una ‘persona’, o es un ‘rol temporal’?», «¿Un contrato es un ‘documento’ o un ‘evento legal’?». Podemos intentar crear una taxonomía universal y acabar con un modelo inmanejable, costoso y que no resuelve nada.

    Ontologías orientadas a propósito

    En Ingeniería Ontológica, cuando diseño, no busco la «Verdad absoluta», sino la «Utilidad operativa». Una ontología solo debe contener los conceptos y relaciones estrictamente necesarios para responder a las preguntas de negocio que la organización necesita resolver.

    Una ontología debe diseñarse teniendo en cuenta:

    • Los objetivos del sistema.
    • Los tipos de consultas que se quieren realizar.
    • Los procesos que debe soportar.
    • Las relaciones que se quieren descubrir.
    • Las inferencias que se esperan conseguir.

    Por ejemplo, un sistema sanitario puede organizar medicamentos según:

    • Principios activos.
    • Indicaciones terapéuticas.
    • Regulación.
    • Interacciones.

    Cada enfoque produce un modelo diferente.

    Los grafos permiten:

    • Múltiples relaciones simultáneas.
    • Diferentes perspectivas sobre las mismas entidades
    • Extender el modelo sin romper la estructura.

    Conclusiones

    La clasificación de Borges parece absurda porque no compartimos su sistema de referencia.

    Pero nos recuerda algo importante:

    Toda taxonomía es una forma de ordenar el mundo según ciertos criterios.


    Cuando una organización diseña una ontología o un grafo de conocimiento debería preguntarse:

    • Qué preguntas quiere poder responder
    • Qué relaciones son relevantes.
    • Qué decisiones necesita apoyar.

    Solo entonces la clasificación deja de ser arbitraria y se convierte en una herramienta para generar conocimiento.

    Y en ingeniería del conocimiento esos criterios deben ser explícitos y conscientes.

    La belleza y potencia de la Web Semántica (RDF/OWL) es su flexibilidad. Permite que diferentes departamentos tengan «vistas» distintas del mismo mundo, integradas en un solo grafo.

    Diseñar la arquitectura de datos de una organización requiere tanto de rigor técnico como de visión filosófica para entender el negocio. Si tu empresa está luchando por conectar sus silos de información sin perderse en el intento de cartografiar el universo entero, hablemos.

  • HealthKG: Unificando el Nomenclátor de la AEMPS y el Conocimiento Biológico en un Grafo Semántico

    De archivos XML aislados a un ecosistema de datos sanitarios interoperables con RAG y Análisis Predictivo

    Los datos de medicamentos existen, son públicos y están bien documentados… pero están fragmentados, no están enlazados y no permiten razonamiento ni exploración semántica real.
    Este proyecto aborda ese problema transformando el Nomenclátor oficial de la AEMPS en un grafo de conocimiento sanitario interconectado con ontologías biomédicas internacionales.

    La información sanitaria pública es vasta pero fragmentada. La Agencia Española de Medicamentos (AEMPS) ofrece datos cruciales en XML y Excel; Wikidata y DBpedia poseen el contexto biológico; y las ontologías como ATC o DOID (Human Disease Ontology) estructuran el conocimiento médico. El problema es que estos mundos no se hablan entre sí.

    HealthKG nace con un objetivo: romper estos silos. Es una arquitectura de conocimiento que ingesta, normaliza y vincula estas fuentes para permitir preguntas complejas como: «¿Qué principios activos aprobados en España interactúan con este gen y qué enfermedades tratan según la literatura internacional?»

    Transformación de datos institucionales a Knowledge Graph


    El primer desafío fue transformar los diccionarios XML de la AEMPS (Nomenclátor) y varios archivos en .xls de facturación y medicamentos en tripletas RDF estandarizadas.

    Según define la propia AEMPS:

    «El Nomenclátor de prescripción es una base de datos de medicamentos diseñada para proporcionar información básica de prescripción a los sistemas de información asistenciales.»

    y

    «El Nomenclátor de prescripción incluye para todos los medicamentos autorizados y comercializados, financiados y no financiados, los datos relativos a su identificación e información técnica (a título informativo contiene también información de medicamentos suspendidos, revocados o que han dejado de estar comercializados desde mayo de 2013).»

    El Nomenclátor no modela explícitamente relaciones semánticas entre medicamentos, principios activos y efectos. Este proyecto convierte relaciones implícitas en entidades y propiedades explícitas, habilitando razonamiento y navegación.

    Stack Tecnológico:

    • RML (RDF Mapping Language): Para mapear estructuras XML complejas (prescripciones) a nuestra ontología.
    • Tarql: Para la conversión ágil de archivos Excel/CSV.
    • Apache Jena Fuseki: Como Triple Store para orquestar el grafo.

    Diseño Ontológico y Modelado

    Partiendo de los diccionarios ya creados por el Ministerio y de las propias necesidades del futuro grafo creo las clases y propiedades en Protégé:


    Diseño una ontología central (med:) capaz de actuar como «pegamento» entre las distintas fuentes. Creamos clases que no existían explícitamente en los datos originales, como med:Interacción o med:Biomarcador, transformando simples notas de texto en entidades conectadas.

    Se añaden varias clases no existentes en los diccionarios:

    • med:Medicamento vinculada con prescripciones, principios activos y laboratorios.
    • med:Enfermedad vinculada con principios activos.
    • med:Interacción vincula pares de códigos ATC, y principios activos.
    • med:Duplicidad vincula pares de códigos ATC, y principios activos.
    • med:Biomarcador vincula principios activos y genes.

    Un grafo de contexto de 169M de triples

    Con el objetivo de poseer un grafo de «contexto» para los medicamentos realizo una extracción controlada de Wikidata. El punto de unión básico proyectado van a ser los principios activos. Sustancias químicas, naturales o artificiales utilizadas para la fabricación de medicamentos y que producen un efecto terapéutico. El grafo de «contexto» extraído posee tipos de entidades como: Entidad química, molecular function, biological process, class of disease, gene, taxon, chromosome, y un largo etcétera.

    En sí mismo compone un grafo biológico muy completo. Conteniendo 169.374.083 millones de triples. De esta manera conseguimos un subgrafo temático que utilizo como contexto semántico local y que permite razonamiento cruzado.

    Entity linking multi-grafo

    Un grafo aislado no aporta valor. La potencia de HealthKG reside en su conectividad con la nube de datos abiertos enlazados (LOD):

    • Reconciliación Química: Vinculamos más de 2.200 principios activos de la AEMPS con Wikidata y DBpedia. Esto nos permitió importar propiedades moleculares y genéticas que la AEMPS no posee.
    • Jerarquización ATC: Los códigos ATC planos se vincularon a la ATC Ontology, permitiendo consultas jerárquicas (ej: «Dame todos los antiinflamatorios», no solo el Ibuprofeno).
    • Enfermedades y Tratamientos: Mediante técnicas de procesamiento de texto y coincidencia de etiquetas, inferimos la relación enfermedadTieneTratamiento cruzando datos de Dbpedia y Wikidata con nuestros principios activos.

    Vinculamos datos de:

    • Wikidata
    • Dbpedia (es)
    • ATC ontology
    • DOID
    • DRON

    Estrategias de emparejamiento de entidades en grafos heterogéneos

    Principios activos

    El primer emparejamiento de entidades que realizamos es entre los principios activos de nuestro grafo de medicamentos y las sustancias químicas presentes en el grafo de contexto y en Dbpedia en español para aumentar la conectividad y el acceso a información.

    Este será el puente principal por el que unificar las distintas fuentes que tenemos entre manos y comenzar a lograr que los datos AEMPS dejen de estar aislados. De este modo podremos saltar desde un medicamento a su principio activo y de este a la enfermedad que trata, función que regula, gen, etc o seguir otros caminos en estas relaciones…

    med:PrincipioActivo3.167
    Dbpedia (emparejados)1.153
    Wikidata (emparejados)1.184
    med:esVariacionDePrincipioActivo1.115

    Teniendo en cuenta que 1.115 principios activos son variaciones de otros ya emparejados hemos conseguido emparejar unos 2.200 principios activos, mas de dos tercios del total.

    Consulta para construir los principios que son med:esVariacionDePrincipioActivo:

    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>   
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX med: <http://www.medicamentos.es/>
    construct {
      ?principioactivo2 med:esVariacionDePrincipioActivo ?principioactivo1; #El principio activo 2 será una variación del 1
    }
    WHERE {
      ?principioactivo1 a med:PrincipioActivo;  
                        rdfs:label                 ?principioactivo1label .
      ?principioactivo2 a med:PrincipioActivo;
                        rdfs:label                  ?principioactivo2label ;
                        # El nombre del principio 2 comienza igual que el nombre del prinicipo 1
                        FILTER (strStarts(?principioactivo2label, ?principioactivo1label)). 
      filter (?principioactivo2 != ?principioactivo1 )
    }Lenguaje del código: PHP (php)

    Ejemplo de resultado:

    http://www.medicamentos.es/PrincipioActivo/990
    rdf:type med:PrincipioActivo ;
    rdfs:label "ABACAVIR"@es ;
    med:codigoPrincipioActivo "1111A" ;
    med:nroPrincipioActivo "990" .
    
    http://www.medicamentos.es/PrincipioActivo/11578
    rdf:type med:PrincipioActivo ;
    rdfs:label "ABACAVIR CLORHIDRATO"@es ;
    med:codigoPrincipioActivo "1111CH" ;
    med:nroPrincipioActivo "11578" .
    
    prinactiv:11578 med:esVariacionDePrincipioActivo
    prinactiv:990 .Lenguaje del código: JavaScript (javascript)

    Enfermedades

    Los principios activos son un paso necesario para vincular enfermedades tratadas por los medicamentos. Para generar y vincular enfermedades utilizaremos nuestra clase med:Enfermedad. En nuestro grafo de contexto extraído de Wikidata tenemos un tipo enfermedad (Q112193867) y una propiedad (P2176)que la vincula al principio activo como tratamiento.

    • Primero construimos nuestras entidades med:Enfermedad a partir del tipo Q112193867.
    • Luego generamos la propiedad med:enfermedadTieneTratamiento.

    También quería extraer y vincular enfermedades de Dbpedia. Esta posee la clase Disease, con la que construir la nuestra. Sin embargo, Dbpedia no posee una propiedad que vincule un enfermedad y un tratamiento, para ello desarrollo un método plausible que nos permite crear dicha propiedad.

    Rescatamos los Wikilinks (enlaces dentro de los artículos de Wikipedia) de cada entidad de tipo med:Enfermedad y los comparamos con nuestros principios activos, previamente vinculados con owl:sameAs. Es altamente probable que los artículos sobre una enfermedad contengan referencias a las sustancias que se usan en su tratamiento.

    Construir la relación enfermedad tiene tratamiento Dbpedia:

    PREFIX med: <http://www.medicamentos.es/>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix prinactiv:  <http://www.medicamentos.es/PrincipioActivo/>
    construct {
      ?enfermedad med:enfermedadTieneTratamiento  ?principioActivo.
    }
    WHERE {
      ?enfermedad   a      <http://dbpedia.org/ontology/Disease>.
      ?enfermedad <http://dbpedia.org/ontology/wikiPageWikiLink> ?WikiLink.
      service <https://javiermurcia.tech/lab/Medicamentos> {
        ?principioActivo a med:PrincipioActivo;
                  owl:sameAs ?WikiLink.
      }
    }Lenguaje del código: HTML, XML (xml)

    Esta consulta construye relaciones tratamiento–enfermedad en Dbpedia, donde dicha propiedad no existe explícitamente, usando enlaces internos de Wikipedia como señal semántica.

    Como vemos en la imagen para la enfermedad «Reflujo gastroesofágico» la coincidencia entre tratamientos de la parte superior Dbpedia y la parte inferior grafo de contexto extraído de Wikidata, es altamente significativa.

    Aprovechando que Dbpedia posee categorías construyo una taxonomía de las enfermedades con tratamientos farmacológicos. Lo que resultará muy útil para la navegación posterior. Partiendo de Categoría:Enfermedades_por_especialidad_médica, construimos las demás.

    Códigos ATC

    La AEMPS incluye un diccionario de códigos ATC. El código ATC o Sistema de Clasificación Anatómica, Terapéutica y Química, es un índice de sustancias farmacológicas y medicamentos, organizados según grupos terapéuticos.

    Sin embargo, tal cual se encuentra no compone ni siquiera un árbol jerárquico por el que poder navegar. La solución: vincular mis entidades a la ATC ontology, que posee una organización en subclases que mejorará nuestras consultas, razonamientos y navegación.

    Creando los Biomarcadores como clase e entidades

    La base datos de Prescripciones incluye biomarcadores farmacogenómicos con aquellos principios activos con los que se ha establecido una conexión. Pero estos, no existen como entidades independientes, primero construyo a partir de las prescripciones en las que aparecen, junto a sus principios activos y los vinculo a los genes a los que hacen referencia en el grafo de contexto biológico.

    Interacciones y Duplicidades

    De igual modo ocurre con las interacciones y las duplicidades
    que no existen como entidades sino solamente como relaciones. Lo que hago es relacionar los códigos ATC que interaccionan. Las prescripciones simplemente apuntan a un código ATC con el que interacciona, yo relaciono los códigos ATC y los principios activos:

    Construyendo las interacciones:

    PREFIX med:         <http://www.medicamentos.es/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    construct {
      ?interaccion a med:Interacción;
        med:interaccionaCon  ?ATCinteraccion;
        rdfs:label  ?rdfslabel2;
        med:seRefiereATC ?ATC;
        med:efectoInteraccion ?efectoInteraccion;
        med:recomendacionInteraccion ?recomendacionInteraccion;
        med:tienePrincipioActivo ?PrincipioActivo;
        med:principioActivoInteraccion ?PrincipioActivo2;
    }
    WHERE {
      ?a a med:Prescripción.
      ?a med:codigoATC ?codigoATC.
      BIND(URI(CONCAT( "http://www.medicamentos.es/Interacción/"  ,?codigoATC) )  AS ?label ) .
      ?a  med:tieneComposicionPa ?tieneComposicionPa.
      ?a med:atcInteraccion ?atcInteraccion.
      ?a med:efectoInteraccion ?efectoInteraccion;
         med:recomendacionInteraccion ?recomendacionInteraccion.
      ?b a med:Prescripción;
         med:codigoATC ?atcInteraccion;
         med:tieneComposicionPa ?tieneComposicionPa2;
         med:atcInteraccion ?codigoATC;
         med:efectoInteraccion ?efectoInteraccion;
         med:recomendacionInteraccion ?recomendacionInteraccion.
      ?ATC a med:ATC;
         med:codigoATC ?codigoATC.
      ?ATCinteraccion a med:ATC;
         med:codigoATC  ?atcInteraccion;
         BIND(URI(CONCAT( STR(?label) ,"+") )  AS ?label2 ) .
      BIND(URI(CONCAT( STR(?label2) , ?atcInteraccion) )  AS ?interaccion) .
      BIND(CONCAT( STR(?codigoATC) , "+")   AS ?rdfslabel) .
      BIND(CONCAT( STR( ?rdfslabel) , ?atcInteraccion)   AS ?rdfslabel2) .
      ?PrincipioActivo a  med:PrincipioActivo;
         med:nroPrincipioActivo ?tieneComposicionPa.
      ?PrincipioActivo2 a  med:PrincipioActivo;
         med:nroPrincipioActivo ?tieneComposicionPa2;
         }Lenguaje del código: PHP (php)

    Doid.owl y The Drug Ontology

    Vinculamos con la ontología doid.owl. La Human Disease Ontology, compone una clasificación integral de enfermedades humanas organizadas por etiología. Lo que hago es emparejar las enfermedades que ya poseo con una ontología profesional para aumentar la conectividad y la base de verificabilidad del grafo.

    Finalmente vinculo también nuestros principios activos con la ontología dron (The Drug Ontology). Yendo de nuestros principios a los extraídos de Wikidata, usamos sus labels en inglés y de ellos hacia la dron.

    Navegación por descubrimiento semántico

    Para hacer el grafo accesible, desarrollé una interfaz de Navegación por Descubrimiento. A diferencia de un buscador tradicional, aquí el usuario «surfea» las relaciones:

    • De un Laboratorio en el mapa -> a sus Medicamentos en una línea de tiempo.
    • De un Medicamento -> a su Principio Activo -> a las Enfermedades que trata.
    • Visualización de Interacciones y Duplicidades no como listas de alerta, sino como grafos de red.

    En la Home comenzamos con un listado de Laboratorios farmacéuticos que tienen una sede en España desplegados en un mapa. Podemos seleccionarlos y cargar los medicamentos que les corresponden en una línea de tiempo.


    Podemos cargar un laboratorio seleccionándolo y cargarlo en una página especial:


    Si seleccionamos cualquier medicamento en la línea de tiempo abrimos una página especial para medicamentos:


    En esta y en las siguientes vistas usamos la librería vis.js para visualizar las entidades y relaciones del grafo y navegamos a través del propio grafo haciendo clic en ellas. Podemos cargar los principios activos del medicamento, las prescripciones, los códigos ATC, etc.

    Tenemos una vista donde desplegar medicamentos en una linea de tiempo por fecha de autorización:

    …una forma de visualizar la historia de la farmacología.

    En la vista Prescripciones se pueden visualizar todas las propiedades de la base de datos Nomenclátor de Prescripciones, y por supuesto muchos de sus nodos son navegables y abren otras vistas:


    La vista ATC es particularmente interesante pues podemos navegar por sus jerarquías de códigos a los que se añaden los principios activos y los medicamentos cuando están vinculados:


    La vista para los principios activos es muy completa. En ella tenemos una descripción, si está disponible y navegación a través de los nodos a a los códigos ATC, clases de sustancia a la que pertenece y enfermedades para las que sirve como tratamiento.


    Tenemos también acceso a las posibles interacciones, medicamentos y prescripciones para ese principio activo. Igualmente podemos acceder a nuestro grafo de contexto para ese principio activo (Wikidata):

    Además contamos con una vista propia para las interacciones:


    Y otra para duplicidades:


    Contamos con una vista para las enfermedades, con doble visualización de datos: tanto de Dbpedia como de Wikidata y tenemos navegación por categorías de enfermedades en el panel lateral.


    Poseemos vistas para Taxones, Biomarcadores y Genes que aparecen con asiduidad en las relaciones de enfermedades, principios activos…

    Verificación

    Una prueba de verificación de que las deducciones realizadas han sido acertadas es la comparación entre la ficha técnica de un medicamento y la propiedad «tratamiento para» de su principio activo. Siendo el resultado altamente satisfactorio.


    Otro de los test que realizo para comprobar la completitud y capacidad del grafo se muestra en la sección extracción de entidades y razonamiento, donde a partir de una ficha técnica oficial de un medicamento, reconocemos y extraemos entidades gracias al grafo o bien extraemos entidades y las confrontamos entre sí para buscar relaciones entre ellas.


    Reconocimiento de entidades:


    Extracción de entidades, propiedades y relaciones:


    Los resultados son positivos, reconociendo de una única ficha técnica 380 entidades y 131 relaciones relevantes.


    Validación con IA Generativa (RAG)

    (Knowledge Graph como capa de razonamiento para LLMs)

    Realicé un experimento de Retrieval-Augmented Generation (RAG) con el grafo.

    1. Presento una ficha técnica plana a un LLM (Gemini/ChatGPT).
    1. Después Presenté la misma ficha enriquecida con las entidades y relaciones extraídas a partir de mi grafo (CSV estructurado).

    Les paso el resultado en csv de la consulta al grafo de medicamentos que extrae entidades y relaciones de la misma ficha técnica que antes les presenté, explicando de que se trata el csv, su estructura y pidiendo que lo usen junto a la ficha para explicar y extraer nuevas conclusiones.

    Resultado: Los modelos fueron capaces de explicar contraindicaciones y mecanismos de acción con mucha mayor precisión y contexto biológico al disponer de los datos estructurados del grafo. Esto valida el uso de HealthKG como base de conocimiento para asistentes clínicos inteligentes.

    • El grafo añade relaciones nuevas
    • El grafo actúa como “ground truth”

    Prueba 1: Gemini, ChatGPT.

    Prueba 2: Gemini, ChatGPT.

    Futuras mejoras

    • Incorporación de SnomedCT.
    • Conversión e inclusión de los productos sanitarios y los medicamentos veterinarios de la AEMPS.
    • Vinculación de otros grafos biológicos para la configuración de un ecosistema de consulta e investigación.
    • Desarrollo de un sistema RAG sistemático.
    • Incorporación de pathways.

    El Grafo en Cifras

    • 3.7 Millones de tripletas generadas.
    • 169 Millones de tripletas de contexto biológico integradas.
    • 20.000+ Enfermedades catalogadas.
    • 2.700+ Interacciones farmacológicas modeladas.
    med:ATC7.049
    med:BioMarcador267
    med:DCP6.657
    med:DCPF9.882
    med:DCSA2.358
    med:Duplicidad1.658
    med:Enfermedad20.301
    med:Envase50
    med:ExcipienteDeclObligatoria558
    med:FormaFarmaceutica259
    med:FormaFarmaceuticaSimplificada72
    med:Interacción2.763
    med:Laboratorio1.498
    med:Medicamento25.792
    med:MedicamentoPresentación20.296
    med:Prescripción29.377
    med:PrincipioActivo3.167
    med:SituaciónRegistro3
    med:UnidadContenido56
    med:ViaAdministracion57
    Triples Totales3.751.788
    Grafo de contexto biológico169.374.083


    Capacidades utilizadas en el proyecto

    • Diseño de ontologías de dominio complejo.
    • Transformación de datos institucionales a RDF.
    • Entity linking a gran escala.
    • Construcción de grafos de conocimiento sanitarios.
    • Inferencia semántica y razonamiento.
    • Integración KG + LLM.
    • Desarrollo de front-ends semánticos.
  • Ingeniería de Conocimiento a Gran Escala: Infiriendo la Genealogía de 1 Millón de Personas desde Wikidata

    Este proyecto no consiste en consultar genealogías existentes, sino en construir una genealogía ampliada a gran escala mediante inferencia semántica, partiendo de un conjunto mínimo de relaciones primitivas.

    A partir de la propiedad P40 (hijo o hija)de Wikidata se genera, mediante reglas formales, un espacio completo de parentesco: padres, abuelos, tíos, sobrinos, primos, suegros, bisabuelos, etc.

    Diseñé un sistema de inferencia genealógica capaz de expandir automáticamente el conocimiento familiar de casi un millón de personas, generando decenas de millones de nuevas relaciones semánticas de forma consistente.

    El Desafío: Datos incompletos

    En Wikidata hay casi un millón de entidades que son seres humanos y que además tienen hijos. A partir de la propiedad P40, hijo o hija, podemos usarla como propiedad primitiva de la que deducir todas las demás. Wikidata dice quién es hijo de quién, pero no quién es primo de quién.

    Explosión Combinatoria Controlada

    Lo más impresionante de este proyecto no es tener 1 millón de personas, sino calcular relaciones tan alejadas como primos terceros. La cantidad de relaciones crece exponencialmente.

    El reto fue gestionar la explosión combinatoria. Calcular relaciones de primer grado es trivial. Calcular relaciones de sexto grado (primos terceros) en un grafo de 1 millón de nodos requiere una estrategia de inferencia optimizada para no colapsar la memoria.

    Modelado Ontológico

    El primer paso fue crear una ontología minimalista que reflejara los tipos y propiedades fundamentales que rigen las relaciones familiares y genealógicas:

    Diseñé una ontología ligera (lite ontology) para maximizar el rendimiento de las consultas, mapeando las propiedades complejas de Wikidata a un esquema simplificado pero transitivo.

    Seguidamente generamos y descargamos el dump de Wikidata utilizando Wdumper, para ello se seleccionan las entidades que tienen la propiedad P40, aproximadamente un millón.

    Una vez en nuestro poder, se procede a la carga en una TDB2 de Apache Jena Fuseki y comenzamos el proceso de conversión de tipos. Convertimos los tipos básicos de Wikidata a nuestra ontología:

    Q5 (Humano)fami:Persona
    Q6581097 (masculino)fami:Hombre
    Q6581072 (femenino)fami:Mujer
    P22 (padre)fami:tienePadre
    P25 (madre)fami:tieneMadre
    P3373 (hermano o hermana)fami:esHermanaoDe
    P26 (cónyuge)fami:esParejaDe
    P40 (hijo o hija)fami:esPadreDe fami:esMadreDe


    Ahora ya estamos en disposición de utilizar reglas de inferencia o deducción, para a partir de estas relaciones primitivas, deducir todas las demás.

    La Estrategia de Inferencia

    La Lógica de Inferencia

    Para deducir relaciones complejas, descompusimos los vínculos familiares en reglas lógicas basadas en cláusulas de Horn. Por ejemplo, la regla para deducir a una «Tía Materna» se define conceptualmente así:

    Mujer(a)∧Hermana(a,b)∧Madre(b,c)→Tía(a,c)

    Traducción: Si A es mujer, y A es hermana de B, y B es madre de C; entonces A es tía de C.

    Implementación

    dato → modelo → conocimiento inducido

    Inicialmente, implementé un motor de inferencia basado en reglas (Jena Rules) ejecutado en memoria.Tenemos a nuestra disposición, de este modo, un sistema muy completo y robusto para elaborar las inferencias que deseo:

    [TíaDeHermana: (?a rdf:type fami:Mujer), (?a fami:esHermanaoDe ?b), (?b fami:esMadreDe ?c) -> (?a fami:esTiaDe ?c),(?c rdf:type fami:Tía )
    ]Lenguaje del código: JSON / JSON con comentarios (json)

    Este tipo de reglas funcionan muy bien y resulta muy interesante experimentar con ellas y observar como en cada consulta se generan los nuevos nodos para concluir la inferencia. Pero por desgracia todo ocurre en memoria y sólo resulta útil para pequeñas cantidades de datos. Sin embargo, dada la magnitud del grafo (1 millón de nodos semilla), el consumo de RAM se volvió insostenible.

    Para solucionar este cuello de botella, re diseñé la arquitectura de inferencia trasladando la lógica a la base de datos mediante inserciones constructivas SPARQL en cascada. Esto permitió procesar relaciones complejas (hasta primos terceros) persistiendo los datos en disco paso a paso, garantizando la estabilidad del sistema.

    La solución, por tanto, fue transformar cada regla lógica en una operación SPARQL de materialización del conocimiento, convirtiendo el razonamiento dinámico en conocimiento persistente dentro del grafo. Esta estructura permite realizar inserciones masivas en la base de datos de manera eficiente.

    A continuación, el script utilizado para inferir la relación fami:esTiaDe:

    # Regla de Inferencia: Tía Materna
    # Objetivo: Deducir tías basándonos en la relación de hermandad y maternidad.
    
    PREFIX rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX fami: <http://www.relacionesfamiliares/>
    
    INSERT {
        # La Inferencia (Lo que el grafo aprende)
        ?a fami:esTiaDe ?c .
        ?a rdf:type fami:Tía .
    }
    WHERE {
        # Las Condiciones (Lo que el grafo ya sabe)
        ?a rdf:type fami:Mujer .       # 1. 'a' debe ser mujer
        ?a fami:esHermanaoDe ?b .      # 2. 'a' es hermana de 'b'
        ?b fami:esMadreDe ?c .         # 3. 'b' es madre de 'c' (el sobrino/a)
    }Lenguaje del código: PHP (php)


    Diseñé una ejecución en cascada (Batch Processing) donde las reglas se ejecutan en un orden estricto, de tal modo que las posteriores basen sus deducciones en las propiedades anteriores:

    1. Nivel 1: Padres e Hijos (Datos crudos).
    2. Nivel 2: Hermanos y Parejas (Inferidos del Nivel 1).
    3. Nivel 3: Tíos, Abuelos y Nietos (Inferidos del Nivel 2).
    4. Nivel 4: Primos y Primos Segundos (Inferidos del Nivel 3).

    El sistema transforma un conjunto mínimo de hechos biográficos en una estructura de parentesco completa, haciendo explícitas relaciones que no existían en los datos originales.

    El uso del sistema de reglas de Jena fue una prueba conceptual. Demostró que el modelo lógico era correcto, pero no era escalable: las inferencias se realizan en memoria y no pueden sostener un grafo de casi un millón de personas.

    Esta arquitectura por capas permitió generar más de 14 millones de nuevas relaciones sin colapsar el servidor, persistiendo cada nuevo descubrimiento permanentemente en el grafo.

    Resultados

    La relación mas lejana que he podido procesar ha sido la de primo tercero. Aquí un listado de los tipos y propiedades inferidas, y el número de entidades y propiedades generadas:

    Tipos:

    fami:Padre617.285
    fami:Madre327.048
    fami:Hermano48.049
    fami:Hermana18.577
    fami:Tío38.047
    fami:Tía28.027
    fami:Sobrino30.734
    fami:Sobrina20.354
    fami:Primo30.734
    fami:Prima20.354
    fami:Cuñado30.001
    fami:Cuñada27.138
    fami:Yerno151.513
    fami:Nuera158.108
    fami:Nieto259.518
    fami:Nieta135.589
    fami:Abuelo290.979
    fami:Abuela180.322
    fami:Bisnieto215.671
    fami:Bisnieta122.790
    fami:Bisabuelo290.979
    fami:Bisabuela180.322

    Propiedades:

    fami:esPadreDe – fami:tienePadre1.078.808
    fami:esMadreDe – fami:tieneMadre674.446
    fami:esParejaDe521.626
    fami:esHermanaoDe243.069
    fami:esTioDe171.313
    fami:esTiaDe98.030
    fami:esTioPoDe115.830
    fami:esTiaPoDe175.045
    fami:esSobrinoDe77.295
    fami:esSobrinaDe54.058
    fami:esPrimoDe306.103
    fami:esPrimaDe220.748
    fami:esPrimoSegundoDe567.860
    fami:esPrimaSegundaDe456.780
    fami:esPrimoTerceroDe1.368.013
    fami:esPrimaTerceraDe1.131.703
    fami:esCuñadoDe83.734
    fami:esCuñadaDe76.267
    fami:esSuegroDe367.997
    fami:esSuegraDe266.293
    fami:esYernoDe271.422
    fami:esNueraDe303.845
    fami:esAbueloDe605.914
    fami:esAbuelaDe430.228
    fami:esNietoDe638.119
    fami:esNietaDe398.027
    fami:esBisabueloDe1.479.216
    fami:esBisabuelaDe1.100.983
    fami:esBisNietoDe804.848
    fami:esBisNietaDe559.830


    A partir de menos de un millón de personas y unas pocas propiedades primitivas, el sistema generó más de 40 millones de triples, de los cuales:

    • Casi 2 millones son nuevas afirmaciones de clase,
    • Más de 14 millones son nuevas relaciones familiares explícitas,
    • Alcanzando relaciones de hasta tercer grado de consanguinidad.

    Partiendo de 1 millón de relaciones ‘padre/hijo’, el sistema generó más de 14 millones de nuevas relaciones semánticas. Por cada dato explícito, el sistema infirió 14 datos implícitos.

    El resultado es un motor de genealogía semántica, capaz de:

    • Expandir automáticamente redes familiares,
    • Detectar parentescos complejos,
    • Validar la coherencia de grupos históricos,
    • Cruzar genealogía con tiempo, espacio y categorías culturales.


    Propiedades de relaciones familiares presentes en la extracción de Wikidata:

    P22 (tiene padre)540.417
    P25 (tiene madre)335.367
    P3373 (hermano hermana)161.007
    P26 (esposo/a)468.102
    P40 (tiene hijo/a)1.770.308
    Total Wikidata3.275.201
    Total propiedades inferidas14.647.450

    Datos Originales (Wikidata) vs Datos Enriquecidos


    La aplicación web: una exploración multidimensional

    Para explotar el grafo generado y mostrar sus capacidades ideo una aplicación web basada en grafo centrada en el descubrimiento semántico.

    Las vistas cubren cuatro elementos o dimensiones del personaje en cuestión. En la parte superior tenemos las relaciones familiares o genealógicas propiamente dichas:


    La aplicación no muestra árboles genealógicos estáticos, sino que permite explorar las relaciones familiares desde cuatro dimensiones:

    • Parentesco (grafo)
    • Tiempo (línea de vida)
    • Espacio (mapa)
    • Contexto cultural (categorías de Dbpedia)

    Debajo de ella, encontramos una línea de tiempo donde se disponen las mismas personas relacionadas según su fecha de nacimiento para visualizar en la dimensión temporal las genealogías.


    La tercera vista es la geográfica, gracias a una consulta buscamos, si existe, la ciudad de nacimiento de todos los familiares y los ubicamos en una mapa. Conseguimos así seguir las relaciones entre el parentesco y su dispersión geográfica.


    Como siempre es posible rizar el rizo y puesto que resulta relativamente sencillo saltar de las entidades de Wikidata a las de Dbpedia, cargamos las categorías a las que pertenece el personaje, si es que tiene:


    Categorías que nos sirven para cargar nuevas personas vinculadas a ellas y para abrir una nueva página especial para categorías. En ella se despliegan en un mapa y en una línea de tiempo las personas que pertenecen a ella:

    Validación del grafo a través de categorías históricas

    Además, las categorías nos sirven para poner en marcha un algoritmo que pone a prueba la exactitud de las inferencias realizadas: Buscar Parentesco, que intenta buscar parentescos familiares entre los miembros de la categoría cargada.

    Se trata de un test lógico. El sistema demuestra su corrección cuando detecta automáticamente que los emperadores romanos del siglo I pertenecen a dos dinastías sin vínculo genealógico directo. A través de este y otros ejemplos, conseguimos un caso de validación semántica.

    Comprobamos que las inferencias se han ejecutado correctamente puesto que los Emperadores de Roma del siglo I pertenecieron a dos dinastías o familias sin vínculos directos entre ellas, y eso es lo que refleja el algoritmo cuando busca los parentescos:

    Mujeres a través de los siglos

    Ante el desequilibrio existente entre hombres y mujeres en el grafo. Algo de lo que no podemos culpar a Wikidata sino a nuestra propia cultura. Decido iniciar el proceso de descubrimiento semántico con una página que permite cargar categorías de mujeres por siglos:

    De este modo, el proyecto pone de manifiesto sesgos estructurales en los datos históricos y ofrece herramientas para explorarlos activamente, como la navegación específica por mujeres históricas por siglos.

    A partir de este inicio de navegación podemos cargar una categoría en concreto como por ejemplo: «Mujeres de la Antigua Grecia«:


    Y seguidamente seleccionar una mujer y cargar su genealogía y relaciones familiares en detalle:


    En estas vistas podemos cargar nuevas personas haciendo clic o doble clic así como cargar textos explicativos sobre cada una, extraídos de Dbpedia. De modo que podemos recorrer líneas familiares a través de la historia a golpe de clic, explorando durante horas.


    Otro detalle a tener en cuenta es que podemos incluir el Qname de Wikidata de cualquier persona en la URL, y tratar de rescatar sus relaciones familiares o genealogía:


    Análisis de Endogamia Histórica

    Como ejemplo de uso que puede ser ampliamente desarrollado he creado una sección donde visualizar personas que tuvieran parentesco y además fueran pareja: hermanos, primos, primos segundos…


    En una sección especial, como caso de uso, analizamos los parentescos de diversas dinastías europeas para comprobar parentescos cercanos entre parejas.


    Conclusión: Del Dato Genealógico a la Inteligencia de Redes

    Este proyecto ilustra el potencial de la Web Semántica y los Grafos de Conocimiento para descubrir patrones ocultos en grandes volúmenes de datos (Big Data). Hemos pasado de un listado de nacimientos a una red compleja que permite analizar la dispersión geográfica de familias, detectar endogamia histórica y visualizar dinastías completas en tiempo real.

    La capacidad para modelar ontologías, gestionar inferencias masivas y construir interfaces de descubrimiento es aplicable a múltiples sectores:

    • Sector Legal y Administrativo: Gestión avanzada de registros civiles y sucesiones.
    • Investigación Biomédica: Rastreo de antecedentes genéticos en grandes poblaciones.
    • Humanidades Digitales: Análisis de redes de poder históricas.
    • Estudios demográficos.
    • Sistemas genealógicos profesionales.
    • Bases de datos históricas.

    Los grafos de conocimiento no solo almacenan información, sino que pueden razonar, expandirse y generar nuevo conocimiento estructurado.

    Si deseas construir sistemas de inferencia semántica, expandir conocimiento a partir de reglas formales y la inteligencia Artificial Simbólica o transformar bases de datos relacionales en grafos de conocimiento vivos, puedo ayudarte a diseñar la ontología, el modelo de inferencia y la infraestructura técnica.

    Estadísticas

    Triples totales40.593.509
    Afirmaciones de clase nuevas1.986.827
    Afirmaciones de propiedad nuevas14.647.450
    Personas944.334
  • El Cerebro Digital del Patrimonio: Construyendo el Grafo Semántico del Patrimonio Monumental Español

    El Problema de la Dispersión

    Las bases de datos relacionales fallan al intentar conectar la multidimensionalidad del arte (patrimonio histórico) (autor, estilo, lugar, tiempo, contexto). Mi objetivo: crear un modelo unificado que permita navegar el patrimonio no por listas, sino por contextos.

    El patrimonio cultural español está disperso en múltiples fuentes heterogéneas, con modelos de datos poco interoperables y sin una estructura semántica que permita razonamientos complejos o exploración avanzada.

    Este proyecto demuestra cómo construir un grafo de conocimiento unificado de monumentos de España, basado en una ontología propia, integrando Wikidata, Dbpedia y vocabularios institucionales, y explotarlo mediante un front-end semántico.

    El objetivo no es solo mostrar datos, sino demostrar un flujo completo de ingeniería semántica: modelado ontológico, extracción masiva de entidades, normalización, enlazado, inducción de conocimiento y publicación web basada en grafos. Es, en definitiva, un proyecto de arquitectura del conocimiento.

    La Ontología (El Cimiento)

    La ontología parte de un estudio sistemático y se fundamenta en sus definiciones en el Tesauro de Bienes Culturales, Tesauro de Contextos Culturales y en las clases de Wikidata y Dbpedia. Lo que garantiza interoperabilidad.

    Alrededor de la clase padre Sitio_de_Interés, se organiza la ontología. Esta expresa cualquier tipología ubicable y definible de monumento, resto, etc. Encontramos clases genéricas como Arquitectura Civil, Militar, Religiosa, etc. que subsumen una plétora de clases que definen tipos más concretos como Castillo o Catedral.

    La ontología actúa, así, como una “columna vertebral semántica” que permite armonizar datos abiertos, datos colaborativos y vocabularios institucionales.

    La dimensión temporal queda cubierta con las clases Siglo y Época Histórica, que nos permiten tratar con divisiones de periodos temporales que estudia la Historia y subsumir así las entidades.

    Las clases Estilo Artístico y Cultura Arqueológica aportan divisiones y dimensiones culturales y antropológicas a las entidades.

    Cada clase y entidad posee, en lo posible, vínculos a sus definiciones en colecciones exteriores (rdfs:isDefinedBy rdfs:seeAlso) además de etiquetas alternativas (skos:altLabel) para facilitar búsquedas por palabra en la propia ontología. Esto nos garantiza que las ontología esté interconectada, respaldada por definiciones aceptas ampliamente y con mayor acceso a información.

    En resumen la ontología de monumentos:

    • No es una ontología cerrada.
    • Es una ontología de integración.
    • Está alineada con:
      • Tesauro de Bienes Culturales.
      • Tesauro de Contextos Culturales.
      • Clases de DBpedia.
      • Clases de Wikidata.

    Ingeniería de Datos: Estrategia de Ingesta

    Wikidata posee gran cantidad de datos, pero sus clases resultan a menudo caóticas. Para extraer solo la «señal» y descartar el «ruido», optimizando costes computacionales, implementé una estrategia de slicing semántico usando Wdumper.

    La extracción es dirigida por ontología y a la vez esta se completa gracias a la extracción. Filtrando solo tipologías de entidades relevantes para monumentos de España.

    Esta estrategia permite trabajar con volúmenes masivos de datos manteniendo control semántico y eficiencia computacional, algo imprescindible en proyectos reales de Web Semántica.

    Las extracciones son montadas en una TDB2 de Apache Jena Fuseki, y mediante consultas Insert de SPARQL los tipos y propiedades son mapeados a la ontología, obteniendo la estructura lógica deseada.

    El Corazón del Sistema: Enriquecimiento y Normalización

    • Normalización Geográfica: Gracias a mi grafo geográfico de Lugares de España, corregí la anarquía de la propiedad P131 de Wikidata, ubicando cada monumento en su jerarquía administrativa correcta (Provincia/Municipio).
    • La vinculación de entidades con Dbpedia en español se realiza del mismo modo que el grafo de lugares de España: Por ID/Estructura: Wikidata ↔ Wikipedia ↔ DBpedia (Mapeo directo). (con método robusto basado en schema:about).
    • Creación de un grafo de apoyo con los Wikilinks de Wikipedia/Dbpedia, que a través de la relación skos:related se relacionan con los Sitios de interés. Los Wikilinks son enlaces que se encuentran en los artículos de Wikipedia que dirigen a otros artículos, o entidades de Dbpedia, en nuestro caso.
    • Generación de contexto Histórico (Wikilinks): No solo importé el monumento, sino su ecosistema. Al traer los Wikilinks y categorizarlos, el grafo sabe qué ‘Sucesos Históricos‘ ocurrieron en el ‘Castillo X‘ y las personas relacionadas con el lugar.

    Inducción semántica de conocimiento ontológico


    Con lo que tenemos ahora mismo en el grafo y en la ontología somos capaces de hacer consultas como: «¿En qué lugares hay Palacios de estilo Barroco y cuales son sus arquitectos? O mejor aún ¿Qué tipos de monumentos existentes tienen estilo Barroco?

    Sin embargo, estas consultas necesitan recuperar primero las propiedades de cada entidad, lo que yo pretendo es inducirlas, es decir, elevar las propiedades de las entidades a las propias clases:

    
    monu:Barroco monu:tieneTipo monu:Casa_Solariega , monu:Cruz_monumental , monu:Retablo , monu:Plaza_porticadaLenguaje del código: CSS (css)

    Este proceso inductivo eleva propiedades directamente a las clases desde la entidades, generando nuevas relaciones, basadas, en los «datos» y relacionando todas las clases entre si:

    • tipos con estilos
    • estilos con siglos
    • siglos con tipos
    • tipos con culturas
    • culturas con siglos
    • tipos con lugares

    De este modo construimos un Motor de Recomendación Semántica, transformando datos implícitos en conocimiento explícito.

    • Antes sabíamos que «La Catedral de Burgos tiene estilo Gótico«. Ahora el grafo sabe que «El Gótico se caracteriza por la presencia de Catedrales«.
    • Esto permite al frontend sugerir «Tipos de monumentos probables» cuando el usuario filtra por un estilo, sin que un humano haya programado esa regla.

    Esto dota al sistema de «sentido común» arquitectónico. El frontend no necesita reglas hardcodeadas; «sabe» qué esperar de un monumento barroco basándose en la evidencia de los datos acumulados, permitiendo filtros predictivos y navegación por descubrimiento.

    Obtenemos una ontología que posee mayor conocimiento de la realidad directamente desde sus propias clases.

    • Las clases dejan de ser solo contenedores.
    • Se convierten en nodos activos de conocimiento.
    • Se enriquecen automáticamente desde los datos.
    • Aparece una ontología viva, no estática.

    Uso del grafo como motor de inferencias

    Gracias al grafo de monumentos pude realizar el experimento que menciono en Toponimia Histórica (ver en acción) en el que logré situar con plausibilidad 2.594 posibles emparejamientos, en los lugares históricos donde originalmente fueron creados o erigidos los monumento o Sitios de interés.

    Prueba de que el grafo no solo describe, sino que permite formular hipótesis históricas., y nos permite:

    • Razonamiento histórico.
    • Reubicación semántica.
    • Hipótesis plausibles.
    • Uso del grafo como motor de inferencias.

    Explorador semántico: Visualizando la Inteligencia

    Construido para poner a prueba algunas de las capacidades del grafo. La filosofía de la interfaz es la de partir de un Tipo, Siglo, Estilo, Cultura o Edad Histórica y a través de una cadena de consultas SPARQL y gracias a las propiedades inducidas, obtener a parte de los propios Sitios de interés, siglos, estilos, culturas, provincias, arquitectos, personas, eventos históricos, vinculados a esa clase inicial. Estas nuevas clases relacionadas sirven para filtrar la clase principal.

    El usuario construye consultas semánticas complejas sin escribir SPARQL. Lo que nos permite una auténtica navegación por grafo de conocimiento.

    Se utilizan consultas SPARQL en cadena para cargar todas las relaciones semánticas de la clase y las entidades. Y constituye una interfaz de consulta ontológica de pleno derecho.

    Cada nueva clase o lugar fruto de la inducción puede usarse como filtro dentro del resultado principal:

    Románico + Centro Histórico

    Románico + Guerra de los Dos Pedros


    Existe una vista de detalle de cada Sitio de interés haciendo clic o doble clic en él:


    Una línea de tiempo nos permite desplegar los monumentos por fechas y filtrar por tipos, provincias y estilos:


    También un editor SPARQL donde realizar consultas y explorar el grafo de monumentos de España:

    En la sección Paseo por el tiempo uso un bucle de consultas sparql para cargar de forma automática y secuencial monumentos por siglos, estilos, culturas, provincias…generando una experiencia de sucesión temporal gracias al grafo y demostrando su consistencia temporal.

    Recomendaciones para una mejora y ampliación del grafo:

    • Sería posible y deseable transformar, mapear e incluir los datos de monumentos y lugares que poseen las Comunidades Autónomas, e incluso los Ayuntamientos para aumentar y mejorar su alcance.
    • Añadir elementos arquitectónicos y cualidades artísticas (bóveda de cañón…)
    • Extracción de entidades de las descripciones para aumentar la densidad del grafo.
    • Implementar y mejorar la navegación por temas.

    Qué demuestra este proyecto

    Este proyecto demuestra capacidad para:

    • Diseñar ontologías complejas.
    • Integrar múltiples fuentes RDF heterogéneas.
    • Ejecutar procesos masivos de entity linking.
    • Normalizar modelos semánticos inconsistentes.
    • Inducir nuevo conocimiento ontológico.
    • Diseñar front-ends basados en grafos.
    • Publicar documentación ontológica profesional (LODE, WIDOCO).
    • Crear infraestructuras reales de grafos de conocimiento.

    Aplicaciones profesionales

    • Portales de patrimonio cultural semánticos.
    • Turismo cultural inteligente.
    • Catálogos históricos enriquecidos.
    • Sistemas de recomendación culturales.
    • Integración con GIS y GeoSPARQL.
    • Investigación en humanidades digitales.
    • Proyectos de digitalización institucional.

    Estadísticas

    Grafo:

    Sitios de interés142.884
    Con coordenadas geográficas118.712
    Con imagen52.959
    Con estilo artístico30.380
    Con cultura arqueológica22.853
    Con siglo15.350
    Con año de construcción15.129
    Con época histórica6.027
    Con arquitecto3.181
    Vinculados con Dbpedia16.598
    Categorías12.777
    Wikilinks34.922
    Triples1.2878.447

    Ontología:

    Clases220
    Propiedades de objeto77
    Propiedades de datos27

    Inducciones:

    Nuevas afirmaciones165.849

    De los Datos al Conocimiento Estratégico


    La construcción del Grafo de Monumentos de España demuestra que la Web Semántica es mucho más que una tecnología de archivo; es un motor de descubrimiento capaz de transformar datos aislados en activos inteligentes. Al procesar más de 12 millones de tripletas y aplicar razonamiento inductivo, hemos convertido un listado plano en un ecosistema navegable que «entiende» contextos históricos y geográficos.

    Estas mismas metodologías de Ingeniería del Conocimiento, normalización de datos heterogéneos y enriquecimiento semántico son directamente aplicables a otros sectores, desde la gestión de catálogos complejos en e-commerce hasta la integración de datos corporativos o sistemas de recomendación inteligente.

    Si tu organización necesita romper silos de información, diseñar ontologías a medida o transformar grandes volúmenes de datos en un Knowledge Graph explotable, hablemos. Ofrezco servicios profesionales de consultoría e implementación técnica para llevar tus datos al siguiente nivel de inteligencia.

    Enlaces a recursos

  • Unificando España en un Grafo: Ingeniería de Datos Semánticos con Wikidata e IGN


    Los sistemas de información geográfica tienen enormes capacidades, pero no contamos con un grafo que nos proporcione una arquitectura conceptual que nos permita hacer consultas de alta complejidad sobre datos y estructuras geográficas de España.


    A pesar de ser abundante, los datos geográficos sobre España están dispersos (IGN, Wikidata, DBpedia), son incoherentes jerárquicamente y difíciles de consultar en su conjunto. Y sobre todo no tienen una base semántica con la que razonar.


    Por eso me propuse crear un Grafo de Conocimiento unificado y normalizado. La ontología más el grafo consiguen que tengamos a nuestra disposición razonamiento semántico geográfico para la totalidad del país.

    Un grafo geográfico de este tipo debe permitirnos hacer razonamientos del tipo: Una entidad está ubicada en un lugar, ese lugar tiene un tipo (municipio, localidad) y este último está contenido en otras entidades mayores como una provincia. De ese modo obtenemos mayor contexto geográfico y semántico sobre la primera.


    Existen grafos semánticos con mucha información geográfica sobre España pero esta se encuentra inconexa y vagamente jerarquizada:

    • Wikidata: Muy rica fuente de datos, pero las relaciones de dependencia territorial resultan a menudo caóticas.
    • DBpedia: rica en categorías y descripciones, pero sin información geográfica exacta.
    • Tesaruo Geográfico del Ministerio de Cultura: fuente normalizada y oficial, pero sin información geográfica exacta.
    • BTN100: tras su transformación a rdf contiene una gran cantidad de información geográfica exacta, pero sus tipos y clases están aisladas del resto de grafos.


    Objetivos del proyecto

    • Construir un grafo homogéneo.
    • Crear una ontología clara y reutilizable.
    • Unificar datos de Wikidata, BTN100, DBpedia y Tesauro MEC.
    • Permitir inferencias geográficas robustas.

    Arquitectura y diseño del grafo


    Articulación de las clases


    La ontología se fundamenta en la superclase Lugar, que unifica cualquier tipo de entidad que podamos ubicar en el espacio geográfico. De ella dependen varias subclases que agrupan conceptualmente las entidades:

    • Asentamiento humano.
    • Lugar Administrativo.
    • Lugar Marítimo y Fluvial.
    • Lugar Transporte.
    • Lugar Montaña.

    Las propiedades se mantienen al mínimo que permite la expresividad de relaciones de “contención” entre entidades y sus propiedades inversas.

    Decisiones clave de modelado

    Como la intención es la creación de un grafo lo más completo posible, creo un modelo híbrido:

    • Administrativo: Siguiendo estándares oficiales (IGN/Eurostat).
    • Físico: Adaptando la flexibilidad de Wikidata.


    De este modo conseguimos un modelo donde podemos preguntar, por ejemplo, por ríos o accidentes geográficos ubicados o contenidos en entidades administrativas,
    uniendo dos dominios que suelen estar separados en bases de datos relacionales.

    Extracción (Wdumper)


    Para evitar el coste computacional de procesar el dump completo de Wikidata, implementé una estrategia de slicing semántico usando Wdumper, filtrando solo el subgrafo relevante para la geografía española.

    SPARQL avanzado: inserciones masivas y razonamiento jerárquico

    Una vez que tenemos los tipos y propiedades gracias a la ontología podemos asignar primero los tipos y después construir las propiedades con eficacia.

    El problema de la Jerarquía (P131)

    Uno de los mayores retos de Wikidata es la inconsistencia en la propiedad P131 (located in). Para normalizar la jerarquía administrativa española y permitir inferencias transitivas correctas, diseñé una serie de consultas SPARQL de actualización (INSERT/DELETE) que reordenan la cadena de dependencias:

    Algoritmo en forma de SPARQL:

    Si dos entidades tienen la relación <em>P131: A <P131> B, entonces:</em>
    
    <em>A </em>lugares:Contenida_en_entidades_mayores B y su inversa
    
    B lugares:Posee_entidades_menores BLenguaje del código: HTML, XML (xml)
    
    Si dos entidades tienen la relación <em>P131: A <P131> B y B pertenece a una clase con una propiedad que relaciona a las entidades de la clase a la que pertenece con las entidades de la clase A, entonces,</em>
    por ejemplo:
    Si
    A <P131> B
    A rdf:type Lugares:Municipio
    B rdf:type Lugares:Provincia
    Entonces
    A lugares:Esta_contenido_en_Provincia B y su inversa
    B lugares:Contiene_Municipios ALenguaje del código: HTML, XML (xml)

    Entity Matching multifuente: Wikidata ↔ BTN-100 ↔ DBpedia ↔ Tesauro MEC


    Interconectar entidades entre grafos es la mejor forma de garantizar que nuestros datos sean fiables, completos, interoperables y de tener a nuestra disposición la mayor cantidad de información posible.

    Se han usado diversas estrategias de reconciliación:

    • Por ID/Estructura: Wikidata ↔ Wikipedia ↔ DBpedia (Mapeo directo). (con método robusto basado en schema:about).
    • Por Texto (Fuzzy): Etiquetas coincidentes con el Tesauro MEC.
    • Wikidata ↔ BTN100 con normalización lingüística.
    • Geosparql (Futuro/Intento): la coincidencia por coordenadas es el siguiente paso lógico para desambiguar lugares con el mismo nombre (ej. «Santa María»).


    Tarql : Se utiliza como una herramienta de Rapid Prototyping para convertir CSVs «legacy» a RDF limpio.

    Propagación inductiva de propiedades a partir de categorías DBpedia


    Dado que Dbpedia incluye como skos:Concept las Categorías de Wikipedia, como medio alternativo a los tipos y clases para subsumir entidades. Vinculé dichas categorías a las entidades el grafo como prueba experimental. Aportando así una capa adicional de relaciones al grafo.

    El objetivo es añadir más propiedades a cada categoría. Basadas estas en las entidades que contienen, a través de en un proceso “inductivo” para posteriormente rescatar mayor cantidad de entidades de las que posee la categoría originalmente.


    Con la búsqueda de texto: “Camino de Santiago Francés”, accedemos a entidades del grafo que han quedado vinculadas a dicha categoría, en este caso localidades por las que cruza.

    Resultados del proyecto

    • 120.000 lugares integrados y armonizados.
    • 100 clases ontológicas.
    • 17 propiedades de objeto consolidadas.
    • Jerarquías corregidas y unificadas.

    Implementación Web


    Se implementa una aplicación web donde visualizar los datos y relaciones del grafo. Utiliza las librerías leaftlet.js para mapas, Wicket.js (una biblioteca ligera de Javascript que lee y escribe cadenas de texto bien conocido (WKT)) Vis.js para visualizaciones y Yasgui para implementar un punto SPARQL donde realizar consultas.

    Inferencias semánticas que ahora son posibles

    Aplicaciones prácticas

    • Análisis territorial avanzado.
    • Cruce con datos inmobiliarios, turísticos, comerciales, logísticos.
    • Visualización geográfica semántica.
    • Motores de recomendación basados en grafos.
    • Análisis Inmobiliario.
    • Rutas óptimas basadas en semántica.
    • Turismo inteligente.
    • Análisis de mercado.
    • Cross-selling geolocalizado.
    • Visualización territorial para GIS.
    • Análisis de accesibilidad.
    • Catálogos inmobiliarios basados en contexto semántico.
    • Sistemas de recomendación.
    • Periodismo de Datos.

    Próximos pasos

    • GeoSPARQL.
    • Inferencias espaciales.
    • Validación SHACL.
    • Publicar un endpoint.
    • Herramientas de visualización.
    • Inclusión de datos de detalle sobre calles, vías, etc.

    Conclusión

    • No existe un grafo geográfico unificado de España tan completo.
    • Fusiona fuentes oficiales, crowdsourced y académicas.
      • BTN100 = oficial
      • Wikidata = colaborativa
      • DBpedia = académica
      • Tesauro MEC = institucional cultural
    • Se implementan técnicas de alto nivel
      • Ontología sólida
      • SPARQL avanzado
      • Entity linking
      • Limpieza semántica
      • Normalización multifuente
      • Razonamiento territorial

    ¿Necesitas integrar datos heterogéneos en tu organización? Contacta conmigo.

    Enlaces a recursos

    Estadísticas

    TipoNúmero de entidadesDbpedia sameAsTesauros sameAsBTN sameAs
    lugares:Lugar120.50143.06938.48074.698
    lugares:Asentamiento_Humano70.0667.13012.15515.484
    lugares:Lugar_Administrativo11.0549.7447.0668.876
    lugares:Lugar_Marítimo_y_Fluvial19.3081.27782.009
    lugares:Lugar_Transporte6.2051.647
    7.703
    lugares:Lugar_Montaña1.45716711516
  • Transformando el Patrimonio de Murcia: De XML estático a Web Semántica Inteligente

    Gran parte de los datos culturales publicados por administraciones públicas se distribuyen en formatos cerrados o semi-estructurados, difíciles de integrar, reutilizar o cruzar con otras fuentes.

    Este proyecto aborda ese problema mediante técnicas de Web Semántica, transformando datos institucionales en un grafo de conocimiento interoperable.

    Objetivos del proyecto

    El objetivo no era solo publicar una web, sino demostrar un flujo completo de transformación, modelado, enriquecimiento semántico y explotación de datos culturales.

    Es decir la conversión de datos a rdf y su normalización con una ontología owl, que permita integrar esos datos a otras fuentes y grafos.


    Transformar descripciones estáticas en un grafo de conocimiento navegable al tiempo que convertimos datos aislados y sin contexto temporal ni relacional en LOD.

    Transformación y normalización de datos


    Partimos de la conversión del archivo Lugares de interés de la Región de Murcia. Puesto a disposición por la Comunidad Autónoma de la Región de Murcia, y que contiene información sobre lugares destacados por su interés turístico y cultural.

    Comenzando con el archivo en formato XML, lo transformé a formato CSV con objeto de utilizar la librería Tarql, que es una herramienta de línea de comandos que convierte archivos CSV a RDF utilizando la sintaxis SPARQL 1.1.

    Tarql nos permite mapear cada campo del archivo CSV a las clases y propiedades previamente elaboradas en una ontología, así como asignar el tipo de dato adecuado. Como por ejemplo, coordenadas espaciales o fechas.


    Script de Tarql:

    PREFIX monu: <http://www.monumentos.es/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX lugares: <http://www.monumentos.es/lugares/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX owl:   <http://www.w3.org/2002/07/owl#>
    PREFIX  geo:   <http://www.w3.org/2003/01/geo/wgs84_pos#>
    PREFIX geosparql: <http://www.opengis.net/ont/geosparql#>
    PREFIX  rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    CONSTRUCT {
      ?URI a monu:Sitio_de_interés;
        rdf:type ?Tipo_;
        rdf:type ?Subtipo_;
        rdfs:label ?Nombre_;
        rdfs:comment ?Descripción_;
        monu:Está_en_Provincia lugares:Provincia_de_Murcia;
        monu:Está_en_Municipio ?Municipio_;
        monu:Está_en_localidad ?Pedanía;
        monu:CP ?CP_;
        monu:Dirección ?Dirección_;
        monu:TLF ?Teléfono_;
        monu:FAX ?FAX_;
        monu:Email ?Email_;
        monu:Web ?URL_Real;
        monu:Web ?URL_Corta;
        geo:lat ?lat_;
        geo:lon ?lon_;
        monu:Imagen1 ?Foto_1;    
    }
    FROM <file:/-/Monumentos-Región-de-Murcia-comas.csv>
    WHERE {
      BIND (URI(CONCAT('http://www.monumentos.es/', ENCODE_FOR_URI(?Nombre))) AS ?URI)
      BIND (IRI(CONCAT('http://www.monumentos.es/lugares/', ENCODE_FOR_URI(?Municipio))) AS ?Municipio_)
      BIND (URI(CONCAT('monu:', ENCODE_FOR_URI(?Subtipo))) AS ?Subtipo_)
      BIND (URI(CONCAT('http://www.monumentos.es/', ENCODE_FOR_URI(?Tipo))) AS ?Tipo_)
      BIND (STRLANG(?dirección, "es") as ?Dirección_)
      BIND (xsd:string(?FAX) AS ?Fax)
      BIND (STRDT(?Teléfono,xsd:string) as ?Teléfono_)
      BIND (STRDT(?Email,xsd:string) as ?Email_)
      BIND (STRDT(?CodigoPostal,xsd:string) as ?CP_)
      BIND (STRDT(?Latitud,xsd:float) as ?lat_)
      BIND (STRDT(?Longitud,xsd:float) as ?lon_)
      BIND (STRLANG(?Nombre, "es") as ?Nombre_)
      BIND (STRLANG(?Descripción, "es") as ?Descripción_)
      BIND (STRDT(?Fax,xsd:string) as ?FAX_)
    }Lenguaje del código: PHP (php)


    Este proceso con Tarql no es solo conversión entre formatos, sino mapping semántico:

    • Asignación de clases OWL.
    • Tipado de literales (fechas, coordenadas).
    • Creación de URIs persistentes.
    • Normalización del modelo de datos.

    Y demuestra cómo transformar datos tabulares en un grafo semántico reutilizable, alineado con una ontología propia y preparado para su integración con otras fuentes RDF.

    Ontología


    El mapeo se fundamentó en las clases, tipos y propiedades de una ontología OWL sobre patrimonio monumental, de elaboración propia, que tiene por objetivo su uso en el ámbito de todo el país.

    La motivación de la ontología de monumentos:

    • Para este y futuros proyectos necesitaba una ontología para monumentos que fuera completa y coherente.
    • DBpedia o Wikidata no ofrecen la coherencia lógica y semántica que buscaba.
    • Posee clases y tipos que se adaptan a España y a Europa Occidental en general, aunque puede ser ampliada fácilmente.

    La ontología, por tanto, no se limita a replicar categorías existentes, sino que proporciona una estructura conceptual coherente para describir bienes culturales de forma homogénea en todo el territorio nacional.

    Enriquecimiento Manual

    El csv de Lugares de interés de la Región de Murcia no contenía datos tales como fechas de creación, estilos, siglos, etc. Importantes para completar el grafo y por ello decido enriquecer “manualmente” los datos.

    La calidad de un Grafo de Conocimiento depende de la integridad de sus datos. Detecté carencias críticas en la fuente original (fechas, estilos) e implementé una fase de curación de datos, combinando scripts de normalización en Tarql con validación manual para asegurar la consistencia histórica.

    Extracción de Entidades


    Realizamos un reconocimiento de entidades a partir de los textos de descripción de cada lugar de interés o monumento, utilizando Dbpedia como grafo “generalista” y el Tesauro de bienes culturales del Ministerio de Cultura como diccionario especializado en el tema que tratamos.

    • Se trata de entity linking semántico.
    • Uso combinado de:
      • DBpedia (grafo generalista).
      • Tesauro MEC (vocabulario especializado).
    • Creación de relaciones semánticas reutilizables (skos:related).

    Este proceso transforma texto libre en conocimiento estructurado, permitiendo búsquedas y razonamientos imposibles en un enfoque tradicional.

    Cada monumento pasa así de ser una ficha descriptiva a convertirse en un nodo densamente conectado dentro de un grafo cultural. Con una rica red de relaciones semánticas que van más allá de la propia ontología.

    Como ejemplo del resultado podemos ver la entidad “Acueducto de los Arcos” y su texto descriptivo, del cual se lograron reconocer y extraer las entidades subrayadas, que luego son vinculadas mediante la propiedad skos:related:

    monu:Acueducto_de_los_Arcos a monu:Sitio_de_interés , monu:Arquitectura_Civil , monu:Acueducto , owl:NamedIndividual ;

    rdfs:comment «El Acueducto de los Arcos Fue declarado Monumento Histórico Artístico Nacional por Real Decreto 1757/1982 de 18 de junio. Conocido como el Acueducto de la Cequeta conduce el agua elevada por la Rueda de Alcantarilla desde la acequia de la Alquibla o Barreras, cruzando por la cañá en dirección hacia la BozNegra, por debajo del casco urbano. La Noria, solicitada por la Diócesis de Cartagena en 1451 al Concejo de Murcia y construida en 1457 ha sido susituida en varias ocaciones como muestran las diferentes reconstrucciones de la canal. La primera noria debió de cumplir su función hasta 1549, cuando fue construida tras la riada de 1545, que asoló la Villa de Alcantarilla. Tras varias renovaciones a lo largo de su historia, llegamos a 1956, fecha en la que la Sociedad Metalúrgica y Terrestre de Alicante instala la actual noria. Con la construcción de la variante de la N-340 se demolieron varios arcos, quedando dividido a ambos lados de la carretera. Las excavaciones arqueológicas que se están llevando a cabo en el entorno del acueducto muestran la existencia de restos romanos anteriores (estructuras arquitectónicas y material cerámicos de los siglos I al III d.c). El Acueducto esta formado por un conjunto de arcos de medio punto cuya función es sostener el cajal de ladrillo. El acueducto cuenta con un total de 22 arcadas desde la Rueda.»@es;


    Entidades extraídas:

    monu:Acueducto_de_los_Arcos   skos:related  
          <http://es.dbpedia.org/resource/N-340> , 
          <http://es.dbpedia.org/resource/Diócesis_de_Cartagena> , 
          <http://es.dbpedia.org/resource/1549> , 
          <http://es.dbpedia.org/resource/Monumento_Histórico_Artístico_Nacional> , 
          <http://es.dbpedia.org/resource/Alquibla> , 
          <http://es.dbpedia.org/resource/1545> , 
          <http://es.dbpedia.org/resource/Monumento_Histórico> , 
          <http://es.dbpedia.org/resource/1457> , 
          <http://es.dbpedia.org/resource/Rueda_de_Alcantarilla> , 
          <http://es.dbpedia.org/resource/1982> , 
          <http://tesauros.mecd.es/tesauros/bienesculturales/1008125> , 
          <http://tesauros.mecd.es/tesauros/bienesculturales/1196792> , 
          <http://es.dbpedia.org/resource/1956> , 
          <http://es.dbpedia.org/resource/Real_Decreto> , 
          <http://es.dbpedia.org/resource/Monumento_Histórico_Artístico> , 
          <http://es.dbpedia.org/resource/1451> , 
          <http://es.dbpedia.org/resource/Acueducto> , 
          <http://es.dbpedia.org/resource/Alcantarilla> .Lenguaje del código: HTML, XML (xml)

    Tanto de Dbpedia como del Tesauro de Bienes Culturales
    conseguimos 8357 relaciones skos:related.


    En un ecomerce, diario, servicio virtual… el procedimiento para la construcción de un sistema de recomendación de productos o contenido comenzaría del mismo modo. 

    La Categorización Inductiva

    Puesto que tanto los conceptos del Tesauro como las entidades de Dbpedia tienen una relación de pertenencia a Categorías que las engloban, me pareció buena idea dotar de esa capa de abstracción lógica y semántica a cada lugar de interés o monumento.

    Las categorías funcionan como una ontología ‘inducida’, permitiendo agrupar entidades heterogéneas bajo conceptos compartidos sin necesidad de definirlos explícitamente en la ontología original.

    Por ejemplo. gracias a conectar nuestros monumentos con Dbpedia, el sistema ‘aprendió’ automáticamente que el «Mármol de Macael«‘ y el «Ladrillo» son «Materiales de Construcción«, permitiendo crear un filtro de búsqueda por materiales sin haber etiquetado manualmente ni un solo monumento. Esto nos permite un comportamiento semántico avanzado.

    Aquí podemos ver como diversas entidades extraídas quedan subsumidas bajo una categoría común, en este caso “Materiales de construcción”:

    <http://es.dbpedia.org/resource/Categoría:Materiales_de_construcción>:
                <http://es.dbpedia.org/resource/Teja_árabe>
                <http://es.dbpedia.org/resource/Puerta_del_Perdón>
                <http://es.dbpedia.org/resource/Acero>
                <http://es.dbpedia.org/resource/Mármol_de_Macael>
                <http://es.dbpedia.org/resource/Acero_corten>
                <http://es.dbpedia.org/resource/Hebilla>
                <http://es.dbpedia.org/resource/Ladrillo>
                <http://es.dbpedia.org/resource/Vidrio>
                <http://es.dbpedia.org/resource/Mármol_de_Carrara>
                <http://es.dbpedia.org/resource/Acero_inoxidable>
                <http://es.dbpedia.org/resource/Verja>
                <http://es.dbpedia.org/resource/Mármol>
                <http://es.dbpedia.org/resource/Cristal>
                <http://es.dbpedia.org/resource/Tapial>
                <http://es.dbpedia.org/resource/Puerta>Lenguaje del código: HTML, XML (xml)


    De igual modo para las vinculaciones hechas con el Tesauro de Bienes Culturales:

    <https://tesauros.cultura.gob.es/tesauros/bienesculturales/1001184> Elemento arquitectónico:
          <http://tesauros.mecd.es/tesauros/bienesculturales/1008524> Suelo
          <http://tesauros.mecd.es/tesauros/bienesculturales/1001323> Bóveda
          <https://tesauros.cultura.gob.es/tesauros/bienesculturales/1005161> Pavimento
          <https://tesauros.cultura.gob.es/tesauros/bienesculturales/1007537> Moldura
          <https://tesauros.cultura.gob.es/tesauros/bienesculturales/1001096> LadrilloLenguaje del código: HTML, XML (xml)


    Frontend impulsado por Backend Semántico


    Uno de los objetivos era llevar esta estructura de grafo a una página web. Es decir, crear una web basada en grafo de conocimiento que utilizara las clases, tipos y propiedades para construir la arquitectura de contenido:

    • Una web generada desde un grafo.
    • Arquitectura de contenidos basada en clases y propiedades.
    • Navegación semántica.
    • Recomendaciones por tipología, estilo, ubicación.
    • Filtros basados en relaciones inferidas.


    Los menús reflejan las clases y propiedades principales de la ontología:


    Las páginas de detalle incluyen el texto de la descripción, clases y categorías de la ontología, recomendaciones en base a las tipologías, ubicaciones, estilo, etc…


    Gracias a la extracción de entidades, en la parte inferior, tenemos relaciones adicionales:


    Podemos consultar sus definiciones en Dbpedia o en el Tesauro y también son útiles para hacer filtrado de lugares de interés por esas relaciones extraídas:


    Se incluye una línea de tiempo en la que desplegar los monumentos por tipos y estilos según su fecha de creación o construcción:


    También una sección donde visualizar la ontología, las entidades, y las relaciones extraídas:


    Tenemos una sección especial para navegar con las entidades y las categorías extraídas:


    Y se incluye un punto SPARQL para realizar consultas:

    Estadísticas del proyecto

    Sitios de interés461
    Entidades extraídas8.357
    Categorías dbpedia135
    Categorías Tesauro474
    Número de triples2.6181
    Categorías navegables Ontología135
    Categorías navegables Extracción8.357

    Aplicaciones prácticas

    • Portales culturales semánticos.
    • Turismo inteligente.
    • Recomendadores culturales.
    • Integración con GIS.
    • Análisis de patrimonio por épocas, estilos o materiales.
    • Enriquecimiento automático de catálogos.
    • Sistemas de recomendación en ecommerce y webs.

    Qué demuestra este proyecto:

    • Dominio de Web Semántica.
    • Transformación de datos reales.
    • Modelado ontológico.
    • SPARQL avanzado.
    • Entity linking.
    • Publicación web basada en grafos.