资源描述
科技制作报告
题 目 网络舆情监督系统的研究与实现
学校(院系)
学生姓名: 学号:
指导教师
完成时间
基于网络舆情监督系统的热点话题挖掘
摘要
随着互联网的普及使用,以及互联网上所承载和传播的信息规模及其蕴含价值越来越大,使之成为各行各业、机构以及个人获取信息重要的来源之一。截至2013年9月底,中国网民数量达到6.04亿,互联网普及率达到45%,超过世界平均水平。 在Internet普及的过程中,网民们积极地参与网络讨论、自由发表个人观点和自主传播思想文化,从而形成了网络舆情。
网络舆情是人们受各种事件的刺激,通过互联网传播他们对于该事件的所有认知、态度、情感以及行为倾向的集合。网络舆情主要通过新闻评论、BBS、聊天室、博客、即时通信、电子邮件和微博等形成并传播。由于网络的便捷性、白发性和匿名性,使得网络舆情的广泛传播常常会导致事件的放大和升级,从而形成舆论导向,引发舆论热点,甚至会对事件的发展以及结果产极大的影响。因此加强对网络舆情的监测,挖掘出网络舆情的热点对于掌握网络舆情动向和引导网络舆情的发展具有极其重要的现实意义。
关键词: 网络舆情 热点
一、 绪论
1.1、 研究背景
互联网在我国发展十分迅速,它影响了我们生活的方方面面,不仅是衣食住行,甚至还包括我们的世界观和价值观。80后90后以及现在的00后,对于互联网的依赖的程度越来越高。例如,一点鼠标,就有快递送货上门;找地方住还没有去,已经知道房间;机票和火车票等都有网上票务网站;甚至连谈恋爱都是在网上。互联网是人们生活的另一种延伸,每个人都可以发表自己的观点,而且同时也可以发泄对现实生活中的不满,人们对于社会的各种问题在网络上发表自己的看法与意见,这就形成了网络舆情。
网络舆情是指在一定的社会空间之内,通过网络围绕社会事件的发生、发展以及变化,民众对于公共问题和社会管理者产生的和持有的社会政治态度、信念以及价值观。是较多民众对于社会中的各种现象、问题所表达的信念、态度、意见以及情绪等表现的总和。网络舆情形成迅速,且对社会影响巨大。随着互联网的高速发展,人们对社会突发事件关注的积极性也在不断的提高,网民对于某一事件的关注主要通过在网上发表自己的言论来传递信息和向其他网民施加影响,一传十十传百,通过这种“信息接力”关系,形成一股强大的社会力量,从而反过来影响社会的发展。而网民的这种“信息踪迹”主要是通过在网络上的文字、图片、视频以及表情等内容体现出来的,所以提取以及搜集网络上的这些信息也就成为了舆情监控的首要目标和重要前提。
没有规矩不成方圆,这对互联网来说也是一样的。互联网的虚化世界有着隐蔽性的特征,监管不能面面俱到。正是由于其隐蔽性,造谣诽谤等一系列侵权行为层出不穷。更有甚者,利用互联网传播反党反社会的言论,严重影响了国家的安全。这些负面甚至是违法的消息的传播,不仅不利于社会稳定,国家安全,同时也危害着互联网自身的发展。这使得网民对互联网的消息不再信任,这会有碍互联网自身的发展。互联网的问题很复杂,社会上丑陋的一面都会在互联网上展现出来,但是由于互联网巨大的传播效应,其危害远大于传统方式。
因此网络舆情监督的研究十分迫切。
1.2、 本文研究内容
本课题首先从网络舆情分析研究的背景出发,了解现有的网络舆情分析相关的理论,然后在此基础上对网络舆情分析的关键技术分析,最后是在热点方面的应用举例。
二、 相关技术理论综述
2.1、网络爬虫技术
网络爬虫,又名“网络蜘蛛”,是通过网页的链接地址来寻找网页,从网站某一个页面开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到按照某种策略把互联网上所有的网页都抓取完为止的技术。
种子URL
URL队列
网络爬虫分类:
Ø 通用网络爬虫
通用网络爬虫是不分主题,根据网络爬虫的控制策略随机分配爬行任务的爬虫。通用网络爬虫之间不存在主题方面的通讯与合作,目标是尽可能多的搜集质量好的页面,但对于页面内容没有要求,包含所有方面。
Ø 主题网络爬虫
主题网络爬虫是面向主题的,以特定主题为目标访问页面的爬虫。主题网络爬虫的目标是尽可能多的爬行与主题相关的资源,尽可能少的爬行与主题无关的页面,过滤掉无关网页,使某个主题的资源覆盖率变大,同时要求相关资源质量好。
网页抓取策略:
Ø 广度优先
① 以结点作为父结点,找出它所有的下一层子结点;
② 从下一层最左边一个节点开始,进行步骤①;
③ 重复步骤②,直到遍历所有结点。
Ø 深度优先
以结点作为父结点,找出它的下一个结点
从下一个结点开始,重复步骤①;直到沿一条支路到达最后一个结点;
选择上一条支路的倒数第二个结点,重复步骤②;
重复步骤③,直到遍历所有结点。
本文的网络爬虫借助Nutch实现。Nutch是一个基于Lucene的优秀开源搜索引擎, 它是最早用到MapReduce的项目(Hadoop原来是Nutch的一部分)。如今, MapReduce编程方式占据了Nutch核心结构的大部分, 它极大地方便了编程人员在不会分布式并行编程的情况下, 将自己的程序运行在分布式系统上。Nutch主要分为两个部分:网络爬虫和查询。网络爬虫的主要作用是从网络上抓取网页数据并建立索引; 查询则主要是利用这些索引来检索用户所提交的关键词并产生和返回查找结果。
Nutch基于MapReduce模式的分布式网络爬虫工作过程, 如下所示:
读取URL种子文件到Crawl DB, 然后进行下面的抓取程序。
(1) 循环①~④到指定的抓取深度:
① 从Crawl DB生成抓取列表;
② 根据抓取列表中的URL抓取网页;
③ 分析处理抓取的内容;
④ 更新Crawl DB库。
(2) 转化每个页面中外部对它的链接。
(3) 建立索引
在上面的介绍中,成功的进行了一次nutch抓取,并建立了一个索引库。但是在实际应用中,这个索引库必须要进行更新,加入新的内容。所以,我们就需要进行recrawl,再次爬行。
recrawl并不是简单的再次爬行而已,而是要跟以前的内容作比较,对于静态页面不更新,只对动态的页面更新,因此更为复杂。
2.2、网页文本预处理技术
要对网页上的信息进行分析首先要对网页进行一系列的网页文本预处理工作,使处理后的网页信息用来进行下一步的工作。其主要包括去除重复网页的去重技术,提取文章的主要内容的提取技术,中文分词技术以及文本聚类技术。
2.2.1、文本提取
爬取到的网页中的数据非常复杂,大多以无结构与非半结构化结合的方式掺杂在一起,这种信息存储方式与传统的文本存储不同,其信息庞杂,网页的控制信息与网页内容相互混和,给信息提取带来了一定的难度。所以,为了把数据以结构化的形式存储便于进行分析,首先要做的一点就是提取出网页中的正文内容,去除网页链接和网页格式标注等无用的信息。而这就需要结合HTML源码格式进行分析,从而提取出文档的标题、内容以及新的链接三部分内容。
2.2.2、文本去重
网络舆情信息中存在众多的重复和转载信息,所以大量的数据中也存在着一定数量的冗余网页。因此在舆情的检索与后续的分析处理过程中,从多个地址返回相同内容的概率很大。这不仅影响了对舆情态势分析的准确程度与用户对舆情检索的满意程度,还浪费了大量的资源维护消耗与存储空间。因此,有必要引入网页排重技术,从而最大程度地避免这一现象。
去重过程大致如下:
从输入文档提取出合理特征;
再与先前提取的特征进行比较、判定;
2.2.3、中文分词
对中文文本进行处理时,第一项工作一般是进行中文分词,这是由中文语言的特性所决定的。中文分词,就是把中文语句划分成一个个以“词”或者“词语”为单位的单独元素,中文的语句就是由这样的一个个“词”连缀而成。
进行自然语言处理的最小单元是词语,而在以英语为代表的拉丁语系语言中,通常都以空格作为天然的词语分隔符,因此在对英文文本进行处理时并不存在词语划分的问题。而对于由古代文言文、白话文发展而来的现代中文而言由于保留了之前的传统,词语与词语之间并没有天然的分隔符,如空格、逗号、,顿号、分号之类的,因此我们需要对中文文本进行人为的词语切分,而将一个个汉字组成的句子切分成一个个词语,就是所谓的中文分词。
中文分词算法的研究持续了很长的时间,出现了各种各样的分词算法,现有分词算法总的说来基本可以分为三种:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法。
本课程借助IKAnalyzer实现中文分词。IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。其采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。对中英联合支持不是很好,在这方面的处理比较麻烦.需再做一次查询,同时是支持个人词条的。优化的词典存储,更小的内存占用。支持用户词典扩展定义。
借助IKAnalyzer能很好实现中文分词。
三、 网络舆情分析关键技术实现
3.1、开发实现环境
本课题在windows系统下实现,借助了java开发工具eclipse。由于本课题的网络爬虫用Nutch实现,因此配置Cygwin借此方便运行Nutch,Cygwin是一个在windows平台上运行的类UNIX模拟环境。安装配置tomcat查看nutch的爬取结果。
在获取页面文本信息到本地后,使用eclipse对数据进行去重、分词最后聚类出所挖掘的网络舆情,并进行推荐。
3.2、舆情信息获取
通过nutch的网络爬虫获取特定网站的内容。安装配置cygwin和nutch的过程在这里省略,安装测试cygwin如图1所示:
图1
使用nutch爬取指定网页,在cygwin执行指令
a) 首先切换进入nutch-1.2的目录;
b)运行命令:export LANG="zh_CN.GBK"(设置linux环境变量)
c)运行命令:bin/nutch crawl urls -dir crawled -depth 4 -threads 3 -topN 30
d)bin/nutch readseg -dump crawled1/segments/20140517192906/ segdb -nocontent -nofetch -nogenerate -noparse –noparsedata(解析爬取结果到本地文件dump)
配置tomcat查看爬取结果 http://localhost:8080/nutch-1.2/ 。这里所爬取的网页是搜狐新闻
图2
本地查看爬取结果:
图3
3.3、舆情信息处理
1、在eclipse运行程序对原始数据提取中文文本,结果为:(程序见附录)
图4
2、实现中文分词(程序见附录):
图5
3、分词后进行词频统计(程序见附录):
图6
3.4、舆情热点
经过分词、词频统计和无意义词去除等数据处理后就可以进行文本聚类,运用聚类算法把关联紧密的词语聚类起来从而得到一个热点话题。
图7
通过计算词频来分析话题的热度,从而将最热的话题推荐出来。
四、 总结与展望
本文首先从背景介绍了网络舆情基本情况和相关特征,然后针对网络舆情的关键技术进行分析和实现。给出了网络舆情监督的舆情信息获取和信息处理的实现过程。
本课题实现的只是网络舆情监督系统的部分功能,提高的方面有在爬取部分对多个信息源进行爬取如博客、微博、论坛、百度贴吧和新闻评论等,并对其进行分类后存入数据库,构建一个庞大的舆情信息数据库。信息处理方面做得更加准确为后面的舆情推荐系统提高数据,以一个客户端的方式为用户提供各种舆情信息。有望在未来实现整个系统的功能。
参考文献
[1]唐勇. 互联网舆情监控系统的设计与实现[D].北京邮电大学,2013.
[2]殷风景. 面向网络舆情监控的热点话题发现技术研究[D].国防科学技术大学,2010.
[3]黄美璇. 基于聚类分析的网络舆情监控系统的设计[J]. 宝鸡文理学院学报(自然科学版),2011,04:40-44.
[4]刘杜杨. 网络舆情监督管理系统的设计与实现[D].电子科技大学,2013.
[5]韩威. 网络舆情热点发现与话题跟踪技术研究[D].哈尔滨工业大学,2012.
[6]许志凯. 网络舆情分析关键技术的研究与实现[D].哈尔滨工业大学,2011
附录
提取中文文本程序:
package pock;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExtractionC {
public static void main(String[] args) throws IOException{
File dir =new File("E:/学习/大三");
Filter filter =new Filter("txt");
File fs1[]=dir.listFiles(filter);
Scanner s=null;
PrintWriter pwrite=null;
int i;
try{
pwrite =new PrintWriter("E:/学习/大三/jieguo.txt");
for(i=0;i<fs1.length;i++){
s=new Scanner(new FileReader(fs1[i]));
while(s.hasNextLine()){
String strLine=s.nextLine();
for (int j = 0; j < strLine.length(); j++) {
String s1 = strLine.charAt(j) + "";
byte[] by = s1.getBytes();
if (by.length == 2) {
System.out.print(s1);
pwrite.print(s1);
}
}
}
System.out.print("\n");
pwrite.println();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}finally{
if(s!=null)
s.close();
if(pwrite!=null)
pwrite.flush();
pwrite.close();
}
}
}
class Filter implements FilenameFilter{
String extent;
Filter (String extent)
{
this.extent=extent;
}
public boolean accept(File dir,String name)
{
return name.endsWith("."+extent);
}
}
中文分词程序:
import java.io.*;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class Testio{
public static void main(String[] args) throws IOException{
File text = new File("D:\\text.txt");
FileWriter f=new FileWriter("D:\\output.txt");
String s = openTextFile(text); //读取文件
//System.out.println(s);
/*中文分词 */
StringReader re = new StringReader(s);
IKSegmenter ik = new IKSegmenter(re,true);
Lexeme lex = null;
while((lex=ik.next())!=null)
{
System.out.print(lex.getLexemeText()+" ");
f.write(lex.getLexemeText()+" ");
}
}
/* 中文分词 */
public static String openTextFile(File source)
{
StringBuffer text = new StringBuffer();
BufferedReader br = null;
try{
br = new BufferedReader(new FileReader(source));
String info = null;
while((info = br.readLine()) != null){
text.append(info+"\n");
}
}catch(FileNotFoundException e){
System.err.println("文件未找到");
}catch(IOException e){
System.err.println("文件读取出错");
}catch(Exception e){
System.err.println(e.getMessage());
}finally{
try{
br.close();
}catch(IOException e){
System.err.println(e.getMessage());
}
}
return text.toString();
}
}
词频统计程序:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
public class Ciping {
public static void main(String args[]) throws IOException {
File f = new File("D:\\text.txt");
String text = openTextFile(f);
/*
String text = "IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目 Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为 面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。\n" +
"\n" +
"IKAnalyzer3.0特性:\n" +
"\n" +
"采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。\n" +
"\n" +
"采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。\n" +
"\n" +
"优化的词典存储,更小的内存占用。支持用户词典扩展定义\n" +
"\n" +
"针对Lucene全文检索优化的查询分析器IKQueryParser(作者吐血推荐);采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。";
*/
int topWordsCount=30;
Map<String,Integer> wordsFrenMaps=getTextDef(text);
sortSegmentResult(wordsFrenMaps,topWordsCount);
}
//读取文件//
public static String openTextFile(File source){
StringBuffer text = new StringBuffer();
BufferedReader br = null;
try{
br = new BufferedReader(new FileReader(source));
String info = null;
while((info = br.readLine()) != null){
text.append(info+"\n");
}
}catch(FileNotFoundException e){
System.err.println("文件未找到");
}catch(IOException e){
System.err.println("文件读取出错");
}catch(Exception e){
System.err.println(e.getMessage());
}finally{
try{
br.close();
}catch(IOException e){
System.err.println(e.getMessage());
}
}
return text.toString();
}
private static void sortSegmentResult(Map<String, Integer> wordsFrenMaps,
int topWordsCount) {
// TODO 自动生成的方法存根
System.out.println("排序前:================");
Iterator<Map.Entry<String,Integer>> wordsFrenMapsIterator=wordsFrenMaps.entrySet().iterator();
while (wordsFrenMapsIterator.hasNext()){
Map.Entry<String,Integer> wordsFrenEntry=wordsFrenMapsIterator.next();
System.out.println(wordsFrenEntry.getKey()+" 的次数为"+wordsFrenEntry.getValue());
}
List<Map.Entry<String, Integer>> wordFrenList = new ArrayList<Map.Entry<String, Integer>>(wordsFrenMaps.entrySet());
Collections.sort(wordFrenList, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> obj1, Map.Entry<String, Integer> obj2) {
return obj2.getValue() - obj1.getValue();
}
});
System.out.println("排序后:================");
for(int i=0;i<topWordsCount&&i<wordFrenList.size();i++){
Map.Entry<String,Integer> wordFrenEntry=wordFrenList.get(i);
if(wordFrenEntry.getValue()>1){
System.out.println(wordFrenEntry.getKey()+" 的次数为"+wordFrenEntry.getValue());
}
}
}
private static Map<String, Integer> getTextDef(String text) throws IOException {
// TODO 自动生成的方法存根
Map<String, Integer> wordsFren=new HashMap<String, Integer>();
IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(text), true);
Lexeme lexeme;
while ((lexeme = ikSegmenter.next()) != null) {
if(lexeme.getLexemeText().length()>1){
if(wordsFren.containsKey(lexeme.getLexemeText())){
wordsFren.put(lexeme.getLexemeText(),wordsFren.get(lexeme.getLexemeText())+1);
}else {
wordsFren.put(lexeme.getLexemeText(),1);
}
}
}
return wordsFren;
}
}
无意义词语去除程序:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class KeyWordFilter
{
private static Pattern pattern = null;
// 从words.properties初始化正则表达式字符串
private static void initPattern()
{
StringBuffer patternBuf = new StringBuffer("");
try{
InputStream in = KeyWordFilter.class.getClassLoader().getResourceAsStream("words.properties");
Properties pro = new Properties();
pro.load(in);
Enumeration enu = pro.propertyNames();
patternBuf.append("(");
while(enu.hasMoreElements()){
patternBuf.append((String)enu.nextElement()+"|");
}
patternBuf.deleteCharAt(patternBuf.length()-1);
patternBuf.append(")");
pattern = Ppile(new String(patternBuf.toString().getBytes("ISO-8859-1"), "gb2312"));
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
}
private static String doFilter(String str){
Matcher m = pattern.matcher(str);
str = m.replaceAll("");
return str;
}
public static void main(String[] args)throws IOException
{
// String str = "国敏感词一院学位办就敏感词三的报道表示敏感词二";
File text = new File("D:\\input.txt");
String str = openTextFile(text);
FileWriter f =new FileWriter("D:\\out.txt");
System.out.println("str:"+str);
initPattern();
Date d1 = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss:SSS Z");
System.out.println("start:"+formatter.format(d1));
System.out.println("共"+str.length()+"个字符 " + KeyWordFilter.doFilter(str));
//f.write("febdfgb");
Date d2 = new Date();
System.out.println("end:"+formatter.format(d2));
}
private static String openTextFile(File source) {
StringBuffer text1 = new StringBuffer();
BufferedReader br = null;
try{
br = new BufferedReader(new FileReader(source));
String info = null;
while((info = br.readLine()) != null){
text1.append(info+"\n");
}
}catch
展开阅读全文