当前位置: 首页 > news >正文

信息检索与数据挖掘 | 【实验】排名检索模型

文章目录

  • 📚实验内容
  • 📚相关概念
  • 📚实验步骤
    • 🐇分词预处理
    • 🐇构建倒排索引表
    • 🐇计算query和各个文档的相似度
    • 🐇queries预处理及检索函数
      • 🔥对输入的文本进行词法分析和标准化处理
      • 🔥检索函数
    • 🐇调试结果

📚实验内容

  1. 在Experiment1的基础上实现最基本的Ranked retrieval model
    • Input:a query (like Ron Weasley birthday)
    • Output: Return the top K (e.g., K = 100) relevant tweets.
  2. Use SMART notation: lnc.ltn
    • Document: logarithmic tf (l as first character), no idf and cosine normalization
    • Query: logarithmic tf (l in leftmost column), idf (t in second column), no normalization
  3. 改进Inverted index
    • 在Dictionary中存储每个term的DF
    • 在posting list中存储term在每个doc中的TF with pairs (docID, tf)

📚相关概念

  • 信息检索与数据挖掘 | (五)文档评分、词项权重计算及向量空间模型
  • 词项频率(term frequencey):t在文档中的出现次数。
  • 文档集频率(collection frequency):词项在文档集中出现的次数。
  • 文档频率(document frequency):出现t的所有文档的数目。
  • 逆文档频率
    在这里插入图片描述
  • t f − i d f t , d tf-idf_{t,d} tfidft,d计算
    在这里插入图片描述
    在这里插入图片描述
  • 相似度计算
    在这里插入图片描述
  • 查询权重机制
    在这里插入图片描述

📚实验步骤

🐇分词预处理

  1. 将输入的推特文档转换为小写,这里统一处理,使得后续查询不区分大小写。

  2. 根据特定标记在推特文档中查找并确定关键部分信息的位置索引,并提取出推特文档中的tweetid和tweet内容。

  3. 对提取出的文本内容进行分词处理,并将单词转换为其单数形式。

  4. 对分词后的词列表进行词形还原,主要针对动词的还原操作。同时,筛去[“text”, “tweetid”]

  5. 将筛选出的有效词添加到最终结果列表中,并返回。

    #分词预处理
    def tokenize_tweet(document):# 统一处理使查询不区分大小写document = document.lower()# 根据特定标记在推特文档中查找并确定关键部分信息的位置索引# 这里的减1减3是对引号逗号切入与否的调整a = document.index("tweetid") - 1b = document.index("errorcode") - 1c = document.index("text") - 1d = document.index("timestr") - 3# 将推特文档中的tweetid和text内容主要信息提取出来document = document[a:b] + document[c:d]# 分词处理,并将单词转换为其单数形式terms = TextBlob(document).words.singularize()# 将分词后的词列表进行词形还原,并筛选出不属于无用词的有效词result = []for word in terms:# 将当前词转换为Word对象expected_str = Word(word)# 动词的还原操作expected_str = expected_str.lemmatize("v")if expected_str not in uselessTerm:# 筛去["text", "tweetid"],添加到result中result.append(expected_str)return result
    

