模糊匹配(学习一)

背景:在预处理的过程中,要将基础疾病按照ICD-10的标准,对应转换成代码,数据量大概1000~1500,尝试利用R语言进行匹配。

遇到的问题:基础疾病选用的是医生的诊断,不规范的写法导致匹配困难。

4.7更新

尝试解决一:python的批量匹配,用的是jieba库,但是匹配效果不好,可以说很差,不知道哪里的问题,刚开始摸索python,后续待解决

from gensim import corpora, similarities, models
import jieba
import pandas as pd

find = pd.read_csv("2.1.csv")   ###基础疾病

data = pd.read_csv("6.1.csv")   ###ICD-10


data_split_word = data.diease.apply(list)
dictionary = corpora.Dictionary(data_split_word.values)
data_corpus = data_split_word.apply(dictionary.doc2bow)
find_split_word = find.V1.apply(list)
dictionary2 = corpora.Dictionary(find_split_word.values)
find_corpus = find_split_word.apply(dictionary2.doc2bow)

tfidf = models.TfidfModel(data_corpus.to_list())
index = similarities.SparseMatrixSimilarity(
    tfidf[data_corpus], num_features=len(dictionary))

result = []
for corpus in find_corpus.values:
    sim = pd.Series(index[corpus])
    result.append(data.diease[sim.nlargest(3).index].values)
result = pd.DataFrame(result)
print(result)

result.rename(columns=lambda i: f"匹配{i+1}", inplace=True)
result = pd.concat([find, result], axis=1)

参考的方法见:批量模糊匹配的三种方法_小小明-代码实体的博客-CSDN博客_批量模糊匹配

后来将jieba.lcut改成list(),效果也不好,日后有空再琢磨。

尝试解决二:利用R的stringdist包,目前正在尝试,也许效果不错。

找匹配的最相似的前三项,顺便将对应的ICD代码附在后面,程序很穷举,耗时很长,不要求了。

(跑之前在excel里给待选排个序;记得算数量时不要计算空行)

library(readr)
library(stringdist)

X <- read.csv("2.csv",header=T)
SIX <- read.csv("6.1.csv",header=T)
SIX<-SIX[-1,]
Y<-matrix(nrow=1083,ncol=9)

{
  t1=proc.time()
  for(i in 1:1083){
    print(i)
    s=1000;m=1000;n=1000;q=1000
    for(j in 1:22543){
      Y[i,1]<-X[i,2]
      t<-stringdist(X[i,2], SIX[j,2],method = "jaccard")
      if(t==0){q<-t
      Y[i,2]<-SIX[j,2]
      Y[i,3]<-SIX[j,1]
      Y[i,4:9]<-NA
      break
      }
      else if(t<=s){
        if(t<=m){
          if(t<=n){
            if(t<=q){
              q<-t
              n<-q
              Y[i,3]<-Y[i,2]
              Y[i,7]<-Y[i,6]
              Y[i,2]<-SIX[j,2]
              Y[i,6]<-SIX[j,1]
            }
            else{n<-t
            m<-n
            Y[i,4]<-Y[i,3]
            Y[i,8]<-Y[i,7]
            Y[i,3]<-SIX[j,2]
            Y[i,7]<-SIX[j,1]}
          }
          else{m<-t
          s<-m
          Y[i,5]<-Y[i,4]
          Y[i,9]<-Y[i,8]
          Y[i,4]<-SIX[j,2]
          Y[i,8]<-SIX[j,1]}
        }
        else{s<-t
        Y[i,5]<-SIX[j,2]
        Y[i,9]<-SIX[j,1]}
      }
    }
  }
  t2=proc.time()
  t=t2-t1
  print(paste0('执行时间:',t[3][[1]],'秒'))
}
Y<-cbind(X[1:1083,1],Y)
write.csv( Y ,  "A.csv")


4.8更新

改了一个地方:距离小的往前放,本来在前面的往后排。

加了一个地方:在距离为0的时候,直接跳出循环,只保留最接近的选项。

最后出来的效果不错,对于短文本来说,这个的效果应该是在力求保证正确率的程序里相对较好的,至少我已经满意了。

过程中试了两个距离计算方法,一个jaccard,一个cosine,jaccard不考虑词频,cosine考虑词频。对于基础疾病来讲,jaccard的效果会好一点。

后续还需要人工进行比较,在四个候选选项里挑一个最接近的,也另有四个候选里没有正确选项的,需要自行改正,比如“冠心病”,标准写法是“冠状动脉性心脏病”,但是机器来比较几乎不可能选到正确的。(烦)

你可能感兴趣的:(R语言学习,r语言)