文本摘要实验报告

摘要

摘要[中文]

本实验主要关注子模函数最大化,并基于该方法实现了抽取式文本摘要。本实验借助 requests 和 BeautifulSoup 等库,选取包含诸多同主题英文文本的新闻网站 ChinaDaily 进行爬取,通过对网站 culture/heritage 种子页面以及对包含具体新闻内容的页面的源代码进行分析,借助爬虫获取所需同主题文本内容。通过转换为小写、去除标点符号等非文本、进行词干提取等手段,对许多同主题长文本进行文本预处理;并借助 genism 库,获得各个文本的关键词列表。最终,以贪心算法思想,通过爬山算法,提取出100句每轮迭代中覆盖关键词最多的句子,得到抽取式文本摘要。

Abstract [英语]

This experiment mainly focuses on the maximization of submodular function, and based on this method, extractive text summarization is realized. This experiment uses libraries such as requests and BeautifulSoup to select the news website ChinaDaily that contains many English texts on the same subject to crawl. Through the analysis of the website culture/heritage seed page and the source code of the page containing specific news content, the crawler obtains all the information. Need to be the same as the subject text content. By converting to lowercase, removing non-text such as punctuation, and performing stemming, many long texts with the same topic are preprocessed; and with the help of the genism library, the keyword list of each text is obtained. Finally, with the idea of greedy algorithm, through the hill-climbing algorithm, the 100 sentences that cover the most keywords in each round of iteration are extracted, and the extractive text summary is obtained.

一、 项目概述(阐明该项目的科学和应用价值,以及相关工作进展并描述项目的主要内容)

目前关于子模函数最大化,可分为三类问题:最大化受基数约束的子模函数,无约束的子模最大化和子模福利。

最大化受基数约束的子模函数问题:输入是非负单调子模函数 f:N→R≥0f : N → R_{≥0}f:N→R≥0​,以及 111 到 nnn 之间的整数 kkk ,目标为找到大小最大为 kkk 的集合 AAA 来最大化函数 fff 。

解决该问题的算法主要有:The Greedy Algorithm(f,k)(f, k)(f,k),Random Greedy(f,k)(f, k)(f,k),以及Sample Greedy(f,k,ε)(f, k, ε)(f,k,ε)。

  1. The Greedy Algorithm(f,k)(f, k)(f,k) 算法从空集开始,然后在 k 次迭代中向其中添加元素。在每次迭代中,算法向其当前解添加将该解的值增加最多的单个元素。该算法的近似比可达到1−1/e1 - 1 /e1−1/e 。
  2. Random Greedy(f,k)(f, k)(f,k)算法是The Greedy Algorithm(f,k)(f, k)(f,k)的随机化版本,适用于子模型目标函数 f 不是单调的情况。该算法在每次迭代中找到大小至多为 k 的集合 M,最大化集合中元素相对于当前解的总边际贡献。然后,该算法在其当前解中最多添加一个 M 中的元素,这种选择方式使得 M 的每个元素都有恰好 1/k 的概率被添加到解中。该算法近似比为1/e1/ e1/e 。若fff 单调,则近似比为1−1/e1 - 1 /e1−1/e。
  3. Sample Greedy(f,k,ε)(f, k, ε)(f,k,ε)算法思路为查询元素的随机子集,并使用它以足够高的概率恢复 M 的至少一个元素(即,找到相对于当前解,其边际贡献在前 k 个边际贡献中的元素)。其中,ε∈[e−k,1−1/e]ε ∈ [e^{−k} , 1 − 1/e]ε∈[e−k,1−1/e],用于平衡oracle queries的数量和输出的质量。该算法近似比为(1−1/e−ε)(1 − 1/e − ε)(1−1/e−ε)。

无约束的子模最大化问题:子模最大化的变形,目标仍然为最大化子模函数,但是对于可选的可行子集没有限制。

解决该问题的算法主要有:Random Sample(f)(f)(f) 和 Double Greedy(f)(f)(f)。

  1. Random Sample(f)(f)(f) 算法以 1/2 的概率独立地将每个元素带到解中。该算法维护两个随机解,且每次加到解中的元素u1,u2,……,unu_{1},u_{2},……,u_{n}u1​,u2​,……,un​是N 中元素的某种(任意)排序。该算法是无约束下模最大化问题的1/4 近似算法。如果函数 f 还是对称的,那么算法是 1/2 近似算法。
  2. Double Greedy(f)(f)(f)算法中随机变量的行为与它们在算法Random Sample(f)(f)(f) 中的行为非常相似,除了现在进行将 uiu_{i}ui​ 元素添加到一个随机解中,还是将它从另一个随机解中移除的操作的概率大小是由函数 f 决定的。该算法是无约束下子模函数最大化的 1/2 近似算法。

