AI图鉴

AI图鉴首页 › AI 资讯 › 把一部古典小说建模成知识图谱:红楼梦图鉴的数据、本体和单文件 HTML

把一部古典小说建模成知识图谱:红楼梦图鉴的数据、本体和单文件 HTML

来源:掘金 · 发布时间:11-04 · 由 AI图鉴每小时自动聚合

把《红楼梦》前80回整理成 JSON + OWL 本体 + 单文件 HTML:115 人、51 事、54 地、71 条逐日记录,免费开源,部署在 GitHub Pages。

把一部古典小说建模成知识图谱:红楼梦图鉴的数据、本体和单文件 HTML

最近做了一个 side project:《红楼梦·人物事件地理图鉴》,把《红楼梦》前八十回整理成一个可交互的网页——人物谱、逐日事件、地图、诗词检索,再加一张知识图谱。免费、开源。

这篇不讲红学,主要聊工程上的几个问题:数据怎么组织、本体怎么设计、古代的时辰和地名怎么"翻译"成程序能处理的东西,以及为什么最后交付的是一个单独的 HTML 文件。

一、数据来源

底本是《红楼梦脂评汇校本》(甲戌本系统),回目、正文摘句、脂批都依此本。我从版面里解出了前八十回的正文和批语,放在 data/chapters.json。

按各回统计字段 n_chars 加总,正文共 623,645 字;n_comments 加总,批语 5,634 条(其中夹有回目标记,不全是批语正文)。第十七、十八回在汇校本里未分回,所以仍是 80 条章节记录。

人物与情节插图取自清代改琦《红楼梦图咏》和孙温《绘全本红楼梦》,以 base64 形式嵌进页面(img 里共 255 张),每张都有 imgsrc / imgcap 记录出处和图注。

二、数据结构

仓库 data/ 下有四个文件。

1. honglou_data.json:页面用到的全部结构化数据,顶层键是:

people, places, events, relations, quotes, years, eras, maps,

chapters, gems, days, onto, china, img, imgsrc, imgcap

数量:people 115、places 54、events 51、relations 163、quotes(脂批)14、eras 7、gems(诗词曲赋判词等)117、days 71。一条人物记录长这样(节选):

{

"id": "jiajing", "name": "贾敬", "fam": "贾",

"role": "宁府老爷,袭爵后弃家好道",

"nick": ["炼丹翁"], "place": "玄真观",

"birth": -25, "death": "红楼十七年四月廿六夜", "death_ch": 63,

"mentions": 20, "first": 2,

"chapters": [2, 10, 13, 18, 53, 63, 64], "cls": "zhuzi"

}

人物关系用了最省事的四元组:[主体, 客体, 关系, 备注]。

["jiamu", "baoyu", "祖孙", "隔代最疼"]

细粒度的关系词(祖孙、叔侄、翁婿……)再通过 onto.rel2prop 映射到本体里的粗粒度属性,比如 "祖孙": "qinshu"(血亲眷属)。这样页面上显示"祖孙"这样贴近原文的词,图谱里又能按大类聚合。

2. chapters.json:80 条,每条字段为 num, title, start_pdf, end_pdf, body, comments:

{ "num": 1, "title": "甄士隐梦幻识通灵贾雨村风尘怀闺秀",

"start_pdf": 12, "end_pdf": 28,

"body": "甄士隐梦幻识通灵 贾雨村风尘怀闺秀① 列位看官,你道此书从何而来?……" }

start_pdf / end_pdf 保留了在原 PDF 中的页码,方便回查。

3. mentions.json:只有一个键 first_seen,记录 159 个姓名/称呼的出现统计:

"贾母": { "chapter": 3, "count_at_first": 41, "total": 1717,

"chapters": [3, 4, 5, 6, …, 80] }

注意人物谱里的"提及次数"不是直接拿这里的数——同一个人有姓名、简称、外号,需要另行归并。

4. ontology.ttl:同一套知识的 OWL / Turtle 序列化,下一节展开。

三、本体设计

本体分两层:模型层(TBox)定义类和属性,实例层(ABox)放具体的人、事、地。前缀用的是 http://example.org/honglou#。

类:7 个顶层类——人物、事件、地点、家族、纪年、脂批、作品;下挂 22 个子类。人物按身份分 7 类(主子姻眷、官宦皇亲、仆婢仆役、优伶伶人、医卜清客、方外僧道、市井平民),事件按性质分 9 类,地点按虚实分 6 类。

:人物 a owl:Class .

:事件 a owl:Class .

:地点 a owl:Class .

:主子姻眷 rdfs:subClassOf :人物 .

:诗社雅集 rdfs:subClassOf :事件 .

:园林院苑 rdfs:subClassOf :地点 .

