编写此脚本的目的:
本人从事软件测试工作,近两年发现项目成员总会提出一些内容相似的问题,导致开发抱怨。一开始想搜索一下是否有此类工具能支持查重的工作,但并没找到,因此写了这个工具。通过从纸上谈兵到着手实践,还是发现很多大大小小的问题(一定要动手去做喔!),总结起来就是理解清楚参考资料、按需设计、多角度去解决问题。
脚本进行相似度分析的基本过程:
1、获取Bug数据。读取excel表,获取到“BugID”和“Bug内容”
2、获取指定格式的Bug关键字集合。使用“jieba包”,采用“搜索模式”,对Bug内容进行分词,获取到分词表后,使用“正则表达式”过滤,拿到词语(词语长度>=2),提出掉单个字、符号、数字等非关键字
3、计算词频(TF)。在步骤2中获取到关键字总量,在本步骤,则对筛选后的关键字进行频率统计,最后得出“TF值(关键字出现频率/总词数)”
4、获取词逆文档频率(IDF)(也可以理解为权重)。在本步骤,有个重要的前提就是“语料库”,这里我没有使用开放、通用的语料库,而是使用本项目的“测试用例步骤、约束条件”等内容,唯一的原因就是“很适应Bug内容的语言场景”,在此模块,也是采用分词,然后利用参考资料中的计算公式,获取到每个“关键词”的IDF值,并存至名称为“get_IDF_value.txt”的文件中(一开始没放到这里,导致出现重复、多次进行本步骤计算,几kb的文本内容还能接受,几百kb的就......当时跑了一夜都没完!)
5、获取TF_IDF值,并据此对Bug关键字进行倒序排列,然后硬性截取所有Bug排位前50%的关键字,并形成集合,然后以冒泡的形式,从第一个Bug开始,进行“相似度计算”(公式见参考资料),最终将相似度大于阀值的Bug,以形式“Bug编号_1(被比对对象)-Bug编号_2(比对对象)”打印到名称为“bug_compare_result.xls”的Excel表中
过程中一些特殊点的处理:
1、“所有Bug排位前50%的关键字,并形成集合”之所以创建该列表是为减少单个列表或字典在多个函数使用的频率,肯定是可以减少脚本问题频率的。
2、语料库的选择是为适应使用需求
3、得到TF_IDF值的目的只是为了获取到“排位前50%的Bug关键字”
4、逆文档频率(IDF)值会存储至“get_IDF_value.txt”文件中,每次运行脚本时会提醒是否更改语料库
说明:
1、代码友好性差,技术能力有限。当然可塑性很高 ~ ~
2、出于练习的目的,独立编写“IDF计算”的脚本,并放到另一路径下
源码:(纯生肉,通过代码注释还是能看到本人设计过程的心态)
sameText.py
--------------------sameText.py--------------------------
#-*- coding:utf-8 -*- import jieba import re import CorpusDatabase.getIDF as getIDF import math import xlrd import xlwt import time #######获取原始bug数据 re_rule_getTF = re.compile(r"^([\u4e00-\u9fa5]){2,20}")#选择中文开头,且文字长度为2-20,一定要记住哇 Top_List = []#将分词的列表和TF_IDF值前50%的列表合于此处 Compare_CosResult = []#相似度大于??(可调整)的问题号 BugID_List = []#用于存放BugID getIDF_get_IDF_value = {}#存储语料库中各关键词的权重 xiangsidu = 0.8 ########### def read_Originalbase(filename): Original_Bug_Dict = {} book = xlrd.open_workbook(filename) sheet_name = book.sheet_by_index(0) nrows = sheet_name.nrows for i in range(nrows): Original_Bug_Dict[sheet_name.row_values(i)[0]] = sheet_name.row_values(i)[1] return Original_Bug_Dict ###########词频统计################### def get_TF_value(test_String_one): word_counts = 0#统计除空、单字、符号以外的总词数 counts = {} counts_two = {} words_re_TF = [] words = jieba.lcut_for_search(test_String_one) #这边得加段正则表达式的,筛除掉words非中文且单字的内容,并构建words_re_TF for i in words: if re.match(re_rule_getTF,i): words_re_TF.append(i) #统计每个分词的出现次数,即总词数量counts Top_List.append(words_re_TF)#全局的作用列表,很关键 for word in words_re_TF: word_counts = word_counts + 1 counts[word] = counts.get(word,0) + 1#为关键字出现次数进行统计,从0开始,get中第一个为key,0为赋给其对应的value #获取每个关键字在整句话中出现的频率,即最终词频 for count in counts: counts_two[count] = counts_two.get(count,(counts[count]/