子模福利问题:The Greedy Algorithm for Submodular Welfare({fi}i=1k)(\{fi\}_{i=1}^{k})({fi}i=1k​)算法从空assignment开始,然后在每次迭代中,将一个尚未分配的项目分配给该项目具有最大边际贡献的买方。该算法是子模福利问题的 1/2 近似算法。

参考:Buchbinder N, Feldman M. Submodular functions maximization problems[M]//Handbook of Approximation Algorithms and Metaheuristics, Second Edition. Chapman and Hall/CRC, 2018: 753-788.

二、 问题描述(问题定义)

实验任务:子模函数最大化算法的实现和改进

实验要求:

  • 从Web爬取某一主题的文本数据
  • 对爬取到的文本库进行预处理,以提取关键词。预处理技术如:分词、去除停用词、stemming等
  • 实现基于最大子覆盖问题的文本摘要算法,并从语料库中抽取100条摘要(集合元素可以是word或k-gram)
  • 实验报告中应说明摘要算法的性能,如执行时间、摘要的质量等

三、 方法(问题解决步骤和实现细节)

问题解决步骤

爬虫

基本思路

导入所需模块,构造请求头,读取种子页面,其中包含了许多<a herf>链接,将链接存储在一个列表中,再一一爬取,得到具体的新闻内容。

实现过程
种子页面的选取

为保证有足够丰富的文本来支撑后续的文本分析,首先需要选取一个包含许多同主题文本的网页作为种子页面。我在此选择了chinadaily网站的culture and heritage板块作为爬取的对象,一方面是该网站有对于新闻的分类,可以直接爬取相应板块下的内容;一方面是该板块文章内容多数较长,不至于出现一篇文章只有一句话描述的情况,导致不符合实验需要。

查看种子页面:https://www.chinadaily.com.cn/culture/heritage

可以看到该页面上有许多文章链接

此外,该页面还有分页处理存在:

经过对网页样式的研究,可以看到该页面的“左侧新闻列表”部分,每一页有15个新闻链接,指向15个包含具体新闻内容的页面。

具体新闻链接的获取

思路:首先得到culture and heritage板块下的各个page的链接,然后再从这些page的链接出发,得到各个具体新闻页面的链接。

具体步骤:

查看该页面的源代码,寻找包含“左侧新闻列表”中的新闻链接的部分,以及为了保证爬取的具体新闻数量足够,寻找包含分页信息的部分。

查看包含分页信息的部分:

可以看到,分页的url即为在种子页面的url上外增/page_页面编号,比如://www.chinadaily.com.cn/culture/heritage/page_2.html

于是通过以下代码,访问指定页面:

urls = url+'/page_{}'.format(i)+'.html'
soup = get_response(urls,headers)

查看包含“左侧新闻列表”中的新闻链接的部分:

容易发现,每个具体新闻链接都可以在 <span class="tw3_01_2_t"></span>中找到,并且该class下只有包含所需的具体新闻链接,而没有其他<a herf>存在。于是能够通过以下语句,获取各个新闻链接。

for tag in soup.find_all(name='span',class_='tw3_01_2_t'):link = tag.find('a')bf = link.get('href')

最终,将所有新闻的链接全部存储在一个列表中。

具体新闻文本内容获取

基本思路:根据新闻文本是否有分页,可以将之大致分为长文本和短文本两类。为了保证文章长度较长,以更好地保证关键词提取的效果,在此先筛选出有分页的文本,再对此进行内容的爬取,并将各篇新闻存储到各个txt文件里。

具体步骤:

首先,分析具体新闻页面的网页源代码。如果有分页,则如下;若无,则不存在如下代码段。

可以看到,若分页信息存在,则所以页面链接都存储在<div id="div_currpage"></div>中。并且每个<a herf></a>标签对中都存放着页面的计数。

于是通过以下代码,能够得到各个页面的链接。