对象属性:共 21 个。其中人物—人物关系 10 个:血亲眷属、夫妻妾室、主仆役使、朋友知交、情缘私恋、仇怨对立、师恩庇护、交易勾结、事缘交往、泛关联;其余把不同类型连起来,如 参与(人物→事件)、发生于(事件→地点)、居于、撰作、所咏、题于、位于。

:血亲眷属 a owl:ObjectProperty ; rdfs:domain :人物 ; rdfs:range :人物 .

:参与 a owl:ObjectProperty ; rdfs:domain :人物 ; rdfs:range :事件 .

:发生于 a owl:ObjectProperty ; rdfs:domain :事件 ; rdfs:range :地点 .

实例层直接引用:

:jiamu :血亲眷属 :baoyu . # 祖孙:隔代最疼

:e3 a :身世遭际 ; :hasTitle "元宵失英莲·葫芦庙火" ;

:hasSeason "红楼元年·元宵/三月十五" ; :inChapter 1 ;

:inEra :era1 ; :occursAt :gusu .

用 rdflib 解析了一下实际数据:

import rdflib

g = rdflib.Graph(); g.parse("data/ontology.ttl")

len(g) # 3428

整个 .ttl 文件解析出 3428 条 RDF 三元组(含 TBox 声明、类型断言和数据属性)。页面上图谱显示的"3311 条三元组"是 onto.triples 字段里的统计口径,两者不是同一个数,这里如实说明。实例里用到的人物关系属性有 9 种(泛关联 声明了但目前没有实例),最多的是 参与 289 条、血亲眷属 54 条、主仆役使 28 条。

四、时间建模

小说里的时间是"红楼纪年 + 农历 + 时辰",程序没法直接排序。我的做法:

- 以宝玉出生那年为"红楼元年",years 和 eras(7 段)给出每年覆盖的回次;

- days 里 71 条逐日记录,每条有 y(红楼纪年)、m、d、mo(数值月份,用于排序);

- 原文没写明日期、靠情节推定的,est: true,页面上标"约 / 推定"——71 条里有 42 条是推定的;

- 写明时辰的,用 tm_m 字段附上现代钟点,共 29 条。

比如第十四回"凤姐协理宁国府":

{ "id": "d015", "y": 12, "m": "9月", "d": "约26日", "ch": 14,

"title": "凤姐协理宁国府", "ev": "e13", "pl": "ningfu",

"tm": "卯正二刻点卯·戌初查夜",

"tm_m": "卯正二刻(6:30)点卯 · 巳正(10:00)早饭 · 午初刻(11:15)领牌回事 · 戌初(19:00)查夜" }

每个时辰两小时,分"初""正",每刻 15 分钟:卯正是 6:00,加二刻就是 6:30。

要注意:51 条 events 是情节单元,71 条 days 是带日期的流水,二者通过 ev 字段互相引用,并不是同一份清单。

五、地理建模

maps 有三层:city(天下形势)、fu(荣宁二府)、yuan(大观园)。第一层的底图是今日省级行政区划(阿里云 DataV GeoAtlas),地名落点采用周汝昌"京—宁双城"说:京都即今北京,金陵即今南京,姑苏、扬州是实录地名。

{ "id": "gusu", "name": "姑苏", "kind": "city",

"region": "江南·今江苏苏州", "cls": "zhoufu" }

有争议的地方不硬编码成定论:大如州、平安州、黑山村、大荒山等推考落点在图上用虚线标出,注明"存疑"或"一家之言";太虚幻境是梦境,不入地理。荣宁二府和大观园的平面则按黛玉进府路线、游园顺序约拟,不是实测。

六、单文件交付 + GitHub Pages

最终产物是一个约 4.4 MB 的 index.html,数据、图片、省界都内嵌,页面里没有引用任何外部 URL。好处很实际:

- 不用安装、构建,也不需要后端,双击就能打开;

- 断网能看,发给别人一个文件就够了;

- 部署到 GitHub Pages 只要把 Pages 指到 main 分支根目录。

data/ 里那几个 JSON 和 TTL 是给想复用数据的人准备的,页面本身不依赖它们。

七、开源与贡献

项目免费开源,代码和数据都在仓库里:

纪年、地名、人物关系、引文有疏漏的地方,欢迎提 Issue 或 PR。改动推定日期或有争议的落点时,请保留"约""推定""一家之言"这些标注——这个项目的原则是不把推考写成定论。

本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。

相关 AI 工具

相关免费羊毛

同源资讯

阅读原文(juejin.cn)

标题、摘要与正文均来自该信源的公开页面,版权归原作者所有;本站自动聚合与翻译,仅作出处跳转。

← 返回 AI 资讯列表AI工具图鉴首页

返回 AI图鉴首页 · 提交工具 · 商务合作 · 关于本站 · 609 款 AI 工具分类导航 · 每日 AI 热门项目与动态