• 第一次个人编程作业


    第一次个人编程作业

    GitHub链接

    GitHub链接

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

    str1:去符号后的原文文件

    str2:去符号后的抄袭版论文文件

    alll_words:存放所有的词

    str1_words_code/str2_words_code:记录str1,str2中每个词出现的次数

    关键算法:

    余弦相似度算法(计算个体间的相似度)

    在三角形中,余弦函数的计算公式为:

    在直角坐标系中,二维空间中余弦函数的计算公式为:

    多维空间中余弦函数的计算公式为:

    算法举例

    str1:今天是星期天,天气晴,今天晚上我要去看电影

    str2:今天是周天,天气晴朗,我晚上要去看电影

    1. 使用结巴分词和停用词表对两个句子进行分词

      str1_words=['今天','是','星期天','天气','晴','今天','晚上','我','要','去','看','电影']

      str2_words=['今天','是','周天','天气','晴朗','晚上','我','要','去','看','电影']

    2. 对所有的词进行编码

      set={'今天','是','星期天',‘周天’,'天气','晴','晴朗',今天','晚上','我','要','去','看','电影'}

      word_dict={'今天':0,'是':1,'星期天':2,‘周天’:3,'天气':4,'晴':5,'晴朗':6,今天':7,'晚上':8,'我':9,'要':10,'去':11,'看':12,'电影':13}

    3. 计算每个词出现的次数

      str1_words_code=[1,1,1,0,1,1,0,1,1,1,1,1,1,1]

      str2_words_code=[1,1,0,1,1,0,1,0,1,1,1,1,1,1]

    4. 计算余弦相似度

      [cos(Θ)=frac{1*1+1*1+1*0+0*1+1*1+1*0+0*1+1*0+1*1+1*1+1*1+1*1+1*1+1*1}{sqrt{1^2+1^2+1^2+0^2+1^2+1^2+0^2+1^2+1^2+1^2+1^2+1^2+1^2+1^2}*sqrt{1^2+1^2+0^2+1^2+1^2+0^2+1^2+0^2+1^2+1^2+1^2+1^2+1^2+1^2}}=0.80 ]

    余弦相似度:相似度越小,距离越大;相似度越大,距离越小。余弦值越接近1,表示两个向量越相似;余弦值越接近0,表示两个向量越不相似。

    计算模块接口部分的性能改进

    记录在改进计算模块性能上所花费的时间及改进的思路

    改进计算模块性能上所花费的时间较少,主要是增加了try except语句的使用和对标点符号进行了处理(try:尝试执行的代码;except:出现错误的处理

    性能分析图

    代码比较简单,没有包装成函数,所以没有展示消耗最大的函数。

    计算模块部分单元测试展示

    测试的函数

    • 结巴分词

      #使用结巴分词对str1,str2进行分词,将所有的词放在set中
      cutwords = []
      stops = open('stop_words.txt','r',encoding='utf-8-sig')
      for oneword in stops:
          oneword = re.sub("
      ","",oneword)   #将oneword中的'
      '替换为''
          cutwords.append(oneword)    #将该次放在cutwords的最后
      stops.close()
      str1_words = [i for i in jieba.cut(str1,cut_all=True) if (i not in cutwords) and i!='']
      str2_words = [i for i in jieba.cut(str2,cut_all=True) if (i not in cutwords) and i!=''] #全模式切分
      all_words = set(str1_words).union(set(str2_words)) #集合
      
    • 计算余弦值

      改进前

      #计算余弦值并输出结果
      item1 = 0
      item2 = 0
      sum = 0
      for i in range(len(str1_words_code)):
          sum += str1_words_code[i]*str2_words_code[i]
          item1 += pow(str1_words_code[i],2)
          item2 += pow(str2_words_code[i],2)
      
      answer = round(float(sum)/(math.sqrt(item1)*math.sqrt(item2)),3)#返回浮点数四舍五入的值
      print("%f"%answer)
      

      改进后

      #计算余弦值并输出结果
      item1 = 0
      item2 = 0
      sum = 0
      for i in range(len(str1_words_code)):
          sum += str1_words_code[i]*str2_words_code[i]
          item1 += pow(str1_words_code[i],2)
          item2 += pow(str2_words_code[i],2)
      
      try:
          answer = round(float(sum)/(math.sqrt(item1)*math.sqrt(item2)),3)#返回浮点数四舍五入的值
      except ZeroDivisionError:   #出现异常情况
          answer = 0.00
      data = open("ans.txt",'w+')
      print("%f"%answer,file=data)
      data.close()
      

    测试的函数及构造测试数据的思路

    测试的函数包括使用结巴分词进行分词,计算余弦值。使用结巴分词进行分词和计算余弦值是余弦相似度算法的核心,所以需要构造测试数据来观察和分析结巴分词后得到的结果。

    先检查特例,输入相同文本时得到的重复率会不会是1,输入源文件和空白文档时能不能正常运行,结果就发现了会产生分母为0的现象,所以增加了try except语句的使用,之后便使用样例中的源文件和增删改后的抄袭版文件进行测试。

    orig.txt
    orig.txt
    余弦相似度 = 1.000000
    
    orig.txt
    blank.txt
    余弦相似度 = 0.000000
    
    orig.txt
    orig_0.8_add.txt
    余弦相似度 = 0.995000
    
    orig.txt
    orig_0.8_del.txt
    余弦相似度 = 0.997000
    
    orig.txt
    orig_0.8_dis_1.txt
    余弦相似度 = 0.999000
    
    orig.txt
    orig_0.8_dis_3.txt
    余弦相似度 = 0.998000
    
    orig.txt
    orig_0.8_dis_7.txt
    余弦相似度 = 0.998000
    
    orig.txt
    orig_0.8_dis_10.txt
    余弦相似度 = 0.997000
    
    orig.txt
    orig_0.8_dis_15.txt
    余弦相似度 = 0.992000
    
    orig.txt
    orig_0.8_mix.txt
    余弦相似度 = 0.998000
    
    orig.txt
    orig_0.8_rep.txt
    余弦相似度 = 0.996000
    

    测试覆盖率

    计算模块部分异常处理说明

    • 测试空白文档,产生了分母为0的现象,所以增加了try except语句的使用。

    try:
        answer = round(float(sum)/(math.sqrt(item1)*math.sqrt(item2)),3)#返回浮点数四舍五入的值
    except ZeroDivisionError:   #出现异常情况
        answer = 0.00
    

    PSP表格

    PSP2.1 Personal Software Process Stages 预计耗时(分钟) 实际耗时(分钟)
    Planning 计划
    · Estimate · 估计这个任务需要多少时间 60 40
    Development 开发
    · Analysis · 需求分析 (包括学习新技术) 1000 1200
    · Design Spec · 生成设计文档 60 30
    · Design Review · 设计复审 30 30
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 20
    · Design · 具体设计 90 60
    · Coding · 具体编码 300 720
    · Code Review · 代码复审 30 60
    · Test · 测试(自我测试,修改代码,提交修改) 180 360
    Reporting 报告
    · Test Repor · 测试报告 120 60
    · Size Measurement · 计算工作量 30 30
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 30
    · 合计 1990 2640

    总结

    刚开始拿到这个题目的时候搜了一个下午的资料,毫无头绪...后面花了好长的时间去学Python,尽管最后写出来的东西不是那么满意,但是收获真的很大,拖延症晚期选手终于开始学Python了,希望接下来还能学到更多东西。冲冲冲!

  • 相关阅读:
    windows的一组常用运行命令
    nfs:server is not responding,still trying 原因与解决方案
    MYSQL外键(Foreign Key)的使用
    byte[]转字符串编码问题
    /usr/bin/ld: cannot find lGL
    Linux查看用户及分组
    NAND和NOR flash的区别
    Win7+Ubuntu11.10(EasyBCD硬盘安装)
    Win7+Ubuntu12.04.1硬盘安装错误及解决方案
    Linux内核编译时错误
  • 原文地址:https://www.cnblogs.com/jinnian1120/p/13687434.html
Copyright © 2020-2023  润新知