bf = soup.find('div', id='div_currpage')
pattern = re.compile(r'\d+') #至少匹配一个数字
for link in bf.find_all('a'):if pattern.match(link.string):hr = link.get('href')page_list.append('https:'+hr)

其次,寻找网页源代码中包含文本信息的部分:

可以看到,具体文本信息被包含在<div id="Content"></div>之间。

于是,通过以下代码,取出文本信息:

bf = soup.find('div', id='Content')
for string in bf.stripped_strings:content_str+=string

最终,保存到.txt文件中。

文本预处理与关键词提取

基本思路

主要使用nltk库与正则化匹配方式,完成对文本的预处理。借助gensim库,进行关键词提取,并在此基础上,对关键词进行词干提取。

实现过程

重新读入.txt文件

对文本进行清洗,转换为小写,去除其中的标点符号,数字等

使用gensim.summarization.keywords,提取关键词

使用nltk.stem.PorterStemmer,对关键词进行词干提取,防止关键词表现为如复数形式,而和其他形式匹配不上的情况

将每个文本都进行如上操作,最终将所有关键词合并为一个new_keyword_ls。

基于最大子覆盖的抽取式文本摘要

基本思路

爬山算法

算法思路:对于给定的关键词集合W={w1,w2,...,wn}W = \{ w_{1},w_{2},...,w_{n} \}W={w1​,w2​,...,wn​},以及候选句子集合D={s1,s2,...,sm}D = \{s_{1},s_{2},...,s_{m}\}D={s1​,s2​,...,sm​},其中s1,s2,...,sms_{1},s_{2},...,s_{m}s1​,s2​,...,sm​为包含不同关键词的集合,每轮迭代选择对关键词覆盖函数f(S)边际贡献最大的句子,加到摘要集合S中。

输入:循环次数k

输出:集合S

for i = 1 to k do

​ 选择集合 $u = argmax_{s \in V}[f(S \cup {s}) - f(S)] $;

​ S←S∪u;S \leftarrow S \cup {u};S←S∪u;

return S;

算法实现:

sen_ls:列表,存储将文本进行划分后的所有句子

keyword_dic:字典,key为句子下标,value为句子的关键词列表

keywordnum_ls:列表,按序存储对应句子中关键词个数

每轮迭代:

  1. 从keywordnum_ls中查找数值最大,即关键词个数最多的对应下标i
  2. 以下标i为key,从keyword_dic中取出对应的value的关键词列表List
  3. 根据关键词列表List,删去keyword_dic的所有value中存在于List中的元
  4. 根据更新后的keyword_dic,重新计算出keywordnum_ls
  5. 迭代到100轮前,重复上述步骤
实现过程

首先将各个文本按句划分,并使用sen_ls列表进行存储,以下为部分sen_ls:

将句子下标与句子所拥有的关键词列表对应起来,建立字典keyword_dic,以下为部分keyword_dic:

对应下标,建立列表keywordnum_ls,存储各个句子有效的关键词个数,以下为部分keywordnum_ls:

使用爬山算法,首先得到关键词个数最多的句子的下标,随后将该句子对应的关键词都从句子中删除,再次选取关键词个数最多的句子的下标,重复以上步骤。以下为每轮选出的句子下标:

以下为选出的100句摘要的句子的下标:

最终,对应于下标,将原始句子打印出来,并存储到newsresult.txt文件中:

实现细节

爬虫

文本选取

问题描述:

由于新闻有些长度过短,有些仅仅是对于某张照片的描述信息,如下:

为尽量保证文本长度较长,故而选择性爬取具有分页信息的长文本。

先定义如下变量:

bf = soup.find('div', id='div_currpage')

若其取值为None,则说明无分页信息,不是长文本,为保证文本质量不进行爬取。若不为None,则进行爬取。

于是通过以下代码,能够得到各个长新闻页面的链接。

page_list = []
if bf != None:page_list.append(links)#本身第一个页面的url#加上https:pattern = re.compile(r'\d+') #至少匹配一个数字for link in bf.find_all('a'):if pattern.match(link.string):hr = link.get('href')page_list.append('https:'+hr)

文本预处理与关键词提取

无法将关键词全部从keyword_dic中删去的问题

原本的update_keyword_dic函数:

