Python实现列表匹配
注:此为项⽬之前所作利⽤实现⽂档的分词及词频统计的后续⼯作,主要做推荐所⽤。该代码相⽐普适性不强,只是针对项⽬所需编写。下⾯是链接:python3.6实现⽂档词频统计 - CSDN博客
摘要:每个⽂章对应⼀个,⾥⾯包含着[⽂件名,分词1,分词2,。。。。,分词15],。要进⾏⽂章的最佳匹配与推荐,思路是以15个分词作为特征,进⾏list与list之间的交集运算。我们认为交集元素数⽬最多的最匹配,⼀样多的情况下,分词的序号(例如分词1、分词3、分词10的1、3、10)代表着其重要性,计算他们的和,越⼩则优先级最⾼。
难点的详细解释放在代码后⾯。
环境:win10+pycharm2018.1+Python3.6
第三⽅库:⽆
输⼊:python3.6实现⽂档词频统计 - CSDN博客 最后⽣成的 结果汇总.txt
输⼊⽂件⽰例(不必⼀致,只是为了运⾏结果说明):
PTA.docx,节点,题⽬,存储,输出,算法,做法,路径,循环,集合,时间,数据,元素,最⼩,数组,两个
⾼级程序设计语⾔.docx,⽅法,对象,类型,变量,语句,数组,int,Java,执⾏,String,实例,数据,循环,声明,引⽤
计算机组成原理复习纲要.docx,中断,⽅式,地址,CPU,周期,指令,程序,执⾏,设备,寄存器,寻址,DMA,数据,主存,接⼝
离散数学合⼦童.docx,运算,关系,元素,系统,⽣成,代数,同态,函数,排列,单位,映射,盒⼦,原理,递推,an
软件⼯程内部终版.docx,系统,测试,需求,设计,过程,开发,软件,功能,模型,描述,故障,活动,对象,关系,时间
⼭软智库_计算机⽹络_,发送,数据,⽹络,协议,接收,传输,连接,信号,服务,智库,⼭软,地址,信道,TCP,主机
数据库_可编辑.docx,属性,事务,关系,数据,索引,元组,记录,查询,连接,实体,函数,Ti,依赖,搜索,数据库
智库内部编辑版_操作系统概念.docx,进程,系统,⽂件,内存,磁盘,线程,程序,调度,资源,⽤户,执⾏,访问,等待,时间,地址1
⾯向对象开发技术(1).doc,对象,⽅法,public,继承,接⼝,模式,⼦类,定义,抽象,实例,void,类型,⽗类,属性,new
数据结构复习纲要见解.doc,元素,节点,链表,数组,操作,插⼊,搜索,描述,路径,删除,⼆叉树,时间,排序,遍历,位置
Alpha_1_操作系统概念_,进程,调度,程序,PCB,系统,CPU,状态,执⾏,内存,fork,创建,3.1,信息,上下⽂,切换
Alpha_1_操作系统概念_,内存,页表,地址,进程,逻辑,空间,分配,分页,碎⽚,⼤⼩,偏移量,长度,寄存器,作业,吉鹏
代码:
1fr = open("分词结果汇总.txt")
2data = []
3for line in fr:
4    line = place("\n", "")
5    data.append(line.split(","))
6fr.close()
7
8#把标签list转化合并为string,并加在每篇⽂章的最后⼀列
9def list2String():
10    for i in range(len(data)):
11        string = ""
12        for j in range(1,len(data)-1):
13            string=string+data[i][j]
14        data[i].append(string)
15
16    print (data)
17
python获取数组长度18#python 两个list 求交集,并集,差集 - CSDN博客  blog.csdn/bitcarmanlee/article/details/51622263
19#获取两个list的交集返回值是list
20def intersection(listA,listB):
21    #求交集的两种⽅式
22    retA = [i for i in listA if i in listB]
23    # retB = list(set(listA).intersection(set(listB)))
24    return retA
25#获取两个list的并集返回值是list
26def union(listA,listB):
27    #求并集
27    #求并集
28    retC = list(set(listA).union(set(listB)))
29    return retC
30#获取两个list的补集返回值是list
31def complement(listA,listB):
32    #求差集,在B中但不在A中
33    retD = list(set(listB).difference(set(listA)))
34    return retD
35
36#获取权重最⼩的序号index
37def getMinIndex(list):
38    min=100
39    if(len(list)==1):
40        index=0
41    else:
42        for i in range(len(list)):
43            if (list[i] < min):
44                min = list[i]
45                index = i
46    return index
47
48#寻与其最相似的⽂章
49def findSimilarity(singleDataAsList):
50    # ⽣成包含匹配数⽬最多的⽂章的列表。如[[7, '进程', '内存'], [10, '进程', '内存']]
51    allresult = [["初始值"]]
52    max = -1
53    for i in range(len(data)):
54        if (data[i]!=singleDataAsList): #不能与⾃⾝⽐较
55              a = data[i]
56            intersectionResult = intersection(a,singleDataAsList)
57            print (intersectionResult)
58            if (len(intersectionResult) > max and len(intersectionResult) != 0):  # and len(intersectionResult)!=0
59                max = len(intersectionResult)
60                allresult.pop()
61                intersectionResult.insert(0, i)
62                allresult.append(intersectionResult)
63            elif (len(intersectionResult) == max):
64                intersectionResult.insert(0, i)
65                allresult.append(intersectionResult)
66
67    # ⽣成相应的列表的权重如[5, 10]
68    allweight = [0] * len(allresult)
69    for i in range(len(allresult)):
70        for j in range(1, len(allresult[i])):
71            for k in range(len(data[allresult[i][0]])):
72                if (data[allresult[i][0]][k] == allresult[i][j]):
73                    allweight[i] = allweight[i] + k
74
75    print (allresult)
76    print (allweight)
77
78    minIndex = getMinIndex(allweight)
79    title = data[allresult[minIndex][0]][0]
80
81    print ("最匹配的⽂章是:" + title)
82
83b=data[-1]  #以最后⼀篇⽂章⽰例
84findSimilarity(b)
运⾏结果不⽣成⽂件,只打印信息,如图所⽰:
因为我们是拿最后⼀篇⽂章来做例⼦的,最后⼀篇⽂章是截取的操作系统内存部分章节的内容。那么理应我们得到的最匹配的⽂字是操作系统的⽂档。结果证明与预想的符合,该推荐还是有⼀定意义的。
评价总结:
推荐效果:所做测试不是很多,但效果尚可接受,均与预想符合。
耗时:⾮常短,⼤约⼀秒就可完成。采⽤列表匹配后⼤⼤节省了时间。
重点解释:
1.为什么⽤列表匹配,⽽不⽤建⽴稀疏矩阵,计算cos等常规⽅法?
因为⽂档对于实际项⽬是未知的,所以⽆法确定的⽂档的分词会产⽣什么结果,所以⽆法建⽴⼀些预定的分词。其次由于分词的多样⾏,即使我们预先定义好⼀些同义词和近义词,仍然是⼀个巨⼤的分词库。这样势必会导致产⽣的⽂档*分词的矩阵极其稀疏,当⽂档数⽬达到⼀定量时,运算耗时会成指数增长。考虑到时间因素,不得已放弃常规⽅法。
采⽤list匹配,优化的部分在于省去⼀些本不必要的计算,⽐如两篇⽂档的交集本就为0或者为1(代指很少),这种根本⽆需进⾏cos计算,因为根本不可能是最优结果。所以⽤list匹配先求出交集,在交集最
多的⼏个候选集⾥再次计算。这样虽然⽐计算cos相似度在精确度⽅⾯有不⾜,但是⼤⼤节约了运算时间和资源,性价⽐较⾼。
2.如何进⾏列表匹配?
⼀开始想到的是最基础的设置⼏个for循环,但对于for循环要慎重考虑。毕竟当⽂档数⽬很多后,for循环是指数增长的罪魁祸⾸。后来查阅⼀些资料,在⼀篇博客⾥发现不错的解决⽅案。
python 两个list 求交集,并集,差集 - CSDN博客
⾥⾯提供了两种⽅法,选⽤其中⼀种即可。(代码注释⾥有解释,可看代码)
3.对于交集数⽬同样的⽂档怎么进⼀步划分?
⾸先要明确,有同样数⽬的交集,并不代表相似程度就⼀样。回过头来捋⼀捋,我们假定分词代表着⽂章的内容,词频越⾼代表性越强。我们的list⾥⾯也是按词频的⼤⼩排序的。所以有同样元素数⽬的交集,元素的代表性(词频)也是不⼀样的,这就是我们⼆次筛选的依据。即利⽤分词的序号(例如分词1、分词3、分词10的1、3、10)来模拟词频,模拟重要性。
如上图所⽰,这三篇⽂章的分词的交集的重要度的和分别是13,5,10。前⾯的2,7,10是⽂章序号。数⽬越⼩,重要性越⾼。故第7篇⽂章最符合,根据前⾯的序号(7)匹配到⽂章名,输出最后的结果。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。