V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qile11
V2EX  ›  程序员

如何将文本结构化并提取数据

  •  
  •   qile11 · 2018-07-24 09:13:26 +08:00 · 4748 次点击
    这是一个创建于 2315 天前的主题,其中的信息可能已经有所发展或是发生改变。

    数据库有如下一段诊断语句

    心脏测值:略 enter    心脏位置正常,各腔室内径正常,室间隔、左室后壁厚度、回声正常,室壁运动未见明显不协调,心脏各瓣膜结构、回声正常,
    CDFI:收缩期三尖瓣可见少量反流信号。Doppler 示二尖瓣频谱 A 峰增高。enter    心包腔内未扫及明显积液回声。enter    双侧甲状腺外形对称,不大,峡部不厚,被膜光滑,腺实质回声不均匀,实质内可见多个大小不等的等回声、低回声及囊性回声,结节较大约 23×13mm,边界清楚,形态规整,较大位于右叶。CDFI:腺实质内血供不丰富。enter    右侧颈动脉后壁内膜面处可见大小约 6.7×2.0mm 的斑块附着,左侧颈动脉窦后壁内膜面处可见一大小约 7.4×2.1mm 的斑块附着;双侧椎动脉未见异常。enter    肝脏大小、形态正常,包膜完整,实质回声均匀,肝内管状结构走形、内径正常。肝静脉、门静脉内径正常,肝周间隙未见异常。enter    胆囊外形不大,轮廓清楚,囊壁不厚,囊壁上可见一大小约 6mm 的附壁高回声,胆汁透声良好,肝外胆管未见明显增粗。enter    脾脏大小、形态正常,包膜完整,实质回声均匀,脾静脉内径正常,脾周间隙未见异常。enter    胰腺大小、形态正常,包膜完整,实质回声均匀,胰管不扩张。enter    双肾大小、形态正常,包膜完整,右肾实质内可见一大小约 14mm 的囊性无回声区,边界清楚,形态规整,左肾实质回声均匀,肾窦回声密集,肾盂、肾盏不扩张,未见结石影。  enter    双侧输尿管未见明显扩张。enter    膀胱充盈良好,膀胱壁不厚,内壁光滑,腔内未见明显结石及占位回声。
    
    前列腺外形增大,宽径 41mm,前后径 42mm,上下径 43mm,轮廓清楚,实质内可见不规则片状强回声,另可见一大小约 8mm 的囊性无回声区,边界清楚,形态规整。entr
    

    我想把这段文本数据里面的各个参数提取出来,如 key 心脏测试:vaule 略、key 心脏位置:value 正常 key 前列腺外形:vaule 增大、key 前列腺宽径:value41mm、key 前列腺前后径:value42mm 、key 前列腺上下径:value43mm 这样我就可以使用 python 程序分析统计每个病因和相互关系。

    我想法是,先根据句号把文本分隔成列表,然后使用正则替换处理,但是正则也不是万能的,有些关联语句不好写正则。 方法二:使用分词方式,把文本按一个已有的分词列表进行替换比如列表['胆囊外形不大','心脏位置正常','双侧甲状腺外形对称'],存在列表里面的文本就将对应的文本替换为对应的键值对,比如有'心脏位置正常' 直接替换为:key 心脏位置:value 正常 但是这样替换有很大一部分会遗漏尤其特殊描述,比如“前列腺外形增大,宽径 41mm,前后径 42mm。。。。”这个后面的宽径和前后径就不好取,别的项目如心脏出现这个字段“宽径、前后径”也容易混肴

    想问下大家有没有好的办法,或者一些高效实用的 python 库文件可以有效实现这个功能。

    9 条回复    2018-07-24 17:35:33 +08:00
    wqzjk393
        1
    wqzjk393  
       2018-07-24 09:30:52 +08:00
    pandas.read_csv(split=xxx)
    liuzhedash
        2
    liuzhedash  
       2018-07-24 09:44:29 +08:00
    两个思路:
    简单思路:搜索关键词(就是你的 key ),后面的几个字就是 value
    复杂思路:NLP 分词,我没仔细试过,但是理论上应该可行
    --------------------
    两个思路都没法保证一个百分之白准确的信息提取,这属于看起来简单,实际上比较棘手的问题。
    wqzjk393
        3
    wqzjk393  
       2018-07-24 09:45:29 +08:00
    我觉得把不如把特征全部写一个列表里,然后遍历并正则匹配,然后结构化表示。就是说比如把把心脏测值、心脏位置什么的放列表里,然后正则遍历,如果后面有分号那么就不管它,如果没那么 replace 成加分号的
    mhycy
        4
    mhycy  
       2018-07-24 09:51:38 +08:00
    这不仅仅是个分词问题还是个语义理解的问题。
    对于目标无异常的报告基本都是自动生成的结果(提供选项医生手选)直接关键字匹配也能抓出来
    但是对于目标有异常的报告,结果是人手输入的,会非常不规则。
    mhycy
        5
    mhycy  
       2018-07-24 09:54:49 +08:00
    补充举例:这份报告中的甲状腺数据
    > 双侧甲状腺外形对称,不大,峡部不厚,被膜光滑,腺实质回声不均匀,实质内可见多个大小不等的等回声、低回声及囊性回声,结节较大约 23×13mm,边界清楚,形态规整,较大位于右叶。CDFI:腺实质内血供不丰富。
    tyss
        6
    tyss  
       2018-07-24 10:11:58 +08:00
    最近也在做文本结构化的工作,目前是通过正则进行文本分层,然后提前相应的关键字,文本样式多样化太头疼
    littlewin
        7
    littlewin  
       2018-07-24 10:17:09 +08:00
    是否考虑嵌套
    https://github.com/antlr/antlr4 可以研究一下
    takato
        8
    takato  
       2018-07-24 13:12:23 +08:00
    如果需要的是结构化数据本身,见各位的回答。

    但如果你需要的结果并不是结构化数据本身,通常应该直接绕过它,直接用 char embedding。
    同时在后面的模型中处理好后续实体之间可能的依赖关系。
    saulshao
        9
    saulshao  
       2018-07-24 17:35:33 +08:00
    这个其实是在分析一段文本。分析结果是一个预计(有限集合)中的键值对。
    我觉得这个基本的思路就一个:从小样本入手,写一个全程能跑起来的小规模程序。然后逐步扩展到大量样本。
    技术思路大概是:首先用你能想到的分隔符(做成可配置的)分割文本,然后对每段文本先抽出英文部分,再进行中文 NLP 分词(你的思路是人工干),标记 NLP 分词的结果,找出你需要的关键字(关键词),标记同义词,最后找出值来进行结构化。
    这并不能保证 100%准确,但是我觉得你持续这么干上 2 个月,应该可以满足基本需求。
    这个过程的工作量主要会消耗在人工校对关键词,以及同义词标记。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2847 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:06 · PVG 08:06 · LAX 16:06 · JFK 19:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.