Healthsea:用于探索健康补剂效果的端到端spaCy管道
2021年12月15日 • 38分钟阅读
博客:spaCy, Prodigy | 命名实体识别 | 文本分类 | 生物医学
利用机器学习和自然语言处理创造更好的健康获取方式。本文介绍了Healthsea的开发历程,这是一个端到端的spaCy管道,用于分析用户对补充产品的评论并提取其对健康的潜在影响。
大家好,我是Edward!我是一名机器学习工程师。在团队的共同努力下,我们一直在开发Healthsea,以进一步扩展spaCy宇宙。在这篇博客中,我将带大家了解训练不同NLP模型、创建自定义组件并将它们组装成spaCy v3管道的过程!
目录
- 🪐 第1节:Healthsea介绍
- 📝 第2节:理解问题
- ✨ 第3节:命名实体识别
- 🐾 第4节:Clausecat
- ⚙️ 第5节:生产环境中的Healthsea
- 🚀 第6节:历程
第1节:Healthsea介绍
1.1 创造更好的健康获取方式
Healthsea分析与健康影响相关的补充剂用户评论。基于此分析,为特定用户查询提供产品推荐。对于许多人来说,补充剂是维持健康和实现个人目标的补充手段。由于越来越受欢迎,消费者可以获得更多种类的产品。
例如维生素D3(胆钙化醇,维生素D的四种形式之一),当皮肤暴露在UVB光下时会自然产生。特别是在冬季和阳光不足的地方,人们经常补充维生素D3以预防缺乏并支持健康生活方式。然而,市场上大多数产品可能是多余的,或者以“数量优先于质量”的方式生产以最大化利润。由此产生的产品白噪声使得很难找到合适的补充剂。
1.2 预期内容
本文介绍了一种分析用户评论的技术方法,并作为概念验证。我们利用spaCy内置的命名实体识别和文本分类功能,结合自定义创建的子句分割和实体掩码组件,构建并训练了一个机器学习管道。
重要提示:Healthsea是一个实验性项目,结果不应作为解决健康问题的基础。在谨慎解读的前提下,探索这一领域的数据可能具有价值。
第2节:理解问题
2.1 解构评论
大多数情况下,评论是衡量产品质量的良好指标。它们可以提供关于口味、服务、运输,尤其是健康效果的有趣见解。基于此,第一个挑战是检测并过滤与健康相关的评论。
我们可以将“关节疼痛”作为一个指标,因为它与健康问题相关联。可以安全地假设,每次提到健康方面(如关节疼痛)都与描述该方面如何被产品影响的描述相关。
2.2 健康方面
为了找到健康方面,我们需要定义它们。首先想到的概念是疾病和症状,通常希望通过“减少”它们来改善。ICD-11(国际疾病分类)是一个包含各种疾病和症状健康信息的数据库。
评论也可能包含更普遍的健康问题,如“吃饭时疼痛”。我们将ICD-11分类术语和普遍健康问题这一组标记为Condition。
我们还希望检测既不是疾病也不是症状的健康方面,例如“让我的皮肤焕发光泽”、“现在睡眠好多了”、“提高了我的精力水平”。这些是通常希望“增加”的健康方面,我们称之为Benefit。
2.3 健康效果
检测到Condition或Benefit实体后,下一步是提取它们如何受到产品影响。我们可以使用“增加”和“减少”作为指标,将健康效果分类为正向或负向:
- “这增加了我的condition” → 负向
- “这减少了我的condition” → 正向
- “这增加了我的benefit” → 正向
- “这减少了我的benefit” → 负向
如果健康方面既未增加也未减少,则视为Neutral效果。我们还添加了一个Anamnesis(既往史)类,作为一个临时缓存,用于收集和链接相关信息。
2.4 数据是一切
我们使用来自某在线补剂市场的数据。数据集包含多达100万条匿名评论,涵盖10,000种产品,并包含有用的元信息,如产品评分和有用计数。数据还包含产品成分,使我们能够提供产品和成分推荐。
在数据清洗方面,我们过滤了所有非英语评论,排除了词数低于一定阈值的评论,并将它们格式化为utf-8。
2.5 完整管道
我们将分析分解为多个较小的处理步骤:检测健康方面、分类健康效果、汇总所有信息等。因此,我们将其实现为端到端管道,可以添加只关注单一任务的模块化组件。
第3节:命名实体识别
为了检测健康方面,我们使用命名实体识别(NER),即识别文本中不重叠的跨度(如专有名词和类似表达)的任务。我们将使用spaCy内置的NER架构,训练带有两个标签(Condition和Benefit)的模型。
3.1 标注规则
标注数据是训练模型的第一步,事先考虑一致的标注规则至关重要。我们使用第2.2节中为健康方面定义的规则。标注过程中,我们将确保考虑由多个词/数字组成的实体(如“2型糖尿病”)和缩写(如“ADHD”)。
3.2 Prodigy
本项目使用Prodigy进行数据标注。Prodigy是一个由主动学习驱动的强大标注工具,支持各种NLP任务。其可视化界面使得标注和处理大量数据更加容易,同时通过为当前任务提供特殊配方来提高效率。
3.3 标注
NER模型的标注包含5060个示例,其中1893个示例提及一个或多个实体,3167个无实体:
| 示例类型 | 数量 | 百分比 |
|---|---|---|
| 有实体 | 1893 | 37.41% |
| 无实体 | 3167 | 62.59% |
| 总计 | 5060 | 100% |
3.4 训练
spaCy v3引入了一个配置系统,允许在单个文件中管理管道中的所有超参数和设置。管道目前包含一个Tok2Vec组件和一个EntityRecognizer组件。
我们准备了三种配置进行评估:
- Tok2Vec嵌入
- 带预训练向量的Tok2Vec嵌入
- Transformer嵌入(albert-base-v2)
3.5 评估
使用Weights & Biases跟踪训练结果。预训练帮助模型表现稍好,并在训练早期提高准确率。两者平均F1分数均接近0.8。Transformer表现更好,但运行时间更慢。
第4节:Clausecat
为了将健康效果分类为正向、负向、中性和既往史四类,我们使用文本分类。目标是让模型学习哪些词表示“增加”、“减少”或都不表示。
4.1 子句分割
当句子包含多个健康方面时,我们需要将句子分割成子句。例如:“这对关节疼痛很好,但也引起了皮疹。”分割后得到两个子句,每个子句恰好包含一个健康方面。
为了处理类似“这对关节疼痛很好,但对髋部疼痛不好”的情况,我们不进行简单分割,而是创建同一句子的两个版本,每个版本掩码不同的实体。掩码使用通用标记(如_CONDITION_)替换相关实体,有助于模型更好地泛化。
4.2 Benepar
我们使用Benepar解析器实现子句分割,这是一个执行成分句法分析的spaCy宇宙组件。成分句法分析提供了更多关于并列结构的细节。
4.3 分割组件
创建自定义spaCy组件ClauseSegmentation,执行基于Benepar和NER结果的分割和掩码逻辑。组件将分割索引保存在自定义属性._.clauses中。
4.4 Clausecat组件
修改内置的textcat组件以支持掩码和分割逻辑,命名为Clausecat。创建自定义Thinc模型,将自定义掩码层链接到现有textcat模型。
4.5 聚合组件
聚合组件合并Clausecat的预测,并创建患者信息缓存以链接健康方面和健康效果。当同一健康方面在评论中被多次提及时,聚合多个预测为最终分类,保存在._.health_effects中。
4.6 标注
在标注Clausecat数据之前,我们以与训练时相同的方式预处理数据:分割评论、掩码实体,然后进行标注。
4.7 训练
最终管道包含以下组件:sentencizer、tok2vec、ner、benepar、segmentation、clausecat、aggregation。
4.8 评估
预训练对clausecat性能的提升远大于对NER模型的提升。负向和既往史类由于样本不平衡表现较差,但预训练显著提升了这两个类的准确率。
第5节:生产环境中的Healthsea
管道构建完成后,可通过spacy package打包并通过pip安装使用。
5.1 端到端评估
管道能正确处理简单评论,也能处理复杂情况如:“这对膝盖疼痛完美,但对髋部疼痛无效” → 正确分割并分别预测为正向和中性。既往史类和工作: “医生诊断我患有失眠。服用产品后症状消失!” → 正确识别为既往史后接正向。
5.2 大规模分析
使用Healthsea分析了100万条评论的完整数据集,基于结果提供产品推荐。
5.3 虚假评论
通过检测可疑行为(如每天写多条评论、许多5星或0星评论、完全相同内容的评论)来识别虚假评论。约12%的客户被标记为“可疑”,其评论将受到惩罚分数以降低影响。
5.4 评分结果
评分公式考虑了效果分数、评分分数、有用分数和可疑分数。产品分数还考虑了提及比例,帮助评论较少但提及率高的产品获得更高分数。
5.5 聚类健康方面
使用预训练权重计算相似度,在90%相似度阈值下对实体进行聚类,以改善搜索。
第6节:历程
成功构建了Healthsea管道,现在可以根据评论者的反馈提供产品推荐。Healthsea的架构历经两年开发,从简单的基于规则的完全不奏效的情感分析开始。
未来计划:
- 应用关系抽取和共指消解识别文本中的产品提及
- 将实体链接与ICD-11集成
- 获取更多数据和标注
- 使用图数据库和搜索引擎返回产品推荐FINISHED