gpt4 book ai didi

sparql - 获取 protege 中的矩阵

转载 作者:行者123 更新时间:2023-12-02 07:20:01 26 4
gpt4 key购买 nike

我的工作是关于推荐系统的图书馆书籍。作为输入我需要书分类本体。在我的本体论中对图书馆书籍进行分类。除了兄弟类“作者”、“书籍”、“Isbn”之外,该分类还有 14 个类别。书籍类中的个体是书籍的主题(大约600个主题),作者类中的个体是名称的作者,也是isbn类。我用 protege 4.1 设计了这个本体。

我还手动收集了属于书籍类别的一部分。该对象属性的名称为“hasSubject”,与类别相关的各个书籍类。示例书籍“A”有主题类别“S”和“F”以及...结果我想获得属于书籍类别的矩阵。如果这本书属于某个类别,则为 1,否则为 0。如下所示:

     cat1   cat2   cat3   
book1 1 0 0
book2 1 0 1
book3 1 1 0

在此示例中表示 book1 属于类别 1,不属于类别 2 和 3。我如何在 protege 中使用 sparql 来完成此工作?

最佳答案

处理固定数量的类别

给定数据,例如

@prefix : <http://example.org/books/> .

:book1 a :Book, :Cat1 .
:book2 a :Book, :Cat1, :Cat3 .
:book3 a :Book, :Cat1, :Cat2 .

您可以使用类似的查询

prefix : <http://example.org/books/>

select ?individual
(if(bound(?cat1),1,0) as ?Cat1)
(if(bound(?cat2),1,0) as ?Cat2)
(if(bound(?cat3),1,0) as ?Cat3)
where {
?individual a :Book .
OPTIONAL { ?individual a :Cat1 . bind( ?individual as ?cat1 ) }
OPTIONAL { ?individual a :Cat2 . bind( ?individual as ?cat2 ) }
OPTIONAL { ?individual a :Cat3 . bind( ?individual as ?cat3 ) }
}
order by ?book

根据是否存在某些三元组来绑定(bind)某些变量(尽管它们绑定(bind)的特定值并不重要)以获得如下结果:

$ arq --data data.n3 --query matrix.sparql
-----------------------------------
| individual | Cat1 | Cat2 | Cat3 |
===================================
| :book1 | 1 | 0 | 0 |
| :book2 | 1 | 0 | 1 |
| :book3 | 1 | 1 | 0 |
-----------------------------------

处理任意数量的类别

这是一个似乎在耶拿有效的解决方案,尽管我不确定具体结果是否得到保证。 (更新:基于此 answers.semanticweb.com question and answer ,似乎 SPARQL 规范不能保证这种行为。)如果我们有更多的数据,例如,关于哪些东西是类别,哪些是书籍,例如

@prefix : <http://example.org/books/> .

:book1 a :Book, :Cat1 .
:book2 a :Book, :Cat1, :Cat3 .
:book3 a :Book, :Cat1, :Cat2 .

:Cat1 a :Category .
:Cat2 a :Category .
:Cat3 a :Category .

然后我们可以运行一个子查询,按顺序选择所有类别,然后为每本书计算一个字符串,指示该书是否属于每个类别。

prefix : <http://example.org/books/>

select ?book (group_concat(?isCat) as ?matrix) where {
{
select ?category where {
?category a :Category
}
order by ?category
}
?book a :Book .
OPTIONAL { bind( 1 as ?isCat ) ?book a ?category . }
OPTIONAL { bind( 0 as ?isCat ) NOT EXISTS { ?book a ?category } }
}
group by ?book
order by ?book

输出:

$ arq --data data.n3 --query matrix2.query
--------------------
| book | matrix |
====================
| :book1 | "1 0 0" |
| :book2 | "1 0 1" |
| :book3 | "1 1 0" |
--------------------

它更接近问题中的输出,并处理任意数量的类别。但是,这取决于每个 ?book 以相同顺序处理 ?category 的值,我不确定这是否得到保证。

我们甚至可以使用这种方法为表格生成标题行。同样,这取决于每个 ?book 以相同顺序处理的 ?category 值,这可能无法保证,但似乎在耶拿有效。要获取类别标题,我们需要做的就是创建一行,其中 ?book 未绑定(bind),并且 ?isCat 的值指示特定类别:

prefix : <http://example.org/books/>

select ?book (group_concat(?isCat) as ?matrix) where {
{
select ?category where {
?category a :Category
}
order by ?category
}

# This generates the header row where ?isCat is just
# the category, so the group_concat gives headers.
{
bind(?category as ?isCat)
}
UNION
# This is the table as before
{
?book a :Book .
OPTIONAL { bind( 1 as ?isCat ) ?book a ?category . }
OPTIONAL { bind( 0 as ?isCat ) NOT EXISTS { ?book a ?category } }
}
}
group by ?book
order by ?book

我们得到这个输出:

--------------------------------------------------------------------------------------------------------
| book | matrix |
========================================================================================================
| | "http://example.org/books/Cat1 http://example.org/books/Cat2 http://example.org/books/Cat3" |
| :book1 | "1 0 0" |
| :book2 | "1 0 1" |
| :book3 | "1 1 0" |
--------------------------------------------------------------------------------------------------------

使用一些字符串操作,您可以缩短用于类别的 URI,或加宽数组条目以获得正确的对齐方式。一种可能性是这样的:

prefix : <http://example.org/books/>

select ?book (group_concat(?isCat) as ?categories) where {
{
select ?category
(strafter(str(?category),"http://example.org/books/") as ?name)
where {
?category a :Category
}
order by ?category
}

{
bind(?name as ?isCat)
}
UNION
{
?book a :Book .
# The string manipulation here takes the name of the category (which should
# be at least two character), trims off the first character (string indexing
# in XPath functions starts at 1), and replaces the rest with " ". The resulting
# spaces are concatenated with "1" or "0" depending on whether the book is a
# member of the category. The resulting string has the same width as the
# category name, and makes for a nice table.
OPTIONAL { bind( concat(replace(substr(?name,2),"."," "),"1") as ?isCat ) ?book a ?category . }
OPTIONAL { bind( concat(replace(substr(?name,2),"."," "),"0") as ?isCat ) NOT EXISTS { ?book a ?category } }
}
}
group by ?book
order by ?book

产生以下输出:

$ arq --data data.n3 --query matrix3.query
-----------------------------
| book | categories |
=============================
| | "Cat1 Cat2 Cat3" |
| :book1 | " 1 0 0" |
| :book2 | " 1 0 1" |
| :book3 | " 1 1 0" |
-----------------------------

这几乎正是您在问题中所表达的内容。

关于sparql - 获取 protege 中的矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17924869/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com