惯例三件套
软件工程 | 班级地址 |
---|---|
这个作业要求在哪里 | 点击 |
这个作业的目标 | 完成个人编程练习,学习git和github的联动使用,学习去重算法simhash的原理与实现 |
Github 此项目链接 | 点击 |
- 基本情况:
- simhash算法实现:
- 分词算法:jieba
- 调用库:jieba、re
- 核心算法:getfile()、simhashalgo()、haiming()
- 相似度:采用simhash值相除后取精确值 - 测试单元:
- 算法:unittest
- 测试用例:祖传六份orig.txt - 待优化地方:
- 初始的测试用例是包含html文本的,由于文本关键词提取必须去除html文本标签内的英文的缘故,此处设计的simhash算法只针对中文,后可通过更改停词库和更改正则表达式进行修改
- simhash算法实现:
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 15 |
Estimate | · 估计这个任务需要多少时间 | 40 | 30 |
Development | 开发 | 400 | 540 |
Analysis | 需求分析 (包括学习新技术) | 120 | 90 |
Design Spec | 生成设计文档 | 50 | 40 |
Design Review | 设计复审 | 20 | 15 |
Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 15 |
Design | 具体设计 | 50 | 60 |
Coding | 具体编码 | 30 | 20 |
Code Review | 代码复审 | 30 | 50 |
Test | 测试(自我测试,修改代码,提交修改 | 30 | 80 |
Reporting | 报告 | 90 | 90 |
Test Repor | 测试报告 | 40 | 30 |
Size Measurement | 计算工作量 | 15 | 15 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 25 |
合计 | 985 | 1115 |
核心步骤
一.分词
此处我合并了打开文本、提取文本、清洗文本的步骤,由于jieba库中能直接调用jieba.analyse.extract_tags,返回一个经过tf-idf处理结果后的列表。此列表包含了能自定义个数n的最高权重排名前n个关键词,以及关键词对应的权重值,能非常方便后续结果的处理,因此我使用了jieba库,通过这个getfile()函数我实现了导入、清洗、分词与获得权重,返回一个{关键词:权重}的字典以及字典长度
二.hash
此处的hash算法较为复杂,主要的思路就是把汉字对应的ASCII码进行hash运算,通过尽量确保每个词对应的hash编码不同来确保最后数组运算时各数据能代表原先的汉字,最后转化为一个64位长度的二进制序列来进行之后的运算。
三.加权、降维操作
此处我定义的simhashalgo()函数就是最关键的步骤,通过前面的getfile()以及hash函数返回来的权重与特征向量的hash值,我们能通过各关键词加权、关键词的相加与最后降维成单列10序列,能把原本分散于64位的汉字特征值最后特征式地降维到单列数字中,具体数学公式还有待推导,但最后得到的simhash值就是该文本关键词加权后的降维特征词(简单说就是通过把n个特征词加权后同一列的数字相加,得到一个偏向于1或0的代表值),通过与simhash值的比较,就能实现推断文本在关键词上是否存在相似性,以及相似性的大致估计。由于相似的文章关键词权重应该都相差不大,因此有差别的位数也只会有少数几位,simhash算法又因此被称作“局部敏感hash算法”
(我的代码实现就是普通地进行加权、相加、判断大小后取值、整合成单行的01序列,最后返回对应的列表)
四.haiming和相似
没啥好讲的,就是从定义出发,比较simhash值中不同的位数来推断相似性
单元测试
使用unittest:
就是非常简单的拼接地址+调用上面设计好的simhash算法,简单易操作。感谢廖雪峰老师的简要文档
测试效果图:
性能分析
使用pycharm自带的profile方法
个人总结
1.这次实验用到了我一直很感兴趣的去重算法,因此在算法的琢磨与研究上花费了出乎意外的时间,导致后面的报告部分被相应地压缩了,这点得反省。
2.参考了网上的大量文献后,我弄懂了关于simhash的大部分内容,但对于诸如海明距离用于关键词判断的阈值、关键词选取个数对最后结果的影响、相似度如何运算(除法个人觉得不大妥当)、关键词如何降维到二维的01序列也就是string_hash算法的设计(这个参考了专业博客的算法,并非完全原创)这些问题都有待思考和解决
3.过于执着于算法实现而忽略了其他更简便也更适合少规模对比的算法(gensim,余弦,动态规划等),思维模式应该要更加灵活