自然语言处理与信息检索系统

目录

  • 引言
  • 词嵌入
  • 实现信息检索系统

谷歌拥有数以万亿计的网页,它是如何高效地为搜索相关网页而不需要页面URL的呢?信息检索系统允许基于文档的有意义信息高效地搜索文档。正如所知,两个句子可能结构完全不同,使用的词汇也不同,但它们可能具有相同的含义。在NLP中,目标是捕获句子的含义,通过使用各种NLP概念,将在本文中详细探讨。

问题陈述

执行基于上下文含义的信息检索系统。

解决方案

执行信息检索有多种方法。但使用词嵌入是一种既简单又高效的方法。词嵌入考虑了上下文含义,而不管句子结构如何。

信息检索系统的应用

信息检索系统的应用包括文档检索、段落检索、搜索引擎和问答系统。

词嵌入

已经写过一篇关于各种特征提取技术的文章,包括词嵌入的实现,如果还没有阅读,可以通过查看。词嵌入能够理解句子的含义,不管词汇结构如何。例如,“喜欢他”和“爱他”在使用词嵌入时几乎具有相同的含义。

将使用Python实现信息检索系统。在实现过程中,需要遵循以下步骤:

  • 获取数据
  • 清洗数据
  • 加载预训练的word2vec
  • 获取文档的上下文含义
  • 比较查询与文档

创建了自己的数据集,包含4个文档,为了更好地理解,将使用一个小数据集。

Doc1 = ["""浪费自然资源是一个非常严重的问题,因为都知道自然资源是有限的,但仍然没有感觉到。使用它超过需要的,政府也鼓励人们节约自然资源。"""] Doc2 = ["""机器学习是现在非常流行的研究领域,正在进行持续的研究,机器学习是关于数学的。分析模式解决问题。"""] Doc3 = ["""现在书籍正在失去它的魅力,因为手机和智能设备已经取代了旧时代,书籍现在以数字方式印刷,这节省了纸张,最终节省了成千上万的树木。"""] Doc4 = ["""站在门后的男子是MS DHONI,他快速的手在门后是印度的一大优势,但Pant现在正在继承DHONI的遗产,但他没有那么快。"""]

这里有4个文档,数据集将是一个由逗号分隔的文档列表。

将一次性导入所有将被使用到的依赖。

import numpy as np import nltk import itertools from nltk.corpus import stopwords from nltk.tokenize import sent_tokenize, word_tokenize import scipy from scipy import spatial import re tokenizer = ToktokTokenizer() stopword_list = nltk.corpus.stopwords.words('english')

在NLP中,数据清洗总是概括训练并承诺更好的结果。加载数据后进行数据清洗始终是一个好习惯。

def remove_stopwords(text, is_lower_case=False): pattern = r'[^a-zA-z0-9s]' text = re.sub(pattern," ",''.join(text)) tokens = tokenizer.tokenize(text) tokens = [tok.strip() for tok in tokens] if is_lower_case: cleaned_token = [tok for tok in tokens if tok not in stopword_list] else: cleaned_tokens = [tok for tok in tokens if tok.lower() not in stopword_list] filtered_text = ' '.join(cleaned_tokens) return filtered_text

函数remove_stopwords逐个处理文档,并返回清洗后的文档。首先使用正则表达式移除所有不必要的字符。移除不必要的字符后,对过滤后的单词进行标记化,并使用stopword_list过滤掉所有停用词。

将使用预训练的300维词向量。可以使用这个下载词向量。建议在Kaggle上创建一个笔记本,如果不想下载大文件的世界向量。

glove_vectors = dict() file = open('../input/glove6b/glove.6B.300d.txt', encoding = 'utf-8') for line in file: values = line.split() word = values[0] vectors = np.asarray(values[1:]) glove_vectors[word] = vectors file.close()

glove_vectors是一个字典,包含单词作为键和特征向量作为值。glove.6B.300d这个词嵌入是在60亿个单词上训练的,特征向量长度为300。如果一个单词不在词向量字典中,它将返回一个长度为300的零向量。

一个文档包含许多句子,一个句子根据句子中出现的单词数量有许多向量。要总结文档的含义,需要平均文档中所有句子的含义。在NLP的语言中,平均文档中所有句子的特征向量。

out_dict = {} for sen in fin: average_vector = (np.mean(np.array([get_embedding(x) for x in nltk.word_tokenize(remove_stopwords(sen))]), axis=0)) dict = { sen : (average_vector) } out_dict.update(dict)

字典out_dict包含文档作为键和它们的平均特征向量作为相应的值。平均特征向量将文档的含义编码为向量。

到目前为止,已经拥有每个文档的特征向量,需要构建一个函数,可以根据它们的含义比较特征向量。两个词的相似性可以通过它们的特征向量之间的余弦距离来计算。

def get_sim(query_embedding, average_vector_doc): sim = [(1 - scipy.spatial.distance.cosine(query_embedding, average_vector_doc))] return sim

函数get_sim接受查询的特征向量和所有文档的特征向量,并返回查询和文档之间的相似性。如果相似性sim更高,接近1,可以认为它几乎具有相同的含义。如果相似性sim更接近0,可以认为它们的含义不同。

def Ranked_documents(query): query_word_vectors = (np.mean(np.array([get_embedding(x) for x in nltk.word_tokenize(query.lower())],dtype=float), axis=0)) rank = [] for k,v in out_dict.items(): rank.append((k, get_sim(query_word_vectors, v))) rank = sorted(rank,key=lambda t: t[1], reverse=True) print('Ranked Documents :') return rank[0]
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485