美文网首页
文档表示之倒排索引(inverted index)与布尔(boo

文档表示之倒排索引(inverted index)与布尔(boo

作者: Mr_Relu | 来源:发表于2019-05-14 20:39 被阅读0次

    编程环境:

    anaconda + Spyder
    Win10 + python3.6
    完整代码及数据已经更新至GitHub,欢迎fork~GitHub链接


    声明:创作不易,未经授权不得复制转载
    statement:No reprinting without authorization


    内容概述:

    任务:

    在tweets数据集上构建inverted index;

    实现Boolean Retrieval Model,使用TREC 2014 test topics进行测试;

    Boolean Retrieval Model:

    Input:a query (like Ron Weasley birthday)
    Output: print a list of top k relevant tweets.
    支持and, or ,not;查询优化可以选做;

    注意:

    对于tweets与queries使用相同的预处理;

    一、对推特数据的处理

            打开推特的文本数据发现数据具有较好的结构性,信息主要有userName、clusterNo、text、timeStr、tweetId、errorCode、textCleaned、relevance这些部分的信息,但是除了红色标注的,对于我们的检索任务而言,其它的都是冗余的,我们首先需要集中提取出红色的三部分信息来建立inverted index的postings。
            按行读取每条tweet后调用tokenize_tweet方法对其进行处理,并进行分词后对单词的统一变小写、单复数和动词形式统一等处理,使用TextBlob工具包,处理后的推特如下所示:


    image.png

    然后进行分词等处理后的推特如下:

    image.png
    最后再构建postings,采用字典结构,其中将每个单词作为键值,后面跟着包含该单词的tweet的tweetid列表。
    image.png

    二、对查询的输入进行处理

    注意需要对查询进行和tweet同样的分词等处理,保持一致性,主要代码如下所示:

    terms=TextBlob(document).words.singularize()
        result=[]
        for word in terms:
            expected_str = Word(word)
            expected_str = expected_str.lemmatize("v")
            if expected_str not in uselessTerm:
                result.append(expected_str)
        return result
    

            主要是对输入的查询进行语义逻辑的识别,判断是什么样的布尔查询,在本次实验中,针对单个and、or、not(A and B、A or B、A not B)三种布尔查询进行了实现,并在此基础上对双层逻辑的如A and B and C、A or B or C、(A and B) or C、(A or B) and C的实现,并作为功能拓展实现了对一般输入语句进行的排序查询,可以返回排序最靠前的若干个结果。如下所示:(用查询的单词在该文档中出现的个数/总数作为简单的排序分数)

    def do_search():
        terms = token(input("Search query >> "))
        if terms == []:
            sys.exit()  
        #搜索的结果答案   
        
        if len(terms)==3:
            #A and B
            if terms[1]=="and":
                answer = merge2_and(terms[0],terms[2])          
            #A or B       
            elif terms[1]=="or":
                answer = merge2_or(terms[0],terms[2])           
            #A not B    
            elif terms[1]=="not":
                answer = merge2_not(terms[0],terms[2])
            #输入的三个词格式不对    
            else:
                print("input wrong!")
            
        elif len(terms)==5:
            #A and B and C
            if (terms[1]=="and") and (terms[3]=="and"):
                answer = merge3_and(terms[0],terms[2],terms[4])
                print(answer)
            #A or B or C
            elif (terms[1]=="or") and (terms[3]=="or"):
                answer = merge3_or(terms[0],terms[2],terms[4])
                print(answer)
            #(A and B) or C
            elif (terms[1]=="and") and (terms[3]=="or"):
                answer = merge3_and_or(terms[0],terms[2],terms[4])
                print(answer)
            #(A or B) and C
            elif (terms[1]=="or") and (terms[3]=="and"):
                answer = merge3_or_and(terms[0],terms[2],terms[4])
                print(answer)
            else:
                print("More format is not supported now!")
        #进行自然语言的排序查询,返回按相似度排序的最靠前的若干个结果
        else:
            leng = len(terms)
            answer = do_rankSearch(terms)
            print ("[Rank_Score: Tweetid]")
            for (tweetid,score) in answer:
                print (str(score/leng)+": "+tweetid)
    

    其中merge合并列表时采用同时遍历的方法,降低复杂度为O(x+y),如下merge2_and所示:

    def merge2_and(term1,term2):
        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   
    

    三、查询测试展示

    1、A and B、A or B、A not B:

    image.png image.png image.png

    2、A and B and C、A or B or C、(A and B) or C、(A or B) and C:

    image.png image.png image.png image.png

    3、一般的语句查询:

    image.png
    image.png

    小结:

           根据inverted index的模型完成了布尔的查询的要求,复杂的布尔查询也可以在基本的and、or、not逻辑基础实现上嵌套实现,最后通过用查询的单词在该文档中出现的个数/总数作为简单的排序检索比较简陋,结果需要进一步评估,在本次inverted index模型中没有考虑TF、IDF和文档长度等信息,还需要进一步完善来满足更高级的应用需求。


    声明:创作不易,未经授权不得复制转载
    statement:No reprinting without authorization


    相关文章

      网友评论

          本文标题:文档表示之倒排索引(inverted index)与布尔(boo

          本文链接:https://www.haomeiwen.com/subject/jabdaqtx.html