Create Graph from Triples (with properties)¶
Creating a graph from existing triples is simple with WhyHow. You simply need to build an array of triples and run create_graph_from_triples()
.
Triples¶
A triple consists of three components: a head (subject), a relation (predicate), and a tail (object). It represents a statement or a fact about the relationship between two entities. The components of a triple are defined as follows:
Head (Subject): The head, or subject, is the entity or concept that the statement is about. It is typically represented by a node in the knowledge graph.
Relation (Predicate): The relation, also known as the predicate, defines the nature of the connection between the subject and the object. It specifies how the subject and object are related. Relations are simply strings which represent the type of relationship between the head and tail.
Tail (Object): The tail, or object, is the entity or value that the subject is related to through the predicate. It can be another node in the graph or a literal value (e.g., a string, number, or date).
Nodes¶
The head and tail objects are Nodes. A node is a data object representing a specific entity, such as a person, place, thing, or concept. Nodes are the vertices or points in a graph, and they are connected to other nodes through edges or relationships. Nodes have the following key characteristics:
Name: Each node in a graph has a name that acts as a unique identifier that distinguishes it from other nodes. This identifier can be a numeric value, a string, or any other data type that ensures uniqueness within the graph.
Label: Nodes have a label that categorizes or classifies it. Labels can group nodes based on their common characteristics or types. For example, nodes representing people can be labelled "Person", while nodes representing cities can be labeled "City".
Properties: Nodes can have associated properties or attributes that provide additional information about the entity they represent. Properties are key-value pairs that describe the node's characteristics. For example, a node representing a person can have properties like "name", "age", "gender", and "occupation".
In WhyHow, you can add properties to nodes or relationships.
Here's what your triple might look like in WhyHow:
{
"triple": {
"head": {
"label": "Person",
"name": "Alice",
"properties": {
"age": 30,
"occupation": "Engineer"
}
},
"tail": {
"label": "Company",
"name": "TechCorp",
"properties": {
"location": "San Francisco",
"industry": "Technology"
}
},
"relation": {
"name": "works_for",
"properties": {
"employment_type": "Full-time",
"department": "Engineering",
"salary_range": "$80,000 - $100,000"
}
}
}
}
Example¶
In this example, we'll create a list of triples with properties on the nodes and relations and use them to build a graph using create_graph_from_triples()
. First, we'll randomly generate a list of triples showing relationships between people and the companies they work for. Each person will have properties like age and occupation, and their relationship with the company will have properties like department and salary.
from whyhow import WhyHow, Triple, Node, Relation
from random import choice, randint, sample
from datetime import datetime, timedelta
# Dummy data for triple generation
person_names = [
"Alex", "Jordan", "Taylor", "Morgan", "Casey", "Riley", "Jamie", "Avery", "Parker", "Quinn", "Reese", "Charlie",
"Skyler", "Dakota", "Emerson", "Finley", "Harley", "Justice", "Kai", "Kendall", "Payton", "Phoenix", "River",
"Rowan", "Sage", "Shannon", "Shawn", "Tanner", "Terry", "Tristan", "Tyler", "Val", "Zion"
]
company_names = [
"TechCorp", "DataWorks", "Global Solutions", "CodeCrafters", "DataMasters", "TechSolutions", "Innovatech",
"DataTech", "CodeMasters", "TechWorks", "AISolutions"
]
occupations = ["Software Engineer", "Data Scientist", "Product Manager", "Analyst", "Designer", "Consultant"]
skills = ["Python", "JavaScript", "Data Analysis", "Machine Learning", "UI/UX Design", "Project Management"]
department = ["Engineering", "Product", "Design", "Data"]
# Generate random persons
person_nodes = {
name: Node(
label="Person",
name=name,
properties={
"age": randint(22, 65),
"occupation": choice(occupations),
"skills": ", ".join(sample(skills, k=randint(1, 3))),
"experience_years": randint(1, 20)
}
)
for name in person_names
}
# Generate random triples using the pre-created person nodes
triples = [
Triple(
head=person_nodes[name],
relation=Relation(name="worked_for", properties={"department": choice(department), "salary": randint(50000, 150000)}),
tail=Node(
label="Company",
name=choice(company_names)
)
)
for name in person_names
]
print(triples[:3])
[Triple(triple_id=None, head=Node(node_id=None, label='Person', name='Alex', chunk_ids=None, properties={'age': 35, 'occupation': 'Designer', 'skills': 'Data Analysis', 'experience_years': 11}, created_at=None, updated_at=None, graph_id=None), tail=Node(node_id=None, label='Company', name='DataTech', chunk_ids=None, properties=None, created_at=None, updated_at=None, graph_id=None), relation=Relation(name='worked_for', properties={'department': 'Product', 'salary': 106079}), chunk_ids=None, created_at=None, updated_at=None), Triple(triple_id=None, head=Node(node_id=None, label='Person', name='Jordan', chunk_ids=None, properties={'age': 25, 'occupation': 'Product Manager', 'skills': 'Python, UI/UX Design, JavaScript', 'experience_years': 14}, created_at=None, updated_at=None, graph_id=None), tail=Node(node_id=None, label='Company', name='AISolutions', chunk_ids=None, properties=None, created_at=None, updated_at=None, graph_id=None), relation=Relation(name='worked_for', properties={'department': 'Data', 'salary': 148587}), chunk_ids=None, created_at=None, updated_at=None), Triple(triple_id=None, head=Node(node_id=None, label='Person', name='Taylor', chunk_ids=None, properties={'age': 52, 'occupation': 'Designer', 'skills': 'UI/UX Design, Project Management, Machine Learning', 'experience_years': 17}, created_at=None, updated_at=None, graph_id=None), tail=Node(node_id=None, label='Company', name='Global Solutions', chunk_ids=None, properties=None, created_at=None, updated_at=None, graph_id=None), relation=Relation(name='worked_for', properties={'department': 'Data', 'salary': 79609}), chunk_ids=None, created_at=None, updated_at=None)]
Now that we have our triples, we can create a graph from them using the create_graph_from_triples()
function.
whyhow_client = WhyHow(api_key='<whyhow api key>', base_url="https://api.whyhow.ai")
workspace = whyhow_client.workspaces.create(name="Triple Property Demo")
graph = whyhow_client.graphs.create_graph_from_triples(triples=triples, workspace_id=workspace.workspace_id, name="Properties Graph")
Now, if we get the triples from the graph, we can see the properties of each node and relation.
whyhow_client = WhyHow(api_key='<whyhow api key>', base_url="https://api.whyhow.ai")
response = whyhow_client.graphs.get_all_triples(graph_id=graph.graph_id)
triples = list(response)
print(f"head properties: ",triples[0].head.properties)
print(f"relation properties: ",triples[0].relation.properties)
head properties: {'age': 28, 'occupation': 'Software Engineer', 'skills': 'Python, Machine Learning', 'experience_years': 2} relation properties: {'department': 'Design', 'salary': 97820}
Here's a look at the graph we created. Click here to check it out for yourself!