当前位置: 首页 > 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等于下一条指令的地址 运行…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...