《hadoop进阶》基于hadoop和hive的微博热词跟踪系统


打开微信扫一扫,关注微信公众号【数据与算法联盟】

转载请注明出处:http://blog.csdn.net/gamer_gyt 
博主微博:http://weibo.com/234654758 
Github:https://github.com/thinkgamer

代码下载地址:点击查看

--------------------------------------------------------------------------------------------------------------------------------------------------

写在前边的话

          这篇文章应该是有史以来写的时间最长的一篇文章,我记得是今年暑假之前开始的,后来因为种种原因吧(找工作,开始工作,电脑重装,换工作等等),导致现在才写完,算是一篇迟到了二个月的文章,实在是不好意思,曾经也想过不写了,但是后来还是坚持了下来,只想分享给大家

        整片博客分为这几个部分 :       

                 1:微博热词跟踪系统概述

                 2:需求分析

                 3:算法模型

                 4:架构设计

                 5:程序实现

                 6:结果可视化

        另外需要注意的是本文所有数据均为测试数据,只是为了验证代码的可用性和整个流程是否能够走通

一:微博热词跟踪系统概述

   

            微博是当今社会消息传播的主要途径,汇集了社会各层人士,能充分代表人们的呼声和社会发展的趋势,其具备了新闻的时效性和广泛性,那么对于微博内容,传播的分析在一定程度上能得到更大价值,比如看些图展示的是“老九门”这个此最近一个月出现的频率,即hot程度

          那么接下来我们将要实现的就是类似于上图这样的一个功能


二:需求分析

          现假设我们的数据源是这样的,一天的微博信息在一个文件夹下,每个小时内的微博内容在一个文件内,如图:

           最终我们要得到的数据要存入Hive数据库,处于方便我们这里选用分区表,以天和小时作为分区依据,表每行有四个字段,分别是day,hour,word,num(时间点精确到小时),类似于以下的,非真实数据(最后一列为分区字段):

                          

           表的 描述如下:

                          


三:算法模型

          采用的是hadoop作为计算模型,计算结果保存在hive数据库中,中间所有的任务作为串行流在mainJob中执行。

          当运行代码的时候,会提示输入你想查看的关键词走势:eg,佳能

                         

          然后运行程序,显示出折线图


四:架构设计

          整个代码函数的目录为:

                          

         mainJob作为主函数,首先调用JobWorker作为计算,在JobWorker中会调用hdfsGYT(这是我封装的一个java操作hdfs的库,感兴趣的朋友可以看下之前关于他的文章:点击阅读),然后调用inHive函数将计算结果保存在hive中,最后调用lineCharts从hive数据仓库中读取数据,画出折线图

          PS:读到这里,许多朋友可能会想,你这样做岂不是太麻烦了,完全可以直接将计算结果传给LineCharts进行可视化,加了一个inHive岂不是多此一举,的确是那样,但是换一个角度想,本篇博客只是为了学习,搞明白这样的一个流程,而并不是这些代码就可以用在真实的生产环境中,所以,当我们抱着学习的态度去理解整个代码,我们对整个项目便有了清楚的了解。


五:程序实现

1:hadoop词频统计和过滤实现

        main函数:更多代码点击github地址

package org.apache.mr.hotword;

/**
 * Created by thinkgamer on 16-9-22.
 */
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

public class mainJob {

    public static final String  HDFS = "hdfs://127.0.0.1:9000";
    // public static final Pattern DELIMITER = Pattern.compile("[\t,]");

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException, URISyntaxException {
        // TODO Auto-generated constructor stub
        Map<String,String>  path = new HashMap<String,String>();   //创建一个Map对象
        path.put("input", HDFS+"/file/weibo");
        path.put("output", HDFS+"/file/weibo/output");

        JobWorker.run(path); //针对输入的key_word进行统计
        inHive.run(path);     //调用inHive的run方法,将运行的结果写入hive表
        LineCharts.run();     //将计算的结果以折线的形式画出
    }
}


