精华内容
下载资源
问答
  • 文本相似度

    2018-08-30 18:32:09
    计算文本相似度文本相似度计算,用于鉴别文章是否存在抄袭
  • 文本相似度研究

    2018-10-10 17:57:10
    文本相似度研究 NLPC 文本分类 语义识别,google关于文本相似度最新研究
  • 易语言文本相似度算法源码,文本相似度算法,文本_相似度,min
  • 易语言文本相似度判断模块源码,文本相似度判断模块,文本相似度判断,逐字分割
  • 易语言快速计算文本相似度源码,快速计算文本相似度,取文本相似度,GetMaxLenSubStr,GetCharList,max
  • 1、文本相似度计算的需求始于搜索引擎。搜索引擎需要计算“用户查询”和爬下来的众多”网页“之间的相似度,从而把最相似的排在最前返回给用户。2、主要使用的算法是tf-idftf:term frequency 词频idf:inverse ...

    1、文本相似度计算的需求始于搜索引擎。

    搜索引擎需要计算“用户查询”和爬下来的众多”网页“之间的相似度,从而把最相似的排在最前返回给用户。

    2、主要使用的算法是tf-idf

    tf:term frequency 词频

    idf:inverse document frequency 倒文档频率

    主要思想是:如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

    第一步:把每个网页文本分词,成为词包(bag of words)。

    第三步:统计网页(文档)总数M。

    第三步:统计第一个网页词数N,计算第一个网页第一个词在该网页中出现的次数n,再找出该词在所有文档中出现的次数m。则该词的tf-idf 为:n/N * 1/(m/M) (还有其它的归一化公式,这里是最基本最直观的公式)

    第四步:重复第三步,计算出一个网页所有词的tf-idf 值。

    第五步:重复第四步,计算出所有网页每个词的tf-idf 值。

    3、处理用户查询

    第一步:对用户查询进行分词。

    第二步:根据网页库(文档)的数据,计算用户查询中每个词的tf-idf 值。

    4、相似度的计算

    使用余弦相似度来计算用户查询和每个网页之间的夹角。夹角越小,越相似。

    1 #coding=utf-8

    2

    3

    4 #import warnings

    5 #warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')

    6 importlogging7 from gensim importcorpora, models, similarities8

    9 datapath = 'D:/hellowxc/python/testres0519.txt'

    10 querypath = 'D:/hellowxc/python/queryres0519.txt'

    11 storepath = 'D:/hellowxc/python/store0519.txt'

    12 defsimilarity(datapath, querypath, storepath):13 logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)14

    15 classMyCorpus(object):16 def __iter__(self):17 for line inopen(datapath):18 yieldline.split()19

    20 Corp =MyCorpus()21 dictionary =corpora.Dictionary(Corp)22 corpus = [dictionary.doc2bow(text) for text inCorp]23

    24 tfidf =models.TfidfModel(corpus)25

    26 corpus_tfidf =tfidf[corpus]27

    28 q_file = open(querypath, 'r')29 query =q_file.readline()30 q_file.close()31 vec_bow =dictionary.doc2bow(query.split())32 vec_tfidf =tfidf[vec_bow]33

    34 index =similarities.MatrixSimilarity(corpus_tfidf)35 sims =index[vec_tfidf]36

    37 similarity =list(sims)38

    39 sim_file = open(storepath, 'w')40 for i insimilarity:41 sim_file.write(str(i)+'\n')42 sim_file.close()43 similarity(datapath, querypath, storepath)

    贴一下我的test代码。

    我的test文件querypath是一个问题,datapath是对这个问题的各种回答,我试图通过文本相似度来分析问题和哪个答案最匹配。。

    原博客的测试是querypath是商品描述,datapath是商品的评论,通过文本相似度来分析,商品描述和实际的商品是否差异过大。

    贴一下我的测试数据。很小的数据,就是测试一下这个:

    注意所有的数据已经经过分词处理,分词怎么处理,可以用python的jieba库分词处理。可以参考http://www.cnblogs.com/weedboy/p/6854324.html

    query

    1160439-20170521184117119-1882230664.png

    data

    1160439-20170521184152103-599234217.png

    store(也就是结果)

    1160439-20170521184217244-1809208529.png

    测试结果和问题实际上最应该匹配的对不上。。

    总结:

    1.gensim 除了提供了tf-idf 算法,好好利用

    2.我用jieba分词的忘记删掉停用词了,给结果带来很大影响,jieba库里有函数可以删停用词的

    3.问答系统中,关于问题和答案匹配,如果不用有监督的机器学习是不行的。。

    展开全文
  • 文本相似度的设计与实现

    万次阅读 热门讨论 2017-01-20 15:37:38
    文本相似度的设计与实现 摘要:本文主要设计并实现了一个文本相似度系统,该系统主要功能计算文档之间的相似度,通过使用向量空间模型(VSM,Vector Space Model)及余弦相似度计算公式计算文档之间的相似度,数据...

    欢迎关注“程序杂货铺”公众号,里面有精彩内容,欢迎大家收看^_^

    文本相似度的设计与实现

    摘要:本文主要设计并实现了一个文本相似度系统,该系统主要功能计算文档之间的相似度,通过使用向量空间模型(VSM,Vector Space Model)及余弦相似度计算公式计算文档之间的相似度,数据预处理过程中加入word2vec模型进行语义扩充,从而能够匹配到更多相关文档。

    1. 向量空间模型

    向量空间模型(VSM, Vector SpaceModel)由Salton等人于20世纪70年代年提出[1,2]。向量空间模型的主要思想是将文本内容的处理简化为向量空间中的向量运算,这样将空间上的相似度转化为语义上的相似度。当文档被表示为文档空间的向量时,便可通过计算向量之间的相似性来度量文档间的相似性。文本处理中最常用的相似性度量方式是余弦距离。

    向量空间模型的基本思想:

    给定一篇文档D=D(T1,T2,…Ti,…,Tn),若Ti在文档中既可以重复出现又存在先后次序,因此分析起来会较为困难。针对上述情况,暂不考虑Ti的顺序,并要求Ti互异,此时可将T1,T2,…Ti,…,Tn看作n维坐标,每一维对应相应值Wi,因此D(W1,W2,…,Wi,…,Wn)便可以看作一个n维向量。

    例如:有一篇文档D={大家好,才是真的好},首先进行分词后转换为D={大家/好/才是/真的/好},之后提取出公因词D={大家,好,才是,真的},最后通过向量空间模型将文档转换为对应的向量D={1,2,1,1}。

    向量空间模型只是将文档转换为方便计算的格式,若进行相似度计算,还需使用相似度计算公式进行计算。本文使用余弦相似度计算公式。

    2. 余弦相似度

    余弦相似度计算公式广泛应用于文本数据之间的相似度计算过程中。其数学表达如下:

    计算过程如下:

    例如,有2个文档D1={大家好},D2={才是真的好},首先将D1、D2分词后,D1={大家/好},D2={才是/真的/好},其次提取出公因词D={大家,好,才是,真的},然后通过向量空间模型转换成向量表达,D1={1,1,0,0},D2={0,1,1,1},最后进行相似度计算

    3. 文本相似度系统

    本文主要使用向量空间模型及余弦相似度距离公式进行文本相似度计算任务,系统的基本架构如下图1所示:

    其基本思想为:将文档输入系统,对文档进行数据预处理操作,数据预处理完成后使用向量空间模型将词组转化为向量,之后使用余弦相似度计算公式求解文档之间的相似度,最终将计算后的结果展示出来。

    数据预处理阶段,包括分词、取停用词、word2vec语义扩展,其流程如下图2所示:

    在word2vec语义扩展阶段,Word2vec是Google于2013年发布的一款基于深度学习的开源工具包,主要用于将单词以向量形式表示[3]。Word2vec首先使用语料训练模型,待模型训练结束后,将新的单词输入模型进行预测,模型可按相关度排序将最相近的预测单词展现给用户,通常而言,会将top30展示给用户。

    针对文档语义扩充,系统会先使用搜狗新闻语料训练CBOW模型,待模型训练结束后,将本档中的单词输入CBOW模型进行预测,最终将预测结果扩充回文档中,用于向量空间模型。

    同样以之前的2篇文档为例,D1={大家/好},D2={才是/真的/好},通过word2vec模型后,D1={大家/好/很好/不错},D2={才是/真的/好/很好/不错},提取出公因词D={大家,好,很好,不错,才是,真的},然后通过向量空间模型转换成向量表达,D1={1,1,1,1,0,0},D2={0,1,1,1,1,1},最后进行相似度计算

    通过比较两次的Score值可得出,通过word2vec能够提高文本相似度的计算分值。

    另外系统会计算文档中每一句话所对应的最大匹配及其相似度值,针对文档与文档的相似度计算,本文提出一种平均相似度计算公式,即:

    其中n(dicList1)是所求文档中包含的句子个数,公式的主要思路即将每句话的最大匹配相似度叠加后求取平均值。

    4. 系统设计

    相应代码如下:

    	/**
    	 * 程序运行入口
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		String dir,inputPath1,inputPath2,outputPath,word2vecModel,str1,str2;
    		long start,end,dur;
    		start = System.currentTimeMillis();
    		dir = "data/test/";
    		inputPath1 = dir + "doc3.txt";
    		inputPath2 = dir + "doc3.txt";
    		dir = "data/result/";
    		outputPath = dir + "out3_3.txt";
    		word2vecModel = "model/vectors-sougou.bin";
    		
    		FileHandler fh = new FileHandler();
    		List<String> docList1 = fh.putFileToList(inputPath1);
    		List<String> docList2 = fh.putFileToList(inputPath2);
    		Tool.initWriter1(outputPath);
    		
    		Word2VEC w = new Word2VEC() ;
            	w.loadGoogleModel(word2vecModel) ;
            
            	Model model = new Model();
            	model.run(docList1, docList2 ,w);
            
            	end = System.currentTimeMillis();
            	dur = end - start;
            	System.out.println("dur time = " + (1.0 * dur / 1000) + " s");
            	System.out.println("dur time = " + (1.0 * dur / (1000 * 60)) + " min");
            
    	}/**
    	 * 程序运行入口
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		String dir,inputPath1,inputPath2,outputPath,word2vecModel,str1,str2;
    		long start,end,dur;
    		start = System.currentTimeMillis();
    		dir = "data/test/";
    		inputPath1 = dir + "doc3.txt";
    		inputPath2 = dir + "doc3.txt";
    		dir = "data/result/";
    		outputPath = dir + "out3_3.txt";
    		word2vecModel = "model/vectors-sougou.bin";
    		
    		FileHandler fh = new FileHandler();
    		List<String> docList1 = fh.putFileToList(inputPath1);
    		List<String> docList2 = fh.putFileToList(inputPath2);
    		Tool.initWriter1(outputPath);
    		
    		Word2VEC w = new Word2VEC() ;
            	w.loadGoogleModel(word2vecModel) ;
            
            	Model model = new Model();
            	model.run(docList1, docList2 ,w);
            
            	end = System.currentTimeMillis();
            	dur = end - start;
            	System.out.println("dur time = " + (1.0 * dur / 1000) + " s");
            	System.out.println("dur time = " + (1.0 * dur / (1000 * 60)) + " min");
            
    	}
    

    数据预处理阶段如下:

    public class FileHandler {
    	
    	public static FileReader fr=null;
    	public static BufferedReader br=null;
    	public static String line=null;
    	
    	/**
    	 * input:path
    	 * 将文件内容添加入list中,一句一条
    	 */
    	public List<String> putFileToList(String path) {
    		
    		List<String> docList = new ArrayList<String>();
    		try {
    			fr = new FileReader(path);
    			br = new BufferedReader(fr);
    			while ((line = br.readLine()) != null) {
    				String[] strArr;
    				if(line.contains(".")){
    					strArr = line.split(".");
    					System.out.println(strArr.length);
    				}else if (line.contains("。")) {
    					strArr = line.split("。");
    				}else if (line.contains(".")) {
    					strArr = line.split(".");
    				}else if (line.contains(";")) {
    					strArr = line.split(";");
    				}else {
    					strArr = new String[1];
    					strArr[0] = line;
    				}
    				int i,n;
    				n = strArr.length;
    				for(i = 0;i < n;i++){
    					docList.add(strArr[i]);
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return docList;
    	}
    	
    	/**
    	 * input:path
    	 * output:List<String>
    	 * 读取词典信息,以list返回词典
    	 */
    	public List<String> readDic(String path) {
    		List<String> list = new ArrayList<String>();
    		try {  
                fr=new FileReader(path);
    			br=new BufferedReader(fr);
                while ((line=br.readLine()) != null ) {  
                    StringTokenizer st = new StringTokenizer(line);
                    while(st.hasMoreElements()){
                    	list.add(st.nextToken());
                    }
    			}
                br.close();
                br.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		return list;
    	}
    	
    }
    

     

    public class StringHandler {
    	
    	public static byte[] bt;
    	public static InputStream is;
    	public static Reader read;
    	public static Lexeme t;
    	public static IKSegmenter iks;
    	
    	/**
    	 * input:str
    	 * 将字符串分词转换成数组
    	 */
    	public List<String> stringToArray(String str) {
    		
    		List<String> list = new ArrayList<String>();
    		bt = str.getBytes();
    		is = new ByteArrayInputStream(bt);
    		read = new InputStreamReader(is);
    		iks = new IKSegmenter(read, true);
    		try {
    			while ((t = iks.next()) != null) {
    				list.add(t.getLexemeText());
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return list;
    		
    	}
    	
    	/**
    	 * input:arr
    	 * 使用word2vec将字符数组内容扩充
    	 */
    	public List<String> extendWord(Word2VEC w, List<String> list) {
    	
    		List<String> tempList = new ArrayList<String>();
    		Set<WordEntry> temp;
    		Iterator iter;
    		WordEntry entry;
    		int i,n;
    		n = list.size();
    		for(i = 0;i < n;i++){
    			temp = w.distance(list.get(i));
    			iter = temp.iterator();
    			if(!tempList.contains(list.get(i))){
    				tempList.add(list.get(i));
    			}
    			while(iter.hasNext()){
    				entry = (WordEntry) iter.next();
    				if(!tempList.contains(entry.name)){
    					tempList.add(entry.name);
    				}
    			}
    		}
    		return tempList;
    		
    	}
    	
    	/**
    	 * input:list,stopWordsPath
    	 * 删除停用词,通过读取stopWordsPath中的停用词表,将list中的停用词删除,并返回去除停用词后的list
    	 */
    	public List<String> deleteStopWords(List<String> list, String path2) {
    		
    		FileHandler fh = new FileHandler();
    		List<String> stopDic = fh.readDic(path2);
    		List<String> temp = new ArrayList<String>();
    		int i,n;
    		n = list.size();
    		try {  
    			for(i = 0;i < n;i++){
    				if(!stopDic.contains(list.get(i))){
    					temp.add(list.get(i));
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return temp;
    		
    	}
    }
    
     

    模型计算阶段如下:

    public class Model {
    
    	/**
    	 * input:docList1,docList2 主方法入口及控制器
    	 */
    	public void run(List<String> docList1, List<String> docList2, Word2VEC w) {
    		int i, j, n1, n2;
    		double[] similarArr;
    		int[] locArr;
    		double max, temp;
    		int loc;
    		n1 = docList1.size();
    		n2 = docList2.size();
    		similarArr = new double[n1];
    		locArr = new int[n1];
    		for (i = 0; i < n1; i++) {
    			max = 0.0;
    			temp = 0.0;
    			loc = 0;
    			for (j = 0; j < n2; j++) {
    				try {
    					temp = getSimilar(docList1.get(i), docList2.get(j), w);
    				} catch (IOException e) {
    					temp = 0.0;
    					e.printStackTrace();
    				}
    				if (temp > max) {
    					max = temp;
    					loc = j;
    				}
    			}
    			similarArr[i] = max;
    			locArr[i] = loc;
    		}
    		Tool.output(docList1, docList2, locArr, similarArr);
    	}
    
    	/**
    	 * input:str1,str2 计算2个字符串之间的相似度
    	 */
    	public double getSimilar(String str1, String str2, Word2VEC w) throws IOException {
    
    		double ret = 0.0;
    		// 创建向量空间模型,使用map实现,主键为词项,值为长度为2的数组,存放着对应词项在字符串中的出现次数
    		Map<String, int[]> vectorSpace = new HashMap<String, int[]>();
    		int[] itemCountArray = null;// 为了避免频繁产生局部变量,所以将itemCountArray声明在此
    		Iterator iter;
    		double vector1Modulo = 0.00;// 向量1的模
    		double vector2Modulo = 0.00;// 向量2的模
    		double vectorProduct = 0.00; // 向量积
    		List<String> list1,list1_temp,list2,list2_temp,temp1,temp2;
    		
    		StringHandler sh = new StringHandler();
    		
    		list1_temp = sh.stringToArray(str1);
    		list2_temp = sh.stringToArray(str2);
    		
    		/*
    		//使用word2vec扩充语义
    		temp1 = sh.stringToArray(str1);
    		temp2 = sh.stringToArray(str2);
    		list1 = sh.extendWord(w, temp1);
    		list2 = sh.extendWord(w, temp2);
    		*/
    		list1 = sh.deleteStopWords(list1_temp, Conf.stopWordsPath);
    		list2 = sh.deleteStopWords(list2_temp, Conf.stopWordsPath);
    		
    		int i,n;
    		n = list1.size();
    		for (i = 0; i < n; ++i) {
    			if (vectorSpace.containsKey(list1.get(i)))
    				++(vectorSpace.get(list1.get(i))[0]);
    			else {
    				itemCountArray = new int[2];
    				itemCountArray[0] = 1;
    				itemCountArray[1] = 0;
    				vectorSpace.put(list1.get(i), itemCountArray);
    			}
    		}
    		
    		// 对str2处理
    
    		n = list2.size();
    		for (i = 0; i < n; ++i) {
    			if (vectorSpace.containsKey(list2.get(i)))
    				++(vectorSpace.get(list2.get(i))[1]);
    			else {
    				itemCountArray = new int[2];
    				itemCountArray[0] = 0;
    				itemCountArray[1] = 1;
    				vectorSpace.put(list2.get(i), itemCountArray);
    			}
    		}
    
    		// 计算相似度
    		iter = vectorSpace.entrySet().iterator();
    		while (iter.hasNext()) {
    			Map.Entry entry = (Map.Entry) iter.next();
    			itemCountArray = (int[]) entry.getValue();
    			vector1Modulo += itemCountArray[0] * itemCountArray[0];
    			vector2Modulo += itemCountArray[1] * itemCountArray[1];
    			vectorProduct += itemCountArray[0] * itemCountArray[1];
    		}
    		vector1Modulo = Math.sqrt(vector1Modulo);
    		vector2Modulo = Math.sqrt(vector2Modulo);
    		// 返回相似度
    		ret  = (vectorProduct / (vector1Modulo * vector2Modulo));
    		return ret;
    
    	}
    
    }
    

     

     

    参考文献:

     

    [1]Salton G, Lesk M E. Computer Evaluation of Indexing and Text Processing[J].Journal of the Acm, 1968, 15(1):8-36.

    [2]Salton. The SMART Retrieval System—Experiments in Automatic DocumentProcessing[C]// Prentice-hall, Inc Upper Saddle River. Prentice-Hall, Inc.1971.

    [3]苏增才.基于word2vec和SVMperf的网络中文文本评论信息情感分类研究[D].河北科技大学,2015.


    本文代码下载地址:

    http://download.csdn.net/detail/u013473512/9742055

    https://github.com/Emmitte/DocDistance

    欢迎关注“程序杂货铺”公众号,里面有精彩内容,欢迎大家收看^_^

    展开全文
  • 本文实例讲述了Python实现简单的文本相似度分析操作。分享给大家供大家参考,具体如下:学习目标:1.利用gensim包分析文档相似度2.使用jieba进行中文分词3.了解TF-IDF模型环境:Python 3.6.0 |Anaconda 4.3.1 (64-...

    本文实例讲述了Python实现简单的文本相似度分析操作。分享给大家供大家参考,具体如下:

    学习目标:

    1.利用gensim包分析文档相似度

    2.使用jieba进行中文分词

    3.了解TF-IDF模型

    环境:

    Python 3.6.0 |Anaconda 4.3.1 (64-bit)

    工具:

    jupyter notebook

    注:为了简化问题,本文没有剔除停用词“stop-word”。实际应用中应该要剔除停用词。

    首先引入分词API库jieba、文本相似度库gensim

    import jieba

    from gensim import corpora,models,similarities

    以下doc0-doc7是几个最简单的文档,我们可以称之为目标文档,本文就是分析doc_test(测试文档)与以上8个文档的相似度。

    doc0 = "我不喜欢上海"

    doc1 = "上海是一个好地方"

    doc2 = "北京是一个好地方"

    doc3 = "上海好吃的在哪里"

    doc4 = "上海好玩的在哪里"

    doc5 = "上海是好地方"

    doc6 = "上海路和上海人"

    doc7 = "喜欢小吃"

    doc_test="我喜欢上海的小吃"

    分词

    首先,为了简化操作,把目标文档放到一个列表all_doc中。

    all_doc = []

    all_doc.append(doc0)

    all_doc.append(doc1)

    all_doc.append(doc2)

    all_doc.append(doc3)

    all_doc.append(doc4)

    all_doc.append(doc5)

    all_doc.append(doc6)

    all_doc.append(doc7)

    以下对目标文档进行分词,并且保存在列表all_doc_list中

    all_doc_list = []

    for doc in all_doc:

    doc_list = [word for word in jieba.cut(doc)]

    all_doc_list.append(doc_list)

    把分词后形成的列表显示出来:

    print(all_doc_list)

    [['我', '不', '喜欢', '上海'],

    ['上海', '是', '一个', '好', '地方'],

    ['北京', '是', '一个', '好', '地方'],

    ['上海', '好吃', '的', '在', '哪里'],

    ['上海', '好玩', '的', '在', '哪里'],

    ['上海', '是', '好', '地方'],

    ['上海', '路', '和', '上海', '人'],

    ['喜欢', '小吃']]

    以下把测试文档也进行分词,并保存在列表doc_test_list中

    doc_test_list = [word for word in jieba.cut(doc_test)]

    doc_test_list

    ['我', '喜欢', '上海', '的', '小吃']

    制作语料库

    首先用dictionary方法获取词袋(bag-of-words)

    dictionary = corpora.Dictionary(all_doc_list)

    词袋中用数字对所有词进行了编号

    dictionary.keys()

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]

    编号与词之间的对应关系

    dictionary.token2id

    {'一个': 4,

    '上海': 0,

    '不': 1,

    '人': 14,

    '北京': 8,

    '和': 15,

    '哪里': 9,

    '喜欢': 2,

    '在': 10,

    '地方': 5,

    '好': 6,

    '好吃': 11,

    '好玩': 13,

    '小吃': 17,

    '我': 3,

    '是': 7,

    '的': 12,

    '路': 16}

    以下使用doc2bow制作语料库

    corpus = [dictionary.doc2bow(doc) for doc in all_doc_list]

    语料库如下。语料库是一组向量,向量中的元素是一个二元组(编号、频次数),对应分词后的文档中的每一个词。

    [[(0, 1), (1, 1), (2, 1), (3, 1)],

    [(0, 1), (4, 1), (5, 1), (6, 1), (7, 1)],

    [(4, 1), (5, 1), (6, 1), (7, 1), (8, 1)],

    [(0, 1), (9, 1), (10, 1), (11, 1), (12, 1)],

    [(0, 1), (9, 1), (10, 1), (12, 1), (13, 1)],

    [(0, 1), (5, 1), (6, 1), (7, 1)],

    [(0, 2), (14, 1), (15, 1), (16, 1)],

    [(2, 1), (17, 1)]]

    以下用同样的方法,把测试文档也转换为二元组的向量

    doc_test_vec = dictionary.doc2bow(doc_test_list)

    doc_test_vec

    [(0, 1), (2, 1), (3, 1), (12, 1), (17, 1)]

    相似度分析

    使用TF-IDF模型对语料库建模

    tfidf = models.TfidfModel(corpus)

    获取测试文档中,每个词的TF-IDF值

    tfidf[doc_test_vec]

    [(0, 0.08112725037593049),

    (2, 0.3909393754390612),

    (3, 0.5864090631585919),

    (12, 0.3909393754390612),

    (17, 0.5864090631585919)]

    对每个目标文档,分析测试文档的相似度

    index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=len(dictionary.keys()))

    sim = index[tfidf[doc_test_vec]]

    sim

    array([ 0.54680777, 0.01055349, 0. , 0.17724207, 0.17724207,

    0.01354522, 0.01279765, 0.70477605], dtype=float32)

    根据相似度排序

    sorted(enumerate(sim), key=lambda item: -item[1])

    [(7, 0.70477605),

    (0, 0.54680777),

    (3, 0.17724207),

    (4, 0.17724207),

    (5, 0.013545224),

    (6, 0.01279765),

    (1, 0.010553493),

    (2, 0.0)]

    从分析结果来看,测试文档与doc7相似度最高,其次是doc0,与doc2的相似度为零。大家可以根据TF-IDF的原理,看看是否符合预期。

    最后总结一下文本相似度分析的步骤:

    1、读取文档

    2、对要计算的多篇文档进行分词

    3、对文档进行整理成指定格式,方便后续进行计算

    4、计算出词语的词频

    5、【可选】对词频低的词语进行过滤

    6、建立语料库词典

    7、加载要对比的文档

    8、将要对比的文档通过doc2bow转化为词袋模型

    9、对词袋模型进行进一步处理,得到新语料库

    10、将新语料库通过tfidfmodel进行处理,得到tfidf

    11、通过token2id得到特征数

    12、稀疏矩阵相似度,从而建立索引

    13、得到最终相似度结果

    更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

    希望本文所述对大家Python程序设计有所帮助。

    本文标题: Python实现简单的文本相似度分析操作详解

    本文地址: http://www.cppcns.com/jiaoben/python/230389.html

    展开全文
  • 英文文本相似度/文本推理/文本匹配数据集——MSRP
  • 易语言源码易语言文本相似度算法源码.rar 易语言源码易语言文本相似度算法源码.rar 易语言源码易语言文本相似度算法源码.rar 易语言源码易语言文本相似度算法源码.rar 易语言源码易语言文本相似度算法源码.rar ...
  • 文本相似度比较java

    2019-05-06 09:01:09
    文本相似度的比较,java实现,文本相似度的比较,java实现java实现java实现
  • 文本相似度计算

    2015-10-12 10:33:37
    通过文本距离,实现文本相似度的计算。利用的是LevenShiten Distance距离法
  • 文本相似度综述

    千次阅读 2019-10-23 22:09:03
    本文目录文本相似度的定义文本相似度计算方法基于字符串的方法基于语料库的方法基于词袋VSMLSA、PLSALDA(需要进一步了解)基于神经网络基于搜索引擎基于世界知识基于本体基于网络知识其他方法句法分析混合方法 文本...

    文本相似度的定义

    文本相似度定义式
    其中, common(A,B) 是 A 和 B 的共性信息,description(A,B) 是描述 A 和 B 的全部信息, 公式(1)表达出相似度与文本共性成正相关。由于没有限制应用领域, 此定义是被较多采用的概念。

    相似度一般可用[0,1]之间的实数表示, 该实数可通过语义距离计算获得。相似度与语义距离呈反比关系, 语义距离越小, 相似度越高; 语义距离越大则相似度越低。通常用公式(2)表示相似度与语义距离的关系。
    文本相似度与语义距离的关系式
    其中, Dis(Sa, Sb)表示文本 Sa、Sb之间的非负语义距离, α为调节因子, 保证了当语义距离为 0 时公式(2)具有意义。

    文本相似度计算中还有一个重要概念是文本表示(如word2vec), 代表对文本的基本处理, 目的是将半结构化或非结构化的文本转换为计算机可读形式。文本相似度计算方法的不同的本质是文本表示方法的不同。

    文本相似度计算方法

    在这里插入图片描述

    基于字符串的方法

    该方法从字符串匹配度出发, 以字符串共现和重复程度为相似度的衡量标准。 根据计算粒度不同, 可将方法分为基于字符(Character-Based)的方法和基于词语(Term-Based)的方法。一类方法单纯从字符或词语的组成考虑相似度算法, 如编辑距离、汉明距离、余弦相似度、Dice 系数、欧式距离; 另一类方法还加入了字符顺序, 即字符组成和字符顺序相同是字符串相似
    的必要条件 , 如最长公共子串 (Longest CommonSubstring, LCS)、Jaro-Winkler; 再一类方法采用集合思想, 将字符串看作由词语构成的集合, 词语共现可用集合的交集计算, 如 N-gram、Jaccard、Overlap Coefficient。表 1 列出了主要方法, 其中 Sa、Sb表示字符串 A、B。
    在这里插入图片描述
    基于字符串的方法是在字面层次上的文本比较,文本表示即为原始文本。该方法优点是原理简单、易于实现,现已成为其他方法的计算基础。缺点是的是将字符或词语作为独立的知识单元, 并未考虑词语本身的含义和词语之间的关系。 以同义词为例, 尽管表达不同, 但具有相同的含义, 而这类词语的相似度依靠基于字符串的方法并不能准确计算。

    基于字符串的方法也称作“字面相似度方法”, 其中较为典型的方法包括最长公共子串 (Longest
    Common Substring, LCS)、编辑距离、Jaccard 等。基于字符串的方法没有考虑文本的语义信息, 计算效果受到很大限制。 为解决这一问题, 学者们开始对语义相似度方法展开研究, 包括基于字符串的方法、基于语料库的方法、基于世界知识的方法和其他方法。

    (编辑距离、汉明距离、LCS、N-gram、余弦相似度、欧氏距离、Jaccard还需进一步了解。)

    基于语料库的方法

    基于语料库的方法利用从语料库中获取的信息计算文本相似度。

    基于语料库的方法可以分为: 基于词袋模型的方法、基于神经网络的方法和基于搜索引擎的方法。 前两种以待比较相似度的文档集合为语料库,后一种以 Web 为语料库。

    基于词袋

    词袋模型(Bag of Words Model, BOW)建立在分布假说的基础上, 即“词语所处的上下文语境相似, 其语义则相似”。基本思想是不考虑词语在文档中出现的顺序, 将文档表示成一系列词语的组合。 根据考虑的语义程度不同, 基于词袋模型的方法主要包括向量空间模型(Vector Space Model, VSM)、潜在语义分析(Latent Semantic Analysis, LSA)、概率潜在语义分析(Probabilistic Latent Semantic Analysis, PLSA)和潜在狄利克雷分布(Latent Dirichlet Allocation, LDA)。

    VSM

    20 世纪 60 年代末, Salton 等提出 VSM[16], 这种方法受到广大学者的青睐。基本思想是将每篇文档表示成一个基于词频或者词频 – 逆文档频率 (Term Frequency-Inverse Document Frequency, TF-IDF)权重的实值向量, 那么 N 篇文档则构成 n 维实值空间, 其中空间的每一维都对应词项, 每一篇文档表示该空间下的一个点或者向量。而两个文档的相似度就是两个向量的距离, 一般采用余弦相似度方法计算。
    [16] Salton G, Wong A, Yang C S. A Vector Space Model forAutomatic Indexing [J]. Communications of the ACM, 1975,18(11): 613-620.
    【17】【18】两篇论文是对VSM的一些改进。
    [17] 郭庆琳, 李艳梅, 唐琦. 基于 VSM 的文本相似度计算的研究 [J]. 计算机应用研究, 2008,25(11): 3256-3258. (GuoQinglin, Li Yanmei, Tang Qi. Similarity Computing of
    Documents Based on VSM [J]. Application Research of Computers, 2008, 25(11): 3256-3258.)
    [18] 李连, 朱爱红, 苏涛. 一种改进的基于向量空间文本相似度算法的研究与实现 [J]. 计算机应用与软件, 2012, 29(2):282-284. (Li Lian, Zhu Aihong, Su Tao. Research and
    Implementation of An Improved VSM-based Text Similarity Algorithm [J]. Computer Applications and Software, 2012,29(2): 282-284. )
    基于 VSM 的方法基本原理简单, 但该方法有两个明显缺点: 一是该方法基于文本中的特征项进行相似度计算, 当特征项较多时, 产生的高维稀疏矩阵导致计算效率不高; 二是向量空间模型算法的假设是文本中抽取的特征项没有关联, 这不符合文本语义表达。

    LSA、PLSA

    LSA[19]算法的基本思想是将文本从稀疏的高维词汇空间映射到低维的潜在语义空间, 在潜在语义空间计算相似性。(有点像word2vec的思想) LSA 是基于 VSM 提出来的, 两种方法都是采用空间向量表示文本, 但 LSA 使用潜在语义空间, 利用奇异值分解(Singular Value Decomposition, SVD)技术对高维的词条–文档矩阵进行处理, 去除了原始向量空间的某些“噪音”, 使数据不再稀疏。 Hofmann[20] 在 LSA 基础上 引入主题层, 采用期望最大化算法(Expectation Maximization, EM)训练主题, 得到改进的 PLSA 算法。 LSA 本质上是通过降维提高计算准确度, 但该算法复杂度比较高, 可移植性差。 比较之下, PLSA具备统计基础, 多义词和同义词在 PLSA 中分别被训练到不同的主题和相同的主题下, 从而避免了多义词、同义词的影响, 使得计算结果更加准确, 但不适用于大规模文本。
    [19] Landauer T K, Dumais S T. A Solution to Plato’s Problem:The Latent Semantic Analysis Theory of Acquisition,Induction, and Representation of Knowledge [J].Psychological Review, 1997, 104(2): 211-240.
    [20] Hofmann T. Probabilistic Latent Semantic Analysis [C]//Proceedings of the 15th Conference on Uncertainty in Artificial Intelligence.1999.

    LDA(需要进一步了解)

    LDA[21] 主题模型是一个三层贝叶斯概率模型, 包含词、主题和文档三层结构。采用 LDA 计算文本相似性的基本思想是对文本进行主题建模, 并在主题对应的词语分布中遍历抽取文本中的词语, 得到文本的主题分布, 通过此分布计算文本相似度[22]。 与 PLAS 不同的是, LDA 的文档到主题服从 Dirichlet 分布, 主题到词服从多项式分布, 此方法适用于大规模文本集, 也更具有鲁棒性熊大平等[23] 提出利用 LDA计算问句相似度, 将查询语句和问题分别用 LDA 主题分布概率表示, 采用余弦相似度计算二者的相似度, 效果有了一定的提高, 尤其对特征词不同但主题相似的问题有突出效果, 该方法适用于单个问句。张超等[24] 将 LDA 分别应用于文本的名词、动词和其他词, 得到不同词性词语的相似度,综合加权三个相似度计算文本相似度, 此方法由于将建模过程并行化, 从而降低了时间复杂度。
    [21] Blei D M, Ng A Y, Jordan M I. Latent Dirichlet Allocation [J].Journal of Machine Learning Research, 2003, 3: 993-1022.
    [22] 王振振, 何明, 杜永萍. 基于 LDA 主题模型的文本相似度计 算 [J]. 计算机科学 , 2013, 40(12): 229-232. (WangZhenzhen, He Ming, Du Yongping. Text SimilarityComputing Based on Topic Model LDA [J]. ComputerScience, 2013, 40(12): 229-232. )
    [23] 熊大平, 王健, 林鸿飞. 一种基于 LDA 的社区问答问句相似度计算方法 [J]. 中文信息学报, 2012, 26(5): 40-45.(Xiong Daping, Wang Jian, Lin Hongfei. An LDA-based Approach to Finding Similar Questions for Community Question Answer [J]. Journal of Chinese Information Processing, 2012, 26(5): 40-45. )
    [24] 张超, 陈利, 李琼. 一种 PST_LDA 中文文本相似度计算方法 [J]. 计算机应用研究, 2016, 33(2): 375-377,383. (ZhangChao, Chen Li, Li Qiong. Chinese Text Similarity Algorithm Based on PST_LDA [J]. Application Research of Computers,2016, 33(2): 375-377,383. )

    基于神经网络

    通过神经网络模型生成词向量(Word Vector、WordEmbeddings 或 Distributed Representation)[25-26] 计算文本相似度是近年来自然语言处理领域研究较多的方法。不少产生词向量的模型和工具也被提出, 如Word2Vec[27]和 GloVe[28]等词向量的本质是从未标记的非结构文本中训练出的一种低维实数向量, 这种表达方式使得类似的词语在距离上更为接近, 同时较好地解决了词袋模型由于词语独立带来的维数灾难和语义不足问题。Kenter 等[29] 合并由不同算法、语料库、参数设置得到的不同维度词向量并训练出特征, 经过监督学习算法得到训练分类器, 利用此分类器计算未标记短文本之间的相似度分数。Kusner 等[30] 提出使用词向量计算文档相似度的新方法, 即在词向量空间里计算将文档中所有的词移动到另一文档对应的词需要的最小移动距离(Word Mover’s Distance, WMD), 求解出来的 WMD 则是两个文档的相似度Huang 等[31] 在WMD 的基础上提出改进方法——监督词移动距离(Supervised-WMD, S-WMD), 实质上加入新文档特征“re-weighting”和新移动代价“metric A”, 令 WMD 方法适用于可监督的文本。

    基于神经网络方法与词袋模型方法的不同之处在于表达文本的方式。 词向量是经过训练得到的低维实数向量, 维数可以人为限制, 实数值可根据文本距离调整, 这种文本表示符合人理解文本的方式, 所以基于词向量判断文本相似度的效果有进一步研究空间。

    [25] Hinton G E. Learning Distributed Representations ofConcepts[C]//Proceedings of the 8th Annual Conference ofthe Cognitive Science Society. 1986.
    [26] Bengio Y, Ducharme R, Vincent P, et al. A NeuralProbabilistic Language Model [J]. Journal of MachineLearning Research, 2003, 3(6): 1137-1155.
    [27] Mikolov T, Sutskever I, Chen K, et al. DistributedRepresentations of Words and Phrases and Their Compositionality [C]//Proceedings of the 26th International Conference on Neural Information Processing Systems. 2013.
    [28] Pennington J, Socher R, Manning C D. GloVe: Global Vectors for Word Representation [C]//Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing. 2014: 1532-1543.
    [29] Kenter T, Rijke M D. Short Text Similarity with Word Embeddings [C]//Proceedings of the 24th ACM International on Conference on Information and Knowledge Management.2015: 1411-1420.
    [30] Kusner M J, Sun Y, Kolkin N I, et al. From Word Embeddings to Document Distances [C]//Proceedings of the 32nd International Conference on Machine Learning. 2015.
    [31] Huang G, Guo C, Kusner M J, et al. Supervised Word Mover’s Distance [C]//Proceedings of the 30th Conference on Neural Information Processing Systems. 2016.

    基于搜索引擎

    随着 Web3.0 时代的到来, Web 成为内容最丰富、数据量最大的语料库, 与此同时搜索引擎相关算法的进步, 使得有任何需求的用户都可通过搜索找到答案 。 自 从 Cilibrasi 等 [32] 提 出 归 一 化 谷 歌 距 离(Normalized Google Distance, NGD) 之后, 基于搜索引擎计算语义相似度的方法开始流行起来。其基本原理是给定搜索关键词 x、y, 搜索引擎返回包含 x、y 的网页数量 f (x)、f (y)以及同时包含 x 和 y 的网页数量f (x, y), 计算谷歌相似度距离如公式(3)[32]所示。
    在这里插入图片描述
    但是该方法最大的不足是计算结果完全取决于搜索引擎的查询效果, 相似度因搜索引擎而异。 刘胜久等[33]采用多个搜索引擎的搜索结果, 根据搜索引擎的市场份额为其赋予权重, 得到的结果更加综合全面。

    一些学者提出通过分析返回网页内容计算相似度, Sahami 等[34]将查询关键词返回的网页内容构建为语境向量(Context Vector), 采用相似度核函数计算语境向量之间的相似度, 比单纯使用搜索数量计算相似度有更丰富的语义信息。第三类方法是综合搜索结果数量和搜索结果内容, 陈海燕[35]定义了语义片段, 即两个关键词共同出现的片段, 通过分析网页内容获取语义片段数量, 替换包含两个关键词的网页数量, 得到较为精确的相似度。

    基于搜索引擎的相似度方法为相似度计算提供了丰富的语义信息, 计算结果依赖于搜索引擎的搜索效果以及对网页内容的语义分析效果, 所以精确获取返回网页数量和有效分析网页内容成为关键问题。

    [32] Cilibrasi R L, Vitanyi P M B. The Google Similarity Distance[J]. IEEE Transactions on Knowledge and Data Engineering,2007, 19(3):370-383.
    [33] 刘胜久, 李天瑞, 贾真, 等. 基于搜索引擎的相似度研究与 应 用 [J]. 计 算 机 科 学 , 2014, 41(4): 211-214. (Liu Shengjiu, Li Tianrui, Jia Zhen, et al. Research and Application of Similarity Based on Search Engine [J].Computer Science, 2014, 41(4): 211-214. )
    [34] Sahami M, Heilman T D. A Web-based Kernel Function for Measuring the Similarity of Short Text Snippets [C]//Proceedings of the 15th International Conference on World Wide Web. 2006: 377-386.
    [35] 陈海燕. 基于搜索引擎的词汇语义相似度计算方法 [J].计算机科学, 2015, 42(1): 261-267. (Chen Haiyan. Measuring Semantic Similarity Between Words Using Web Search Engines [J]. Computer Science, 2015, 42(1): 261-267.)

    基于世界知识

    基于世界知识的方法是指利用具有规范组织体系的知识库计算文本相似度, 一般分为两种: 基于本体知识和基于网络知识。前者一般是利用本体结构体系中概念之间的上下位和同位关系, 如果概念之间是语义相似的, 那么两个概念之间有且仅有一条路径[7,10]。而网络知识中词条呈结构化并词条之间通过超链接形式展现上下位关系, 这种信息组织方式更接近计算机的理解。概念之间的路径或词条之间的链接就成为文本相似度计算的基础。

    基于本体

    文本相似度计算方法使用的本体不是严格的本体概念, 而指广泛的词典、叙词表、词汇表以及狭义的本体。随着 Berners-Lee 等提出语义网的概念, 本体成为语义网中对知识建模的主要方式, 在其中发挥着重要作用。由于本体能够准确地表示概念含义并能反映出概念之间的关系, 所以本体成为文本相似度的研究基础[7]最常利用的本体是通用词典, 例如 WordNet、《知网》(HowNet)和《同义词词林》等, 除了词典还有一些领域本体, 例如医疗本体、电子商务本体、地理本体、农业本体等。

    结合 Hliaoutakis[36] 、Batet 等[37]的研究, 将基于本体的文本相似度算法概括为 4 种: 基于距离(EdgeCounting Measures)、基于内容(Information Content Measures)、基于属性(Feature-based Measures)和混合式(Hybrid Measures)相似度算法。表 2 列出了各种方法的基本原理、代表方法和特点。

    基于本体的方法将文本表示为本体概念以及概念之间的关系, 该方法能够准确反映概念内在语义关系,是一种重要的语义相似度计算方法, 主要缺点如下:
    ①本体一般需要专家参与建设, 耗费大量时间和精力,而已有的通用本体存在更新速度慢、词汇量有限等问题, 不适用于出现的新型词语;
    ②利用本体计算文本相似度, 首先是在词语层次进行计算, 然后累加词语相似度获得长文本相似度, 相对基于语料库的方法对文本整体处理而言计算效率较低;
    ③无论是通用本体还是领域本体, 本体之间相互独立将带来本体异构问题, 不利于跨领域的文本相似度计算。

    在这里插入图片描述

    基于网络知识

    由于本体中词语数量的限制, 有些学者开始转向基于网络知识方法的研究, 原因是后者覆盖范围广泛、富含丰富的语义信息、更新速度相对较快, 使用最多的网络知识是维基百科、百度百科。网络知识一般包括两种结构, 分别是词条页面之间的链接和词条之间的层次结构。孙琛琛等[50]将其概括为: 文章网络和分类树(以树为主题的图)。最早使用维基百科计算语义相关度是 Strube 等[51]提出的 WikiRelate!方法, 基本原理是在维基百科中检索出与词语相关的网页, 并通过抽取网页所属类别找到分类树, 最终基于抽取的页面以及在分类法中的路径计算相关度。该方法利用了维基百科的层次结构,计算效果与基于本体的方法相当, 然而此方法更适用于词语丰富的文本。Gabrilovich 等[52]提出 ESA 方法,
    基于维基百科派生出高维概念空间并将词语表示为维基百科概念的权重向量, 通过比较两个概念向量(比如采用余弦值方法)得到语义相关度, 计算效果优于人工判读。ESA 比 WikiRelate!表达更加复杂的语义, 而且模型对用户来说简单易懂, 鲁棒性较好。Milne 等[53]提出的 WLM 方法仅使用维基百科的链接结构以及较少的数据和资源, 比 ESA 简单, 但计算结果不如 ESA理想。严格来说, 这些方法是计算文本语义相关度,
    其包括范围比语义相似度大, 但是这些方法为基于维基百科的语义相似度计算提供了良好的借鉴。盛志超等[54]提出一种模仿人脑联想方式的方法, 基于维基百科页面的链接信息, 并依托 TF-IDF 算法得到词语相似度, 尽管取得了一定的效果, 但是将维基百科的页面信息和类别信息以较为简单的方式结合成统一的。彭丽针等[55]考虑到维基百科页面的社区现象[56], 对带有标签的页面采用 HITS 算法获取社区类别, 基于词语类别与链接关系计算相似度, 实验证明该方法具有一定的可行性和有效性, 但由于未深入分析页面内容导致语义程度较弱。与维基百科类似, 百度百科作为众人参与可协作的中文百科全书, 到 2017 年 1 月已经有超过 1 400 万的词条, 数据量成为百度百科相较于其他语料库的绝对优势。詹志建等[57]在分析百科词条结构的基础上,采用向量空间模型计算百科名片、词条正文、相关词条的相似度, 采用基于信息内容的方法计算开放分类的相似度, 最终加权得到词条相似度, 计算效果优良,但是该方法对词条语义信息的分析并不深入。尹坤等[58]在计算方法中引入图论思想, 将百度百科视为图, 词条视为图中节点, 采用 SimRank 方法计算词条之间的相似度。该方法充分利用了百科词条之间的链接关系,但仅对于相关词条较多的词条有好的效果, 而对于相关词条较少的词条的计算效果则不理想。综上所述, 基于网络知识的文本相似度计算方法大多利用页面链接或层次结构, 能较好地反映出词条的语义关系。但其不足在于: 词条与词条的信息完备程度差异较大, 不能保证计算准确度; 网络知识的产生方式是大众参与, 导致文本缺少一定的专业性。识源, 过于简单, 缺乏一定的理论支撑。

    其他方法

    句法分析

    混合方法

    展开全文
  • simhash文本相似度

    2015-09-01 18:46:26
    文本相似度判断 simhash 海明距离判断为相似
  • 易语言源码易语言文本相似度判断模块源码.rar 易语言源码易语言文本相似度判断模块源码.rar 易语言源码易语言文本相似度判断模块源码.rar 易语言源码易语言文本相似度判断模块源码.rar 易语言源码易语言文本...
  • 中文文本相似度/文本推理/文本匹配数据集——XNLI
  • 中文文本相似度/文本推理/文本匹配数据集——OCNLI
  • 英文文本相似度/文本推理/文本匹配数据集——Quora
  • 中文文本相似度/文本推理/文本匹配数据集——LCQMC
  • 英文文本相似度/文本推理/文本匹配数据集——SciTail
  • 英文文本相似度/文本推理/文本匹配数据集——SNLI
  • 英文文本相似度/文本推理/文本匹配数据集——SICK
  • 英文文本相似度/文本推理/文本匹配数据集——MUltiNLI

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,973
精华内容 13,189
关键字:

文本相似度