信息检索实验1-Inverted index and Boolean Retrieval Model
作者:互联网
实验题目 :Inverted index and Boolean Retrieval Model
实验内容:– 使用我们介绍的方法,在tweets数据集上构建inverted index;
– 实现Boolean Retrieval Model,使用TREC 2014 test topics 进行测试;
– Boolean Retrieval Model:
• Input:a query (like Ron and Weasley)
• Output: print the qualified tweets.
• 支持and, or ,not;查询优化可以选做。
实验目的:实现布尔检索模型
实验环境:Windows10、Spyder(Anaconda3)
实验原理分析:
1.针对布尔查询,其实就是查询(Queries)被表示为关键词的布尔组合,用“and、or、not”连接起来,并用括弧指示优先次序.
2.词项关联矩阵:就是将对应文档里出现的terms标记为0 1并且用矩阵的形式表示出来的方法。
由上图的布尔表达式为 Brutus AND Caesar AND NOT Calpurnia,即为查询莎士比亚剧本的哪一部是包含Brutus和凯撒但是不包含Calpurnia的。最简单的检索方式就是枚举,说白了,就是检索他所有的剧本,这种方法带来的后果就是会花费大量的时间,所有后面需要构建倒排索引,有了索引对结果的排序等有很大的好处。
3.倒排索引的应用:倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
按照docId排序后:
索引构建:
索引构建具体过程:
第一步是收集构建索引的文档集,将检索所需要的检索文档收集起来。
第二步,将文本转化为词条,即词条序列,我们从文档中读出<词条,docID>二元组。
第三步,令牌化并排序,就是将单词的其他形式复原,然后再排序,按词项排序,然后每个词项按docID排序。
第四步,构建倒排索引表,是词典和倒排记录表,某个词项在单篇文档中的多次出现会被合并,拆分成词典和倒排记录表两部分,每个词项出现的文档数目(doc.frequency, DF)会被加入
数据处理:
取tweet前5行数据举例分析
{“userName”: “Mariah Peoples”, “clusterNo”: 82, “text”: "House may kill Arizona-style immigration bill, Rep. Rick Rand says: The House is unlikely to pass the “Ari… http://tinyurl.com/4jrjcdz”, “timeStr”: “Sun Jan 23 00:02:37 +0000 2011”, “tweetId”: “28965792812892160”, “errorCode”: “200”, “textCleaned”: " ", “relevance”: 2}
{“userName”: “servando”, “clusterNo”: 35, “text”: “Mourners recall Sarge Shriver’s charity, idealism \n (AP): AP - R. Sargent Shriver was always an optimist, pio… http://bit.ly/gqMcdG”, “timeStr”: “Sun Jan 23 00:07:48 +0000 2011”, “tweetId”: “28967095878287360”, “errorCode”: “200”, “textCleaned”: " ", “relevance”: 1}
{“userName”: “Heide Eversoll”, “clusterNo”: 60, “text”: “Bass Fishing Techniques: 2 Fantastic Tips To Improve Your Casting Skills”, “timeStr”: “Sun Jan 23 00:10:05 +0000 2011”, “tweetId”: “28967672074993664”, “errorCode”: “200”, “textCleaned”: " ", “relevance”: 2}
{“userName”: “Ailsa Hung”, “clusterNo”: 97, “text”: “#Financial Aid | Proper Method Of Getting Financial Aid For Education http://ping.fm/BK0R3 #applying-for-financial-aid financial-aid-essay #”, “timeStr”: “Sun Jan 23 00:11:03 +0000 2011”, “tweetId”: “28967914417688576”, “errorCode”: “200”, “textCleaned”: " ", “relevance”: 2}
{“userName”: “Brothy”, “clusterNo”: 89, “text”: “Supreme Court: NASA’s intrusive background checks OK http://bit.ly/h2jgy9”, “timeStr”: “Sun Jan 23 00:13:18 +0000 2011”, “tweetId”: “28968479176531969”, “errorCode”: “200”, “textCleaned”: " ", “relevance”: 2}
由tweets里面数据所反映的情况来看,它并不是严格地按照表格形式来存储每一个数据的,所以我们在搜索过程中才会出现各种各样的问题。所以我们引入一个函数库textblob(TextBlob 是一款 Pythonic 的文本处理工具,用于处理文本数据,它提供了一个简单的 API,用于潜入常见的自然语言处理(NLP)任务,如词性标注、名词短语提取、情感分析、分类、翻译等)。
实验的过程其实就是要在文档的基础上建立索引,通过观察数据,我们发现"username",“clusterno”,“text”,“timestr”,“tweetid”,“errorcode”……这几个属性,唯一能标识对应文档的就是tweetID,所以选取它为主键,进行数据检索,并在最终的结果里将答案输出。而对于这五行数据,我们也发现,它所对应的是一个文档,所以在编程过程中,我们按行处理数据,并将其进行转化。
以下代码是对文本文档进行处理,就是将所有的单词进行统计,将大写字母全部还原为小写,单词改变后的形式也全部还原,便于检索。对应索引构建的第二步第三步的过程,将文本转化为词条的形式,并且按docID排序,这种格式化的处理对信息提取等也很重要。
def tokenize_tweet(document): #文件的属性
document=document.lower() #将所有大写字母返回小写字母并返回字符串
a=document.index("username") #返回指定的索引名称
b=document.index("clusterno")
c=document.rindex("tweetid") - 1
d=document.rindex("errorcode")
e=document.index("text")
f=document.index("timestr") - 3 #获取时间戳
#提取twwetid,username,tweet内容三部分主要信息
document=document[c:d] + document[a:b] + document[e:f]
terms=TextBlob(document).words.singularize() #词干提取,单词名词变单数,含特殊处理
result=[]
for word in terms:
expected_str=Word(word)
expected_str=expected_str.lemmatize("v") #lemmatize() 方法 对单词进行词形还原,名词找单数,动词找原型
if expected_str not in uselessTerm:
result.append(expected_str)
return result
实验结果截图:
1.and操作:
2.not操作:
3.or操作:
Codes
# -*- coding: utf-8 -*-
"""
lab-1
author:bad-kids
"""
import sys
from collections import defaultdict
from textblob import TextBlob #导入文本处理工具
from textblob import Word
uselessTerm=["username","text","tweetid"]
postings=defaultdict(dict) #inverted
def tokenize_tweet(document): #文件的属性
document=document.lower() #将所有大写字母返回小写字母并返回字符串
a=document.index("username") #返回指定的索引名称
b=document.index("clusterno")
c=document.rindex("tweetid") - 1
d=document.rindex("errorcode")
e=document.index("text")
f=document.index("timestr") - 3 #获取时间戳
#提取twwetid,username,tweet内容三部分主要信息
document=document[c:d] + document[a:b] + document[e:f]
terms=TextBlob(document).words.singularize() #词干提取,单词名词变单数,含特殊处理
result=[]
for word in terms:
expected_str=Word(word)
expected_str=expected_str.lemmatize("v") #lemmatize() 方法 对单词进行词形还原,名词找单数,动词找原型
if expected_str not in uselessTerm:
result.append(expected_str)
return result
#读取文档
def get_postings():
global postings
f=open(r"E:\myClass2\data-mining\expriment\lab1\tweets.txt") #打开document文件
lines=f.readlines()
for line in lines:
line=tokenize_tweet(line) #令牌化,解析一行数据
tweetid=line[0]
line.pop(0)
unique_terms=set(line)
for te in unique_terms:
if te in postings.keys():
postings[te].append(tweetid)
else:
postings[te]=[tweetid]
def op_and(term1,term2): #and与操作
global postings #全局变量
answer=[]
if(term1 not in postings) or (term2 not in postings):
return answer
else:
i=len(postings[term1]) #获取词长度
j=len(postings[term2])
x=0
y=0
while x<i and y<j:
if postings[term1][x]==postings[term2][y]:
answer.append(postings[term1][x])
x+=1
y+=1
elif postings[term1][x]<postings[term2][y]:
x+=1
else:
y+=1
return answer
def op_or(term1,term2): #或操作
answer=[]
if(term1 not in postings) and (term2 not in postings):
answer=[]
elif term2 not in postings:
answer=postings[term1]
elif term1 not in postings:
answer=postings[term2]
else:
answer=postings[term1]
for item in postings[term2]:
if item not in answer:
answer.append(item)
return answer
def op_not(term1,term2): #非操作
answer=[]
if term1 not in postings:
return answer
elif term2 not in postings:
answer=postings[term1]
return answer
else:
answer=postings[term1]
ANS=[]
for ter in answer:
if ter not in postings[term2]:
ANS.append(ter)
return ANS
def do_rankSearch(terms): #倒排索引
Answer=defaultdict(dict)
for item in terms:
if item in postings:
for tweetid in postings[item]:
if tweetid in Answer:
Answer[tweetid]+=1
else:
Answer[tweetid]=1
Answer=sorted(Answer.items(),key=lambda asd: asd[1],reverse=True)
return Answer
def token(doc):
doc=doc.lower()
terms=TextBlob(doc).words.singularize()
result=[]
for word in terms:
expected_str=Word(word)
expected_str=expected_str.lemmatize("v")
result.append(expected_str)
return result
def do_search(): #查询
terms=token(input("input your search query >> "))
if terms==[]:
sys.exit()
if len(terms)==3:
if terms[1]=="and":
answer=op_and(terms[0],terms[2])
print(answer)
elif terms[1]=="or":
answer=op_or(terms[0],terms[2])
print(answer)
elif terms[1]=="not":
answer=op_not(terms[0],terms[2])
print(answer)
else:
print("there is a syntax error!")
else:
leng=len(terms)
answer=do_rankSearch(terms)
print("[Rank_Score: Tweetid]")
for(tweetid,score) in answer:
print(str(score/leng)+ ": " + tweetid)
def main():
get_postings()
while True:
do_search()
if __name__ == "__main__":
main()
标签:index,terms,Inverted,索引,Boolean,str,document,postings 来源: https://blog.csdn.net/qq_43738932/article/details/112648411