
上一篇提到史丹佛大學的 Noy & McGuinness 提出一個很實用的流程,被很多人當作本體論開發 101,你可以在這裡下載。
七步驟如下:
- (Determine Domain and Scope)
- 考慮重複使用,不要從零開始 (Consider Reusing Existing Ontologies)
- 列出重要術語 (Enumerate Important Terms)
- 定義類別與階層的 is-a 關係 (Define Classes and the Class Hierarchy)
- 定義屬性 (Define Properties – Slots)
- 定義約束 (Define Facets of Slots)
- 建立實例 (Create Instances)
接下來就一步一步建構披薩本體。
七步建構披薩本體
1. 確定領域與範圍 (Determine the domain and scope)
在動手之前,先問自己:「這個本體論是用來解決什麼問題的?」這決定了複雜度邊界。
- 領域 (Domain):披薩、配料、菜單分類。
- 範圍 (Scope):
- 要涵蓋:各種披薩的分類規則 (什麼是素食?什麼是辣味?)、配料的層級 (起司、肉、蔬菜)。
- 不涵蓋:披薩的營養成分 (卡路里)、價格、庫存管理、外送路徑。
- 關鍵問題 (Competency Questions):
- 「這個披薩是素食的嗎?」
- 「有哪些披薩有放莫扎瑞拉起司?」
2. 考慮重複使用現有本體論 (Consider reusing existing ontologies)
不要重新發明輪子。
- 披薩案例:這是史丹佛大學的教學案例,所以作為學習者我們應該要從頭做起。但在真實世界中,你可能會引用「食物本體 (Food Ontology) 描述食材,或「計量單位本體論 (Units of Measure Ontology)」描述重量和尺寸。
- 實作:假設需要描述「辣度」,我們可以引用外部定義好的「辛辣等級」標準,例如大辣、中辣或小辣,而不是自己發明一套。
3. 列出重要術語 (Enumerate important terms)
先撇開階層,把腦中想到的相關詞彙全部倒出來、列舉出來。
- 清單:Pizza、Base (餅皮)、Topping (配料)、Cheese (起司)、Mozzarella (莫扎瑞拉)、Ham (火腿)、Pepperoni (義大利辣香腸)、Tomato、Spicy、Vegetarian、 American、Italian、Thin and Crispy (薄脆)…
- 目的:確保沒有遺漏核心概念,這也是未來 Class 和 Property 的候選名單。
4. 定義類別與階層 (Define the classes and the class hierarchy)
這是骨架搭建的過程,通常採用 Top-down (由上而下) 的方法。
- Top Level (頂層):
Thing -> Pizza, PizzaBase, PizzaTopping。
這三個是互斥的 disjoint - Drill Down (向下細分):
PizzaTopping -> CheeseTopping, MeatTopping, VegetableToppingCheeseTopping -> Mozzarella, ParmesanMeatTopping -> Ham, Pepperoni
注意:確保 Mozzarella is-a CheeseTopping,邏輯必須通順。
5. 定義屬性 (Define the properties of classes – Slots)
類別只是名詞,屬性是讓它們產生關聯的動詞。在 OWL 中分為兩種主要屬性:
- Object Properties (物件屬性。連接兩個類別):
hasTopping連接Pizza -> PizzaToppinghasBase連接Pizza -> PizzaBaseisToppingOf連接PizzaTopping ->Pizza,這是hasTopping的反向屬性。
- Data Properties (資料屬性。連接類別與數值):
- 雖然披薩本體論較少用,但可以想像:
hasCaloricValue是整數,hasPrice是浮點數。
- 雖然披薩本體論較少用,但可以想像:
6. 定義屬性的限制 (Define the facets of the slots)
這是最核心的邏輯定義層,也是讓機器能「推理」的關鍵。
- Cardinality (數量限制):
- 一個
Pizza必須 剛好有 1 個hasBase(Functional Property)。
- 一個
- Value Type (數值類型/範圍限制):
- Existential (∃ some):
Pizza必須有 至少一個hasBase指向PizzaBase。 - Universal (∀ only):
VegetarianPizza的hasTopping必須全部都是VegetarianTopping(或者是 Cheese/Fruit)。
- Existential (∃ some):
- Domain & Range:
hasTopping的 Domain 是Pizza,因為只有披薩能有配料;Range 是PizzaTopping,因為配料只能是配料類別。
7. 建立實例 (Create instances)
這一步在披薩案例中有個特殊的陷阱。
- 常見誤區:不少人以為「瑪格麗特披薩」是一個 Instance (實例)。
- 本體論觀點:在菜單上,
MargheritaPizza其實是一個 Class (類別),因為它代表「一種」披薩,而不是你盤子上那塊「特定的」披薩。 - 真正的實例 (Individuals):
MyOrder_001(這是我週五晚上點的那片具體的披薩)。- 我們設定
MyOrder_001是MargheritaPizza的一個 Instance。 - 機器推理:因為
MyOrder_001是MargheritaPizza,且MargheritaPizza被定義為素食,所以推論出MyOrder_001也是素食的。
用 Markdown 描述披薩本體
用 Markdown 可以描述概念模型 (Conceptual Model) 與邏輯公理 (Logical Axioms)。
## **1\. 簡介與範圍 (Introduction & Scope)**
### **1.1 目的**
本本體論旨在描述各類披薩、其組成成分(配料、餅皮)以及基於成分的分類規則。其核心目標是支援自動化推理,以判斷披薩的類別(例如:自動識別某披薩是否為素食)。
### **1.2 涵蓋範圍 (Scope)**
* **包含:** 披薩種類、餅皮種類、配料種類(肉類、蔬菜、起司、海鮮)、辛辣程度分類、素食分類。
* **不包含:** 價格、庫存量、營養成分(熱量、蛋白質)、烹飪時間。
### **1.3 關鍵提問 (Competency Questions)**
本體論構建完成後,必須能回答以下問題:
1. 這款披薩是素食披薩嗎?
2. 這款披薩屬於辛辣披薩嗎?
3. 瑪格麗特披薩(Margherita)包含哪些配料?
---
## **2\. 類別階層 (Class Hierarchy / Taxonomy)**
所有類別皆繼承自 `owl:Thing`。以下為主要的分類樹狀結構:
* **DomainConcept** (抽象層)
* **Pizza** (披薩本體)
* `NamedPizza` (如:Margherita, Americana...)
* `VegetarianPizza` (邏輯定義類別)
* `SpicyPizza` (邏輯定義類別)
* **PizzaBase** (餅皮)
* `ThinAndCrispyBase`
* `DeepPanBase`
* **PizzaTopping** (配料)
* `CheeseTopping`
* `MozzarellaTopping`
* `ParmesanTopping`
* `MeatTopping`
* `HamTopping`
* `PepperoniTopping`
* `SpicyBeefTopping`
* `VegetableTopping`
* `TomatoTopping`
* `MushroomTopping`
* `PepperTopping` (甜椒)
* `SeafoodTopping`
* `AnchoviesTopping`
**限制條件 (Disjoint Axioms):** `Pizza`, `PizzaBase`, `PizzaTopping` 彼此為 **Disjoint Classes (不相交)**。即一個實體不可能同時是披薩又是配料。
---
## **3\. 屬性定義 (Property Definitions)**
### **3.1 物件屬性 (Object Properties)**
描述類別之間的關係。
| 屬性名稱 (Label) | 定義域 (Domain) | 值域 (Range) | 特性 (Characteristics) | 描述 |
| :---- | :---- | :---- | :---- | :---- |
| **hasBase** | `Pizza` | `PizzaBase` | Functional | 披薩具有餅皮 |
| **isBaseOf** | `PizzaBase` | `Pizza` | Inverse of `hasBase` | 餅皮屬於披薩 |
| **hasTopping** | `Pizza` | `PizzaTopping` | \- | 披薩具有配料 |
| **isToppingOf** | `PizzaTopping` | `Pizza` | Inverse of `hasTopping` | 配料屬於披薩 |
| **hasIngredient** | `Pizza` | `Thing` | Transitive | 一般性的成分關係 (父屬性) |
### **3.2 資料屬性 (Data Properties)**
描述類別的數值特徵(本範疇較少使用,僅列範例)。
| 屬性名稱 | 定義域 | 值域 (Data Type) | 描述 |
| :---- | :---- | :---- | :---- |
| **hasSpicinessLevel** | `PizzaTopping` | `xsd:integer` | 辣度等級 (0-10) |
---
## **4\. 邏輯公理與限制 (Logical Axioms & Restrictions)**
此部分使用 **Manchester Syntax** 描述,這是讓推理機運作的核心規則。
### **4.1 基礎存在限制 (Existential Restrictions)**
描述一個合法的披薩必須具備的基本條件。
* **Class:** `Pizza`
* **SubClassOf:** `hasBase` **some** `PizzaBase`
* *(解釋:每一個披薩都必須至少有一個餅皮)*
### **4.2 定義類別 (Defined Classes / Equivalent Classes)**
這是推理機自動分類的依據。
#### **A. 素食披薩 (VegetarianPizza)**
如何定義什麼是素食披薩?
Class: VegetarianPizza
EquivalentTo:
Pizza
AND (hasTopping ONLY (CheeseTopping OR VegetableTopping))
**注意:** 使用 `ONLY` (Universal Quantification) 來確保**除了**起司和蔬菜外,沒有其他類型的配料(如肉類)。
#### **B. 辣味披薩 (SpicyPizza)**
Class: SpicyPizza
EquivalentTo:
Pizza
AND (hasTopping SOME (SpicyBeefTopping OR PepperoniTopping))
**注意:** 只要有(SOME)一種配料是辣的,整塊披薩就是辣的。
### **4.3 命名披薩的定義 (Named Pizza Definitions)**
描述具體菜單上的披薩配方。**關鍵在於使用 Closure Axiom(封閉公理)**。
#### **A. 瑪格麗特披薩 (MargheritaPizza)**
Class: MargheritaPizza
SubClassOf:
Pizza,
hasTopping SOME MozzarellaTopping,
hasTopping SOME TomatoTopping,
hasTopping ONLY (MozzarellaTopping OR TomatoTopping)
**邏輯解析:**
1. 必須有莫扎瑞拉起司 (SOME)。
2. 必須有番茄 (SOME)。
3. **封閉公理 (Closure):** 配料**只能是** (ONLY) 莫扎瑞拉或番茄。如果不加這一行,在開放世界假設下,推理機無法確認它是否包含其他隱藏配料。
#### **B. 美式臘腸披薩 (AmericanaPizza)**
Class: AmericanaPizza
SubClassOf:
Pizza,
hasTopping SOME PepperoniTopping,
hasTopping SOME MozzarellaTopping,
hasTopping SOME TomatoTopping,
hasTopping ONLY (PepperoniTopping OR MozzarellaTopping OR TomatoTopping)
---
## **5\. 實例範例 (Individuals / Instantiation)**
模擬真實世界的點餐資料。
* **Individual:** `MyOrder_Fri_001`
* **Types:** `Pizza`
* **Facts:**
* `hasBase` \-\> `DeepPanBase_Instance`
* `hasTopping` \-\> `Mozzarella_Instance`
* `hasTopping` \-\> `Tomato_Instance`
**預期推理結果 (Expected Reasoning Result):** 當啟動推理機 (如 HermiT) 時,`MyOrder_Fri_001` 應該會被自動歸類為:
1. `MargheritaPizza` (因為成分符合定義)
2. `VegetarianPizza` (因為成分皆為素食)
3. **不會**是 `SpicyPizza`
---
## **6\. 版本歷程 (Version History)**
* **v1.0 (2025-09-24):** 初始草案,包含基本階層與素食邏輯定義。
* **v0.9:** 僅包含類別階層 (Taxonomy),尚未加入屬性限制。
用 Semantic JSON Model 描述披薩本體
將本體論轉換為 JSON 結構,幫助軟體工程師理解如何結構化地儲存與交換「邏輯規則」。
個 JSON 結構完整對應了上述用 Markdown 制定的規格書,並將類別 (Classes)、屬性 (Properties) 與邏輯規則(Axioms) 清楚地分開。
{
"ontology_meta": {
"uri": "http://www.example.org/ontologies/pizza",
"version": "1.0",
"description": "A pizza ontology for learning OWL reasoning."
},
"schema_definitions": {
"classes": [
{
"id": "Pizza",
"parent": "Thing",
"disjoint_with": ["PizzaBase", "PizzaTopping"],
"description": "The main concept representing a pizza."
},
{
"id": "PizzaBase",
"parent": "Thing",
"subclasses": ["ThinAndCrispyBase", "DeepPanBase"],
"disjoint_with": ["Pizza", "PizzaTopping"]
},
{
"id": "PizzaTopping",
"parent": "Thing",
"subclasses": [
{ "id": "CheeseTopping", "subclasses": ["MozzarellaTopping", "ParmesanTopping"] },
{ "id": "MeatTopping", "subclasses": ["HamTopping", "PepperoniTopping"] },
{ "id": "VegetableTopping", "subclasses": ["TomatoTopping", "MushroomTopping"] }
],
"disjoint_with": ["Pizza", "PizzaBase"]
}
],
"object_properties": [
{
"id": "hasBase",
"domain": "Pizza",
"range": "PizzaBase",
"type": "Functional",
"description": "Every pizza must have exactly one base."
},
{
"id": "hasTopping",
"domain": "Pizza",
"range": "PizzaTopping",
"inverse_of": "isToppingOf",
"description": "Relationship linking a pizza to its ingredients."
}
]
},
"logical_rules": {
"restrictions": {
"note": "These rules define the requirements for a valid Pizza instance.",
"definitions": [
{
"class": "Pizza",
"constraint": {
"property": "hasBase",
"quantifier": "some",
"target": "PizzaBase"
}
}
]
},
"defined_classes": {
"note": "Classes defined by logical conditions (Reasoning targets).",
"definitions": [
{
"id": "VegetarianPizza",
"equivalent_to": {
"intersection_of": [
"Pizza",
{
"property": "hasTopping",
"quantifier": "only",
"target": ["CheeseTopping", "VegetableTopping"],
"comment": "Universal Quantification (∀): If it has toppings, they must ALL be cheese or veg."
}
]
}
},
{
"id": "SpicyPizza",
"equivalent_to": {
"intersection_of": [
"Pizza",
{
"property": "hasTopping",
"quantifier": "some",
"target": ["SpicyBeefTopping", "PepperoniTopping"],
"comment": "Existential Quantification (∃): At least one topping must be spicy."
}
]
}
}
]
},
"named_pizza_definitions": {
"note": "Recipes for specific pizzas using Closure Axioms.",
"definitions": [
{
"id": "MargheritaPizza",
"subclass_of": "Pizza",
"requirements": [
{ "property": "hasTopping", "quantifier": "some", "target": "MozzarellaTopping" },
{ "property": "hasTopping", "quantifier": "some", "target": "TomatoTopping" }
],
"closure_axiom": {
"property": "hasTopping",
"quantifier": "only",
"target": ["MozzarellaTopping", "TomatoTopping"],
"comment": "This closes the world. No other toppings are allowed."
}
}
]
}
},
"individuals_data": [
{
"id": "MyOrder_Fri_001",
"declared_type": "Pizza",
"relations": {
"hasBase": "DeepPanBase_Instance_01",
"hasTopping": [
"Mozzarella_Instance_01",
"Tomato_Instance_01"
]
},
"expected_inference": ["MargheritaPizza", "VegetarianPizza"]
}
]
}
JSON 結構解析:對應本體論概念
這份 JSON 的設計邏輯是為了對應 OWL (Web Ontology Language)。以下說明:
schema_definitions(對應 TBox – Terminology Box)
這是定義詞彙的地方。- Nested Subclasses:巢狀結構展示繼承關係 (例如,
CheeseTopping在PizzaTopping之下)。 - Disjoint With:標記
Pizza和PizzaTopping是互斥的,這在資料庫 schema 中很少見,但在本體論中非常重要。
- Nested Subclasses:巢狀結構展示繼承關係 (例如,
- logical_rules (邏輯公理)
模擬推理機的規則。quantifier: "some"(∃): 對應 OWL 的someValuesFrom。例如SpicyPizza的定義中,只要有一個配料是辣的,它就是辣味披薩。quantifier: "only"(∀): 對應 OWL 的allValuesFrom。例如VegetarianPizza的配料集合必須只包含素食類。
named_pizza_definitions(封閉公理)
例如MargheritaPizza中的closure_axiom欄位。- 這模擬了:「除此之外,沒有其他東西了」。
- 如果沒有這一段 JSON 描述,推理機就無法斷定這是一塊素食披薩,因為它會懷疑「也許還有隱藏的火腿」。
individuals_data(對應 ABox – Assertion Box)
這是實際的資料數據。- 我們只宣告它是
Pizza。 - 但透過
expected_inference欄位,我們預期系統能根據上面的規則,自動把它標記為VegetarianPizza。
- 我們只宣告它是
結語
學習描述披薩本體,不需要額外專業知識就能理解,很適合當作第一個練習題。在跟 LLM 對話的過程中,它一直要給我 OWL 和 Python 程式碼,但是都被我制止,我還是先從 Markdown 和 JSON 的描述性語言讓你看見這個結構,之後再繼續擴展。
下一篇,我繼續再用另一個範例重新走過這七個步驟,然後再進入 OWL 和 Python。同時,我也會繼續探索 Anthropic Agent Skills 和 Ontology 的組合拳應用模式。