如何生成RDF數據?

版權聲明:可以任意轉載,轉載時請標明文章原始出處和作者信息:石磊

背景

知識圖譜越來越火,技術人員開始習慣使用Sparql查詢RDF數據。但是,我們如何構建一個RDF數據呢?

因爲之前互聯網上沒有相關工具介紹的文章,所以,這裏,我對常見的兩種RDF構造工具做一個介紹。

相關知識

RDF

“資源描述框架(Resource Description Framework,RDF)”成爲 W3C 推薦標準,與 XML 和 SOAP 等 Web 標準並排。RDF 可以應用於處理特殊輸入數據(如 CRM)的領域,已經廣泛用於社會網絡和自助出版軟件(如 LiveJournal 和 TypePad)。

關於RDF推薦去阮一峯的資源描述框架RDF 進行了解,因爲其介紹的淺顯易懂。

Sparql

比如說我們查詢 mysql, 使用的是sql語言,那麼我們查詢RDf數據,使用的就是SPARQL。

學習這個語言的話,推薦直接去官方學習:https://www.w3.org/TR/rdf-sparql-query/

介紹列表

  • Jena

    Java 語言編寫的,具有推理功能,適合開發和技術研究使用。

  • rdflib

    Python 語言編寫的,但是功能簡單,有基本的查詢和構建功能。

Jena

Java 程序員將越來越多地得益於具有使用 RDF 模型的技能。在本文中,我將帶您體驗惠普實驗室的開放源代碼 Jena Semantic Web Framework(請參閱 官網)的一些功能。您將瞭解如何創建和填充 RDF 模型,如何將它們持久存儲到數據庫中,以及如何使用 RDQL 查詢語言以程序方式查詢這些模型。最後,我將說明如何使用 Jena 的推理能力從本體推斷模型知識。

對於專業人員來說,大家直接閱讀官網就行,但是新手對官網很迷茫,不知道怎麼看,所以將推薦看的東西說一下。

  1. 簡單的RDF介紹和Sparql查詢相結合:http://jena.apache.org/tutorials/rdf_api.html
  2. https://github.com/apache/jena/tree/master/jena-core/src-examples 這裏有十個例子,結合博客把它看懂,基本操作就基本沒問題了。

寫triple

下面的函數分爲SPO中O是否是Node節點來區分。在註釋中舉了兩個例子。並且在主函數中給出了一個測試方式。

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;

import config.Config;

public class WriteRdf {

    public static void main(String[] args) {
        // 函數示例
        Model model = ModelFactory.createDefaultModel();
        writeAnTripleWhenObjectIsNode(model, "數組", "分面", "二維數組");
        model.write(System.out, "N3");
    }

    /**
     * 例子: <周杰倫> <年齡> '35'
     */
    public static void writeAnTripleWhenObjectIsNotNode(Model model, String s, String p, String o) {

        Property property = model.createProperty(p);
        model.createResource(s).addProperty(property, o);
    }

    /**
     * 例子: <周杰倫> <妻子> <昆凌>
     */
    public static void writeAnTripleWhenObjectIsNode(Model model, String s, String p, String o) {
        Resource resource = model.createResource(s);
        Property property = model.createProperty(p);
        RDFNode object = model.createResource(o);
        model.add(resource, property, object);
    }

}

導入RDF數據到Jena中

RDF數據格式有很多,但是jena內部的數據是以TDB形式存在的,需要把RDf這些文本文件轉化爲jena自己的模型。這裏給出三種方法:


    public static void save1() {
        String directory = "C:\\RDFdata\\Database1\\";
        Dataset ds = TDBFactory.createDataset(directory);
        Model model = ds.getDefaultModel();//這裏使用TDB的默認Model
        String source = "C:\\RDFdata\\source\\drugs.nq";
        TDBLoader.loadModel(model, source); 
        ds.end();
        System.out.println("done");
    }

    public static void save2() {
        String directory = "C:\\RDFdata\\Database2\\";
        Dataset ds = TDBFactory.createDataset(directory);
        Model model = ds.getDefaultModel();//這裏使用TDB的默認Model
        FileManager.get().readModel(model, "C:\\RDFdata\\source\\drugs.nq");
        ds.end();
        System.out.println("done");
    }

    public static void save3()  {
        Dataset ds = TDBFactory.createDataset("D:\\RDFdata\\1\\");
        String filename = "D://rdf.nt2";
        RDFDataMgr.read(ds, filename,Lang.N3);
        ds.close();
        System.out.println(" done"); 
    }

