【项目】#防翟天临老师翻车神器# ——实现文本查重
最近找实习的事基本上算是凉了,时间终于没那么紧迫了,学了点QT的皮毛给这个小工具搞了个简单的界面
不准说丑!!!!!!!! 2019-5-18
#############################################################################
最近的热点事件翟天临论文抄袭闹得社交网络沸沸扬扬,作为在学校生活的广大同学们肯定对于论文查重是都是有所耳闻的,为了不要像翟老师那样翻车,大家总会特别在意所谓的重复率,那么论文查重的功能到底是如何实现的呢?
这里我们将文本查重功能实现的程序分为四个步骤
- 文本分词
- 词频统计
- 构成词频向量
- 计算重复率
贴一下整体的代码 https://github.com/GreenDaySky/Function-text-rechecking(这里没有把jieba的工具包贴上来)
文本分词
文章都是以句子构成的,而句子是由许许多多的词构成的,所以其实查重机制的根本应当是根据词语进行的。
那我们就要思考一下如何进行从句子中提取词语完成分词操作了
这里贴一篇对于分词的介绍:https://www.cnblogs.com/BaiYiShaoNian/p/5071802.html
分词操作必然是和庞大的词库有关的,所以我们自己是无法完成的,需要借助工具来实现
这里我使用了jieba自然语言处理这个分词工具进行分词操作
首先我就遇到了一个问题,我下载的jieba分词工具基于Linux系统的UTF8的编码方式,而windows系统的编码方式是GBK类型的,每次使用时必须要进行转换,由于GBK和UTF8直接没有直接的映射关系,这里用UTF16作为中间量进行转换,UTF8和GBK为多字节,UTF16为宽字节
MultiByteToWideChar()为多字节转宽字节函数
https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-multibytetowidechar
WideCharToMultiByte()为宽字节转多字节函数
https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-widechartomultibyte
string TextSimilarity::UTF8toGBK(string s)
{int len1 = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, 0, 0);WCHAR* str1 = new WCHAR[len1];len1 = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, str1, len1);if (len1 <= 0)cout << "转码失败";int len2 = WideCharToMultiByte(CP_ACP, 0, str1, -1, NULL, 0, NULL, FALSE);CHAR* str2 = new CHAR[len2];len2 = WideCharToMultiByte(CP_ACP, 0, str1, -1, str2, len2, NULL, FALSE);if (len2 <= 0)cout << "转码失败";string OutString(str2);if (str1){delete[] str1;str1 = NULL;}if (str2){delete[] str2;str2 = NULL;}return OutString;
}string TextSimilarity::GBKtoUTF8(string s)
{int len1 = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, 0, 0);WCHAR* str1 = new WCHAR[len1];len1 = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, str1, len1);if (len1 <= 0)cout << "转码失败";int len2 = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, FALSE);CHAR* str2 = new CHAR[len2];len2 = WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, len2, NULL, FALSE);if (len2 <= 0)cout << "转码失败";string OutString(str2);if (str1){delete[] str1;str1 = NULL;}if (str2){delete[] str2;str2 = NULL;}return OutString;
}
解决了这个问题之后我们就可以进行调用jieba工具进行分词操作了,这里使用了jieba工具中的Cut函数进行分词
分词完成后我们又会遇到一个小问题,我们句子当中如果所有的被分好的词都被用来进行统计处理,出现最多的词会是什么?大概率是各种代词介词,所谓为了避免这些无用词的被记录我们要将这些个停用词删除掉,停用词就是一个句子当中那些没有实际意义的介词或者我你他这类的代词,我们要调用一个停用词库将分好的词与其进行对比,如果属于停用词就删掉它
词频统计
做完之前的操作我们剩下来的词就是有统计意义的词语了,接下来我们使用unordered_map进行词频统计
typedef std::unordered_map<std::string, int> wordFreq;typedef std::unordered_set<std::string> wordSet;cppjieba::Jieba _jieba;wordSet _stopWordSet;
TextSimilarity::wordFreq TextSimilarity::getWordFreq(const char* filename)
{ifstream fin(filename);if (!fin.is_open()){cout << "open file:" << filename << "failed";return wordFreq();}string line;wordFreq wf;while (!fin.eof()){getline(fin, line);// GBK--> UTF8line = GBKtoUTF8(line);vector<string> words;//对文本进行分词_jieba.Cut(line, words, true);//统计词频for (const auto& e : words){//去掉停用词if (_stopWordSet.count(e) > 0)continue;//统计词频else{if (wf.count(e) > 0)wf[e]++;elsewf[e] = 1;}}}return wf;
}
统计词频结束之后,我们要拿前N个词进行对比,如果是由全词对比显得事倍功半,这时需要一个排序功能的函数
bool cmpReverse(pair<string, int> lp, pair<string, int> rp)
{return lp.second > rp.second;
}vector<pair<string, int>> TextSimilarity::sortByValueReverse(TextSimilarity::wordFreq& wf)
{//unordered_map //map是kv结构的无法直接使用sort进行排序//sort只支持序列容器vector<pair<string, int>> wfvector(wf.begin(), wf.end());sort(wfvector.begin(), wfvector.end(), cmpReverse);return wfvector;
}
使用vector记录排序结果,并将候选词存到天然去重的unorder_set中
void TextSimilarity::selectAimWords(std::vector<std::pair<std::string, int>>& wfvec, wordSet& wset)
{int len = wfvec.size();int sz = len > _maxWordNumber ? _maxWordNumber : len;for (int i = 0; i < sz; i++){//pair<string, int>wset.insert(wfvec[i].first);}
}
构建词频向量
vector<double> TextSimilarity::getVectorQuantity(TextSimilarity::wordSet& wset, TextSimilarity::wordFreq& wf)
{//遍历wordSet中的每一个词vector<double> VectorQuantity;for (const auto& e : wset){if (wf.count(e))//VectorQuantity(value)VectorQuantity.push_back(wf[e]);elseVectorQuantity.push_back(0);}return VectorQuantity;
}
计算重复率
在进行文本查重操作的时候只需要获取用两个文本每一个的前N个高频词的和构建词频向量,然后对比向量之间的差异就能大致获取所谓的重复率
计算向量相似度的方法有许多:欧几里得距离,余弦相似度,jaccard系数,曼哈顿距离
这里我采用了易于实现的余弦相似度进行计算
double TextSimilarity::cosine(std::vector<double> VectorQuantity1, std::vector<double> VectorQuantity2)
{double modular1 = 0, modular2 = 0;double products = 0;assert(VectorQuantity1.size() == VectorQuantity2.size());for (int i = 0; i < VectorQuantity1.size(); i++){//点积products += VectorQuantity1[i] * VectorQuantity2[i];}for (int i = 0; i <VectorQuantity1.size(); i++){//模modular1 += pow(oneHot1[i], 2);}modular1 = pow(modular1, 0.5);for (int i = 0; i <VectorQuantity2.size(); i++){//模modular2 += pow(VectorQuantity1[i], 2);}modular2 = pow(modular2, 0.5);return products / (modular1 * modular2);
}
【项目】#防翟天临老师翻车神器# ——实现文本查重相关推荐
- [转]simhash进行文本查重
有1亿个不重复的64位的01字符串,任意给出一个64位的01字符串f,如何快速从中找出与f汉明距离小于3的字符串? 大规模网页的近似查重 主要翻译自WWW07的 Detecting Near-Dupl ...
- (精品)基于Web的酒店客房管理系统的设计与实现毕业论文+开题报告+项目源码(SSM)及数据库+查重报告
源码获取:我的博客资源页面可以下载!!!! 项目名称 (精品)基于Web的酒店客房管理系统的设计与实现毕业论文+开题报告+项目源码(SSM)及数据库+查重报告 视频介绍 (精品)基于Web的酒店客房 ...
- 文本查重:知识点总结
目录 整体框架 1. 查询文本切分策略 2. 文本相似性计算 2.1 计算粒度 2.2 相似性度量算法 2.3 整体相似度的评估 文本相似度 simhash算法及原理简介 1. 什么是SimHash ...
- 大量文本查重相似度计算功能设计-基于simhash+相似度算法
最近做文本查重功能,陆续遇到一些问题,做一下记录: 1.simhash分桶策略,只适合基本完全相同的文本查重,比如网页查重.64位simhash如果有3位以内的海明距离,则认为文本一致:存储使用hba ...
- 【代码模板】simHash算法文本查重(golang代码实现)
ps: 供自己以后参考以及供了解simhash算法的人看 本代码针对通用文本查重,故所有分词的权重均为1 由于没有安装分词器,所以目前只能对英文句子进行相似度检测 代码只提供一个大致思路,没有做进一步 ...
- 【JavaWeb 爬虫】Java文本查重网页版 爬取百度搜索结果页全部链接内容
! ! 更新:增加了网页过滤判断,只允许域名包含blog,jianshu的网站通过 小技巧 Java中InputStream和String之间的转换方法 String result = new Buf ...
- python实现文本查重系统_NLP之gensim库python实现文本相似度/匹配/查重
目的 给定一个或多个搜索词,如"高血压 患者",从已有的若干篇文本中找出最相关的(n篇)文本. 理论知识 文本检索(text retrieve)的常用策略是:用一个ranking ...
- 文本查重:difflib.SequenceMatcher
目录 1. SequenceMatcher FlowChart 1.1 get_matching_blocks() 1.2 find_longest_match() 1.3 ratio() 2. 例子 ...
- 20190508 文本查重系统(四)
楼上突然知道我的web项目是用python2.7写的,然后,然后我就花了三天的时间改版了,顺便改了很多以前没有发现的bug,是的,还是python写的,这次是python3.6.至于java版本,写完 ...
- 个人项目——论文查重
文章目录 项目概述 0. Gitcode链接 1.PSP表格 2.题目描述 3.算法实现基本思路 3.1simHash算法原理 3.2余弦定理查找相似度 4.模块接口部分 5.执行结果 6.代码测试 ...
最新文章
- 2个月做出一款AI项目?这些学生在DeeCamp上决出两个总冠军
- MongoDB的查询整理
- cortex-M3 的SVC、PendSV异常,与操作系统(ucos实时系统)
- 英文seo外链资源整合,怎么样找国外博客资源?
- win7+ubuntu20.04双系统+easybcd安装以及Reached target Reboot卡住问题
- 2019ICPC西安邀请赛 E. Tree(树剖 + 线段树)
- AndroidManifest.xml清单文件要点
- linux下C++遍历文件夹下的全部文件;Windows/Linux下C++批量修改文件名,批量删除文件...
- xp电脑怎么进入bios
- .Net 自定义应用程序配置 configSections
- building a blog
- sudo: must be setuid root错误解决方法.
- 关于Spring3 MVC的 HttpMediaTypeNotSupportedException
- html制作个人简历
- 微信小程序-image(图片)
- 电商格局谋定重整-万祥军:李玉庭对话中国经济和信息化
- 如何细分目标客户群体,让邮件效果更好?
- 2022.10.13(四)[仿写《百草园到三味书屋》第二段]
- 数据驱动的营销方式和加拿大禁止Clearview AI
- 常用加密与解密算法示例代码