在使用Pipeline串联多个stage时model和非model的区别

train.csv数据:

id,name,age,sex
1,lyy,20,F
2,rdd,20,M
3,nyc,18,M
4,mzy,10,M

数据读取:

 1 SparkSession  spark = SparkSession.builder().enableHiveSupport()
 2                     .getOrCreate();
 3         Dataset<Row> dataset = spark
 4                 .read()
 5                 .format("org.apache.spark.sql.execution.datasources.csv.CSVFileFormat")
 6                 .option("header", true)
 7                 .option("inferSchema", true)
 8                 .option("delimiter", ",")
 9                 //.load("file:///E:/git/bigdata_sparkIDE/spark-ide/workspace/test/SparkMLTest/SanFranciscoCrime/document/kaggle-旧金山犯罪分类/train-new.csv") //PreProcess1
10                 .load("file:///E:/git/bigdata_sparkIDE/spark-ide/workspace/test/SparkMLTest/DataPreprocessing/document/train.csv") //PreProcess2
11                 .persist();
 1     public static void PreProcess2(Dataset<Row> data) {
 2
 3                 data.printSchema();
 4                 // 重新索引标签值
 5                 StringIndexerModel labelIndexer = new StringIndexer()
 6                 .setInputCol("sex")
 7                 .setOutputCol("label")
 8                 .fit(data);
 9
10                 StringIndexerModel nameIndexer = new StringIndexer()
11                 .setInputCol("name")
12                 .setOutputCol("namenum")
13                 .fit(data);
14
15
16                 /*  会报错:Exception in thread "main" java.lang.IllegalArgumentException: Field "namenum" does not exist.
17                  * 原因是:Model类型调用fit时,要求数据集中必须包含InputCol所指定的列名
18                  * 不会将Pipeline某个stage的输出作为InputCol,即使那个stage的OutputCol指定的列名与其相同也不行
19                  * StringIndexerModel name1Indexer = new StringIndexer()
20                 .setInputCol("namenum")
21                 .setOutputCol("namenum1")
22                 .fit(data);*/
23
24
25                 /* 错误原因StringIndexerModel错误一样,features并不是data的列
26                  * VectorIndexerModel featureIndexer = new VectorIndexer()
27                     .setInputCol("features")
28                     .setOutputCol("indexfeatures")
29                     .setMaxCategories(4)
30                     .fit(data);*/
31
32                 //成功
33                 //原因说明:非model时,转换器不会调用fit,而会使用Pipeline某个stage的输出作为InputCol
34                 //由于stage[2]即 assembler已经生成features,故而该处直接使用;
35                 //但是该类型时不能单独使用,必须依赖Pipeline
36                 VectorIndexer featureIndexer = new VectorIndexer()
37                 .setInputCol("features")
38                 .setOutputCol("indexfeatures")
39                 .setMaxCategories(4);
40
41                 //由上述分析可知,该处输入的列可以是多个stage的输出组成,因为VectorAssembler非model
42                 //因此可以使用中间生成结果,且可以使用多个
43                 VectorAssembler assembler = new VectorAssembler()
44                 .setInputCols("id,namenum,age".split(","))
45                .setOutputCol("features");
46
47                 //这里的stage的顺序很重要,一定按照依赖关系顺序放入,如下顺序就会报错:
48                 //Exception in thread "main" java.lang.IllegalArgumentException: Field "features" does not exist.
49                 //Pipeline pipeline = new Pipeline().setStages(new PipelineStage[] {labelIndexer,nameIndexer,featureIndexer,assembler});
50
51                 //将featureIndexer放到assembler即可
52                 Pipeline pipeline = new Pipeline().setStages(new PipelineStage[] {labelIndexer,nameIndexer,assembler,featureIndexer});
53
54                 // Train model. This also runs the indexers.
55                 PipelineModel model = pipeline.fit(data);
56
57                 // Make predictions.
58                 Dataset<Row> result = model.transform(data);
59
60                 result.show(10, false);
61
62     }

root
|-- id: integer (nullable = true)
|-- name: string (nullable = true)
|-- age: integer (nullable = true)
|-- sex: string (nullable = true)

+---+----+---+---+-----+-------+--------------+-------------+
|id |name|age|sex|label|namenum|features |indexfeatures|
+---+----+---+---+-----+-------+--------------+-------------+
|1 |lyy |20 |F |1.0 |1.0 |[1.0,1.0,20.0]|[0.0,1.0,2.0]|
|2 |rdd |20 |M |0.0 |2.0 |[2.0,2.0,20.0]|[1.0,2.0,2.0]|
|3 |nyc |18 |M |0.0 |0.0 |[3.0,0.0,18.0]|[2.0,0.0,1.0]|
|4 |mzy |10 |M |0.0 |3.0 |[4.0,3.0,10.0]|[3.0,3.0,0.0]|
+---+----+---+---+-----+-------+--------------+-------------+

综上分析,可以将原有代码做一简化:

 1 public static void PreProcess2(Dataset<Row> data) {
 2
 3                 data.printSchema();
 4                 // 重新索引标签值
 5                 StringIndexer labelIndexer = new StringIndexer()
 6                 .setInputCol("sex")
 7                 .setOutputCol("label");
 8
 9                 StringIndexer nameIndexer = new StringIndexer()
10                 .setInputCol("name")
11                 .setOutputCol("namenum");
12
13                 VectorIndexer featureIndexer = new VectorIndexer()
14                 .setInputCol("features")
15                 .setOutputCol("indexfeatures")
16                 .setMaxCategories(4);
17
18
19                 VectorAssembler assembler = new VectorAssembler()
20                 .setInputCols("id,namenum,age".split(","))
21                .setOutputCol("features");
22
23                 Pipeline pipeline = new Pipeline().setStages(new PipelineStage[] {labelIndexer,nameIndexer,assembler,featureIndexer});
24
25                 // Train model. This also runs the indexers.
26                 PipelineModel model = pipeline.fit(data);  //以这里的data为基准数据
27
28                 // Make predictions.
29                 Dataset<Row> result = model.transform(data);
30
31                 result.show(10, false);
32
33     }

