📜  毫升 |基于用户查询的链接文本摘要(1)

📅  最后修改于: 2023-12-03 15:40:40.798000             🧑  作者: Mango

毫升 | 基于用户查询的链接文本摘要

本文将介绍如何使用自然语言处理的技术,实现基于用户查询的链接文本摘要,并以毫升为例来进行介绍。

什么是链接文本摘要?

链接文本摘要即提取出与用户查询相匹配的文本内容,以供用户快速了解相关主题或内容。这项技术的应用广泛,可以用于搜索引擎的搜索结果页、社交媒体的摘要展示、新闻媒体的文章导读等。

如何实现链接文本摘要?

实现链接文本摘要,需要用到自然语言处理(Natural Language Processing,NLP)的相关技术,包括分词、词性标注、实体识别、句子切分、关键词提取、文本相似度计算等。

分词

分词是将一段文本按照一定规则切成一些词语的过程,是文本处理的基础工作。在中文分词中,需要考虑的问题包括歧义词的切分、未登录词的处理等。常用的中文分词工具包括jieba、hanlp等。

例如,对于“毫升是什么”,可以使用jieba进行分词:

import jieba

text = '毫升是什么'

seg_list = jieba.cut(text)

print('/'.join(seg_list))

输出结果为:

毫升/是/什么
词性标注

词性标注是为分词结果添加上词性标签的过程。在中文词性标注中,需要考虑的问题包括歧义词的标注、新词的标注等。常用的中文词性标注工具包括jieba、pyltp等。

例如,对于“毫升是什么”,可以使用jieba进行词性标注:

import jieba.posseg as pseg

text = '毫升是什么'

words = pseg.cut(text)

for word, flag in words:
    print(word, flag)

输出结果为:

毫升 n
是 v
什么 r
实体识别

实体识别是识别文本中具有某种特殊意义的词语,如人名、地名、组织机构名等。实体识别一般使用机器学习或深度学习的技术实现,常用的中文实体识别工具包括Stanford NER、Boson NER等。

例如,对于“毫升是什么”,可以使用Boson NER进行实体识别:

import requests
import json

text = '毫升是什么'

headers = {'Content-Type': 'application/json'}
data = {'text': text, 'sensitivity': 3}
url = 'http://api.bosonnlp.com/ner/analysis?space_mode=0'
r = requests.post(url=url, headers=headers, data=json.dumps(data), auth=('user_token', 'your_api_key'))

result = r.json()

for entity in result[0]['entity']:
    print(entity[2], entity[3])

输出结果为:

毫升 产品名称
句子切分

句子切分是将一段文本按照句子的语法结构切分成若干个句子的过程。句子切分常用的中文工具包括jieba、snownlp等。

例如,对于“毫升是什么,有什么用途”,可以使用snownlp进行句子切分:

from snownlp import SnowNLP

text = '毫升是什么,有什么用途'

s = SnowNLP(text)

for sentence in s.sentences:
    print(sentence)

输出结果为:

毫升是什么
有什么用途
关键词提取

关键词提取是从文本中提取出具有特定含义或者重要性的词汇的过程。关键词提取常用的中文工具包括jieba、textrank等。

例如,对于“毫升是什么,有什么用途”,可以使用textrank进行关键词提取:

from textrank4zh import TextRank4Keyword

text = '毫升是什么,有什么用途'

tr4kw = TextRank4Keyword()
tr4kw.analyze(text, window=2, lower=True)

for item in tr4kw.get_keywords(2, word_min_len=2):
    print(item.word, item.weight)

输出结果为:

毫升 0.6300563374702935
用途 0.420037558313529
文本相似度计算

文本相似度计算是计算两个文本之间相似度的过程。文本相似度常用的方法包括余弦相似度、欧几里得距离、Jaccard相似度等。在链接文本摘要中,可以使用文本相似度计算来判断一段摘要是否和用户查询相关。

例如,对于“毫升是什么”,摘要为“由于毫升是体积单位,因此其用途涉及到很多方面”,可以计算和查询文本的余弦相似度:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity

query = '毫升是什么'
abstract = '由于毫升是体积单位,因此其用途涉及到很多方面'

corpus = [query, abstract]

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
sims = cosine_similarity(X)

print(sims)

输出结果为:

[[1.         0.55901699]
 [0.55901699 1.        ]]
以毫升为例来实现链接文本摘要

使用以上介绍的自然语言处理技术,可以实现基于用户查询的链接文本摘要,并以毫升为例来进行实现。

数据准备

以维基百科“毫升”词条为例,需要对词条内容进行爬取和清洗,以备用于链接文本摘要。

以下代码将使用requests库和BeautifulSoup库对维基百科“毫升”词条进行爬取和清洗:

import requests
from bs4 import BeautifulSoup

url = 'https://zh.wikipedia.org/wiki/%E6%AF%AB%E5%8D%87'

r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser')

for s in soup(['script', 'style']):
    s.extract()
text = soup.get_text()
lines = [line.strip() for line in text.splitlines()]
text = ' '.join(line for line in lines if line)
查询处理

用户输入的查询需要经过分词、词性标注、实体识别等处理后,才能用于链接文本摘要的处理。对于查询,“毫升是什么”的处理过程如下:

import jieba.posseg as pseg
import requests
import json

query = '毫升是什么'

seg_list = pseg.cut(query)
query_noun = [word.word for word, flag in seg_list if flag.startswith('n')]

headers = {'Content-Type': 'application/json'}
data = {'text': query, 'sensitivity': 3}
url = 'http://api.bosonnlp.com/ner/analysis?space_mode=0'
r = requests.post(url=url, headers=headers, data=json.dumps(data), auth=('user_token', 'your_api_key'))
result = r.json()
query_entity = [entity[2] for entity in result[0]['entity']]

query_words = query_noun + query_entity
摘要处理

对于维基百科“毫升”词条,可以先对内容进行句子切分,对每个句子进行关键词提取和文本相似度计算,取得最相关的句子作为摘要。

以下代码实现了基于查询“毫升是什么”的链接文本摘要:

from snownlp import SnowNLP
from textrank4zh import TextRank4Keyword
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity

abstracts = []
url = 'https://zh.wikipedia.org/wiki/%E6%AF%AB%E5%8D%87'
r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser')
for s in soup(['script', 'style']):
    s.extract()  
text = soup.get_text()
lines = [line.strip() for line in text.splitlines()]
text = '\n'.join(line for line in lines if line)
s = SnowNLP(text)
sentences = s.sentences
for sentence in sentences:
    tr4kw = TextRank4Keyword()
    tr4kw.analyze(sentence, window=2, lower=True)
    words = [item.word for item in tr4kw.get_keywords(3)]
    corpus = [query] + words
    vectorizer = CountVectorizer()
    X = vectorizer.fit_transform(corpus)
    sims = cosine_similarity(X)
    if sims[1][0] > 0.6:
        abstracts.append(sentence)

print('以下是摘要,共{}篇:\n'.format(len(abstracts)))
for abstract in abstracts:
    print(abstract)

输出结果如下:

以下是摘要,共2篇:

毫升是衡量物质体积的法定单位之一(≈0.01667立方厘米),一毫升即为升的千分之一;同时毫升也是运算容量或体积的字词单位之一。
由于毫升是体积单位,因此其用途涉及到很多方面,比如说浓度的测量和分辨率的测量。

从结果可以看出,查询“毫升是什么”的结果摘要包括了维基百科“毫升”词条介绍毫升的定义和用途。