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 ...
随机推荐
- 利用pandas映射替换两个字典中的映射值
在公司处理报表,中英文映射表与数值表替换 import pandas as pd data = { "a":"值一", "b":" ...
- Linux下bash的一些总结
关于"交互式-非交互式"与"登录-非登陆"shell的总结 关于".bash_profile"和".bashrc"区别的 ...
- 201871010135-张玉晶《面向对象程序设计(Java)》第四周学习总结
201871010135-张玉晶<面向对象程序设计(Java)>第四周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...
- logging.basicConfig配置文件
import sys, logging logging.basicConfig(level=logging.INFO, # 日志等级 # filename: 指定日志文件名 format='level ...
- 第二阶段冲刺(个人)——seven
今天的计划:设计总的界面背景,统一风格. 昨天做了什么?优化登录.注册信息的填写判断.
- 使用emplace操作
C++ 11新标准中引入了三个新成员——emplace_front.emplace和emplace_back,这些操作构造而不是拷贝元素.这些操作分别对应push_front.insert和push_ ...
- 图的遍历 | 1076 bfs
bfs踩了很多坑才写完.注意:出队时不做是否vis判断,但是要加上vis[出队顶点]=1 .入队时进行判断,并且也要 vis[入队顶点]=1 #include <stdio.h> #inc ...
- 【CSP-S膜你考】不怕噩梦 (模拟)
不怕噩梦 题面 蚊子最近经常做噩梦,然后就会被吓醒.这可不好.. 疯子一直在发愁,然后突然有一天,他发现蚊子其实就是害怕某些事. 如果那些事出现在她的梦里,就会害怕. 我们可以假定那个害怕的事其实是一 ...
- ftp 服务的部署
前言FTP 是File Transfer Protocol(文件传输协议), 用户通过一个支持FTP协议的客户机程序,连接到在远程主机上的FTP服务器程序.用户通过客户机程序向服务器程序发出命令,服务 ...
- Windows彻底卸载VMWare虚拟机详细步骤
不能卸载vmware ,原因是VMware的服务在运行中,停止服务就可以卸载了. 点击开始输入[services.msc],然后点击搜索到服务. 找到这个软件的图一的所有项,然后右键它属性. 全部设置 ...