Insert cell
Insert cell
Insert cell
Insert cell
kg = py`from os.path import dirname
import os, io

namespaces = {
"acq": "http://example.org/stuff/",
"foaf": "http://xmlns.com/foaf/0.1/",
}

kg = ${kglab}.KnowledgeGraph(
name = "LINQS simple acquaintance example for PSL",
base_uri = "http://example.org/stuff/",
namespaces = namespaces,
)

with io.open('acq.ttl','wb') as f:
f.write(${await kgzip
.file("kglab-main/dat/acq.ttl")
.arrayBuffer()}.tobytes())

kg.load_rdf("acq.ttl")
kg`
Insert cell
Insert cell
Insert cell
subgraph = py`
kg = ${kg}
excludes = [
kg.get_ns("rdf").type,
kg.get_ns("rdfs").domain,
kg.get_ns("rdfs").range,
]
subgraph = ${kglab}.SubgraphTensor(kg, excludes=excludes)
(subgraph, dir(subgraph), repr(subgraph))
`
Insert cell
acq_vis = py`
kg = ${kg}
VIS_STYLE = {
"foaf": {
"color": "orange",
"size": 5,
},
"acq":{
"color": "blue",
"size": 30,
},
}

pyvis_graph = ${subgraph[0]}.build_pyvis_graph(notebook=True, style=VIS_STYLE)

pyvis_graph.force_atlas_2based()
pyvis_graph.show("tmp.fig04.html")
`
Insert cell
pyVisFrame(acq_vis)
Insert cell
Insert cell
/* Maybe the jvm at https://plasma-umass.org/doppio-demo/ and https://linqs-data.soe.ucsc.edu/maven/repositories/psl-releases/org/linqs/psl-cli/2.1.0/ could get PSL working in JS */
psl = py`${kglab}.PSLModel(
name = "simple acquaintances",
)`
Insert cell
Insert cell
py`
psl = ${psl}
psl.add_predicate("Lived", size=2)
psl.add_predicate("Likes", size=2)
psl.add_predicate("Knows", size=2, closed=False)`
Insert cell
Next, we'll add a set of probabilistic [*rules*](https://psl.linqs.org/wiki/2.2.1/Rule-Specification.html), all with different weights applied:

