Spark机器学习算法实操——LinearRegression

本文详细介绍了如何使用Spark与Hive进行通信,从Hive获取数据并进行预处理,构建LinearRegression线性回归模型,以及将预测结果写回HDFS。配置Spark与Hive通信涉及复制hive-site.xml到Spark目录,并添加JDBC连接器。数据获取使用Spark.sql,转换为libsvm格式。模型构建参照Spark.ml官方文档,预测结果通过追加方式写回HDFS。

任务要求如下:

  • 实现Spark和HIVE与HDFS之间的通信
  • 利用Spark.sql从HIVE中获取数据,并进行预处理以符合Spark机器学习库中输入文件的libsvm格式
  • LinearRegression线性回归模型建模
  • 将得到的预测结果写回HDFS

现在明确了我们的任务目标,就从头开始进行。

配置Spark和Hive之间的通信

Spark内部可以直接让SparkContext从hdfs上获取数据(保证和集群具有相同的网络环境)。

//举例
//创建sparkConf对象,设置spark应用的配置信息
        SparkConf conf = new SparkConf()
                .setAppName("WordCount")
                .setMaster("local");  //spark应用程序要连接的spark集群的master节点的url,local代表的是本地运行
        //.setMaster("spark://ip:port");

        //创建JavaSparkContext对象
        JavaSparkContext sc = new JavaSparkContext(conf);

        //针对输入源(hdfs文件、本地文件等)创建一个初始的RDD
        JavaRDD<String> lines = sc.textFile("hfs://master:9000/wordcount.txt");

在Spark1.6开始之后增加了DataSet数据类型,我们注意到通过SparkContext获得的数据为RDD类型,而通过SparkSession获得的数据为DataSet数据类型。

val sparkSession = SparkSession.builder.
      master("local")
      .appName("example")
      .getOrCreate()
val data = sparkSession.read.text("hdfs://master:9000/wordcount.txt").as[String]

这里的data是DataSet类型的,如果要转化为java可操作的数据类型List或者Array,之后会介绍。因此对于Spark通信hdfs不需要在配置上花费时间。

只需要实现Spark到Hive之间的通信,需要将Hive/conf目录下的hive-site.xml配置文件复制到Spark/Conf目录下(这里假设Hive已经配置好,能和hdfs交互,这里不赘述);同时还要将JDBC连接器copy到Spark/jars下面,例如mysql-connector-5.4.7.jar类似的,如果连接器版本过高要下载更低版本的。如果出现其他问题,就在Google吧。

Spark从Hive中获取数据

这里直接粘一下我的项目代码

SparkConf conf = new SparkConf().setAppName("sterilizedmilk").setMaster("local");;
        SparkSession spark = SparkSession
                .builder()
                .appName("sterilizedmilk")
                .config(conf)
                .enableHiveSupport()  //支持hive
                .getOrCreate();
        String querySql = "SELECT * FROM myth.sterilizedmilk";
        Dataset<Row> data = spark.sql(querySql);
        data_sterilizedmilk = data.collectAsList();

之前说过Spark封装了自己的sql函数,跟其他的sql语法一样,只需要写成字符串执行就可。查询到的结果为DataSet<Row>类型的数据,这个类型自带了两个函数:

  1. collect():可以将数据类型返回Array格式
  2. collectAsList():将数据类型返回List格式

获得的结果可以直接java遍历操作。下面就需要将数据以Spark.ml算法官方文档中使用的文件结构存储。libsvm格式如下:

Label1 para1:value1 para2:value1
Label2 para1:value2 para2:value2

这里就不沾代码了,直接按照格式写入文件就成。

构建LinearRegression模型

这部分没什么好说的,直接去看官方文档给的示例吧!很清楚也很简洁Spark.ml传送门

将预测结果写会HDFS

我这里选择的是追加的方式直接将结果写回hdfs上,也可以保存在服务器本地,再上传至hdfs(个人觉得麻烦)。

public static void write_prediction_hdfs(List<Row> prediction, String path) throws Exception{

        //获取precition数据
        int interval = (int)(data_regression.size() * 0.9);

        for(int i = interval; i < data_regression.size(); i++){
            ArrayList<Float> temp = data_regression.get(i);
            temp.add(Float.parseFloat(prediction.get(i-interval).get(2).toString()));
            data_prediction.add(temp);
        }
        //将prediction数据写入hdfs中
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS","hdfs://master:9000");
        FileSystem fs = FileSystem.get(conf);
        FSDataOutputStream out = fs.create(new Path(path));
        //写出
        for(int i = 0; i < data_prediction.size(); i++) {
            String re = "";
            for(int j = 0;j<data_prediction.get(i).size();j++) {
                if(j == data_prediction.get(i).size()-1){
                    re = re + data_prediction.get(i).get(j).toString() + "\n";
                }
                else{
                    re = re + data_prediction.get(i).get(j).toString() + " ";
                }
            }
            out.write(re.getBytes("UTF-8"));
        }
        out.close();
    }

可以看到通过追加的方式写hdfs,就需要配置项,也就是Configuration,这个是hadoop.conf包下的Configuration,通过这个来链接hdfs,传入的path就是hdfs下的目录,文件将要写入的位置。for循环里面的都是我为了数据格式好看一些做的一些操作,嫌麻烦可以直接把数据每行toString()之后就写。

 

项目的完整代码已经提交到Github上,需要自取:传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值