Entiteiten extraheren voor kennisgrafieken
Herkenning van benoemde entiteiten, extractie van relaties en vullen van grafen.
Entiteiten extraheren voor kennisgrafieken is een gratis AI-agenten-les op CoddyKit. Dit is les 1 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject AI-agenten. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus AI-agenten bevat in totaal 4 lessen.
Wat is entiteitsextractie?
Entiteitsextractie (herkenning van benoemde entiteiten, NER) identificeert benoemde zaken in tekst: mensen, organisaties, locaties, datums en meer. Dit is de eerste stap bij het opbouwen van een kennisgrafiek uit ongestructureerde tekst.
Basisprincipes van spaCy NER
Het model en_core_web_sm van spaCy herkent standaardtypen voor entiteiten: PERSON, ORG, GPE (geopolitieke entiteit), DATE, MONEY en meer.
import spacy
# Load English model (install: python -m spacy download en_core_web_sm)
nlp = spacy.load('en_core_web_sm')
text = 'Elon Musk founded SpaceX in 2002 in Hawthorne, California. Tesla is headquartered in Austin, Texas.'
doc = nlp(text)
for ent in doc.ents:
print(f'{ent.text:30} {ent.label_:15} {spacy.explain(ent.label_)}')
# Output:
# Elon Musk PERSON People, including fictional
# SpaceX ORG Companies, agencies...
# 2002 DATE Absolute or relative dates
# Hawthorne, California GPE Countries, cities, statesEntiteiten extraheren als gestructureerde gegevens
Zet de entiteitsresultaten van spaCy om naar een gestructureerde indeling die geschikt is om in een kennisgrafiek op te slaan. Groepeer entiteiten per type en verwijder dubbele entiteiten binnen een document.
import spacy
from collections import defaultdict
nlp = spacy.load('en_core_web_sm')
def extract_entities(text: str) -> dict:
doc = nlp(text)
entities = defaultdict(set)
for ent in doc.ents:
entities[ent.label_].add(ent.text.strip())
# Convert sets to lists for JSON serialization
return {k: list(v) for k, v in entities.items()}
text = 'Apple CEO Tim Cook announced new products. The event was held in Cupertino on September 12, 2023.'
result = extract_entities(text)
import json
print(json.dumps(result, indent=2))
# {
# "ORG": ["Apple"],
# "PERSON": ["Tim Cook"],
# "GPE": ["Cupertino"],
# "DATE": ["September 12, 2023"]
# }Relatie-extractie met LLM
spaCy identificeert entiteiten, maar niet de relaties ertussen. Vraag een LLM: Wat is de relatie tussen X en Y? om verbindingen voor je kennisgrafiek te extraheren.
import openai
import json
client = openai.OpenAI(api_key='sk-...')
def extract_relations(text: str, entities: list) -> list:
if len(entities) < 2:
return []
entity_list = ', '.join(entities)
prompt = (
f'Given this text and these entities: {entity_list}\n\n'
f'Text: {text}\n\n'
'Extract relationships between the entities. '
'Return a JSON array of objects with fields: '
'subject (string), relation (string), object (string). '
'Use concise relation labels like FOUNDED_BY, WORKS_AT, LOCATED_IN, ACQUIRED_BY.'
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'}
)
result = json.loads(response.choices[0].message.content)
return result.get('relations', [])
text = 'Elon Musk founded SpaceX in Hawthorne, California.'
entities = ['Elon Musk', 'SpaceX', 'Hawthorne']
relations = extract_relations(text, entities)
print(relations)
# [{'subject': 'Elon Musk', 'relation': 'FOUNDED', 'object': 'SpaceX'},
# {'subject': 'SpaceX', 'relation': 'LOCATED_IN', 'object': 'Hawthorne'}]Entiteitsnormalisatie
Dezelfde entiteit kan in verschillende schrijfwijzen voorkomen: Elon Musk, Musk, E. Musk. Normalisatie zet deze om naar een canonieke vorm voordat je ze aan de grafiek toevoegt.
import openai
import json
client = openai.OpenAI(api_key='sk-...')
def normalize_entities(entity_mentions: list, entity_type: str) -> dict:
'''
Groups variations of the same entity together.
Returns {canonical_name: [mention1, mention2, ...]}
'''
if len(entity_mentions) <= 1:
return {m: [m] for m in entity_mentions}
mentions_str = json.dumps(entity_mentions)
prompt = (
f'These are {entity_type} entity mentions from text: {mentions_str}\n'
'Group mentions that refer to the same entity. '
'Return JSON: {"groups": [["canonical", "alias1", "alias2"], ...]}'
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'}
)
result = json.loads(response.choices[0].message.content)
normalized = {}
for group in result.get('groups', []):
if group:
canonical = group[0]
for mention in group:
normalized[mention] = canonical
return normalized
mentions = ['Elon Musk', 'Musk', 'E. Musk', 'Tim Cook']
result = normalize_entities(mentions, 'PERSON')
print(result)Dubbele entiteiten verwijderen
Controleer voordat je een entiteit in een kennisgrafiek invoegt of deze al bestaat. Gebruik benaderend vergelijken of canonieke ID's om dubbele entiteiten uit meerdere documentbronnen samen te voegen.
from difflib import SequenceMatcher
class EntityRegistry:
def __init__(self, similarity_threshold=0.85):
self.entities = {} # {canonical_name: entity_data}
self.threshold = similarity_threshold
def similarity(self, a: str, b: str) -> float:
return SequenceMatcher(None, a.lower(), b.lower()).ratio()
def find_existing(self, name: str) -> str:
for canonical in self.entities:
if self.similarity(name, canonical) >= self.threshold:
return canonical
return None
def add_entity(self, name: str, entity_type: str, metadata: dict = None) -> str:
existing = self.find_existing(name)
if existing:
print(f'Merged "{name}" -> "{existing}"')
return existing
self.entities[name] = {'type': entity_type, 'metadata': metadata or {}}
print(f'New entity: "{name}"')
return name
registry = EntityRegistry()
registry.add_entity('OpenAI', 'ORG', {})
registry.add_entity('Open AI', 'ORG', {}) # Merged
registry.add_entity('OpenAI Inc', 'ORG', {}) # Merged
registry.add_entity('Microsoft', 'ORG', {})Meerdere documenten verwerken
Verwerk documenten bij het opbouwen van een kennisgrafiek uit een corpus achtereenvolgens en verzamel de entiteiten en relaties. Houd bij uit welk document elk feit afkomstig is (herkomst).
import spacy
from typing import List, Dict
nlp = spacy.load('en_core_web_sm')
@dataclass
class KGFact:
subject: str
relation: str
obj: str
source_doc: str
def process_corpus(documents: List[Dict]) -> List:
facts = []
entity_registry = EntityRegistry()
for doc in documents:
doc_id = doc['id']
text = doc['text']
# Extract entities
spacy_doc = nlp(text)
persons = [ent.text for ent in spacy_doc.ents if ent.label_ == 'PERSON']
orgs = [ent.text for ent in spacy_doc.ents if ent.label_ == 'ORG']
# Register entities (deduplication)
for p in persons:
entity_registry.add_entity(p, 'PERSON')
for o in orgs:
entity_registry.add_entity(o, 'ORG')
print(f'Processed doc {doc_id}: {len(persons)} persons, {len(orgs)} orgs')
return entity_registry.entities
docs = [
{'id': 'doc1', 'text': 'Sundar Pichai leads Google.'},
{'id': 'doc2', 'text': 'Google CEO Sundar Pichai spoke at the conference.'}
]
entities = process_corpus(docs)Entiteitstypen voor kennisgrafieken
Ontwerp je entiteitentaxonomie voordat je de grafiek bouwt. Veelvoorkomende typen voor een zakelijke kennisgrafiek zijn: Person, Organization, Product, Location, Event, Technology. Aangepaste typen zijn afhankelijk van je domein.
ENTITY_TYPES = {
'PERSON': {
'description': 'Individual human being',
'properties': ['name', 'title', 'email'],
'spacy_labels': ['PERSON']
},
'ORGANIZATION': {
'description': 'Company, institution, or group',
'properties': ['name', 'industry', 'founded'],
'spacy_labels': ['ORG']
},
'LOCATION': {
'description': 'Geographic place',
'properties': ['name', 'country', 'coordinates'],
'spacy_labels': ['GPE', 'LOC', 'FAC']
},
'PRODUCT': {
'description': 'Product or service (custom, not in spaCy)',
'properties': ['name', 'category', 'version'],
'spacy_labels': ['PRODUCT']
}
}
# Map spaCy labels to our types
def map_spacy_to_entity_type(spacy_label: str) -> str:
for entity_type, config in ENTITY_TYPES.items():
if spacy_label in config['spacy_labels']:
return entity_type
return 'UNKNOWN'
print(map_spacy_to_entity_type('ORG')) # ORGANIZATION
print(map_spacy_to_entity_type('GPE')) # LOCATION
print(map_spacy_to_entity_type('PERSON')) # PERSONspaCy en LLM combineren
Gebruik spaCy voor snelle, goedkope entiteitsdetectie en alleen een LLM voor moeilijkere taken: relatie-extractie, het ondubbelzinnig maken van entiteiten en het verwerken van domeinspecifieke entiteiten die spaCy niet herkent.
import spacy
import openai
nlp = spacy.load('en_core_web_sm')
client = openai.OpenAI(api_key='sk-...')
def full_extraction_pipeline(text: str) -> dict:
# Step 1: Fast spaCy extraction
doc = nlp(text)
entities = [
{'text': ent.text, 'type': ent.label_}
for ent in doc.ents
if ent.label_ in ['PERSON', 'ORG', 'GPE', 'PRODUCT']
]
if len(entities) < 2:
return {'entities': entities, 'relations': []}
# Step 2: LLM relation extraction (only when we have multiple entities)
entity_names = [e['text'] for e in entities]
relations = extract_relations(text, entity_names)
return {
'entities': entities,
'relations': relations
}
text = 'Satya Nadella of Microsoft acquired Activision Blizzard for $69 billion.'
result = full_extraction_pipeline(text)
print('Entities:', result['entities'])
print('Relations:', result['relations'])Geëxtraheerde gegevens valideren
Valideer geëxtraheerde entiteiten voordat je ze in de kennisgrafiek opslaat. Controleer of entiteiten van onderwerp en object bekend zijn, relatielabels uit je goedgekeurde begrippenlijst komen en de gegevens volledig zijn.
VALID_RELATIONS = {
'FOUNDED_BY', 'WORKS_AT', 'LOCATED_IN', 'ACQUIRED_BY',
'PARTNERED_WITH', 'INVESTED_IN', 'CEO_OF', 'PRODUCT_OF'
}
def validate_relation(relation: dict, known_entities: set) -> tuple:
errors = []
subject = relation.get('subject', '')
relation_label = relation.get('relation', '')
obj = relation.get('object', '')
if not subject:
errors.append('Missing subject')
if not obj:
errors.append('Missing object')
if relation_label not in VALID_RELATIONS:
errors.append(f'Unknown relation: {relation_label}')
if subject and subject not in known_entities:
errors.append(f'Unknown entity: {subject}')
if obj and obj not in known_entities:
errors.append(f'Unknown entity: {obj}')
return len(errors) == 0, errors
known = {'Elon Musk', 'SpaceX', 'California'}
relation = {'subject': 'Elon Musk', 'relation': 'FOUNDED_BY', 'object': 'SpaceX'}
valid, errors = validate_relation(relation, known)
print('Valid:', valid, 'Errors:', errors)De grafiek stapsgewijs opbouwen
Bouw de kennisgrafiek stapsgewijs op wanneer nieuwe documenten binnenkomen. Verwerk elk document, extraheer entiteiten en relaties, verwijder dubbele entiteiten, valideer de gegevens en voeg ze toe aan of werk ze bij in de graafdatabase.
def build_knowledge_graph_incremental(new_documents: list, graph_db, entity_registry):
for doc in new_documents:
print(f'Processing document: {doc["id"]}')
# Extract
extraction = full_extraction_pipeline(doc['text'])
# Register and deduplicate entities
canonical_entities = {}
for entity in extraction['entities']:
canonical = entity_registry.add_entity(
entity['text'],
entity['type']
)
canonical_entities[entity['text']] = canonical
# Upsert node in graph
graph_db.upsert_node(canonical, entity['type'])
# Validate and insert relations
for relation in extraction['relations']:
# Map to canonical names
subj = canonical_entities.get(relation['subject'], relation['subject'])
obj = canonical_entities.get(relation['object'], relation['object'])
valid, errors = validate_relation(
{'subject': subj, 'relation': relation['relation'], 'object': obj},
set(canonical_entities.values())
)
if valid:
graph_db.upsert_edge(subj, relation['relation'], obj, doc['id'])
else:
print(f'Skipping invalid relation: {errors}')
print('Graph build pipeline defined')Kennistoets: entiteitsextractie
Test je begrip van entiteitsextractie voor kennisgrafieken.
Samenvatting van entiteitsextractie
Een complete pijplijn voor entiteitsextractie voor kennisgrafieken combineert: spaCy NER voor snelle entiteitsdetectie, relatie-extractie op basis van een LLM, entiteitsnormalisatie om schrijfwijzen aan canonieke namen te koppelen, het verwijderen van dubbele entiteiten om overbodige knopen te voorkomen, validatie vóór het invoegen en het bijhouden van de herkomst om te weten uit welk document elk feit afkomstig is.
Leer AI-agenten met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 60
- Lessen
- 239
Veelgestelde vragen
Is de les “Entiteiten extraheren voor kennisgrafieken” gratis?
Ja — de volledige tekst van “Entiteiten extraheren voor kennisgrafieken” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus AI-agenten wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus AI-agenten bevat in totaal 4 lessen.
Wat leer ik in “Entiteiten extraheren voor kennisgrafieken”?
Herkenning van benoemde entiteiten, extractie van relaties en vullen van grafen. Je oefent met AI-agenten door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met AI-agenten te beginnen?
Ervaring vooraf is niet nodig. AI-agenten op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Entiteiten extraheren voor kennisgrafieken”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over AI-agenten?
Ja. Elke les over AI-agenten bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Entiteiten extraheren voor kennisgrafieken
- Neo4j-query's vanuit agenttools
- Vector- en graafretrieval combineren
- Een kennisverrijkte agent bouwen