spark过滤算子+StringIndexer算子出发的一个逻辑bug
问题描述:
在一段spark机器学习的程序中,同时用到了Filter算子和StringIndexer算子,其中StringIndexer在前,filter在后,并且filter是对stringindexer的输出列设置了过滤条件,filter算子之后将数据集灌到随机森林中(试过决策树分类和逻辑回归同样都会触发bug,与filter后面具体是什么算子没有关系),然后再运行的时候报了一个错,错误的原因是源数据中出现了stringindexer模型中没有的标签值。用过stringindexer这个算子的人应该了解,这个算子其实就是把输入数据集中的某一列(一般是离散值)进行编码,按照值出现的次数降序排序存放到一个数组中,然后每种标签值就被映射为它在数组中对应的下标值,这样讲离散的字符串变量转换为double类型的值,方便后面灌入到机器学习算法中进行处理。回到我之前说的报的错误:源数据中出现了stringindexer模型中没有的标签值。这个就很费解,因为stringindexer是根据输入数据进行训练得到的模型,然后我现在用同样的一份数据通过stringindexer训练的模型再进行转换却出现了问题!!
这个问题我想了很久,最后发现跟spark-sql中的基于规则的优化(RBO)有关,具体的说跟PredictionPushdown(过滤条件下推)有关。回到spark程序中,我开始仔细分析整个数据处理流程。stringindexer的输入数据集其实是通过两个数据集进行内等连接得到的,我们知道内等连接其实是能够对数据起到过滤效果的。
另一方面,filter算子由于PredictionPushdown的优化,在实际进行物理计算的时候并不是在stringindexer转换之后执行的,而是被下推到了其中一张表读取的最开始的时候,并且这个下推的过滤条件中是带有一个UDF的,因为在我的程序中,filter算子是对stringindexer输出列设置过滤条件,那么这个输出列再源数据中是不存在的,源数据中只存在stringindexer的输入列,因此实际上下推后的过滤条件是先对这个原始标签列转换为double类型,然后再根据filter中设置的过滤条件判断这个double类型的值,从而实现真正的过滤逻辑。
至此,产生bug的所有条件已经具备,我再把为什么会出现这个错误的原因整个理一下:
原始数据有两张表,对这两张表进行join后的数据输入到stringindexer中,假设其中一张表中有一列标签列rawlabel,他的离散值是'a','b','c','d',但是经过join后只剩下了'a','b','c'三种值,那么这个数据输入到stringindexer进行训练后得到的模型中保存了一个map, map的内容是('a'->0,'b'->1,'c'->2), stringindexer的模型根据这个map对输入的数据进行转换。 那么rawlabel经过stringindexer转换后产生一个新的输出列convertedlabel, 然后filter算子对convertedlabel设置的条件是小于1。ok,至此整个计算逻辑已经完了,但是在实际执行的时候,对于convertedlabel的过滤条件会连着stringindexer模型中的map被整合成一个UDF下推到其中一张表的数据读取阶段,这时候如果读到一条rawlabel的值是'd'的数据,那么输入这个UDF中就会在map中找不到对应的映射,这时候就会报错。
以上就是这个问题的来龙去脉,我们可以避免这个bug,也就是当stringindexer前面有join这样的算子,那么在stringindexer之后不要对stringindexer的输出列设置过滤条件,可以从业务逻辑上考虑把过滤算子提前到stringindexer之前,直接对原始的列设置等价的过滤条件。
spark过滤算子+StringIndexer算子出发的一个逻辑bug的更多相关文章
- 记一个逻辑bug
1 从数据库中找出一个学生能选的毕业设计(毕设的select or not 字段表示本题目是否已经被选 此时就按照其值为n来查询) 2 用户选择某个毕设后,先更新毕设表(select ...
- Spark(二)算子详解
目录 Spark(二)算子讲解 一.wordcountcount 二.编程模型 三.RDD数据集和算子的使用 Spark(二)算子讲解 @ 一.wordcountcount 基于上次的wordcoun ...
- Spark MLlib 之 StringIndexer、IndexToString使用说明以及源码剖析
最近在用Spark MLlib进行特征处理时,对于StringIndexer和IndexToString遇到了点问题,查阅官方文档也没有解决疑惑.无奈之下翻看源码才明白其中一二...这就给大家娓娓道来 ...
- 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...
- [OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
http://blog.csdn.net/poem_qianmo/article/details/25560901 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...
- 边缘检测:Canny算子,Sobel算子,Laplace算子
1.canny算子 Canny边缘检测算子是John F.Canny于 1986 年开发出来的一个多级边缘检测算法.更为重要的是 Canny 创立了边缘检测计算理论(Computational the ...
- spark 2.3 导致driver OOM的一个SparkPlanGraphWrapper源码的bug
背景 长话短说,我们部门一个同事找到我,说他的spark 2.3 structured streaming程序频繁报OOM,从来没有坚持过超过三四天的,叫帮看一下. 这种事情一般我是不愿意看的,因为大 ...
- Sobel算子 Scharr算子 Laplacian算子
图像梯度处理 Sobel算子 水平方向: 对于线条A和线条B,右侧像素值与左侧像素值的差值不为零,因此是边界 上下像素值差值为0,左右素值的差值不为零,分布为正负, 离的近的为2,离的远的为1 P5= ...
- 客户的一个紧急bug,我用了两种方式进行 C# 反编译修改源码
一:背景 1. 讲故事 周五下午运营反馈了一个紧急bug,说客户那边一个信息列表打不开,急需解决,附带的日志文件也发过来了,看了下日志大概是这样的: 日期:2020-11-13 12:25:45,92 ...
随机推荐
- djabgo 中间件
1.中间件是发生在request和response 之间,都会经过中间键, 上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承Middleware ...
- 第03节-BLE协议各层数据格式概述
本篇博客根据韦大仙的视频,整理所得. 对于BLE系统,它分为上下两块.上面那一块,我们称为host主机.下面这一块是controller,你可以简单的认为它就是一个蓝牙芯片. 对于host这一块,它运 ...
- destoon聚合搜索页面模板
最近学习大型站点SEO策略,谈到关于大站需要做聚合页面tags,所以根据destoon系统自己做了一个聚合页面,在此分享给吾爱的朋友,一起学习参考! 模板演示站点:http://zhimo.yuanz ...
- 三星固态Dell版的960g的sm863a硬盘
smart参数 CrystalDiskMark测试 AS SSD 测试 HD Tune Pro测试 DiskGenius查看 总结: 按我的测试,性能比sm865的还好,不知道咋回事,按三星给的参数这 ...
- Maven 中 dependencyManagement 标签使用
1.在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器. 2.pom.xml文件中,jar的版本判断的两种途径 1:如果dependenci ...
- Spring Cloud微服务安全实战_3-4_API安全机制之认证
认证:登录和认证是 两个概念,比如你两周.一个月,可能只登录了一次,但认证却是每次访问都要经过的步骤. 对于图中的认证不成功,也要继续处理,这个我觉得得看业务,比如管理系统,不登录就不让你访问,但对 ...
- 【jupyter】文件解压
Jupyter使用便捷,但是不能上传文件夹.可以将文件夹压缩,上传后再利用python或者terminal进行解压. windows 可以用python的zipfile包来解压.比如: import ...
- C语言中宏的相关知识
2019/04/27 16:02 1.宏的定义:宏定义就是预处理命令的一种,它允许用一个标识符来表示一个字符串.格式如下: #define name(宏名) stuff(字符串) 本质就是使用宏名去替 ...
- Java 并发系列之一:java 并发体系
1. java 并发机制的底层原理实现 1.1 volatile 1.2 synchronized 1.3 原子操作 2. java 内存模型(JMM) 3. java并发基础线程 4. java ...
- 16 个超级实用的 Java 工具类
阅读本文大概需要 4 分钟. 出处:alterem juejin.im/post/5d4a25b351882505c105cc6e 在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用 ...