4. 财务知识图谱建模:本体设计、实体类型定义、关系类型定义

好,咱们进入正题。这一章讲的是知识图谱的“骨架”——本体设计。说白了,就是你要告诉机器:这个世界里有哪些东西,它们之间怎么扯上关系的。

我刚开始做知识图谱那会儿,犯过一个低级错误。我把“公司”和“子公司”当成两种实体来建模,结果关系乱成一锅粥。后来才明白,实体类型要抽象,关系类型要具体。这个教训,我记到现在。

4.1 本体设计:先搭骨架,再填肉

本体设计,你可以理解成盖房子的图纸。图纸画不好,后面装修再漂亮也白搭。

我个人习惯,先画一个顶层概念图。财务分析里,核心就三样东西:(实体)、有什么(属性)、和谁有关系(关系)。

核心原则:

  • 实体要少而精:别把什么都当实体。比如“董事长”和“CEO”,都是“高管”这个实体类型的一个实例。
  • 关系要明确:关系就是动词。比如“投资”、“控股”、“竞争”。动词越清晰,查询越精准。
  • 属性要够用:每个实体带哪些属性,想清楚。比如公司要有“注册资本”、“成立日期”。

下面这张图,是我常用的财务知识图谱顶层结构。你看一眼就明白了。

公司 高管 产品 行业 供应链 任职 生产 属于 上下游 投资/控股 图例:实体类型(椭圆) | 关系类型(连线+标签) | 核心实体:公司

💡 我的经验:别一上来就想把所有东西都塞进本体。先做最小可行版本,跑通一条查询路径再说。比如先只建“公司-高管-任职”这个三角关系,验证数据质量。

4.2 实体类型定义:这四种就够了

财务分析里,我一般只定义四种核心实体。多了反而乱。

4.2.1 公司(Company)

这是绝对的主角。所有关系都围着它转。

  • 属性:公司名称、股票代码、注册资本、成立日期、注册地址、法人代表、主营业务描述。
  • 实例:贵州茅台(600519.SH)、腾讯控股(00700.HK)。

4.2.2 高管(Executive)

高管是公司的“大脑”。我见过有人把“董事”和“监事”分开建模,其实没必要。统一叫“高管”,用“职位”属性区分就行。

  • 属性:姓名、性别、出生年份、学历、职位、任职起始日期、薪酬。
  • 实例:丁雄军(贵州茅台董事长)、马化腾(腾讯董事会主席)。

4.2.3 产品(Product)

产品是公司收入的来源。注意,这里的产品是“业务线”级别的,不是SKU级别的。

  • 属性:产品名称、所属行业、营收占比、毛利率、主要竞争对手。
  • 实例:飞天茅台(白酒产品)、微信(社交产品)。

4.2.4 行业(Industry)

行业是分类标签。它帮我们把公司归堆,方便做横向对比。

  • 属性:行业名称、行业代码(如申万行业分类)、平均市盈率、政策风险等级。
  • 实例:白酒行业(SW110000)、互联网行业(SW120000)。

⚠️ 避坑指南:我曾经把“供应链”也当成实体类型,结果发现它本质上是“公司”之间的关系。供应链里的每个节点,其实都是一家公司。所以后来我把“供应链”降级为关系类型,而不是实体。记住:实体是名词,关系是动词

4.3 关系类型定义:四种关系串起整个图谱

关系是知识图谱的灵魂。没有关系,实体就是孤岛。我重点讲四种最常用的关系。

4.3.1 投资关系(Invests In)

一家公司对另一家公司进行股权投资。这是财务分析里最基础的关系。

  • 方向:投资方 → 被投资方
  • 属性:投资金额、持股比例、投资时间、投资轮次(如A轮、B轮)。
  • 示例:腾讯控股 → 投资 → 美团(持股约17%)。

4.3.2 控股关系(Controls)

控股是投资的特殊形式。持股比例超过50%,或者虽然不到50%但有实际控制权。

  • 方向:控股方 → 被控股方
  • 属性:控股比例、控股方式(直接/间接)、合并报表标志(是/否)。
  • 示例:贵州茅台集团 → 控股 → 贵州茅台(600519.SH)。

关键区别:投资关系不一定会并表,但控股关系一定会并表。做财报分析时,控股关系直接影响合并报表的范围。这个坑我踩过——有一回我把一家联营公司当成了子公司来算营收,结果数据对不上,查了半天才发现是控股比例没搞清楚。

4.3.3 竞争关系(Competes With)

两家公司在同一行业或同一产品市场里抢饭吃。

  • 方向:双向(A竞争B,B也竞争A)
  • 属性:竞争领域(如“高端白酒”)、竞争强度(高/中/低)、市场份额对比。
  • 示例:贵州茅台 ↔ 竞争 ↔ 五粮液(高端白酒市场)。

4.3.4 供应链关系(Supply Chain)

一家公司是另一家公司的上游供应商或下游客户。

  • 方向:供应商 → 采购方
  • 属性:供应产品、年度交易金额、账期、依赖度(独家供应/多源供应)。
  • 示例:宁德时代 → 供应电池 → 特斯拉(上海工厂)。

4.4 实战:用Cypher定义本体

理论说完了,咱们上点代码。我用Neo4j的Cypher语言来演示怎么定义这些实体和关系。你看着眼熟就行,不用背。

// 创建实体类型(节点标签)
CREATE CONSTRAINT company_name_unique IF NOT EXISTS
FOR (c:公司) REQUIRE c.name IS UNIQUE;

CREATE CONSTRAINT executive_name_unique IF NOT EXISTS
FOR (e:高管) REQUIRE e.name IS UNIQUE;

// 创建关系类型
// 投资关系
MATCH (a:公司 {name: '腾讯控股'})
MATCH (b:公司 {name: '美团'})
CREATE (a)-[:投资 {
  金额: 40.0, 
  单位: '亿美元', 
  时间: '2018-10',
  持股比例: 0.17
}]->(b);

// 控股关系
MATCH (a:公司 {name: '贵州茅台集团'})
MATCH (b:公司 {name: '贵州茅台'})
CREATE (a)-[:控股 {
  比例: 0.54, 
  方式: '直接控股'
}]->(b);

// 竞争关系
MATCH (a:公司 {name: '贵州茅台'})
MATCH (b:公司 {name: '五粮液'})
CREATE (a)-[:竞争 {
  领域: '高端白酒',
  强度: '高'
}]->(b);

// 供应链关系
MATCH (a:公司 {name: '宁德时代'})
MATCH (b:公司 {name: '特斯拉'})
CREATE (a)-[:供应链 {
  产品: '动力电池',
  年度交易额: 200,
  单位: '亿元'
}]->(b);

💡 我的习惯:每次建完关系,我都会跑一条查询验证一下。比如查“腾讯投资了哪些公司”,看看结果对不对。数据质量是知识图谱的生命线,别偷懒。

4.5 本体设计的常见误区

最后,我总结几个我亲眼见过的翻车案例。你注意避坑。

误区 错误做法 正确做法
实体粒度太细 把“董事长”、“CEO”、“CFO”都设为独立实体类型 统一用“高管”实体,用“职位”属性区分
关系定义模糊 用“关联”这种万金油关系 用“投资”、“控股”、“竞争”等具体动词
忽略时间维度 关系不带时间属性 每个关系都加上“起始时间”和“结束时间”
过度建模 把“地址”也做成实体 地址作为“公司”的属性即可

嗯,这一章就到这儿。本体设计是知识图谱的根基,花时间想清楚,后面会省很多事。你想想看,如果一开始就把实体和关系定义歪了,后面查出来的数据你敢信吗?