自动提取文章摘要AutoSummary
2015-10-10 12:57
579 查看
在文本搜索引擎项目中,需要对已排序的文章进行摘要提取,然后与标题,路径一起封装成Json数据返回客户端。因此这里我自己写一个自动摘要,来大概完成这个任务。在自动摘要提取过程中,使用了一个分词库:CppJieba分词库。因此在头文件中包含了头文件 “Application.hpp”。
思路:
1、对文章提取关键字。通常,关键字能够代表这篇文章的所描述的内容。因此使用CppJieba分词库中“Application.hpp”中api extract()进行关键字提取。我提取的是前50个,若文章关键字不够50个则取实际个数。关键字的结果已经按照权重的顺序排序好。
2、把文章拆分成句子。这里是只对中文进行处理(英文道理也一样),当遇到句号‘ 。’,问号‘ ? ’,感叹号‘ ! ’,算一句话。把每一句话按顺序保存到vector<string>类型的数组sentences中。
3、遍历关键字数组,对每一个关键字在每一个句子中查找包含该关键字的第一个句子,并把该句子加入到vector<string>类型的数组summary中。
4、若遍历到达关键字上限或者句子数量到达上限,跳出循环。
5、将数组summary中的句子按顺序拼接从摘要。
代码如下:
参考:http://www.ruanyifeng.com/blog/2013/03/automatic_summarization.html
思路:
1、对文章提取关键字。通常,关键字能够代表这篇文章的所描述的内容。因此使用CppJieba分词库中“Application.hpp”中api extract()进行关键字提取。我提取的是前50个,若文章关键字不够50个则取实际个数。关键字的结果已经按照权重的顺序排序好。
2、把文章拆分成句子。这里是只对中文进行处理(英文道理也一样),当遇到句号‘ 。’,问号‘ ? ’,感叹号‘ ! ’,算一句话。把每一句话按顺序保存到vector<string>类型的数组sentences中。
3、遍历关键字数组,对每一个关键字在每一个句子中查找包含该关键字的第一个句子,并把该句子加入到vector<string>类型的数组summary中。
4、若遍历到达关键字上限或者句子数量到达上限,跳出循环。
5、将数组summary中的句子按顺序拼接从摘要。
代码如下:
#ifndef _AUTOSUMMERY_HPP #define _AUTOSUMMERY_HPP #include"../src/Statistics/src/Application.hpp" #include <string> #include<set> #include <utility> #include<vector> #include<iostream> #include<functional> using namespace std; using namespace CppJieba; class AutoSummary { public: AutoSummary(Application &app,int maxSentenceNum=10)//初始化一个自动摘要对象 :maxSentenceNum_(maxSentenceNum), app_(app) {} //自动提取摘要 string summarizer(string & originTxt,int KEYNUM=50) { vector<pair<string,double> > keywords; app_.extract(originTxt,keywords,KEYNUM); //取文章的前50个关键词,按权重排序 vector<string> sentences; //装载句子的数组 getSentences(originTxt,sentences); //把文章拆分成句子 int sentencesNum = sentences.size(); //句子的数量 vector<string> summaryRet; //装包含关键字的句子 set<int> summarySet; //句子去重 set<int>::iterator it; KEYNUM = keywords.size();//如果关键字数量小于50则取实际的数量 for(int i = 0;i<KEYNUM;i++) { for(int j = 0;j<sentencesNum;j++) { int pos = sentences[j].find(keywords[i].first,0); if(pos!=string::npos) { it = summarySet.find(pos); if(it==summarySet.end()) { summaryRet.push_back(sentences[j]);//向数组添加句子 summarySet.insert(j); break; //跳出循环,找下一个关键字 } } } //跳出循环的条件 if(summaryRet.size()>maxSentenceNum_||summaryRet.size()>=sentencesNum) break; } string summaryStr; int i = 0; int num = summaryRet.size(); while(i<num) { summaryStr = summaryStr + sentences[i]+"……"; i++; } return summaryStr; } private: //将文章拆分成句子,私有成员函数,在summarizer()中调用 void getSentences(const string &originTxt,vector<string> &sentenceVec) { int beg=0,end=0,pos=0,pos1=0; int txtSize = originTxt.size(); while(beg<txtSize&&pos!=string::npos) { if((pos=originTxt.find("。",beg))!=string::npos) { if((pos1=originTxt.find("?",beg))!=string::npos) { pos=((pos<pos1)?pos:pos1); if((pos1=originTxt.find("!",beg))!=string::npos) { pos=((pos<pos1)?pos:pos1); } } else if((pos1=originTxt.find("!",beg))!=string::npos) { pos=((pos<pos1)?pos:pos1); } } else if((pos=originTxt.find("?",beg))!=string::npos) { if((pos1=originTxt.find("!",beg))!=string::npos) { pos=((pos<pos1)?pos:pos1); } } else if((pos1=originTxt.find("!",beg))!=string::npos) { pos = pos1; } else { break; } if(pos!=-1) { int len = pos-beg; string sentence(originTxt.substr(beg,len)); sentenceVec.push_back(sentence); beg = pos+3; } } } private: Application & app_;//分词库的引用 int maxSentenceNum_;//摘要中的句子数目,由外部传进。 }; #endif
参考:http://www.ruanyifeng.com/blog/2013/03/automatic_summarization.html
相关文章推荐
- Android悬浮窗实现 使用WindowManager
- PHP: pack/unpack补遗
- Android 自定义Galley中图片未居中显示问题
- 解决ubuntu sudo not found command的问题
- web driver selenium 操作滚动条
- android ndk Application.mk
- overflow(2)
- Swift字典
- 【HttpClient4.5中文教程】【第一章 :基础】1.4 HTTP协议拦截器
- 前端指南
- Mac在github中管理自己的代码(入门篇)
- sql
- HBase笔记
- title滚动
- iOS开发中@property的属性weak nonatomic strong readonly等介绍
- ios开发中WebView,去除(自定义)JS中Alert显示的网址
- 基于redis的tomcat 7.X session同步解决方案
- 行内元素与块状元素的三个区别
- 去掉SSH KEY密码
- [Leetcode]Move Zeroes