def update_keyword_dic(keywordnum_ls, keyword_dic):idx = keywordnum_ls.index(max(keywordnum_ls))keyword_ls = keyword_dic[idx]#对应句子所拥有的关键词#将这些关键词从所有句子的关键词列表中去除for value in keyword_dic.values():for i in value:if i in keyword_ls:value.remove(i)print("最多的关键词对应的句子的关键词字典修改后的长度{},应该是0".format(len(keyword_dic[idx])))#更新各个句子有效的关键词的个数new_keywordnum_ls = keywordnum_in_sen(keyword_dic)return idx, new_keywordnum_ls

如果使用以下keywordnum_ls和keyword_dic的小例子测试这个函数:

keywordnum_ls = [0,1,2,3,4,5]
keyword_dic = {0:[],1:[0],2:[0,1],3:[0,1,2],4:[0,1,2,3],5:[0,1,2,3,4]}
idx, new_keywordnum_ls = update_keyword_dic(keywordnum_ls, keyword_dic)
print(new_keywordnum_ls)

会得到以下结果:

容易发现,没有能够全部删除关键词。进一步观察会发现,该删除方式为间隔式的删除,即每隔一个关键词,删除一个:

于是转换思路,抛弃使用for value in keyword_dic.values()+if i in keyword_ls+value.remove(i)函数的方法,转而使用for key, value in keyword_dic.items()+if i not in keyword_ls+new_value.append(i)的方法:

def update_keyword_dic(keywordnum_ls, keyword_dic):idx = keywordnum_ls.index(max(keywordnum_ls))keyword_ls = keyword_dic[idx]#对应句子所拥有的关键词#将这些关键词从所有句子的关键词列表中去除for key, value in keyword_dic.items():print(value)new_value = []for i in value:print("对value里的{}进行了操作".format(i))if i not in keyword_ls:new_value.append(i)keyword_dic[key] = new_valueprint("最多的关键词对应的句子的关键词字典修改后的长度{},应该是0".format(len(keyword_dic[idx])))#更新各个句子有效的关键词的个数new_keywordnum_ls = keywordnum_in_sen(keyword_dic)return idx, new_keywordnum_ls

能够得到想要的结果:

基于最大子覆盖的抽取式文本摘要

如何比对词干提取后的关键词列表与未经过任何文本清洗的句子

由于上一步关键词提取得到的关键词都为词干提取之后的词,并且都存储在列表中;而最终想要得到的文本摘要的结果是100句完整的句子,直接由原始的文本得来,不应有文本清洗作用其上,那么怎么将词干提取后的关键词列表与未经过任何文本清洗的句子进行比对,是一个必须解决的问题。在此所采用的解决方法,概括而言即为对“下标”的利用。一方面,开设一个列表List1,存储原始的句子;另一方面,开设一个字典Dict,将句子在列表中的下标与其包含的关键词建立的列表一一对应。此外,为使得对于关键词的计数更为方便,同时维护另一个列表List2,对应于存储原始句子的列表List1的下标,存储各个句子有效的关键词个数。通过对于List2中关键词个数最多的下标的选取,以及对于Dict和List2的更新,即能不断得到需要选取的句子的下标。借助这些下标,就能取出List1中对应的原始句子。

sent_tokenize不起作用的问题
from nltk.tokenize import sent_tokenize
txt = "[Photo by Wei Xiaohao/China Daily]The social-media tool\"The sound of stringed instruments like the dutar and the tembur can release stress and spark joy, helping me embrace a moment of tranquility,\" Ahmat Nurdun, 29, says, explaining why he feels a connection with the instruments.As the youngest son of Nurdun Ismayil, a veteran instrument maker in the village, Ahmat chose to follow in his father's footsteps at the age of 15.He witnessed his father's devotion to the craftsmanship of making the instruments and gradually formed an interest in it himself.Based on similar logic, in 2019, Ahmat started to post clips of how he makes the instruments and the family playing them together on the short video sharing platform Kuaishou.His own devotion to the art and the wonderful sound of the instruments have helped him attract more than 48,000 followers on the platform."
sen = sent_tokenize(txt)
print(sen)

对于如以上文本,调用sent_tokenize函数,会导致以下结果:

可见,虽然有句号存在,但是并未进行分词。

查阅得知,该问题是由于sent_tokenize不会对.后没有空格的情况进行分词。

解决:在所有.后都增加空格

