Package: pyrdf2vec
What is RDF2Vec?RDF2Vec is an unsupervised technique that builds further onWord2Vec, where an
embedding is learned per word, in two ways:the word based on its context: Continuous Bag-of-Words (CBOW);the context based on a word: Skip-Gram (SG).To create this embedding, RDF2Vec first creates “sentences” which can be
fed to Word2Vec by extracting walks of a certain depth from a Knowledge
Graph.This repository contains an implementation of the algorithm in “RDF2Vec:
RDF Graph Embeddings and Their Applications” by Petar Ristoski, Jessica
Rosati, Tommaso Di Noia, Renato De Leone, Heiko Paulheim
([paper][original
code]).Getting StartedFor most uses-cases, here is howpyRDF2Vecshould be used to generate
embeddings and get literals from a given Knowledge Graph (KG) and entities:importpandasaspdfrompyrdf2vecimportRDF2VecTransformerfrompyrdf2vec.embeddersimportWord2Vecfrompyrdf2vec.graphsimportKGfrompyrdf2vec.walkersimportRandomWalkerdata=pd.read_csv("samples/countries-cities/entities.tsv",sep="\t")entities=[entityforentityindata["location"]]print(entities)# [#    "http://dbpedia.org/resource/Belgium",#    "http://dbpedia.org/resource/France",#    "http://dbpedia.org/resource/Germany",# ]transformer=RDF2VecTransformer(Word2Vec(epochs=10),walkers=[RandomWalker(4,10,with_reverse=False,n_jobs=2)],# verbose=1)embeddings,literals=transformer.fit_transform(KG("https://dbpedia.org/sparql",skip_predicates={"www.w3.org/1999/02/22-rdf-syntax-ns#type"},literals=[["http://dbpedia.org/ontology/wikiPageWikiLink","http://www.w3.org/2004/02/skos/core#prefLabel",],["http://dbpedia.org/ontology/humanDevelopmentIndex"],],),entities)print(embeddings)# [#     array([ 1.5737595e-04,  1.1333118e-03, -2.9838676e-04,  ..., -5.3064007e-04,#             4.3192197e-04,  1.4529384e-03], dtype=float32),#     array([-5.9027621e-04,  6.1689125e-04, -1.1987977e-03,  ...,  1.1066757e-03,#            -1.0603866e-05,  6.6087965e-04], dtype=float32),#     array([ 7.9996325e-04,  7.2907173e-04, -1.9482171e-04,  ...,  5.6251377e-04,#             4.1435464e-04,  1.4478950e-04], dtype=float32)# ]print(literals)# [#     [('1830 establishments in Belgium', 'States and territories established in 1830',#       'Western European countries', ..., 'Member states of the Organisation#       internationale de la Francophonie', 'Member states of the Union for the#       Mediterranean', 'Member states of the United Nations'), 0.919],#     [('Group of Eight nations', 'Southwestern European countries', '1792#       establishments in Europe', ..., 'Member states of the Union for the#       Mediterranean', 'Member states of the United Nations', 'Transcontinental#       countries'), 0.891]#     [('Germany', 'Group of Eight nations', 'Articles containing video clips', ...,#       'Member states of the European Union', 'Member states of the Union for the#       Mediterranean', 'Member states of the United Nations'), 0.939]#  ]If you are using a dataset other than MUTAG (where the interested entities have
no parents in the KG), it ishighly recommendedto specifywith_reverse=True(defaults toFalse) in the walking strategy (e.g.,RandomWalker). Such a parameterallows Word2Vecto have a better
learning window for an entity based on its parents and children and thuspredict test data with better accuracy.In a more concrete way, we provide a blog post with a tutorial on how to usepyRDF2Vechere.NOTE:this blog uses an older version ofpyRDF2Vec, some commands need
be to adapted.If you run the above snippet, you will not necessarily have the same
embeddings, because there is no conservation of the random determinism, however
it remains possible to do it (SEE:FAQ).InstallationpyRDF2Veccan be installed in two ways:fromPyPIusingpip:pipinstallpyRDF2vecfrom any compatible Python dependency manager (e.g.,poetry):poetryaddpyRDF2vecIntroductionTo create embeddings for a list of entities, there are two steps to do
beforehand:use a KG;define a walking strategy.For more elaborate examples, check theexamplesfolder.If no sampling strategy is defined,UniformSampleris used. Similarly for
the embedding techniques,Word2Vecis used by default.Use a Knowledge GraphTo use a KG, you can initialize it in three ways:From a endpoint server using SPARQL:frompyrdf2vec.graphsimportKG# Defined the DBpedia endpoint server, as well as a set of predicates to# exclude from this KG and a list of predicate chains to fetch the literals.KG("https://dbpedia.org/sparql",skip_predicates={"www.w3.org/1999/02/22-rdf-syntax-ns#type"},literals=[["http://dbpedia.org/ontology/wikiPageWikiLink","http://www.w3.org/2004/02/skos/core#prefLabel",],["http://dbpedia.org/ontology/humanDevelopmentIndex"],],),From a file using RDFLib:frompyrdf2vec.graphsimportKG# Defined the MUTAG KG, as well as a set of predicates to exclude from# this KG and a list of predicate chains to get the literals.KG("samples/mutag/mutag.owl",skip_predicates={"http://dl-learner.org/carcinogenesis#isMutagenic"},literals=[["http://dl-learner.org/carcinogenesis#hasBond","http://dl-learner.org/carcinogenesis#inBond",],["http://dl-learner.org/carcinogenesis#hasAtom","http://dl-learner.org/carcinogenesis#charge",],],),From scratch:frompyrdf2vec.graphsimportKG,VertexGRAPH=[["Alice","knows","Bob"],["Alice","knows","Dean"],["Dean","loves","Alice"],]URL="http://pyRDF2Vec"CUSTOM_KG=KG()forrowinGRAPH:subj=Vertex(f"{URL}#{row[0]}")obj=Vertex((f"{URL}#{row[2]}"))pred=Vertex((f"{URL}#{row[1]}"),predicate=True,vprev=subj,vnext=obj)CUSTOM_KG.add_walk(subj,pred,obj)Define Walking Strategies With Their Sampling StrategyAll supported walking strategies can be found on theWiki
page.As the number of walks grows exponentially in function of the depth,
exhaustively extracting all walks quickly becomes infeasible for larger
Knowledge Graphs. In order to avoid this issue,sampling strategiescan be applied. These will
extract a fixed maximum number of walks per entity and sampling the walks
according to a certain metric.For example, if one wants to extract a maximum of 10 walks of a maximum depth
of 4 for each entity using the random walking strategy and Page Rank sampling
strategy, the following code snippet can be used:frompyrdf2vec.samplersimportPageRankSamplerfrompyrdf2vec.walkersimportRandomWalkerwalkers=[RandomWalker(4,10,PageRankSampler())]Speed up the Extraction of WalksThe extraction of walks can take hours, days if not more in some cases. That’s
why it is important to use certain attributes and optimizepyRDF2Vecparameters as much as possible according to your use cases.This section aims to help you to set up these parameters with some advice.Configure then_jobsattribute to use multiple processorsBy default multiprocessing is disabled (n_jobs=1). If your machine allows
it, it is recommended to use multiprocessing by incrementing the number of
processors used for the extraction of walks:frompyrdf2vec.walkersimportRandomWalkerRDF2VecTransformer(walkers=[RandomWalker(4,10,n_jobs=4)])In the above snippet, the random walking strategy will use 4 processors to
extract the walks, whether for a local or remote KG.WARNING: using a large number of processors may violate the policy of some
SPARQL endpoint servers. This being that using multiprocessing means that
each processor will send a SPARQL request to one server to fetch the hops of
the entity it is processing. Therefore, since these requests may take place in
a short time, this server could consider them as a Denial-Of-Service attack
(DOS). Of course, these risks are multiplied in the absence of cache and when
the entities to be treated are of a consequent number.Bundle SPARQL requestsBy default the SPARQL requests bundling is disabled
(mul_req=False). However, if you are using a remote KG and have a large
number of entities, this option can greatly speed up the extraction of walks:importpandasaspdfrompyrdf2vecimportRDF2VecTransformerfrompyrdf2vec.graphsimportKGfrompyrdf2vec.walkersimportRandomWalkerdata=pd.read_csv("samples/countries-cities/entities.tsv",sep="\t")RDF2VecTransformer(walkers=[RandomWalker(4,10)]).fit_transform(KG("https://dbpedia.org/sparql",mul_req=True),[entityforentityindata["location"]],)In the above snippet, the KG specifies to the internal connector that it uses,
to fetch the hops of the specified entities in an asynchronous way. These hops
will then be stored in cache and be accessed by the walking strategy to
accelerate the extraction of walks for these entities.WARNING: bundling SPARQL requests for a number of entities considered too
large can may violate the policy of some SPARQL endpoint servers. As for the
use of multiprocessing (which can be combined withmul_req), sending a
large number of SPARQL requests simultaneously could be seen by a server as a
DOS. Be aware that the number of entities you have in your file corresponds to
the number of simultaneous requests that will be made and stored in cache.Modify the Cache SettingsBy default,pyRDF2Vecuses a cache that provides aLeast Recently Used
(LRU)policy, with a
size that can hold 1024 entries, and a Time To Live (TTL) of 1200 seconds. For
some use cases, you would probably want to modify thecache policy, increase (or decrease) the
cache size and/or change the TTL:importpandasaspdfromcachetoolsimportMRUCachefrompyrdf2vecimportRDF2VecTransformerfrompyrdf2vec.graphsimportKGfrompyrdf2vec.walkersimportRandomWalkerdata=pd.read_csv("samples/countries-cities/entities.tsv",sep="\t")RDF2VecTransformer(walkers=[RandomWalker(4,10)]).fit_transform(KG("https://dbpedia.org/sparql",cache=MRUCache(maxsize=2048),[entityforentityindata["location"]],)Modify the Walking Strategy SettingsBy default,pyRDF2Vecuses[RandomWalker(2, None,UniformSampler())]as
walking strategy. Using a greater maximum depth indicates a longer extraction
time for walks. Add to this that usingmax_walks=None, extracts more walks
and is faster in most cases than when giving a number (SEE:FAQ).In some cases, using another sampling strategy can speed up the extraction of
walks by assigning a higher weight to some paths than others:importpandasaspdfrompyrdf2vecimportRDF2VecTransformerfrompyrdf2vec.graphsimportKGfrompyrdf2vec.samplersimportPageRankSamplerfrompyrdf2vec.walkersimportRandomWalkerdata=pd.read_csv("samples/countries-cities/entities.tsv",sep="\t")RDF2VecTransformer(walkers=[RandomWalker(2,None,PageRankSampler())]).fit_transform(KG("https://dbpedia.org/sparql"),[entityforentityindata["location"]],)Set Up a Local ServerLoading large RDF files into memory will cause memory issues. Remote KGs serve
as a solution for larger KGs, butusing a public endpoint will be slowerdue to overhead caused by HTTP requests. For that reason, it is better to set
up your own local server and use that for your “Remote” KG.To set up such a server, a tutorial has been madeon our wiki.DocumentationFor more information on how to usepyRDF2Vec,visit our online documentationwhich is automatically updated
with the latest version of themasterbranch.From then on, you will be able to learn more about the use of the
modules as well as their functions available to you.ContributionsYour help in the development ofpyRDF2Vecis more than welcome. In order to
better understand how you can help either through pull requests and/or issues,
please take a look at theCONTRIBUTINGfile.FAQHow to Ensure the Generation of Similar Embeddings?pyRDF2Vec’s walking strategies, sampling strategies and Word2Vec work with
randomness. To get reproducible embeddings, you firstly need touse a seedto
ensure determinism:PYTHONHASHSEED=42pythonfoo.pyAdded to this, you mustalso specify a random stateto the walking strategy
which will implicitly use it for the sampling strategy:frompyrdf2vec.walkersimportRandomWalkerRandomWalker(2,None,random_state=42)NOTE:thePYTHONHASHSEED(e.g., 42) is to ensure determinism.Finally, to ensure random determinism for Word2Vec, you mustspecify a single
worker:frompyrdf2vec.embeddersimportWord2VecWord2Vec(workers=1)NOTE:using then_jobsandmul_reqparameters does not affect the
random determinism.Why the Extraction Time of Walks is Faster ifmax_walks=None?Currently,the BFS function(using the Breadth-first search algorithm) is used
whenmax_walks=Nonewhich is significantlyfasterthan the DFS function
(using the Depth-first search algorithm)and extract more walks.We hope that this algorithmic complexity issue will be solved for the next
release ofpyRDf2VecHow to Silence the tcmalloc Warning When Using FastText With Mediums/Large KGs?Sets theTCMALLOC_LARGE_ALLOC_REPORT_THRESHOLDenvironment variable to a
high value.ReferencingIf you usepyRDF2Vecin a scholarly article, we would appreciate a
citation:@inproceedings{pyrdf2vec,author={Gilles Vandewiele and Bram Steenwinckel and Terencio Agozzino
                  and Michael Weyns and Pieter Bonte and Femke Ongenae
                  and Filip De Turck},title={{pyRDF2Vec: Python Implementation and Extension of RDF2Vec}},organization={IDLab},year={2020},url={https://github.com/IBCNServices/pyRDF2Vec}}