• R语言
  • 如何将文本转换成结构化的指标数据?

接上贴(抓取网页数据时,如何确保想要抓的所有数据都抓下来了?),本楼主得到了类似下面的数据,想寻得方法将文本中的各项数据转换成更加标准的指标形式的结构化数据,比如xx人数是一个指标,xx元是一个指标,都单独作为一列,这样便于后续进行数据分析。

|hrefs|titles|city_name|county_name|result|
|:--:|:--:|:--:|:--:|:--:|
|https://tjgb.hongheiku.com/xjtjgb/xj2020/56049.html|维西傈僳族自治县2023年国民经济和社会发展统计公报|迪庆藏族自治州|维西傈僳族自治县|2023年末,全县养老保险参保人数113428人,其中:城乡居民养老保险参保人数97587人,其中,城镇职工养老保险参保15841人;为1043名企业退休人员发放城镇基本养老待遇3685.60万元,兑现企业退休死亡人员抚恤金、丧葬费91.6783万元;为14名离休人员发放离休人员工资289万元;为2322名机关事业退休人员发放养老金27632万元(其中统筹内基金支出18485万元,统筹外支出9147万元)。参加基本医疗保险人数共148511人,其中:城乡居民基本医疗保险参保人数136742人,城镇职工基本医疗保险参保人数11769人;全县失业保险参保6389人,工伤保险参保10527人。发放年满60周岁以上符合领取待遇人员基础性养老金2944.9939万元,发放残疾人养老补助金42.2780万元。|
|https://tjgb.hongheiku.com/xjtjgb/xj2020/48602.html|成武县2023年国民经济和社会发展统计公报|菏泽市|成武县|社会保障能力稳步提高。2023年机关事业单位退休人员8778人,发放养老待遇7.85亿元;企业单位离退休人员13220人,发放养老待遇3.69亿元;城乡居民养老保险待遇领取人员11.94万人,发放养老待遇2.51亿元;失地农民待遇领取人员7484人,基金支出1969.13万元;失业人员937人次,发放失业金146.31万元,为808名失业人员缴纳职工医疗保险费34.01万元;发放工伤待遇2469.90万元。实现全县居民养老扶贫代缴11020人;确保重度残疾人提前5年享受待遇;2023年我县落实被征地农民社会保障资金到个人账户金额3.8亿元。2023年共发放企业稳岗返还补贴26家,共计128.43万元,稳定就业岗位4047个;发放职业技能提升补贴127人,共计21.55万元;发放一次性扩岗补贴10家,惠及26人,共计3.9万元。|
|https://tjgb.hongheiku.com/xjtjgb/xj2020/36174.html|成武县2022年国民经济和社会发展统计公报|菏泽市|成武县|社会保障能力稳步提高。2022年机关事业单位退休人员8245人,发放养老待遇7.56亿元;企业单位离退休人员12448人,发放养老待遇3.41亿元;城乡居民养老保险待遇领取人员11.42万人,发放养老待遇2.26亿元;失地农民待遇领取人员6707人,基金支出1748.78万元;失业人员663人次,发放失业金101.43万元,为590名失业人员缴纳职工医疗保险费21.87万元;发放工伤待遇2233.12万元,全县居民养老扶贫代缴12357人,确保重度残疾人提前5年享受待遇工作落实到位;2022年我县落实被征地农民社会保障资金个人账户金额3.2亿元;2022年共发放企业稳岗返还补贴88家,计292.76万元,稳定就业岗位5950个;发放一次性留工培训补贴15.85万元;发放职业技能提升补贴80人,共计12.65万元。|

