0

我的项目中有一个问题。我不知道我是否需要使用netbeans。我的工作是关于推荐系统的图书馆书籍。作为输入,我需要书籍分类本体。在我的本体中对图书馆书籍进行分类。此分类有 14 个类别,除了兄弟类 Author、book、Isbn。book 类的个人是 book 的主题(约 600 个主题),author 类的个人是 name 的作者,也是 isbn 类。

我也手动收集并获得了部分属于书的类别。一个对象属性是名称“hasSubject”与类别相关的单个书籍类。示例书“A”具有主题类别“S”和“F”以及……。但作为最终结果,我想应用这个公式:

sim(x,y)=(C1,1)/(C1,0+ C0,1+ C1,1)

其中C1,1表示书“X”和书“Y”属于它的类别数。(它们)和C1,0表示书“X”属于它们但书“Y”不属于它们的类别数. C0,1 表示书“y”属于它们但书“x”不属于它们的类别数。最后在两本书(“A”和“B”)之间获得相似性。不再将这个公式应用到书“A”和书“C”等等。直到在所有书籍之间获得相似性。现在您认为这项工作由 netbeans 或 sparql 在 protégé 中完成?

我想也许我告诉如果我让hasSibinling 属性代表,在每本书Compute 组已经与她共享书籍。(你认为我是什么)

4

1 回答 1

1

您可以使用 SPARQL 计算这种度量,尽管它有点难看。让我们假设一些这样的数据:

prefix dcterms: <http://purl.org/dc/terms/>
prefix : <http://example.org/books/>

:book1 a :Book ; dcterms:subject :subject1 , :subject2, :subject3 .
:book2 a :Book ; dcterms:subject :subject2 , :subject3, :subject4 .
:book3 a :Book ; dcterms:subject :subject4 , :subject5 .

有三本书。第 1 册和第 2 册有两个共同的主题,并且各有一个,而另一个则没有。第 2 册和第 3 册有一个共同主题,但第 2 册有第 3 册没有的 2 个主题,而第 3 册只有第 2 册没有的主题,第 1 册和第 3 册没有共同主题。

这里的技巧是使用一些嵌套的子查询,并在嵌套的不同级别获取不同的值(C10、C01 和 C11)。最里面的查询是

select ?book1 ?book2 (count(?left) as ?c10) where {
  :Book ^a ?book1, ?book2 .
  FILTER( !sameTerm(?book1,?book2) )
  OPTIONAL { 
    ?book1 dcterms:subject ?left .
    FILTER NOT EXISTS { ?book2 dcterms:subject ?left }
  }
}
group by ?book1 ?book2

它抓取每一对不同的书,并计算左书有而右书没有的科目数量。通过将其包装在另一个查询中,我们可以获取右侧书籍具有而左侧书籍没有的主题数量。这使得查询:

select ?book1 ?book2 (count(?right) as ?c01x) (sample(?c10) as ?c10x) where {
  {
    select ?book1 ?book2 (count(?left) as ?c10) where {
      :Book ^a ?book1, ?book2 .
      FILTER( !sameTerm(?book1,?book2) )
      OPTIONAL { 
        ?book1 dcterms:subject ?left .
        FILTER NOT EXISTS { ?book2 dcterms:subject ?left }
      }
    }
    group by ?book1 ?book2
  }

  OPTIONAL { 
    ?book2 dcterms:subject ?right .
    FILTER NOT EXISTS { ?book1 dcterms:subject ?right }
  }
}
group by ?book1 ?book2 

请注意,我们仍然必须选择?book1and ?book2sample(?c10) as ?c10x以便向外传递值。(我们必须使用该名称,?c10x因为该名称?c10已在此范围内使用。最后,我们将其包装在另一个查询中以获取常见主题并进行计算,这给了我们:

prefix dcterms: <http://purl.org/dc/terms/> 
prefix : <http://example.org/books/> 

select ?book1 ?book2 
       (count(?both) as ?c11)
       (sample(?c10x) as ?c10)
       (sample(?c01x) as ?c01)
       (count(?both) / (count(?both) + sample(?c10x) + sample(?c01x)) as ?sim)
where {
  {
    select ?book1 ?book2 (count(?right) as ?c01x) (sample(?c10) as ?c10x) where {
      {
        select ?book1 ?book2 (count(?left) as ?c10) where {
          :Book ^a ?book1, ?book2 .
          FILTER( !sameTerm(?book1,?book2) )
          OPTIONAL { 
            ?book1 dcterms:subject ?left .
            FILTER NOT EXISTS { ?book2 dcterms:subject ?left }
          }
        }
        group by ?book1 ?book2
      }

      OPTIONAL { 
        ?book2 dcterms:subject ?right .
        FILTER NOT EXISTS { ?book1 dcterms:subject ?right }
      }
    }
    group by ?book1 ?book2 
  }

  OPTIONAL { 
    ?both ^dcterms:subject ?book1, ?book2 .
  }
}
group by ?book1 ?book2
order by ?book1 ?book2

这个相当可怕的查询,应用于我们的数据,计算出以下结果:

$ arq --data data.n3 --query similarity.sparql
--------------------------------------------
| book1  | book2  | c11 | c10 | c01 | sim  |
============================================
| :book1 | :book2 | 2   | 1   | 1   | 0.5  |
| :book1 | :book3 | 0   | 3   | 2   | 0.0  |
| :book2 | :book1 | 2   | 1   | 1   | 0.5  |
| :book2 | :book3 | 1   | 2   | 1   | 0.25 |
| :book3 | :book1 | 0   | 2   | 3   | 0.0  |
| :book3 | :book2 | 1   | 1   | 2   | 0.25 |
--------------------------------------------

如果FILTER( !sameTerm(?book1,?book2) )删除该行,从而计算每本书与其自身的相似度,我们会看到正确的值 (1.0):

$ arq --data data.n3 --query similarity.sparql
--------------------------------------------
| book1  | book2  | c11 | c10 | c01 | sim  |
============================================
| :book1 | :book1 | 3   | 0   | 0   | 1.0  |
| :book1 | :book2 | 2   | 1   | 1   | 0.5  |
| :book1 | :book3 | 0   | 3   | 2   | 0.0  |
| :book2 | :book1 | 2   | 1   | 1   | 0.5  |
| :book2 | :book2 | 3   | 0   | 0   | 1.0  |
| :book2 | :book3 | 1   | 2   | 1   | 0.25 |
| :book3 | :book1 | 0   | 2   | 3   | 0.0  |
| :book3 | :book2 | 1   | 1   | 2   | 0.25 |
| :book3 | :book3 | 2   | 0   | 0   | 1.0  |
--------------------------------------------

如果您不需要保留各种 Cmn 值,那么您可以优化这一点,例如,通过计算最里面的查询中的 C01 和中间查询的下一个中的 C10 ,而不是单独投影两者, 只乘以它们的总和 (C10+C01),以便在计算 C11 的最外层查询中,只需执行 (C11 / (C11 + (C10+C01)))。

于 2013-07-20T19:15:33.797 回答