← 返回 Semantica 专题首页 🚀 SEMANTICA · COOKBOOK · 进阶系列

从非结构化文本到本体

Semantica 官方 Cookbook 中文翻译 · 第 31 / 37 篇

📦 semantica 🕸️ 知识图谱 🔎 GraphRAG

欢迎阅读这份关于从非结构化文本中抽取结构化本体的高级指南。本 notebook 探索了 Semantica 中可用的两种强大范式:

  1. 经典 NLP 流水线:使用命名实体识别(NER)和关系抽取。
  2. 生成式 AI 流水线:使用大语言模型(LLM)进行直接的概念建模。

我们将比较这两种方法,可视化结果,并验证生成的本体。

文档API 参考

1设置与安装

确保你已安装 Semantica 及其所有依赖。

# 安装 Semantica 包
!pip install -qU semantica
# 初始化日志记录器
from semantica.utils.logging import get_logger

logger = get_logger("unstructured_guide")
print("Environment setup complete.")

2输入文本

我们将使用一段描述一家科技公司的丰富文本来测试两种抽取方法。

# 定义用于测试两种抽取方法的输入文本
text_corpus = """
QuantumDynamics is a leading AI research lab founded by Dr. Elena Rostova in 2018. 
The lab is headquartered in Zurich, Switzerland, and focuses on quantum computing algorithms. 
Dr. Rostova serves as the Chief Scientist. 
The lab has released products like the Q-1 Processor and the NeuralBridge SDK. 
QuantumDynamics collaborates with major universities such as MIT and ETH Zurich.
"""

3方法 1:经典 NLP 流水线

这种方法自底向上地构建本体: 1. 抽取实体:识别名词/专有名词(例如,"QuantumDynamics"、"Zurich")。 2. 抽取关系:识别连接它们的动词(例如,"headquartered in")。 3. 生成本体:将这些三元组映射到类和属性。

优点:确定性、可追踪、可离线运行。 缺点:依赖于底层 NLP 模型的词汇量和灵活性。

from semantica.semantic_extract import NERExtractor, RelationExtractor
from semantica.ontology import OntologyGenerator, OntologyOptimizer

# 1. 初始化抽取器
ner = NERExtractor()
re = RelationExtractor()

# 2. 抽取实体
print("Extracting entities...")
entities = ner.extract(text_corpus)

# 注意:实体以 Entity 对象(数据类)返回,而不是字典。
# 我们使用点号访问属性(例如,entity.text、entity.label)。
print(f"Found {len(entities)} entities.")
for e in entities[:5]:
    print(f" - {e.text} ({e.label}) [Conf: {e.confidence}]")

# 3. 抽取关系
print("\nExtracting relationships...")
relationships = re.extract(text_corpus, entities)

# 注意:关系以 Relation 对象返回。
print(f"Found {len(relationships)} relationships.")
for r in relationships:
    print(f" - {r.subject.text} -> {r.predicate} -> {r.object.text}")

# 4. 为本体生成准备数据
# OntologyGenerator 期望字典,因此我们转换我们的对象。
# 我们还确保同时处理对象属性和可能的字典键,以增强健壮性。
entities_data = []
for e in entities:
    if hasattr(e, 'to_dict'):
        entities_data.append(e.to_dict())
    else:
        # 为没有 to_dict 的数据类进行手动转换
        entities_data.append({
            "id": getattr(e, "text", str(e)),
            "text": getattr(e, "text", str(e)),
            "type": getattr(e, "label", getattr(e, "type", "Unknown")),
            "confidence": getattr(e, "confidence", 1.0)
        })

relationships_data = []
for r in relationships:
    if hasattr(r, 'to_dict'):
        relationships_data.append(r.to_dict())
    else:
        # 为没有 to_dict 的数据类进行手动转换
        # 处理 subject/object 字段中嵌套的 Entity 对象
        subj = r.subject
        obj = r.object
        subj_text = getattr(subj, "text", str(subj))
        obj_text = getattr(obj, "text", str(obj))

        relationships_data.append({
            "source": subj_text,
            "target": obj_text,
            "type": getattr(r, "predicate", getattr(r, "type", "related_to")),
            "confidence": getattr(r, "confidence", 1.0)
        })

# 5. 生成结构
generator = OntologyGenerator()
nlp_ontology = generator.generate_ontology(
    {"entities": entities_data, "relationships": relationships_data},
    name="QuantumOntologyNLP"
)

# 6. 优化(清理)
optimizer = OntologyOptimizer()
nlp_ontology = optimizer.optimize_ontology(nlp_ontology, remove_redundancy=True)

print(f"\nGenerated NLP Ontology with {len(nlp_ontology['classes'])} classes and {len(nlp_ontology['properties'])} properties.")

4方法 2:生成式 AI 流水线(LLM)

这种方法使用大语言模型来"阅读"文本并直接提出一个模式。

优点:上下文感知、能处理歧义、生成类似人类的类名。 缺点:非确定性、需要 API 访问。

注意:此步骤需要配置好的 LLM 提供方(例如,OpenAI)。

from semantica.ontology import LLMOntologyGenerator

try:
    # 初始化 LLM 生成器(确保在环境变量中设置了 OPENAI_API_KEY)
    llm_gen = LLMOntologyGenerator(provider="openai", model="gpt-4")

    print("Generating ontology with LLM...")
    llm_ontology = llm_gen.generate_ontology_from_text(
        text=text_corpus,
        name="QuantumOntologyLLM"
    )

    print(f"Generated LLM Ontology with {len(llm_ontology['classes'])} classes and {len(llm_ontology['properties'])} properties.")
    print("Classes detected:", [c['name'] for c in llm_ontology['classes']])

except Exception as e:
    print(f"Skipping LLM generation: {e}")
    llm_ontology = None

5用可视化比较结果

让我们并排可视化两个本体(如果可用),以查看结构上的差异。NLP 模型往往更字面化,而 LLM 模型往往更概念化。

# 并排可视化两个本体以比较结构差异
from semantica.visualization import OntologyVisualizer

visualizer = OntologyVisualizer()

# 可视化 NLP 流水线生成的本体
print("--- NLP Approach Visualization ---")
fig_nlp = visualizer.visualize_structure(nlp_ontology, output="interactive")
if fig_nlp: fig_nlp.show()

# 如果 LLM 本体可用,则一并可视化
if llm_ontology:
    print("--- LLM Approach Visualization ---")
    fig_llm = visualizer.visualize_structure(llm_ontology, output="interactive")
    if fig_llm: fig_llm.show()

6导出为 OWL

最后,我们选择最佳模型(或使用 ReuseManager 合并它们,这在其他指南中介绍)并将其导出。

from semantica.export import OWLExporter

exporter = OWLExporter()

# 默认导出 NLP 本体,或者如果偏好则导出 LLM 本体
target_ontology = llm_ontology if llm_ontology else nlp_ontology

output_file = "quantum_ontology.ttl"
exporter.export(target_ontology, output_file, format="turtle")
print(f"Successfully exported ontology to {output_file}")

7小结

你已经学会了: 1. 以编程方式抽取本体:使用 NERExtractor 进行可靠的、数据驱动的建模。 2. 用 AI 生成本体:使用 LLMOntologyGenerator 进行概念性的、高层次的建模。 3. 可视化与比较:使用 OntologyVisualizer 检查结构差异。 4. 验证与导出:在保存为 OWL 标准之前确保质量。