NLP 文本(语义)匹配算法和demo代码介绍

前言

文本匹配一直是自然语言处理(NLP)领域一个基础且重要的方向,一般研究两段文本之间的关系。

文本相似度计算、自然语言推理、问答系统、信息检索等,都可以看作针对不同数据和场景的文本匹配应用。

比如信息检索可以归结为搜索词和文档资源的匹配,问答系统可以归结为问题和候选答案的匹配,复述问题可以归结为两个同义句的匹配,这些自然语言处理任务在很大程度上都可以抽象成文本匹配问题。

而文本匹配整体流程基本上都可以分为两个大的步骤:1)提取文本特征,如果是文段,则首先利用主题模型提取文段的主题文本,再将主题文本的文本特征提取;2)计算文本特征的相似度,相似度较高的文本对,则认为是匹配对较高的文本对,目的就达到了。

词粒度文本匹配

词粒度文本匹配,即是用于计算两个词语之间的文本特征相似度,是文本匹配中最为简单的任务。

计算两个词语之间的文本相似度,可以用word2vec模型来进行比较。

导入gensim的库和对应的语料,语料中包含多个用空格(’ \n ')分开的词语

import gensim

txt_path = 'data/C000008_test.txt'
sentences = [i.split() for i in open(txt_path, 'r', encoding='utf-8').read().split('\n')]
sentences[:3]

中文词语示例

使用上述语料训练word2vec模型,并计算两个词语之间的相似度

model = gensim.models.Word2Vec(
    sentences, vector_size=50, window=5, min_count=1, workers=4)
# compare two word
print(model.wv.similarity('中国', '澳大利亚'))

0.07167525

句粒度文本匹配

基于句子的短文本匹配,是文本匹配领域研究比较多的一个内容,而且最近几年也有比较的文章和模型发布,详情可以参看深度文本匹配survey这篇文章。

本次的基于句粒度文本匹配,选用的SimCSE模型。SimCSE可以看成是SimBERT的简化版,这个模型去掉了SimBERT的生成部分,仅保留检索模型。

SimCSE训练过程中是没有标签,所以把每个句子自身视为相似句传入,本质上来说就是(自己,自己)作为正例、(自己,别人)作为负例来训练对比学习模型。

代码非常简单,主要使用的了hugging face的预训练模型,输出文本句的embeddings特征,然后计算特征相似度即可

from transformers import AutoModel, AutoTokenizer

import os

os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"

tokenizer = AutoTokenizer.from_pretrained("princeton-nlp/sup-simcse-bert-base-uncased")
model = AutoModel.from_pretrained("princeton-nlp/sup-simcse-bert-base-uncased")

# Tokenize input texts
texts = [
    "There's a kid on a skateboard.",
    "A kid is skateboarding.",
    "A kid is inside the house."
]
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
import torch
from scipy.spatial.distance import cosine

# Get the embeddings
with torch.no_grad():
    embeddings = model(**inputs, output_hidden_states=True, return_dict=True).pooler_output

print(embeddings.shape)
embeddings = embeddings.detach().numpy()
from sklearn.metrics.pairwise import cosine_similarity

cos1 = cosine_similarity([embeddings[0]], [embeddings[1]])
cos2 = cosine_similarity([embeddings[0]], [embeddings[2]])

print("Cosine similarity between \"%s\" and \"%s\" is: %.3f" % (texts[0], texts[1], cos1))
print("Cosine similarity between \"%s\" and \"%s\" is: %.3f" % (texts[0], texts[2], cos2))

篇章粒度文本匹配

篇章粒度的文本匹配,首先要使用主题模型对文章主题进行提取,笔者这里使用的gensim库中的LDA模型,算是比较精度的主题模型,但是精度可能就没有那么好。

from nltk.tokenize import RegexpTokenizer
from gensim import corpora, models
import gensim

tokenizer = RegexpTokenizer(r'\w+')
    
# create sample documents
doc_a = "Brocolli is good to eat. My brother likes to eat good brocolli, but not my mother."
doc_b = "My mother spends a lot of time driving my brother around to baseball practice."
doc_c = "Some health experts suggest that driving may cause increased tension and blood pressure."
doc_d = "I often feel pressure to perform well at school, but my mother never seems to drive my brother to do better."
doc_e = "Health professionals say that brocolli is good for your health." 

# compile sample documents into a list
doc_set = [doc_a, doc_b, doc_c, doc_d, doc_e]

# list for tokenized documents in loop
texts = []

# loop through document list
for i in doc_set:
    # clean and tokenize document string
    raw = i.lower()
    tokens = tokenizer.tokenize(raw)
    # add tokens to list
    texts.append(tokens)

# turn our tokenized documents into a id <-> term dictionary
dictionary = corpora.Dictionary(texts)
    
# convert tokenized documents into a document-term matrix
corpus = [dictionary.doc2bow(text) for text in texts]

# generate LDA model
ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=2, id2word = dictionary, passes=20)

然后通过LDA模型求出所有文章的主题词,并计算各个文章之间的相似度矩阵。

如果存在文章较多的情况下,这样的操作是比较耗内存的,不建议这样做,当然,这里是做一个demo,就无所谓了。

index = gensim.similarities.MatrixSimilarity(ldamodel[corpus])

最后便可以求出任一文章与其他文章的相似度

def get_text_sim(text):
    doc_bow = [dictionary.doc2bow(text) for text in [tokenizer.tokenize(text.lower())]]
    print(doc_bow)
    vec_lda = ldamodel[doc_bow]
    sims = index[vec_lda]

    return sims
    
get_text_sim(doc_a)

[[(0, 2), (1, 1), (2, 1), (3, 2), (4, 2), (5, 1), (6, 1), (7, 1), (8, 2), (9, 1), (10, 2)]]
array([[0.99999994, 0.99999577, 0.07365547, 0.9999525 , 0.08877519]],
      dtype=float32)

参考

NLP之文本匹配及语义匹配应用介绍
深度文本匹配survey
NLP 语义匹配:业务场景、数据集及比赛

·

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
基于自然语言处理和机器学习算法的SEO优化代码,主要是通过对关键词的分析、提取和应用,来提高网站的排名和点击率。下面是一些常见的基于自然语言处理和机器学习算法的SEO优化代码: 1. 关键词提取和分析: 通过自然语言处理算法,可以对网站的内容进行分词、词性标注和关键词提取等操作,从而得到网站的关键词列表。这些关键词可以用于网站的标题、描述、内容和标签等方面的优化。 2. 关键词密度和位置优化: 通过机器学习算法,可以对网站的关键词密度和位置进行分析和优化,从而提高网站在搜索引擎中的排名。例如,在网页标题和前几段内容中使用关键词,可以提高关键词的权重。 3. 内容生成和优化: 通过机器学习算法,可以对网站的内容进行生成和优化,从而提高网站的质量和吸引力。例如,使用自然语言处理算法生成符合用户需求的文章,或者对现有文章进行优化和重构。 4. 链接分析和优化: 通过机器学习算法,可以对网站内部和外部链接进行分析和优化,从而提高网站的链接质量和权重。例如,链接到高质量的网站和文章,可以提高网站的权重。 5. 用户行为分析和优化: 通过机器学习算法,可以对用户的搜索行为和点击行为进行分析和优化,从而提高网站的用户体验和点击率。例如,通过对用户搜索关键词进行分析,可以优化网站的关键词和内容。 以上是一些常见的基于自然语言处理和机器学习算法的SEO优化代码示例,可以根据实际情况进行调整和优化。值得注意的是,这些算法需要大量的数据和计算资源支持,需要有专业的团队和技术支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥宅程序员aka不会游泳的鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值