🐇构建倒排索引表

  • 存储term在每个doc中的TF with pairs (docID, tf)。
    在这里插入图片描述
  1. 首先明确,在该过程计算文档词项的对应权重,采用lnc规则,即 logarithmic tf (l as first character), no idf and cosine normalization。
  2. 具体流程如下:
    • 读取内容。文件中每行都代表一条推特。将每一行推特文本分解为单词(词条化),并存储在一个列表line中
    • 利用一个全局变量N记录读取的推特文档数量。
    • 从line中提取tweetid,并从line中删除。
    • 创建一个空字典tf用于统计每个词在当前文档中的出现次数。遍历line中的每个词,通过判断词是否已经在tf字典的键中存在来更新词的出现次数。
    • 对tf字典中的每个词项频率进行logarithmic tf的计算,即将出现次数加1并取对数。(对应logarithmic tf (l as first character))
    • 归一化(对应cosine normalization,遍历tf字典的键(即词项),得到归一化因子。最后,代码再次遍历tf字典的键,并将每个词项的频率乘以归一化因子。得到最后的对应tf权重。
    • 将line转换为集合unique_terms并遍历其中的每个词。
      • 如果该词已经在postings字典的键中存在,则更新该词对应的字典项,将tweetid和权重加入其中。
      • 如果该词不存在于postings字典的键中,则创建该键,并将tweetid和权重加入其中。

  • 统计词频频率
    # 统计词项频率,记录每个词在当前文档中的出现次数
    tf = {}for word in line:if word in tf.keys():tf[word] += 1else:tf[word] = 1
    
  • 1 + l o g ( t f t , d ) 1+log(tf_{t,d}) 1+log(tft,d)
     # logarithmic tffor word in tf.keys():tf[word] = 1 + math.log(tf[word])
    
  • 1 w 1 2 + w 2 2 + . . . + w m 2 \frac{1}{\sqrt{{w_1}^2+{w_2}^2+...+{w_m}^2}} w12+w22+...+wm2 1
     # 归一化,cosine normalizationcosine = 0for word in tf.keys():cosine = cosine + tf[word] * tf[word]cosine = 1.0 / math.sqrt(cosine)for word in tf.keys():tf[word] = tf[word] * cosine
    

🐇计算query和各个文档的相似度

  1. 首先明确,该过程分为两个步骤,首先计算query词项的对应权重,然后求相似度(也即对应词项两个权重相乘并求和)并降序排序。Query权重采用ltn规则,即 logarithmic tf (l in leftmost column), idf (t in second column), no normalization
  2. 具体流程如下:
    • 遍历查询词列表query​,对每个词进行词项频率统计,将结果存储在tf中。
    • 遍历tf字典的键(即查询词),根据每个词在postings中的文档频率(文档出现的次数)计算文档频率df​。若一个词不在postings​中,则将文档频率设置为全局变量 N(表示总的文档数量)。
    • 计算权重tf[word] = (math.log(tf[word]) + 1) * math.log(N / df),对应ltn(logarithmic tf, idf, no normalization)
    • 对于每个查询词,检查它是否postings字典中存在。若存在,则遍历该查询词的倒排索引(文档编号及对应的词项权重),根据每个文档的词项权重和查询词的tf-idf值计算相似度得分
    • 存储得分并进行降序排序,得到一个按照相似度排名的列表,并将其返回作为结果。
    def similarity(query):global score_tidtf = {}# 统计词项频率for word in query:if word in tf:tf[word] += 1else:tf[word] = 1# 统计文档频率for word in tf.keys():if word in postings:df = len(postings[word])else:df = N# 对应ltn,logarithmic tf (l in leftmost column), idf (t in second column), no normalizationtf[word] = (math.log(tf[word]) + 1) * math.log(N / df)# 计算相似度for word in query:if word in postings:for tid in postings[word]:if tid in score_tid.keys():score_tid[tid] += postings[word][tid] * tf[word]else:score_tid[tid] = postings[word][tid] * tf[word]# 按照得分(相似度)进行降序排序similarity = sorted(score_tid.items(), key=lambda x: x[1], reverse=True)return similarity
    

🐇queries预处理及检索函数

🔥对输入的文本进行词法分析和标准化处理

def token(doc):# 将输入文本转换为小写字母,以便统一处理。doc = doc.lower()# 将文本拆分为单个词项,并尝试将词项转换为单数形式terms = TextBlob(doc).words.singularize()# 将分词后的词列表进行词形还原,返回结果列表resultresult = []for word in terms:expected_str = Word(word)expected_str = expected_str.lemmatize("v")result.append(expected_str)return result

🔥检索函数

def Union(sets):return reduce(set.union, [s for s in sets])def do_search():query = token(input("please input search query >> "))result = []if query == []:sys.exit()# set()去除查询词列表中的重复项unique_query = set(query)# 生成一个包含每个查询词对应的tweet的id集合的列表,并且利用Union()函数将这些集合取并集relevant_tweetids = Union([set(postings[term].keys()) for term in unique_query])print("一共有" + str(len(relevant_tweetids)) + "条相关tweet!")if not relevant_tweetids:print("No tweets matched any query terms for")print(query)else:print("the top 100 tweets are:")scores = similarity(query)i = 1for (id, score) in scores:if i <= 100:  # 返回前n条查询到的信息result.append(id)print(str(score) + ": " + id)i = i + 1else:breakprint("finished")

🐇调试结果

在这里插入图片描述


最终代码

import sys
from collections import defaultdict
from textblob import TextBlob
from textblob import Word
import math
from functools import reduceuselessTerm = ["text", "tweetid"]
# 构建倒排索引表,存储term在每个doc中的TF with pairs (docID, tf)
postings = defaultdict(dict)
# 文档数目N
N = 0
# 最终权值
score_tid = defaultdict(dict)#分词预处理
def tokenize_tweet(document):# 统一处理使查询不区分大小写document = document.lower()# 根据特定标记在推特文档中查找并确定关键部分信息的位置索引# 这里的减1减3是对引号逗号切入与否的调整a = document.index("tweetid") - 1b = document.index("errorcode") - 1c = document.index("text") - 1d = document.index("timestr") - 3# 将推特文档中的tweetid和text内容主要信息提取出来document = document[a:b] + document[c:d]# 分词处理,并将单词转换为其单数形式terms = TextBlob(document).words.singularize()# 将分词后的词列表进行词形还原,并筛选出不属于无用词的有效词result = []for word in terms:# 将当前词转换为Word对象expected_str = Word(word)# 动词的还原操作expected_str = expected_str.lemmatize("v")if expected_str not in uselessTerm:# 筛去["text", "tweetid"],添加到result中result.append(expected_str)return result# 构建倒排索引表,存储term在每个doc中的TF with pairs (docID, tf)
# lnc:logarithmic tf, no idf and cosine normalization
def get_postings():global postings, Ncontent = open(r"Tweets.txt")# 内容读取,每一条推特作为一个元素存储在lines中lines = content.readlines()for line in lines:N += 1# 预处理line = tokenize_tweet(line)# 提取处理后的词列表中的第一个元素,即推特文档的tweetidtweetid = line[0]# 提取后删除,不作为有效词line.pop(0)# 统计词项频率,记录每个词在当前文档中的出现次数tf = {}for word in line:if word in tf.keys():tf[word] += 1else:tf[word] = 1# logarithmic tffor word in tf.keys():tf[word] = 1 + math.log(tf[word])# 归一化,cosine normalizationcosine = 0for word in tf.keys():cosine = cosine + tf[word] * tf[word]cosine = 1.0 / math.sqrt(cosine)for word in tf.keys():tf[word] = tf[word] * cosine# 将处理后的词列表转换为集合,获取其中的唯一词unique_terms = set(line)for key_word in unique_terms:if key_word in postings.keys():postings[key_word][tweetid] = tf[key_word]else:postings[key_word][tweetid] = tf[key_word]# query标准化处理
def token(doc):# 将输入文本转换为小写字母,以便统一处理。doc = doc.lower()# 将文本拆分为单个词项,并尝试将词项转换为单数形式terms = TextBlob(doc).words.singularize()# 将分词后的词列表进行词形还原,返回结果列表resultresult = []for word in terms:expected_str = Word(word)expected_str = expected_str.lemmatize("v")result.append(expected_str)return result# 计算query和各个文档的相似度
def similarity(query):global score_tidtf = {}# 统计词项频率for word in query:if word in tf:tf[word] += 1else:tf[word] = 1# 统计文档频率for word in tf.keys():if word in postings:df = len(postings[word])else:df = N# 对应ltn,logarithmic tf (l in leftmost column), idf (t in second column), no normalizationtf[word] = (math.log(tf[word]) + 1) * math.log(N / df)# 计算相似度for word in query:if word in postings:for tid in postings[word]:if tid in score_tid.keys():score_tid[tid] += postings[word][tid] * tf[word]else:score_tid[tid] = postings[word][tid] * tf[word]# 按照得分(相似度)进行降序排序similarity = sorted(score_tid.items(), key=lambda x: x[1], reverse=True)return similaritydef Union(sets):return reduce(set.union, [s for s in sets])def do_search():query = token(input("please input search query >> "))result = []if query == []:sys.exit()# set()去除查询词列表中的重复项unique_query = set(query)# 生成一个包含每个查询词对应的tweet的id集合的列表,并且利用Union()函数将这些集合取并集relevant_tweetids = Union([set(postings[term].keys()) for term in unique_query])print("一共有" + str(len(relevant_tweetids)) + "条相关tweet!")if not relevant_tweetids:print("No tweets matched any query terms for")print(query)else:print("the top 100 tweets are:")scores = similarity(query)i = 1for (id, score) in scores:if i <= 100:  # 返回前n条查询到的信息result.append(id)print(str(score) + ": " + id)i = i + 1else:breakprint("finished")def main():get_postings()while True:do_search()if __name__ == "__main__":main()

参考博客:信息检索实验2- Ranked retrieval model

相关文章:

信息检索与数据挖掘 | 【实验】排名检索模型

文章目录 &#x1f4da;实验内容&#x1f4da;相关概念&#x1f4da;实验步骤&#x1f407;分词预处理&#x1f407;构建倒排索引表&#x1f407;计算query和各个文档的相似度&#x1f407;queries预处理及检索函数&#x1f525;对输入的文本进行词法分析和标准化处理&#x1f…...

玩转AIGC:打造令人印象深刻的AI对话Prompt

玩转AIGC&#xff1a;打造令人印象深刻的AI对话Prompt 《玩转AIGC&#xff1a;打造令人印象深刻的AI对话Prompt》摘要引言正文良好的Prompt&#xff1a;引发AI深度交流的法宝 ✨探讨不同的提问方式1. 常规提问2. 创意提问 对话交流的艺术&#xff1a;倾听与引导的巧妙平衡 ⚖️…...

uniapp vue国际化 i18n

一、安装 vue-i18n npm i vue-i18n 二、新建i18n目录 1、en.json 内容 {"loginPage":{"namePh":"Please enter your login account","passwordPh":"Please enter password"} } 2、zh-CN.json 内容 {"loginPage&qu…...

Docker 启动远程服务访问不了

今天一下午在弄这个 1、防火墙是否关了 firewall-cmd --state2、ip转发开没开 sysctl net.ipv4.ip_forward3、service iptables是不是打开并拦截了 4、检查docker启动的端口号是否一致&#xff0c;或者启动时对不对 5、检查docker的服务是否起来了&#xff0c;比如你的端口号…...

[ACTF2020 新生赛]Exec

【解题过程】 1.打开链接 得到一个能ping 的网站&#xff0c;可以推测这个可以在终端运行的网站。 2.解题思路 在执行的时候我们可以想到命令执行的“&#xff1b;”分号的作用&#xff1a;命令用分号分隔开来&#xff0c;表示它们是两个独立的命令&#xff0c;需要依次执行。…...

Git(三).git 文件夹详解

目录 一、初始化新仓库二、.git 目录2.1 hooks 文件夹2.2 info 文件夹2.3 logs 文件夹2.4 objects 文件夹【重要】2.5 refs 文件夹【重要】2.6 COMMIT_EDITMSG2.7 config2.8 description2.9 FETCH_HEAD2.10 HEAD【重要】2.11 index【重要】2.12 ORIG_HEAD2.13 packed-refs 官网…...

esp32-S3 + visual studio code 开发环境搭建

一、首先在下面链接网页中下载esp-idf v5.1.1离线安装包 &#xff0c;并安装到指定位置。dl.espressif.cn/dl/esp-idf/https://dl.espressif.cn/dl/esp-idf/ 安装过程中会提示需要长路径支持&#xff0c;所以windows系统需要开启长路径使能 Step 1&#xff1a; 打开运行&…...

4.1 网络基础之网络IO

一、编写基本服务程序流程 1、创建套接字 #include <sys/types.h> #include <sys/socket.h>int socket(int domain, int type, int protocol);/* * 参数domain通讯协议族&#xff1a; * PF_INET IPv4互联网协议族&#xff08;常用&#xff09; * PF_INET6 …...

[100天算法】-和为 K 的子数组(day 39)

题目描述 给定一个整数数组和一个整数 k&#xff0c;你需要找到该数组中和为 k 的连续的子数组的个数。示例 1 :输入:nums [1,1,1], k 2 输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。 说明 :数组的长度为 [1, 20,000]。 数组中元素的范围是 [-1000, 1000] &#xff0c;且整…...

Leo赠书活动-02期 【信息科技风险管理:合规管理、技术防控与数字化】

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…...

L2-026 小字辈 - java

L2-026 小字辈 时间限制 400 ms 内存限制 64 MB 题目描述&#xff1a; 本题给定一个庞大家族的家谱&#xff0c;要请你给出最小一辈的名单。 输入格式&#xff1a; 输入在第一行给出家族人口总数 N&#xff08;不超过 100 000 的正整数&#xff09; —— 简单起见&#xff0c…...

排序算法-堆积树排序法(HeapSort)

目录 排序算法-堆积树排序法&#xff08;HeapSort&#xff09; 1、说明 2、算法分析 3、C代码 排序算法-堆积树排序法&#xff08;HeapSort&#xff09; 1、说明 堆积树排序法是选择排序法的改进版&#xff0c;可以减少在选择排序法中的比较次数&#xff0c;进而减少排序…...

名词解释 MongoDB

MongoDB 是一个面向文档的数据库管理系统&#xff0c;它不使用传统的表格结构&#xff0c;而是将数据组织成类似文档的形式&#xff0c;通常使用JSON格式。 文档数据库&#xff1a;数据以文档的形式存储&#xff0c;每个文档可以包含不同的字段&#xff0c;就像一个文件可以包…...

Look Back(cf div3 905)

题意&#xff1a;给你一个长度为n&#xff08;(1≤n≤10^5)数组a[]&#xff0c;你可以进行一个操作 使a[i]a[i]*2,问最少经过多少次这样的操作使的a[]不递减,a[i]>a[i-1]。 输入样例&#xff1a; 6 1 1 2 1 1 3 1 2 1 4 2 3 2 1 5 4 5 4 5 4 10 1 7 7 2 3 4 3 2 1 100 输出…...

Spring框架的发展历程

Spring框架的发展历程 自2004年以来&#xff0c;Spring框架已经成为Java开发人员最受欢迎的开源框架之一。它提供了一个全面的编程和配置模型&#xff0c;旨在简化企业级Java应用程序的开发过程。本文将详细介绍Spring框架的发展历程&#xff0c;以及它如何为Java开发人员提供…...

vue 级联查询5级--省/市/区/街道/社区

<template> <div> 1234 <el-select v-model="provinceVal" @change="selectProvinceFn" placeholder="请选择"> <el-option v-for="item in provinceList" :key="item.code" :label="item.name&q…...

C++并发与多线程(8) | 互斥量

一、互斥量(mutex)的基本概念 互斥量(Mutex)是一种用于多线程编程的同步机制,用于管理共享资源的访问,以确保线程之间不会同时访问某个共享资源,从而避免竞态条件(Race Condition)和数据损坏。下面是互斥量的基本概念: 互斥性(Mutual Exclusion):互斥量用于确保一…...

Power BI 傻瓜入门 3. 选择Power BI的版本

本章内容包括&#xff1a; Excel与Power BI的比较选择Power BI的桌面版和服务版之间的差异了解Microsoft提供的许可选项 挑选正确版本的Power BI可能就像参观世界上最大的糖果店&#xff1a;你可以从许多细微差别的替代品中进行选择。选择可以归结为想要、需要、规模&#xf…...

BadNets:基于数据投毒的模型后门攻击代码(Pytorch)以MNIST为例

加载数据集 # 载入MNIST训练集和测试集 transform transforms.Compose([transforms.ToTensor(),]) train_loader datasets.MNIST(rootdata,transformtransform,trainTrue,downloadTrue) test_loader datasets.MNIST(rootdata,transformtransform,trainFalse) # 可视化样本 …...

freeRTOS内部机制——栈的作用

上图中*pa 和*pb分别为R0&#xff0c;R1&#xff0c;调用C函数时&#xff0c;第一个参数保存在R0中第二个参数保存在R1中。这是约定。 指令保存在哪里&#xff1f; 指令保存在flash上面 LR等于什么? LR是返回地址&#xff0c;函数执行完了过后LR等于下一条指令的地址 运行…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...