2:创建hive表,并将数据导入

       创建表语句:

create table hot_world_table(
     time int,
     word string,
     num int)
comment 'this hot words table'
Partitioned by (day string, hour string)
row format delimited fields terminated by "\t";

       将数据导入数据库

#从本地加载
load data local inpath "/home/thinkgamer/桌面/20160221-r-00000" into table hot_word_table partition(timeday='20160221');
#从hdfs加载
load data inpath "/mr/hot_word/output/20160221-r-00000" into table hot_word_table partition(timeday="20160221")


六:结果可视化

           可视化部分有LineCharts控制,主要利用的是java的jfreechart进行画图

package org.apache.mr.hotword;
/**
 * Created by thinkgamer on 16-9-22.
 */
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import java.util.Map;
import java.util.TreeMap;
public class LineCharts extends ApplicationFrame {
    public LineCharts(String s) {
        super(s);
        setContentPane(createDemoLine());
    }
    public static void run() {
        LineCharts fjc = new LineCharts("热词走势图");
        fjc.pack();
        RefineryUtilities.centerFrameOnScreen(fjc);
        fjc.setVisible(true);
    }
    // 生成显示图表的面板
    public static JPanel createDemoLine() {
        JFreeChart jfreechart = createChart(createDataset());
        return new ChartPanel(jfreechart);
    }
    // 生成图表主对象JFreeChart
    public static JFreeChart createChart(DefaultCategoryDataset linedataset) {
        //定义图表对象
        JFreeChart chart = ChartFactory.createLineChart("热词走势图", // chart title
                "时间", // domain axis label
                "数量", // range axis label
                linedataset, // data
                PlotOrientation.VERTICAL, // orientation
                true, // include legend
                true, // tooltips
                false // urls
        );
        CategoryPlot plot = chart.getCategoryPlot();
        // customise the range axis...
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setAutoRangeIncludesZero(true);
        rangeAxis.setUpperMargin(0.20);
        rangeAxis.setLabelAngle(Math.PI / 2.0);
        return chart;
    }
    //生成数据
    public static DefaultCategoryDataset createDataset() {
        //从Hive中读取数据
        Map<String, String> map = new TreeMap<String, String>();
        map = inHive.getResult();
        for(int i=1;i<13;i++){
            if(map.get(Integer.toString(i))==null){
                map.put(Integer.toString(i),"0");
            }
        }

        DefaultCategoryDataset linedataset = new DefaultCategoryDataset();
        //  各曲线名称
        String series1 = "热词";
        //    横轴名称(列名称)

        String type1 = "1:00";
        String type2 = "2:00";
        String type3 = "3:00";
        String type4 = "4:00";
        String type5 = "5:00";
        String type6 = "6:00";
        String type7 = "7:00";
        String type8 = "8:00";
        String type9 = "9:00";
        String type10 = "10:00";
        String type11 = "11:00";
        String type12 = "12:00";
        linedataset.addValue(Integer.parseInt(map.get("1")), series1, type1);
        linedataset.addValue(Integer.parseInt(map.get("2")), series1, type2);
        linedataset.addValue(Integer.parseInt(map.get("3")), series1, type3);
        linedataset.addValue(Integer.parseInt(map.get("4")), series1, type4);
        linedataset.addValue(Integer.parseInt(map.get("5")), series1, type5);
        linedataset.addValue(Integer.parseInt(map.get("6")), series1, type6);
        linedataset.addValue(Integer.parseInt(map.get("7")), series1, type7);
        linedataset.addValue(Integer.parseInt(map.get("8")), series1, type8);
        linedataset.addValue(Integer.parseInt(map.get("9")), series1, type9);
        linedataset.addValue(Integer.parseInt(map.get("10")), series1, type10);
        linedataset.addValue(Integer.parseInt(map.get("11")), series1, type11);
        linedataset.addValue(Integer.parseInt(map.get("12")), series1, type12);
        return linedataset;
    }
}

      结果是这样的:


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值