1. "Two people who live in the same place are **more** likely to know each other"
2. "Two people who don't live in the same place are **less** likely to know each other"
3. "Two people who share a common interest are **more** likely to know each other"
4. "Two people who both know a third person are **more** likely to know each other"
5. "Otherwise, any pair of people are **less** likely to know each other"
Insert cell
py`
psl = ${psl}
psl.add_rule("Lived(P1, L) & Lived(P2, L) & (P1 != P2) -> Knows(P1, P2)", weight=20.0, squared=True)

psl.add_rule("Lived(P1, L1) & Lived(P2, L2) & (P1 != P2) & (L1 != L2) -> !Knows(P1, P2)", weight=5.0, squared=True)

psl.add_rule("Likes(P1, L) & Likes(P2, L) & (P1 != P2) -> Knows(P1, P2)", weight=10.0, squared=True)

psl.add_rule("Knows(P1, P2) & Knows(P2, P3) & (P1 != P3) -> Knows(P1, P3)", weight=5.0, squared=True)

psl.add_rule("!Knows(P1, P2)", weight=5.0, squared=True)
;`
Insert cell
Insert cell
py`${psl}.add_rule("Knows(P1, P2) = Knows(P2, P1)", weighted=False) ;`
Insert cell
Insert cell
py`${psl}.clear_model()`
Insert cell
Insert cell
subgraph_people = py`
kg = ${kg}
people_iter = kg.rdf_graph().subjects(kg.get_ns("rdf").type, kg.get_ns("foaf").Person)
people_nodes = [ p for p in sorted(people_iter, key=lambda p: str(p)) ]

subgraph_people = ${kglab}.Subgraph(kg, preload=people_nodes)
subgraph_people`
Insert cell
py`dir(${subgraph_people})`
Insert cell
Insert cell
py`sparql = """
SELECT DISTINCT ?p1 ?l
WHERE {
?p1 foaf:based_near ?l
}
"""

kg= ${kg}
# psl =

for row in kg.query(sparql):
p1 = ${subgraph_people}.transform(row.p1)
l = subgraph.transform(row.l)
psl.add_data_row("Lived", [p1, l])`
Insert cell
Insert cell
Insert cell
py`
kg = ${kg}
subgraph_people=${subgraph_people}
subgraph=${subgraph[0]}
psl=${psl}
sparql = """
SELECT DISTINCT ?p1 ?t
WHERE {
?p1 foaf:topic_interest ?t
}
"""

for row in kg.query(sparql):
p1 = subgraph_people.transform(row.p1)
t = subgraph.transform(row.t)
psl.add_data_row("Likes", [p1, t])`
Insert cell
Just for kicks, let's take a look at the internal representation of a PSL predicate, which is a `pandas.DataFrame`:
Insert cell
py`
predicate = ${psl}.model.get_predicate("Likes")
predicate.__dict__
`
Insert cell
df = py`df = psl.trace_predicate("Likes", partition="observations")
df`
Insert cell
Insert cell
targets_rowslist = py`import csv
import io

pd= ${pd}
subgraph_people = ${subgraph_people}
kg = ${kg}
psl = ${psl}
targets = []
rows_list = []

with io.open('knows_targets.txt','wb') as f:
f.write(${await kgzip
.file("kglab-main/dat/psl/knows_targets.txt")
.arrayBuffer()}.tobytes())

with open("knows_targets.txt", "r") as f:
reader = csv.reader(f, delimiter="\t")
for i, row in enumerate(reader):
p1 = int(row[0])
p2 = int(row[1])
targets.append((p1, p2))
p1_node = subgraph_people.inverse_transform(p1)
p2_node = subgraph_people.inverse_transform(p2)
if (p1_node, kg.get_ns("foaf").knows, p2_node) in kg.rdf_graph():
truth = 1.0
rows_list.append({ 0: p1, 1: p2, "truth": truth})

psl.add_data_row("Knows", [p1, p2], partition="truth", truth_value=truth)
psl.add_data_row("Knows", [p1, p2], partition="targets")

elif (p1_node, kg.get_ns("acq").wantsIntro, p2_node) in kg.rdf_graph():
truth = 0.0
rows_list.append({ 0: p1, 1: p2, "truth": truth})

psl.add_data_row("Knows", [p1, p2], partition="truth", truth_value=truth)
psl.add_data_row("Knows", [p1, p2], partition="targets")

else:
print("UNKNOWN", p1, p2)
targets, rows_list
`
Insert cell
Insert cell
Insert cell
py`df_dat = ${pd}.DataFrame(targets_rowslist[1])
df_dat.head().to_html()`
Insert cell
Insert cell
py`
sparql = """
SELECT ?p1 ?p2
WHERE {
?p1 foaf:knows ?p2 .
}
ORDER BY ?p1 ?p2
"""

for row in kg.query(sparql):
p1 = subgraph_people.transform(row.p1)
p2 = subgraph_people.transform(row.p2)
if (p1, p2) not in targets:
psl.add_data_row("Knows", [p1, p2], truth_value=1.0)
sparql = """
SELECT ?p1 ?p2
WHERE {
?p1 acq:wantsIntro ?p2 .
}
ORDER BY ?p1 ?p2
"""

for row in kg.query(sparql):
p1 = subgraph_people.transform(row.p1)
p2 = subgraph_people.transform(row.p2)
if (p1, p2) not in targets:
psl.add_data_row("Knows", [p1, p2], truth_value=0.0)
`
Insert cell
Insert cell
py`${psl}.infer()`
Insert cell
Insert cell
df_results = py`df = ${psl}.get_results("Knows")
df.head()`
Insert cell
Insert cell
py`
pd = ${pd}
dat_val = {}
df = ${df_results}
df_dat = ${pd}.DataFrame(targets_rowslist[1])
subgraph_people =${subgraph_people}

df.insert(1, "p1", "")
df.insert(2, "p2", "")

for index, row in df_dat.iterrows():
p1 = int(row[0])
p2 = int(row[1])
key = (p1, p2)
dat_val[key] = row["truth"]

for index, row in df.iterrows():
p1 = int(row[0])
p2 = int(row[1])
key = (p1, p2)

df.at[index, "diff"] = row["truth"] - dat_val[key]
df.at[index, "p1"] = str(subgraph_people.inverse_transform(p1))
df.at[index, "p2"] = str(subgraph_people.inverse_transform(p2))

df = df.drop(df.columns[[3, 4]], axis=1)
pd.set_option("max_rows", None)

df.head()`
Insert cell
Insert cell
py`${df_results}["diff"].hist();`
Insert cell
Insert cell
py`
df = ${df_results}
df[df["diff"] >= 0.4]
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
pd = py`import pandas as pd #${packagesPy}
pd`
Insert cell
kglab = py`
# make completely sure pyvis got included
import micropip
micropip.install("https://thadk.net/pyodide_packages/pyodide_18_1/pyvis-0.1.9-py2.py3-none-any.whl")


import kglab
# ${otherKglabDependencies} ${kglabDependency} ${micropipDependenciesPy}
kglab
`
Insert cell
py`dir(${kglab})`
Insert cell
py`repr(${kglab})`
Insert cell
Insert cell
import { pyVisFrame } from "@thadk/ex3_0-interactive-graph-visualization-with-pyvis"
Insert cell
import { py, pyodide } from "@thadk/pyodide-18"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more