俺现在毫无头绪,当然,实在没办法的话,只好手动整理了。

    yuanfan 更改标题为「如何将文本转换成结构化的指标数据?

    我有一个思路,总结出城乡居民、城镇职工、机关事业单位等三类养老保险涉及的所有指标名称,然后批量匹配指标数值,不过这么干只能僵硬地匹配指标名称,如下面的栗子,涉及上下文的都没法提取出来。

    data <- data.frame(
      result = c(
        "养老保险参保人数12345人,其中:城乡居民养老保险参保人数97587人。",
        "为1043名企业退休人员发放城镇基本养老待遇3685.60万元;为2322名机关事业退休人员发放养老金27632万元(其中统筹内基金支出18485万元,统筹外支出9147万元)",
        "城乡居民养老保险参保人数9.05万人,其中领取待遇人员6.17万人",
        "2023年陵水县企业基本养老保险费征缴52986.03万元,同比增长22.12%,发放养老待遇47824.21万元,同比增长6.67%;机关养老保险费征缴19591.03万元,同比增长16.07%,发放养老待遇31774.21万元,同比增长14.42%;",
        "2023年牡丹区企业职工基本养老保险基金收入181724万元,支出182819万元。城乡居民基本养老保险基金收入39249万元,支出35593万元,机关事业单位养老保险基金收入84901万元,支出84799万元。"
      )
    )
    
    patterns <-
      c(
        "养老保险参保人数(\\d+\\.?\\d*)(人|万人|万元|亿元)[,;.]{0,1}",
        "城乡居民养老保险参保人数(\\d+\\.?\\d*)(人|万人|万元|亿元)[,;.]{0,1}"
      )
    # 提取指标的函数
    extract_indicators <- function(text, patterns) {
      sapply(patterns, function(pattern) {
        match <- regexpr(pattern, text)
        regmatches(text, match)[1]
      })
    }
    
    # 提取各行的指标
    indicators <-
      lapply(data$result, extract_indicators, patterns = patterns)
    
    # 将嵌套列表转换为数据框
    indicators_df <- do.call(rbind, lapply(indicators, function(row) {
      data.frame(matrix(unlist(row), nrow = 1, byrow = TRUE))
    }))
    
    # 合并原始数据框和提取的指标数据框
    data <- cbind(data, indicators_df)
    
    print(data)

    yuanfan

    坛子里的 markdown 表格功能是不是修过了,我记得发帖的时候:|还是😐,这会再看怎么自动给挪到代码块里杵着了……

      嗷,俺决定手动整理了,筛了近一千条数据出来人工整理(PS就是分城乡居民养老保险、企业养老保险、机关事业单位等三类,每个类别下面整理参保人数(万人) 、缴费人数(万人) 、领取待遇人员(万人) 、缴费收入(万元) 、发放待遇/支出(万元)等五个指标),每天摸鱼鼓捣一点的话,大概一两周就弄完了。虽然俺不嫌烦,但俺也嫌累呀,无论将来哪天,任何小伙伴想到更好的办法,请毫不犹豫来这里给俺讲讲呀。

      可否如此:使用tidyr::separate_rows(),用逗号或分号,将result列进行分割,将原来的一长句话拆成若干列,然后使用stringr对您需要的指标进行提取?

        或许可以试试大模型,大致的思路是先针对一条记录试出合适的提示词,限定好输出格式(比如 json),然后用 R 或者 Python 把提示词和记录拼在一起,然后一条条输给大模型处理。

        之前本地用 ollamaqwen2 进行过这样简单的尝试:

        不过本地挺慢的,可以尝试用 API,现在都有调用的文档,比如讯飞星火阿里云百炼等。

          Claireasstronaut
          用正则表达式做字符串匹配始终有限,因为我国有接近3000个县,尽管都是公文,但县区统计公报对同样的指标还是会写出来许多不同的细节。

          shitao

          实不相瞒,近一千条数据我已经手工整理了600条,剩下的打算今晚熬夜搞完算逑。

          不过你说的这个方法我记住了,如果能用自动化的方法走通这条路的话,回头我就可以把县级统计公报的数据都弄出来了。当然,这个坑先放在这里吧……

            5 天 后

            yuanfan
            我前些天遇到了类似的问题, 我有海量类似的体检报告:

            0 [血脂异常] 建议体检咨询亚健康门诊。 [尿常规异常,血肌酐偏高] 建议肾内科门诊随访。 [血胃泌素17偏低] 建议消化内科门诊随访。 [血甲状腺功能异常] 建议内分泌科门诊就诊。

            需要将其归纳为具体疾病, 疾病/健康状态, 我是这么处理的:

            1. 先验的定义为若干头用于分类, 如Cardiovascular/Urinary/Gastrointestinal等;
            2. 手动归纳20条左右, 每个头都用二分类描述;
            3. 调用GPT4 API, 用如下prompt归纳一千条作用
              我是一名医生, 你将协助我对体检结果进行打分和分类. 
              
              根据体检报告, 你需要评价如下指标: 
              
              如果心电图等证据报告患者的心血管存在损害, 或者建议中存在建议患者赴心内科门诊, 给心血管水平打分为1, 否则为0; 
              ...
              以下是一个例子, 请你按例子中的格式输出结果
              ...
            4. 检查输出结果, 用预训练对剩余的文本进行嵌入, 训练若干头的二分类模型输出结果, 保留质量较高的结果.
              不过题中更类似一个序列填充问题.

            上大模型,用prompt指定它输出json格式的数据就可以。然后一条条发送请求……