运行结果:

root
 |-- id: integer (nullable = true)
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)
 |-- sex: string (nullable = true)

+---+----+---+---+-----+-------+--------------+-------------+
|id |name|age|sex|label|namenum|features      |indexfeatures|
+---+----+---+---+-----+-------+--------------+-------------+
|1  |lyy |20 |F  |1.0  |1.0    |[1.0,1.0,20.0]|[0.0,1.0,2.0]|
|2  |rdd |20 |M  |0.0  |2.0    |[2.0,2.0,20.0]|[1.0,2.0,2.0]|
|3  |nyc |18 |M  |0.0  |0.0    |[3.0,0.0,18.0]|[2.0,0.0,1.0]|
|4  |mzy |10 |M  |0.0  |3.0    |[4.0,3.0,10.0]|[3.0,3.0,0.0]|
+---+----+---+---+-----+-------+--------------+-------------+

原文地址:https://www.cnblogs.com/lyy-blog/p/9523026.html

时间: 2024-10-18 20:08:57

在使用Pipeline串联多个stage时model和非model的区别的相关文章

Android程序运行时权限与文件系统权限的区别

apk程序是运行在虚拟机上的,对应的是Android独特的权限机制,只有体现到文件系统上时才使用linux的权限设置. (1)Android中的apk必须签名 (2)基于UserID的进程级别的安全机制  (3)默认apk生成的数据对外是不可见的  (4)AndroidManifest.xml中的显式权限声明  Android程序运行时权限与文件系统权限的区别

Java运行时异常和非运行时异常

1.Java异常机制 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类.Java中的异常分为两大类:错误Error和异常Exception,Java异常体系结构如下图所示: 图片来源:http://blog.csdn.net/wuwenxiang91322/article/details/10346337 2.Throwable Throwable类是所有异常或错误的超类,它有两个子类:Error和Exception,分别表示错误和异常.其中异

3星|《工作生活双全法则》:我们很容易掉入注重工作时长而非成果的陷阱

工作生活双全法则(<哈佛商业评论>增刊) 工作生活双全法则(<哈佛商业评论>增刊) <哈佛商业评论>讲兼顾工作与生活的3篇文章.总体来说,这在全世界都是个难题.作者的调查和统计结果表明,有些时候工作的压力来自于公司对工作时长的关注超过了对工作成果的关注. 以下是书中一些内容的摘抄: 1:上述两位作者基于对全球4000名高管的访谈,发现成功的高管往往能巧妙地将工作和家庭融合在一起,这样他们就在取得职业成就的同时,保持了与家庭成员的和谐关系.#16 2:最后一点是高管的普遍

[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

原文:[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 周银辉 现象: 大家可以试试下面这个很有趣但会带来Defect的现象:当我们将子窗口按照ShowDialog()的方式显示出来的时候,很明显该窗口是模式化的(即主窗口等待该窗口的返回,主窗口将不相应用户输入),但如果此时将子窗口的Visibility设置成Visibility.Hidden来隐藏窗口,然后再将Visibility设置成Visibility.Visible来

填充路径时使用的非零环绕规则

如果当前路径是循环的,或者包含多个相交的子路径,那么Canvas的绘图环境变量就必须判断,当fill()方法被调用时,应该如何对当前路径进行填充. Canvas在填充互相有交叉的路径时,使用非零环绕规则 非零环绕 对于路径中的任意给定区域,从该区域内部画一条足够长的线段,使此线段的终点完全落在路径范围之外. 接下来将计数器初始化为0,然后,每当这条线段与路径上的直线或曲线相交时,就改变计算器的值.如果是与路径的顺时针部分相交,则加1,如果与路径的逆时针相交,则减1. 若计算器的最终值不是0,那么

QTcpSocket通信编程时阻塞与非阻塞的问题

目标,qt程序作为客户端,windows下winsock作为服务器端,实现两端通信. 开始时写了一个小函数测试: [cpp] view plaincopy QTcpSocket tmpSock;  tcpSock.connectToHost("59.64.159.87",7716);  tcpSock.write(buf,strlen(buf)+1);  msleep(3000);  tcpSock.disconnect(); 测试结果发现客户端只能连接到服务器端,而服务器端收不到客户

C++包含头文件时尖括号和双引号区别

原文链接:http://c.biancheng.net/cpp/biancheng/view/66.html 如果你还看一些别的C++教程,那么你可能很早就发现了,有些书上的#include命令写作#include <文件名>,但有时候又会出现#include "文件名".你会很疑惑,到底哪个是对的呢?为什么要有这两种不同的写法呢? 这两种写法都是正确的写法,但是它们却是有区别的.我们知道C++已经有一些编写好的头文件(比如标准函数库等等),它们存放在VC++的Includ

js调用函数时括号加与不加的区别,function()&amp;function

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>当前系统时间</title> <link rel="stylesheet" href="style.css" /> <scri

运行时异常和非运行时异常

RunntimeException的子类: ClassCastException 多态中,可以使用Instanceof 判断,进行规避 ArithmeticException 进行if判断,如果除数为0,进行return NullPointerException 进行if判断,是否为null ArrayIndexOutOfBoundsException 使用数组length属性,避免越界 这些异常时可以通过程序员的良好编程习惯进行避免的 1:遇到运行时异常无需进行处理,直接找到出现问题的代码,进