txt = "[Photo by Wei Xiaohao/China Daily]The social-media tool\"The sound of stringed instruments like the dutar and the tembur can release stress and spark joy, helping me embrace a moment of tranquility,\" Ahmat Nurdun, 29, says, explaining why he feels a connection with the instruments.As the youngest son of Nurdun Ismayil, a veteran instrument maker in the village, Ahmat chose to follow in his father's footsteps at the age of 15.He witnessed his father's devotion to the craftsmanship of making the instruments and gradually formed an interest in it himself.Based on similar logic, in 2019, Ahmat started to post clips of how he makes the instruments and the family playing them together on the short video sharing platform Kuaishou.His own devotion to the art and the wonderful sound of the instruments have helped him attract more than 48,000 followers on the platform."
txt1 = txt.replace(".",". ")
for sentence in sent_tokenize(txt1):print(sentence)

改变后的结果:

可见,已经能够正确进行句子划分。

四、 实验结果(验证提出方法的有效性和高效性)

  • 得到的抽取式文本摘要

    可见该方法能够进行句子抽取

  • 关键词覆盖率

    在main.py中,使用以下代码,计算关键词覆盖率:

    print("关键词总数为:", len(new_keyword_ls))
    print("覆盖的关键词个数为:",keyword_cover_num)
    print("关键词覆盖率为:", keyword_cover_num/len(new_keyword_ls))
    

    得到结果:

  • 执行效率

    在main.py中,使用以下代码,测试算法的执行时间:

    import timeit
    start = timeit.default_timer()for i in range(0,100):#提取100个句子idx, keywordnum_ls, keyword_cover_num = update_keyword_dic(keywordnum_ls, keyword_dic, keyword_cover_num)sen_chosen_index_ls.append(idx)end = timeit.default_timer()
    print("算法运行时间为:{}s".format(str(end-start)))
    

    得到结果:

  • 内存占用

    在main.py中,使用以下代码查看当前进程的内存占用:

    #当前进程内存占用
    import psutil
    print('当前进程的内存使用:%.4f GB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024 / 1024))
    

    得到结果:

五、 结论(对使用的方法可能存在的不足进行分析,以及未来可能的研究方向进行讨论)

  • keyword_dic构建细节问题

    在构建的keyword_dic中,value都是由关键词构成的列表。由于列表是字符串类型,占用的存储空间相对较大,同时为了更好地查阅字典,机器倾向于将该字典在使用时保存在内存里,导致占用的内存空间较多。如果将各个关键词与二进制数字一一对应,在字典中存放对应的二进制数字而非字符串,可以在不断查阅和修改字典的操作中节省内存和运行时间。

  • 对比“倒排索引”

    在本实验中,采取的方法是构建sentence-keyword字典,但或许也可以构建keyword-sentence字典,以各个keyword作为key,以sentence的ID作为value列表,每次选取到一句之后,将其包含的关键词及其列表一并从字典中删除。在原方法中,删除sentence对应的关键词需要遍历整个字典,若假设字典中键值对数目为n,则时间复杂度为O(n);在这种方法中,删除则只需要O(1)。而更新keywordnum_ls的时间复杂度也有所区别:原方法中,需要遍历字典,计数每个sentence的value列表长度,需要O(n)的时间;在这种方法中,也需要遍历字典,每次在一个keyword对应的value的list中看到相应sentence则对keywordnum_ls中的对应元上进行+1操作,需要O(mn)的时间,m为平均的value列表长度。对比来看,整个更新操作,sentence-keyword字典时间复杂度为2O(n),而keyword-sentence字典时间复杂度为O(1)+O(mn),sentence-keyword字典相对更优。

六、 代码

共包含两个.py文件。使用时先运行spider.py,再运行max_cover.py。

spider.py

作用:实现对chinadaily的culture and heritage板块的新闻内容的爬取

import requests  #爬取网页的库
from bs4 import BeautifulSoup #用于解析网页的库
import redef get_response(urls,headers):response = requests.request("GET", urls, headers=headers) # 获取网页数据response.encoding = response.apparent_encoding # 当获取的网页有乱码时加soup = BeautifulSoup(response.text, 'html.parser')return soupdef get_link_ls(url,headers):#获取120个linklink_list = []#link_list.clear()for i in range(1,9):#print(url+'/page_{}'.format(i)+'.html')'''response = requests.request("GET", urls+'/page_{}'.format(i)+'.html', headers=headers)response.encoding = response.apparent_encodingsoup = BeautifulSoup(response.text, 'html.parser')'''urls = url+'/page_{}'.format(i)+'.html'soup = get_response(urls,headers)for tag in soup.find_all(name='span',class_='tw3_01_2_t'):link = tag.find('a')#print(link.get('href'))bf = link.get('href')link_list.append('https:'+bf)return link_listdef get_page_list(links,headers):'''response = requests.request("GET", link_list[0], headers=headers)response.encoding = response.apparent_encodingsoup = BeautifulSoup(response.text, 'html.parser')'''soup = get_response(links,headers)#print(soup)#print(links)bf = soup.find('div', id='div_currpage')#print(bf)page_list = []page_list.clear()if bf != None:page_list.append(links)#本身第一个页面的url#加上https:pattern = re.compile(r'\d+') #至少匹配一个数字for link in bf.find_all('a'):#print(link.string)if pattern.match(link.string):hr = link.get('href')#print(hr)page_list.append('https:'+hr)#print(page_list)return page_listdef get_page_content_with_pages(page_list,headers,num):content_str = ''for i in range(len(page_list)):'''response = requests.request("GET", links, headers=headers)response.encoding = response.apparent_encodingsoup = BeautifulSoup(response.text, 'html.parser')'''soup = get_response(page_list[i],headers)bf = soup.find('div', id='Content')#print(bf)for string in bf.stripped_strings:#print(string)content_str+=string#print(content_str)with open('D:\\studyroom\\algorithm\\news{}.txt'.format(num), 'a', encoding='utf-8') as f:f.write(content_str)f.close()def main():headers = {'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36",}  # 构造请求头urls = 'https://www.chinadaily.com.cn/culture/heritage'link_list = get_link_ls(urls,headers)#print(link_list)#print(len(link_list))page_list = []k = 0for i in range(len(link_list)):page_list.clear()page_list = get_page_list(link_list[i],headers)#print("page_list{}".format(page_list))if len(page_list) != 0:get_page_content_with_pages(page_list,headers,k)k = k+1if __name__ == "__main__":main()

max_cover.py

作用:文本预处理+关键词提取+基于最大子覆盖的抽取式文本摘要

import re
import string
import os
import nltk
from nltk.tokenize import sent_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
import warnings
warnings.filterwarnings(action='ignore',category=UserWarning,module='gensim')
import gensim
from gensim.summarization import keywords#读入txt文件
def loadtxt(i):with open('D:\\studyroom\\algorithm\\newsdata\\news{}.txt'.format(i),encoding='utf-8',mode="r") as f:    #设置文件对象txt = f.read()txt = txt.replace(".",". ")#后面使用的sent_tokenize在.后无空格时不起作用。为保证结果正确,直接在.后加上空格return txt#去除数据中的非文本部分,转换为小写
def clean_text(text):'''Make text lowercase, remove text in square brackets,remove links,remove punctuationand remove words containing numbers.'''text = str(text).lower()text = re.sub('\[.*?\]', '', text)text = re.sub('<.*?>+', '', text)text = re.sub('[%s]' % re.escape(string.punctuation), '', text)text = re.sub('\n', '', text)text = re.sub('\w*\d\w*', '', text)return text#关键词提取
from gensim.summarization import keywords
def abstract_keywords(text):wordlis = keywords(text, lemmatize=True).split('\n')return wordlis#词干提取
from nltk.stem import PorterStemmer
def stem_word(word_list):stemmer=PorterStemmer()stem_word_list = []for word in word_list:sword=stemmer.stem(word)stem_word_list.append(sword)return stem_word_list#关键词处理
def keyword_process(keywordls):ls = list(set(keywordls))#去重new_ls = []for i in ls:if ' ' not in i:new_ls.append(i)return new_ls#将文本拆分为句子
def split_sentence(txt):sen = []sen = sent_tokenize(txt)return sen#分词
def split_to_word(txt):word_list = []for word in txt.split(' '):word_list.append(word)return word_list#将句子下标与句子所拥有的关键词列表对应起来,建立字典
def sen_have_keyword(sen_ls, new_keyword_ls):k = 0#下标,记录句子是第几句keyword_dic = {}#对应下标,存储句子包含的关键词for i in sen_ls:sen = clean_text(i)word_ls = split_to_word(sen)stem_word_ls = stem_word(word_ls)#sen_ls_processed.extend(stem_word_ls)#这样会把词都混在一起,不能区分句子#直接进行比对keyword_dic[k] = []for keyword in new_keyword_ls:if keyword in stem_word_ls:keyword_dic[k].append(keyword)k = k+1return keyword_dic#计算各个句子有效的关键词的个数
def keywordnum_in_sen(keyword_dic):keywordnum_ls = []for key, value in keyword_dic.items():num = len(value)keywordnum_ls.append(num)return keywordnum_ls#更新句子对应的关键词字典
def update_keyword_dic(keywordnum_ls, keyword_dic):idx = keywordnum_ls.index(max(keywordnum_ls))keyword_ls = keyword_dic[idx]#对应句子所拥有的关键词#print(idx, keyword_ls)#将这些关键词从所有句子的关键词列表中去除for key, value in keyword_dic.items():new_value = []for i in value:if i not in keyword_ls:new_value.append(i)keyword_dic[key] = new_value#print("最多的关键词对应的句子的关键词字典修改后的长度{},应该是0".format(len(keyword_dic[idx])))#更新各个句子有效的关键词的个数new_keywordnum_ls = keywordnum_in_sen(keyword_dic)return idx, new_keywordnum_ls#找到对应于下标的原始句子,并打印
def index_to_originsen(sen_chosen_index_ls, sen_ls):result_ls = []for idx in sen_chosen_index_ls:result_ls.append(sen_ls[idx])print(sen_ls[idx])print("抽取出的句子总数为:{}".format(len(result_ls)))return result_ls#将取出的句子保存于txt文件中
def save_result(result_ls):with open('D:\\studyroom\\algorithm\\newsresult.txt', 'w', encoding='utf-8') as f:for i in result_ls:f.write(i)f.write('\n')f.close()def main():#关键词提取keyword_ls = []path = 'D:\\studyroom\\algorithm\\newsdata'      # 输入文件夹地址files = os.listdir(path)   # 读入文件夹file_num = len(files)#print(file_num)for i in range(0,file_num):txt = loadtxt(i)txt = clean_text(txt)wordls = abstract_keywords(txt)wordls = stem_word(wordls)#print(wordls)keyword_ls.extend(wordls)#print(keyword_ls)new_keyword_ls = keyword_process(keyword_ls)#print(new_keyword_ls)#最大覆盖实现sen_ls = []#存储原本状态的句子集合for i in range(0,file_num):txt = loadtxt(i)sen = split_sentence(txt)sen_ls.extend(sen)keyword_dic = {}#对应下标,存储句子包含的关键词keyword_dic = sen_have_keyword(sen_ls, new_keyword_ls)#print(keyword_dic)keywordnum_ls = keywordnum_in_sen(keyword_dic)#对应下标,存储各个句子有效的关键词的个数#print(keywordnum_ls)#print(len(keywordnum_ls))#爬山算法#首先得到关键词个数最多的句子的下标#随后将该句子对应的关键词都从句子中删除#再次选取关键词个数最多的句子的下标,重复以上步骤sen_chosen_index_ls = []for i in range(0,100):#提取100个句子idx, keywordnum_ls = update_keyword_dic(keywordnum_ls, keyword_dic)sen_chosen_index_ls.append(idx)#print(keywordnum_ls)#print(sen_chosen_index_ls)#打印下标对应的原始句子result_ls = index_to_originsen(sen_chosen_index_ls, sen_ls)save_result(result_ls)if __name__ == "__main__":main()

基于最大子覆盖问题的文本摘要实验相关推荐

  1. 基于TextRank的抽取式文本摘要(英文)

    基于TextRank的抽取式文本摘要(英文) 前言 备注 Talk is cheap, show me the code. 前言 在GitHub上写笔记要经常查看很麻烦,在此记录一些整合的各种代码.能 ...

  2. 使用Word Embedding构造简洁有效的文本摘要系统

    /*版权声明:可以任意转载,转载时请标明文章原始出处和作者信息.*/ author: 张俊林,黄通文,薛会萍 文本摘要是在信息泛滥的时代非常重要的工具,可以帮助用户快速判断文章内容主旨,并以此决定是否 ...

  3. huggingface transformers实战系列-06_文本摘要

    文本摘要简述 随着互联网产生的文本数据越来越多,文本信息过载问题日益严重,对各类文本进行一个"降 维"处理显得非常必要,文本摘要便是其中一个重要的手段.文本摘要旨在将文本或文本集合 ...

  4. 新手探索NLP(九)——文本摘要

    转载自知乎https://zhuanlan.zhihu.com/p/67078700 文本摘要是一种从一个或多个信息源中抽取关键信息的方法,它帮助用户节省了大量时间,用户可以从摘要获取到文本的所有关键 ...

  5. 文本摘要常用数据集和方法研究综述

    [1]侯圣峦,张书涵,费超群.文本摘要常用数据集和方法研究综述[J].中文信息学报,2019,33(05):1-16. 文章目录 LCSTS 数据集定义 NLPCC 数据集定义 自建数据集及其对应方法 ...

  6. 一篇简短的文本摘要综述

    摘要的定义 对海量数据内容进行提炼与总结,以简洁.直观的摘要来概括用户所关注的主要内容,方便用户快速了解与浏览海量内容. 文本摘要 这篇主要讲的还是文本摘要 早期论文 Luhn. The Automa ...

  7. 微软最新论文解读 | 基于预训练自然语言生成的文本摘要方法

    作者丨张浩宇 学校丨国防科技大学计算机学院 研究方向丨自然语言生成.知识图谱问答 本文解读的是一篇由国防科技大学与微软亚洲研究院共同完成的工作,文中提出一种基于预训练模型的自然语言生成方法. 摘要 在 ...

  8. 【论文笔记】QBSUM: 基于查找的文本摘要数据集

    QBSUM: a Large-Scale Query-Based Document Summarization Dataset from Real-world Applications 论文下载地址h ...

  9. 基于BERT-PGN模型的中文新闻文本自动摘要生成——文本摘要生成(论文研读)

    基于BERT-PGN模型的中文新闻文本自动摘要生成(2020.07.08) 基于BERT-PGN模型的中文新闻文本自动摘要生成(2020.07.08) 摘要: 0 引言 相关研究 2 BERT-PGN ...

  10. 独家 | 基于TextRank算法的文本摘要(附Python代码)

    作者:Prateek Joshi 翻译:王威力 校对:丁楠雅 本文约3300字,建议阅读10分钟. 本文介绍TextRank算法及其在多篇单领域文本数据中抽取句子组成摘要中的应用. TextRank ...

最新文章

  1. oracle控制文件发生坏块,控制文件坏块处理方法
  2. vue实现一个星级打分效果_五分钟用vue实现一个五星打分效果
  3. 『码蛋』Android 周刊第1期
  4. 【组合数学】排列组合 ( 多重集排列 | 多重集全排列 | 多重集非全排列 所有元素重复度大于排列数 | 多重集非全排列 某些元素重复度小于排列数 )
  5. BZOJ——T 2097: [Usaco2010 Dec]Exercise 奶牛健美操
  6. 登录账号用户名判断_如何设计 QQ、微信等第三方账号登陆 ?
  7. VCS学习(2)debug simulation mismatches
  8. eclipse: workspace出错导致无法启用的解决
  9. Q新闻丨吃鸡外挂被开源;Dubbo 3.0来了;工信部约谈百度、支付宝、今日头条;内地iCloud服务将转由云上贵州运营...
  10. 百度编辑器Ueditor多文本域实现
  11. 机器人设计必备的软件有哪些
  12. openlayers 设置边界线外圈遮罩
  13. [附源码]计算机毕业设计JAVA汽车租赁系统
  14. 解决javascript提交form出现错误提示:对象不支持此属性或方法
  15. 第二十章 : 正则表达式
  16. qzwxecasd测试1234
  17. 天空盒(Skybox)
  18. 在vue中使用 jquery分页组件
  19. Python 读写文件时报错 ValueError: must have exactly one of create/read/write/append mode
  20. nginx - nginx的配置文件 - 虚拟主机

热门文章

  1. HTML/CSS入门(1)
  2. 你为什么需要认知升级?认知决定你的财富!
  3. 分布式事务之柔性事务
  4. 对称矩阵特征向量正交推导
  5. 特征级融合_自动驾驶系统入门(七)- 多传感器信息融合(MSIF)
  6. 动态规划:HDU1248-钱币兑换问题
  7. 广义表的存储结构及其基本运算
  8. 班级主页效果图html,DW制作网页|html静态页面|班级网页素材|蝶恋花班级主页网站...
  9. 明朝崇祯十年丁丑科状元刘同升后裔在松滋
  10. 怎样修改linux(虚拟机)系统开机密码