统一的标准太重要了（预先解决无形的问题）

用 Python 挖掘事故报告中的死亡人数

今天用 Python 写一个函数，用来识别土木行业事故报告中的死亡人数。我的设计思路如下：

经过观察，80% 的事故报告中有关死亡人数的记录是有规律的，即 “XX 人死亡”，其中 XX 可能是汉语数字也可能是阿拉伯数字。

于是我设计出一个正则表达式，`pattern_death = r'([\d\w]+)(人死亡 | 名工人死亡)' 用以识别出这种模式。

对安徽省的几分调查报告的测试中，我发现这种识别模式会将 “XX 人死亡” 之前的文字也提取出来，比如 “该工程有 5 人死亡”，直到遇到标点符号，因为 ([\d\w]+) 的含义是提取任意数量的汉字或数字。

于是我有设计出第二个正则表达式，pattern_death_num = r'(\d+|[零一二两三四五六七八九十百千万]+)(人死亡|名工人死亡)' ，用以识别出上一种模式识别出的句子中的数字（无论是中文还是阿拉伯的）。

之后我又下载一个第三方库 cn2an ，将中文数字转换为数学数字。

将识别到的数字存放到字典中，没有识别到数字但文本中识别出 “死亡” 的做标记 “待确认”。

虽然我在这里描述的似乎很轻松，但是你无法知道的是，我从最开始的起点走到这个目的地用了多久，以及为了识别条件、避免报错、存放识别出的数据等而为函数设计的逻辑化了多久时间。

在报了许多次错误、迭代了多次之后，这个程序基本上能运行起来了，这个思路已经可以从 393 个事故报告中提取 393-56 份 死亡人数了。

你可能会好奇，图上显示的分明是 57 份文件 “待确认”，那么已提取到数据的数量不应该是 383-57 吗？

没错，这缺少的一份就是今天我要谈论的主角。

一字之差的工作量

这一份数据一直在报错，我不得不在每个省份的文件之间依次测试，找出有问题的文件。

我发现出错的原因是：程序的确识别出了 “X 人死亡”，并且将 “X” 提取了出来，但报错的那份文件用的不是 “二人死亡”，而是是 “两人死亡”。cn2an 这个专门将表示数字的中文转化为阿拉伯数字的库，它只能识别 “二”，无法识别 “两”。

于是我又要设计出一个新的逻辑语句，如果识别出了 “两”，就将它改为 “二”，然后再用 cn2an 将其转化为阿拉伯数字。

我找到这个导致错误的原因并写出解决问题的语句，花了近半个小时。仅仅是一个字的偏差，为了使程序能够适应这种情况，却需要大量的测试。

我并非一个计算机专业的学生，我比较好奇的是，也许 “大量时间花费在解决报错上” 就是软件开发的常态？

言归正传，这是我们提取数据中很简单的一步，为了适配所有可能性，它的工作量并不小。

如果是从文本中提取 “事故性质” 这样的数据，也许描述 “事故性质” 的方式有多种多样（暂时我们不确定），不过它一定比数字要复杂，并且上下文可能没有特殊的格式，如果真是这样，单凭正则表达式可能已经无法完成目的了。

如果正则表达式无法解决这个问题，根据我目前掌握的信息来看，我们就需要复杂的 NLP 技术去识别出命名实体的词语、语义逻辑关系等，让机器理解句子，再将事故原因做分类。而这套规则，需要预设已知的数据库使代码能够理解。

如果我们真的使用 NLP 技术去提取所有事故报告中的 “事故原因”，那么为了做出一个适配所有情况的程序，其工作量一定非常大。

为什么这么费劲

我们之所以在提取数据时这么费劲，是什么原因呢？

答案显而易见，事故报告中大部分信息的记录方式都没有统一的格式，如果格式能够统一，如果每个事故报告中都有一个统一的清单，那么每一种数据只需要一个正则表达式就能够提取出来了，并且对所有文件适配。

只可惜，在事故报告的格式上，没有像秦始皇统一六国的伟大节点。

现在 ChatGPT-4 应该可以自动提取出你所需的数据，只是需要充钱。而我们老师想让我们做一个自动识别的程序，只能说有点难，哈哈。

秦始皇统一六国

秦始皇建立了中国历史上第一个统一的中央集权的封建国家，他不仅仅同意了中国，更重要的是他使书同文、车同轨、行同轮，统一文字、货币。

这些统一，不仅有利于信息的传递、规格的统一，也有助于我们中华文化的传承和发扬。

今天在写代码中遇到了这个 “两” 字引起的报错，以及对提取 “事故性质” 的工作量的思考，是否可以说明 ——统一的标准能在无形中解决许多问题呢？

我认为答案是肯定的。