问题描述:

在一段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的更多相关文章

  1. 记一个逻辑bug

    1     从数据库中找出一个学生能选的毕业设计(毕设的select or not 字段表示本题目是否已经被选 此时就按照其值为n来查询) 2     用户选择某个毕设后,先更新毕设表(select ...

  2. Spark(二)算子详解

    目录 Spark(二)算子讲解 一.wordcountcount 二.编程模型 三.RDD数据集和算子的使用 Spark(二)算子讲解 @ 一.wordcountcount 基于上次的wordcoun ...

  3. Spark MLlib 之 StringIndexer、IndexToString使用说明以及源码剖析

    最近在用Spark MLlib进行特征处理时,对于StringIndexer和IndexToString遇到了点问题,查阅官方文档也没有解决疑惑.无奈之下翻看源码才明白其中一二...这就给大家娓娓道来 ...

  4. 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  5. [OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    http://blog.csdn.net/poem_qianmo/article/details/25560901 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  6. 边缘检测:Canny算子,Sobel算子,Laplace算子

    1.canny算子 Canny边缘检测算子是John F.Canny于 1986 年开发出来的一个多级边缘检测算法.更为重要的是 Canny 创立了边缘检测计算理论(Computational the ...

  7. spark 2.3 导致driver OOM的一个SparkPlanGraphWrapper源码的bug

    背景 长话短说,我们部门一个同事找到我,说他的spark 2.3 structured streaming程序频繁报OOM,从来没有坚持过超过三四天的,叫帮看一下. 这种事情一般我是不愿意看的,因为大 ...

  8. Sobel算子 Scharr算子 Laplacian算子

    图像梯度处理 Sobel算子 水平方向: 对于线条A和线条B,右侧像素值与左侧像素值的差值不为零,因此是边界 上下像素值差值为0,左右素值的差值不为零,分布为正负, 离的近的为2,离的远的为1 P5= ...

  9. 客户的一个紧急bug,我用了两种方式进行 C# 反编译修改源码

    一:背景 1. 讲故事 周五下午运营反馈了一个紧急bug,说客户那边一个信息列表打不开,急需解决,附带的日志文件也发过来了,看了下日志大概是这样的: 日期:2020-11-13 12:25:45,92 ...

随机推荐

  1. 实验十四 团队项目评审&个人学习总结

    实验十四 课程学习总结 项目 内容 这个作业属于哪个课程 (https://www.cnblogs.com/nwnu-daizh/) 这个作业的要求在哪里 (https://www.cnblogs.c ...

  2. nginx 搭建上传服务器

    nginx webdav 服务器搭建 该模块可以为Http webDAV 增加PUT,DELETE,MKCOL,COPY和MOVE等方法.模块在默认编译的情况下是不被包含的,需要指定编译 ./conf ...

  3. mybatis框架-resultMap的自动映射级别-partial 和full的探讨

    现在我们做一个小实验,输出一下上一个案例中没有匹配的属性,注意哦,现在user类中是有内部嵌套的复杂数据类型的 运行结果: 注意到:现在居然连userPassword都打印不出来了,原因就是user类 ...

  4. Linux中关于samba的几个问题

    一.用smbclient命令登录成功但看不了文件 原因:SELinux的阻挡 解决:1.关闭SELinux  :  setenforce 0   (临时生效,重启后失效) 或vi /etc/sysco ...

  5. BST | 1043 BST树与镜像BST树的判断

    较为简单.小于大于的都走一遍就可以AC了 #include <stdio.h> #include <memory.h> #include <math.h> #inc ...

  6. hdu5111 树链剖分,主席树

    hdu5111 链接 hdu 思路 先考虑序列上如何解决. 1 3 2 5 4 1 2 4 5 3 这个序列变成 1 2 3 4 5 1 3 5 5 2 是对答案没有影响的(显然). 然后查询操作\( ...

  7. 【字符串】【P5830】 【模板】失配树

    [字符串][P5830] [模板]失配树 Description 给定一个长度为 \(n\) 的字符串 \(S\),有 \(m\) 次询问,每次询问给定 \(S\) 的两个前缀,求它们的最长公共 bo ...

  8. Spring Boot 知识笔记(创建maven项目、HTTP接口)

    一.使用Maven手工创建SpringBoot应用(IDEA) 1.  点击File——New——Project——Maven——Next,填写相关信息,创建项目. 2.  在pom.xml中添加相关 ...

  9. git: hook 修改提交信息

    git获取数字顺序版本号 因为git的版本使用的是hash值,不能很直观的看出那个版本,所以想找到一种方法,获取顺序的版本号,在网上找到了方法,可以获取顺序版本号 摘自:[使用bash从SVN和Git ...

  10. 搭建Hadoop+Python的大数据开发环境

    实验环境 CentOS镜像为CentOS-7-x86_64-Everything-1804.iso 虚机配置 节点名称 IP地址 子网掩码 CPU/内存 磁盘 安装方式 master 192.168. ...