文本相似度计算

文本相似度计算方案

  • TF-IDF
  1. 基本概念

    TF-IDF是Term Frequency-Inberse Document Frequency的缩写,即‘词频-逆序文本频率’。它由两部分组成,TF和IDF
    TF:词频,文本中各个词的出现频率,并作为文本特征
    IDF:IDF反映了一个词再所有文本中出现的频率,如果一个词在很多文本中出现过,那么它的IDF值应该很低。而反过来如果一个词在比较少的文本中出现,那么它的IDF值比较高。一个极端的情况就是,如果一个词在所有文本中都出现,那么他的IDF值应该是0.
    T F ( w , D i ) = c o u n t ( w ) ∣ D i ∣ TF(w,D_i)=\frac{count(w)}{|D_i|} TF(w,Di)=Dicount(w)
    其中count(w)为关键词w出现的次数, ∣ D i ∣ |D_i| Di为文档 D i D_i Di中所有词的数量
    I D F ( w ) = l o g N 1 + ∑ i = 1 N I ( w , D i ) IDF(w)=log\frac{N}{1+\sum_{i=1}^NI(w,D_i)} IDF(w)=log1+i=1NI(w,Di)N
    T F − I D F = T F ( w , D i ) ∗ I D F ( w ) TF-IDF=TF(w,D_i)*IDF(w) TFIDF=TF(w,Di)IDF(w)

  2. 相似度

    求TF-IDF向量的余玄相似度,值越大越相似

  3. 实例:

     from gensim import corpora, models, similarities
     raw_documents = [  
         '0无偿居间介绍买卖毒品的行为应如何定性',  
         '1吸毒男动态持有大量毒品的行为该如何认定',  
         '2如何区分是非法种植毒品原植物罪还是非法制造毒品罪',  
         '3为毒贩贩卖毒品提供帮助构成贩卖毒品罪',  
         '4将自己吸食的毒品原价转让给朋友吸食的行为该如何认定',  
         '5为获报酬帮人购买毒品的行为该如何认定',  
         '6毒贩出狱后再次够买毒品途中被抓的行为认定',  
         '7虚夸毒品功效劝人吸食毒品的行为该如何认定',  
         '8妻子下落不明丈夫又与他人登记结婚是否为无效婚姻',  
         '9一方未签字办理的结婚登记是否有效',  
         '10夫妻双方1990年按农村习俗举办婚礼没有结婚证 一方可否起诉离婚',  
         '11结婚前对方父母出资购买的住房写我们二人的名字有效吗',  
         '12身份证被别人冒用无法登记结婚怎么办?',  
         '13同居后又与他人登记结婚是否构成重婚罪',  
         '14未办登记只举办结婚仪式可起诉离婚吗',  
         '15同居多年未办理结婚登记,是否可以向法院起诉要求离婚'  
     ]  
    
     import jieba
     texts = [[word for word in jieba.cut(document, cut_all=True)] for document in raw_documents]
     dictionary = corpora.Dictionary(texts)
     corpus = [dictionary.doc2bow(line) for line in texts] ## 用于统计词频
     num_features = max(dictionary.token2id.values()) ## 将每一句话转化为[(单词,词频),(单词,词频)...]
     tfidf = models.TfidfModel(corpus)##构建模型
     idx = similarities.SparseMatrixSimilarity(tfidf[corpus],num_features=num_features)##初始化相似度查询接口
     ##测试
     sentense = jieba.lcut('9一方未签字办理的结婚登记是否有效')
     vec = dictionary.doc2bow(sentense)
     sim=idx[tfidf[vec]]
    
     使用sklearn自带的tf-idf模型
     from sklearn.feature_extraction.text import TfidfVectorizer
     from sklearn.feature_extraction.text import CountVectorizer
    
     raw_documents = [  
      '0无偿居间介绍买卖毒品的行为应如何定性',  
      '1吸毒男动态持有大量毒品的行为该如何认定',  
      '2如何区分是非法种植毒品原植物罪还是非法制造毒品罪',  
      '3为毒贩贩卖毒品提供帮助构成贩卖毒品罪',  
      '4将自己吸食的毒品原价转让给朋友吸食的行为该如何认定',  
      '5为获报酬帮人购买毒品的行为该如何认定',  
      '6毒贩出狱后再次够买毒品途中被抓的行为认定',  
      '7虚夸毒品功效劝人吸食毒品的行为该如何认定',  
      '8妻子下落不明丈夫又与他人登记结婚是否为无效婚姻',  
      '9一方未签字办理的结婚登记是否有效',  
      '10夫妻双方1990年按农村习俗举办婚礼没有结婚证 一方可否起诉离婚',  
      '11结婚前对方父母出资购买的住房写我们二人的名字有效吗',  
      '12身份证被别人冒用无法登记结婚怎么办?',  
      '13同居后又与他人登记结婚是否构成重婚罪',  
      '14未办登记只举办结婚仪式可起诉离婚吗',  
      '15同居多年未办理结婚登记,是否可以向法院起诉要求离婚'  
      ]  
      texts = [ ' '.join(jieba.cut(document, cut_all=True)) for document in raw_documents]
      cv = CountVectorizer()
      cv_fit=cv.fit_transform(texts)
      '''
      结果展示:
       (0, 50)	1##第一列表示文档序号,第二列表示token在字典中的序号,第三列表示在本sentences中的词频数
       (0, 45)	1
       (0, 89)	1
       (0, 73)	1
       (0, 14)	1
       (0, 16)	1
       (0, 53)	1
       (0, 62)	1
    
      '''
      tfidf_transformer = TfidfTransformer()
      tfif_matrix = tfidf_transformer.fit_transform(cv_fit)
      tfif_matrix[0].todense()
      或者直接使用
      from sklearn.feature_extraction.text import TfidfVectorizer
      tfidfVecorizer = TfidfVectorizer()#可自己设置解析方法
      tfidf_matrix  = tfidfVecorizer.fit_transform(texts)
      tfidf_matrix[1].todense()
    
  • word2vec
  1. 将原始的训练语料转换成一个sentence的迭代器

  2. 训练word2vec模型,生成word2vec向量,可以指定模型训练的参数,例如采用的模型(skip-gram或使cbow);负例采样的个数;embedding向量的维数等

  3. 其有两种方案:
    a. 把目标句子的各个词的向量进行相加取平均,然后进行相似度比较
    b. 使用WMD模型(词移距离模型)对模型向量化后的句子进行以下操作:
    ∑ i = 1 , j = 1 n T i j c ( i , j ) \sum_{i=1,j=1}^nT_{ij}c(i,j) i=1,j=1nTijc(i,j)

    其中 c ( i , j ) c(i,j) c(i,j)代表欧式距离

  4. 实例

     from gensim.test.utils import common_texts,get_tmpfile
     from gensim.models import Word2Vec
    
     model = Word2Vec(size=20,window=5,min_count=1,iter=2)
     model.build_vocab(common_texts)
     train = model.train(common_texts,total_examples=58,epochs=2)
     model.wv.vectors##获取隐层向量
     model.most_similar('computer',topn=2)##获取最相似的两个词
     model.similarity('computer','tree')##计算两个次的相似度
    
  • doc2vec

      import gensim
      from gensim.models.doc2vec import Doc2Vec, TaggedDocument
      documents = []
      for k,v in enumerate(common_texts):
          document = TaggedDocument(words = v,tags = [k])
          documents.append(document)
      model = Doc2Vec(size=300,min_count =1,iter=10)
      model.build_vocab(documents)
      model.train(documents=documents,total_examples=model.corpus_count,epochs=model.epochs)
      ## 推测文本向量
      model.random.seed(0
      infer_vector = model.infer_vector(['hello','i','am','wang'],steps=6)
      model.docvecs.most_similar([infert],topn=2)## 获取最相近的句子
    

你可能感兴趣的:(文本相似度计算)