一、实验内容
采用Shinling及Minhash技术分析以下两段文本的Jaccard相似度:
(1) IELTS (International English Language Testing System) conducted by the British Council, University of Cambridge Local Examinations Syndicate and International Development Program of Australian Universities and College: providing grade 6.5 or higher (i.e. 7, 8, 9) overall has been obtained with a breakdown of 6.0 in reading and writing and 5.5 in listening and speaking.
(2) IELTS / UKVI –IELTS 6.5 overall with 6.0 in reading and writing, 5.5 in listening and speaking for Law, Psychology, Architecture, English, Accounting and Finance
二、实验设计(原理分析及流程)
首先,将两个待求的文本写入程序,然后对文本进行k-shingle划分,针对这个实验,我直接将输入文本分解为字符串的集合,针对该两个集合建立集合矩阵模型。针对该矩阵模型,采用行打乱的方法构建最小哈希签名矩阵计算相似度。
第一步:将文档划分为两个单词集合,并构建文档的单词特征向量。然后,用哈希函数将每个单词映射成行编号,并基于这些行构建两篇文档的特征集合矩阵。
第二步:两个文档的特征集合矩阵经随机的行打乱之后,得到的两个最小哈希值相等的概率等于这两个文档的Jaccard相似度。随机n次行打乱产生的n个最小哈希值,构成一个n维的列向量。两篇文档的Jaccard相似度就对应于两篇文档的这两个n维列向量的相似程度。
程序首先将两个文本中的单词使用两个vectors来分开存放。之后根据创建的两个vector的大小,创建特征矩阵(使用二维数组表示)。接着调用生成特征矩阵的函数,该函数同时使用排除字符串集合来排除不必要的字符串统计。最后,调用行打乱函数来模拟行打乱得到结果。
行打乱过程:对两个列向量,使用随机数生成一个随机行号,不断生成直到两个行号对应的字符串存在标志为1(即存在该字符串),两个列向量分别生成两个行号。接着,如果两个行号相同,则可以判定有两个相同的字符串存在,因此击中计数加一,最后使用击中次数除以打乱次数得到Jaccard相似度的近似值。
三、代码:
// shingling.cpp an implementation of shingling algorithm
// 在将给定的文本放入txt文件再读取到一个string a中时,设a的长度为n
// 对相同文本,直接在程序中初始化给string b时,其长度却是n+1
// 不知道是出了什么问题,因此放弃第一种方法,改用直接在程序中初始化
// 该程序直接对单词进行比较
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using std::string;
// 排除单词集合
string NotInc[] =
{
"a", "an", "the", "of", "by", "and", "or"<