每个发达市场都会发布其产品召回信息。欧盟设有“安全门”系统,法国在此基础上运营“RappelConso”平台,美国则将相关工作分散由消费品安全委员会、国家公路交通安全管理局以及三个独立的食品药品监督管理局执法数据库负责。所有这些信息都是免费的、公开的,且大多数都提供了应用程序接口。
因此,查询某产品是否被召回本应是一件简单的事。
然而事实并非如此,其原因比“数据结构模式不同”更为有趣。以下是我们将来自七个来源的十七万六千条召回记录标准化为一个可查询的统一数据集后得出的发现。
数据结构模式确实不同,但这只是简单部分
“安全门”系统以每周报告的形式发布可扩展标记语言文件。“RappelConso”是一个基于 OpenDataSoft 的实例,提供 JavaScript 对象表示法应用程序接口。国家公路交通安全管理局提供包含管道符分隔平面文件的压缩数据包。openFDA 提供带有适当分页功能的整洁 JavaScript 对象表示法数据。消费品安全委员会拥有一个表现基本稳定的表述性状态转移应用程序接口。
将五种数据结构映射到一种模式上,是一项为期一周的枯燥工作,但终点清晰可见。你为每个数据源编写一个标准化程序,编写测试用例,然后即可完成。没有人的项目会在此处失败。
真正的难点在于,各数据源对什么是召回存在分歧。
在 openFDA 的执法报告中,召回事件中的每个产品占一行:一个涉及四十个受影响批次号的事件会生成四十行共享同一个event_id(事件标识符)的记录。一条“安全门”通知是每条通知占一行,可能涵盖同一制造商的多种产品。国家公路交通安全管理局的数据是每次活动占一行,可能涵盖跨越数年的多种车型。
如果在不同数据源之间天真地进行去重,会导致统计不足,因为同样的实际危害合法地以三种不同的记录类型出现。如果完全不去重,客户搜索条形码时,一个事件会得到四十个几乎相同的命中结果。这两种情况都不是人们想要的。
我们保持原始数据源的粒度,并在标识符层面进行协调。如果一个全球贸易项目代码同时出现在 openFDA 的一行记录和“安全门”的一条通知中,查询结果将返回两者,并且从数据负载中可以明显看出,这是两个机构在描述同一种危害,而非两种危害。这一决策并不光鲜,但却是整个项目中影响最为深远的一个。
标识符存在于文本叙述中,而非字段中
你真正想要搜索的内容——条形码、车辆识别代号、型号——通常不是一个独立的字段。
以下是一个真实的 openFDA code_info(代码信息)值,经过轻微修剪:
批次 #1234567,有效期至 2027年03月;通用产品代码 0 36000 29145 2;还包括批次 1234568、
1234569(通用产品代码 036000291452),分销至加利福尼亚州、内华达州、亚利桑那州
这段文字在一个没有固定分隔符的自由文本字段中,包含了以两种写法呈现的一个全球贸易项目代码和三个批次代码。食品药品监督管理局并非疏忽大意。这个字段是专为人类阅读召回通知而设计的,并且很好地完成了这一任务。
因此,必须从文本叙述中提取标识符,这意味着需要进行正则表达式处理,而对自由文本进行正则表达式处理必然会产生误报。0 36000 29145 2 是一个全球贸易项目代码。同样,一个恰好位于“通用产品代码”一词旁边的十二位订单参考号也可能被误判。区分的关键特征在于校验位:真实全球贸易项目代码的最后一位是其他数字的模十校验和,而随机生成的十二位数字通过该测试的概率仅为十分之一。
验证校验位大约需要十五行代码,并能剔除天真正则表达式找到的约五分之一的候选项。如果跳过这一步,你的应用程序接口将会自信地报告针对那些根本不是条形码的标识符的召回信息。
其推论更为重要:无效的标识符必须被拒绝,绝不能返回结果。
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。