查詢

首先獲取到model

        Dataset ds = TDBFactory.createDataset("D:\\pdd\\");
        Model model = ds.getDefaultModel();

然後編寫sparql語句,再進行查詢

                String query111=
                "select (count(*) as ?num)" +
                        " Where"+
                        "{"+    
                            "?s <http://kmap.xjtudlc.com/pdd_data/property/diagnoses_icd9>  ?o. "+
                        "}";
        QueryExecution qexec = QueryExecutionFactory.create(query111, model);
        System.out.println(qexec.getQuery().toString());
        ResultSet resultSet = qexec.execSelect();

        String rerult = ResultSetFormatter.asText(resultSet);
        System.out.println(rerult);

輸出形式有很多,也可以遍歷進行輸出,並輸出自己想要的結果。

比如,我們想獲取某一個屬性o,

            ResultSet resultSet = qexec.execSelect();
        String o="";
        List<QuerySolution> rerult2 = ResultSetFormatter.toList(resultSet);
        System.out.println(rerult2.size());
        for (QuerySolution querySolution : rerult2) {
            o=querySolution.get("o").toString();
            System.out.println(o);
        }

其他

除了這些,jena的特斯就是進行推理,可以將查詢圖進行分析。這裏我用的不多,就不進行展示了。

rdflib

RDFLib工作處理RDF是一個純Python包。

RDFLib包含大多數處理RDF的東西,包括:

  1. 解析和序列化 RDF/XML, N3, NTriples, N-Quads, Turtle, TriX, RDFa and Microdata.
  2. 一個圖模型
  3. 存儲模型.
  4. SPARQL 1.1 實現 - 支持 SPARQL 1.1 查詢和更新數據.

官方網站: https://rdflib.readthedocs.io

導入文件

# 導入nt文件
from rdflib import Graph

g = Graph()

'''
format: 'rdf/xml' 'xml', 'n3', 'nt', 'trix', 'rdfa'
'''
g.parse("icd10.nt", format="n3")

# 打印圖的大小
print(len(g))  # prints 2

# 遍歷所有三元組
import pprint

for stmt in g:
    pprint.pprint(stmt)

支持的文件格式有:’rdf/xml’ ‘xml’, ‘n3’, ‘nt’, ‘trix’, ‘rdfa’

創建RDF文件

增加一個節點,並以turtle形式序列化輸出

from rdflib import Graph
g = Graph()

g.add( (bob, RDF.type, FOAF.Person) )
g.add( (bob, FOAF.name, name) )
g.add( (bob, FOAF.knows, linda) )
g.add( (linda, RDF.type, FOAF.Person) )
g.add( (linda, FOAF.name, Literal('Linda') ) )

print g.serialize(format='turtle')

Sparql查詢

# 利用SPARQL進行查詢
qres = g.query("""
    SELECT *
    WHERE {
      ?subject ?predicate  ?object
    } 
    LImit 10

""")

for row in qres:
    print(row)

對比

  1. python版本的rdflib包 更簡潔,語法簡單,更容易理解
  2. rdflib 的官方文檔更加簡潔,符合新手的認知能力,建議初學者使用python來進行最好!
  3. Jena 文檔首先需要吐槽,很不友好。
  4. Jena的持久化做的比較好,在查詢方式,序列化方式等方面做的更加專業。
  5. Jena 提供了持久化的事務能力。
  6. Jena提供了遠程調用方案,可以解決數據共享問題。我們可以開放一個a SPARQL end-point 讓其他人通過http連連接,就像DBpedia提供的查詢接口一樣。
  7. 總體來說,jena更專業一點,rdflib對新用戶更友好,功能也夠用。

PDD 與 我

作爲核心成員,發佈了一個醫療的數據集PDD,在 http://kmap.xjtudlc.com/pdd/ 同時,我們最近在整理最新的ICD10的數據集,與湘雅醫院、騰訊的醫療大數據實驗室在合作,準備利用知識圖譜進行疾病輔助診斷與藥物推薦等方面工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章