个人项目-论文查重

这个作业属于哪个课程广工2023软件工程
这个作业要求在哪里个人项目作业-论文查重
这个作业的目标设计一个论文查重算法
其他参考文献· 从0到1,了解NLP中的文本相似度
· 一文详解 MD5 信息摘要算法
· 使用simhash计算文本相似度

一、仓库地址

gitcode仓库地址

release


二、PSP表格

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划1515
· Estimate估计这个任务需要多少时间1515
Development开发11801410
· Analysis· 需求分析 (包括学习新技术)200240
· Design Spec· 生成设计文档4060
· Design Review· 设计复审515
· Coding Standard· 代码规范 (为目前的开发制定合适的规范)55
· Design· 具体设计200200
· Coding· 具体编码500550
· Code Review· 代码复审3040
· Test· 测试(自我测试,修改代码,提交修改)200300
Reporting报告80100
· Test Repor· 测试报告4060
· Size Measurement· 计算工作量2025
· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划2015
·合计12751525

三、模块接口的设计与实现过程

3.1 设计原理

对于大文本计算时,simhash比较文本相似度速度快。为了在爬取网页时用于快速去重,Google发明了一种快速衡量两个文本集相似度的算法:simhash。

simhash中使用了一种局部敏感型的hash算法。所谓局部敏感性hash,与传统hash算法不同的是(如MD5,当原始文本越是相似,其hash数值差异越大),simhash中的hash对于越是相似的内容产生的签名越相近。计算出simhash值后,再计算hash值的汉明距离,结合杰卡德系数,即可得到文本的相似性。

3.2 算法的实现过程

  • 第一步,分词——本项目使用hanlp分词的手段
    对文本进行分词操作,同时返回当前词组在文本内容中的权重

  • 第二步,计算hash——本项目使用MD5算法,将词语转换成32位数字字母混合码,再转化成128位hash
    对于每一个得到的词组做hash,将词语表示为用01表示的bit位,需要保证每个hash结果的位数相同。

MD5是一种信息摘要算法。一个字符串或文件或压缩包,执行md5后,可以生成一个固定长度为128bit的串。而且这个串基本上是唯一的。

  • 第三步,加权——利用HanLP.extractKeyword方法过滤关键词并得到词频
    根据每个词组对应的权重,对hash值做加权计算(bit为1则取为1做乘积,bit为0则取为-1做乘积)

  • 第四步,纵向相加:
    将上述得到的加权向量结果,进行纵向相加实现降维

  • 第五步,归一化、降维:
    将最终降维向量,对于每一位大于0则取为1,否则取为0,这样就能得到最终的simhash的指纹签名

  • 第六步,相似度比较——本项目结合汉明距离和杰卡德系数得到相似度
    在这里插入图片描述
    ——关于杰卡德系数的参考博客

3.3 项目的结构

项目分为主类和测试类两个大类,其中主类还放置了两个包,一个是存放着异常处理类的enceptions包,另一个是存放计算相关的工具类和处理文件的工具类的utils包。

  • 项目的结构
    在这里插入图片描述
  • 模块设计

在这里插入图片描述

  • 算法的关键之处
    1.使用hanlp分词手段;
    2.使用MD5算法获取hash值;
    3.计算海明距离并使用杰拉德系数计算文本相似度。

四、模块接口的性能改进

4.1概览

在这里插入图片描述

 内存大概占用270MB。

4.2 所有对象视图

在这里插入图片描述

4.3 调用消耗

以MainTest.getSimilarity2为例
在这里插入图片描述

从方法调用中可以看出,在进行相似度计算时,calculateSimHash使用了56.6%的资源,其中wordHash和hashWeight的遍历就分别占用了38%和17.8%,遍历共占用了56.5%的资源;hanlp的文本分析使用了42.4%的资源,其中关键字提取占用了33.1%,统计词频占用了8.5%。

4.4 性能改进

  • 减少遍历次数:由上述分析,计算simhash值过程中大量使用了遍历,占用了许多资源。因此减少遍历次数可以提升算法效率。
  • 减少hash码位数:本项目中使用MD5算法将词语转化为不重复的唯一的128位二进制编码,但关键词太多会导致消耗大量存储空间存储数值。因此我认为可以减少哈希码位数,减少存储空间的浪费。
  • 改变分词方法:本项目中hanlp分词方法占用了42.4%的资源,如果使用其他较为简单的分词方法,将减少资源的消耗。

4.5 消耗最大函数展示

 static final int HASH_BIT = 128;
    /**
     * 采用MD5算法对关键词进行hash,得到的hash值使用16进制解析,再利用算法取128位二进制数作为hash值
     * @param word 词语
     * @return 128位二进制hash值
     */
    public static String wordHash(String word) throws HashException {
        //如果传入词语为null或“”或“ ”
        if (word == null || StrUtil.isBlank(word) || StrUtil.isEmpty(word)) {
            throw new HashException("词语为空");
        }
        try {
            // 采用MD5算法进行hash
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(word.getBytes(StandardCharsets.UTF_8));
            // hash值转为32位16进制的散列值
            StringBuilder hash = new StringBuilder();
            for (byte b : digest.digest()) {
                hash.append(String.format("%02x", b));
            }
            // 16进制的散列值转为128位二进制码
            StringBuilder finalHash = new StringBuilder();
            String strTemp;
            for (int i = 0; i < hash.length(); i++) {
                // 每一位16进制数加上0000,最后截取后4位,得到便是这位数的二进制
                strTemp = "0000" + Integer.toBinaryString(Integer.parseInt(hash.substring(i, i + 1), 16));
                finalHash.append(strTemp.substring(strTemp.length() - 4));
            }
            // 不为128则为hash异常
            if (finalHash.length() != HASH_BIT) {
                throw new HashException("hash值长度不为128");
            }
            return finalHash.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new HashException("MD5算法异常");
        }
    }

五、模块部分单元测试展示

  共有15个测试,全部通过。

在这里插入图片描述

5.1 单元测试覆盖率

  类覆盖率和方法覆盖率100%,行覆盖率89%

在这里插入图片描述

5.2 部分测试展示

  • 测试写入文件:测试在结果文件写入内容
    在这里插入图片描述
  • 测试读取不存在的文件,找不到指定文件应该抛出异常
    在这里插入图片描述
  • 测试读取文件并查看分词结果
    在这里插入图片描述
  • 测试MD5算法计算hash值
    在这里插入图片描述
  • 测试加权算法
    在这里插入图片描述
  • 测试计算simHash
    在这里插入图片描述
  • 测试计算句子相似度
    在这里插入图片描述
  • 测试计算文本相似度
    在这里插入图片描述
  • 测试6个测试样例
    在这里插入图片描述
    测试用例测试结果写入write.txt:
    在这里插入图片描述

六、模块部分异常处理说明

6.1 FileAnalyseException 测试解析文件异常

  • 转字符串为空或关键词太少
    在这里插入图片描述

6.2 HashException 测试哈希异常

  • hash位数不足128位

在这里插入图片描述

6.3 NotExistFileException 测试文件不存在异常

  • 读取不存在的文件
    在这里插入图片描述

七、传入命令行参数运行程序

  • 以下是6个测试用例的比对结果:
    在这里插入图片描述
    在这里插入图片描述
  • 结果写入write.txt
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boomyuan0000

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值