据对于任何一个企业来说都是非常重要的,为了保证数据 ETL 流程的质量及效率,很多公司都会引入 ETL 工具。目前 ETL 工具有很多,但是针对 ETL 测试的测试工具在业界却比较少见。这是为什么呢?
主要是因为在日常 ETL 测试过程中会遇到很多问题,特别是 Hive SQL 类测试的问题:
(1)测试以手动测试为主,缺少自动化工具;
(2)缺少与数据质量相关的分析工具;
(3)测试中需要重复编写SQL语句,效率较低;
(4)运行SQL语句耗时太长,严重拖慢测试进度;
(5)Shell窗口中的查询结果不易保存,HUE的查询结果易过期且需要手动操作保存;
(6)数据同步场景及ETL场景下,需要对比源表和目标表一致性,缺少对比工具;
(7)实时数据处理场景对数据时效性要求高,测试时场景难以模拟,问题难以复现;
(8)常用测试场景下的用例重复,例如,对拉链表测试、MapReduce脚本的测试缺少通用的测试覆盖用例;
(9)缺少Hive与HBase一致性对比工具。
总的来说,大数据测试存在门槛高、测试效率较低、测试覆盖不全、测试场景不易复现、 测试问题难以定位等问题,今天异步君就给大家介绍一款可以解决上述问题的超好用大数据测试工具——easy_data_test。
easy_data_test
easy_data_test 是用Python编写的,目前它的主要功能有:
(1)支持单表数据量、列空值数据量、列非空值数据量、列最大值、列最小值、列不同值、不同值数据量查询,支持对表结构、任意 select 语句的查询,支持表基本信息查询、值域分析、异常值分析、手机号合规性分析、ID 合规性分析。
(2)支持双表数据量对比、列空值数据量对比、列非空值数据量对比、表结构对比、Hive 双表一致性对比、Hive 与 HBase 一致性对比。
(3)支持查看主备集群及库切换、库表集群信息。
(4)支持实时查看历史执行命令及结果,以 HTML 页面展示全表分析,以 HTML 页面展示值域,以 HTML 页面展示 Hive 双表一致性分析结果。
(5)支持拉链表通用测试(判断拉链表是否断链,判断拉链表日期正确性,对比拉链表与临时表数据量、数值)
easy_data_test功能如此强大,是如何实现的呢?异步君拿到了独家资料,从这个工具的模块设计到技术选型、再到代码实现通通都有,干货满满!下面就让我们来详细看看吧。
模块设计
话不多说,直接上图:
easy_data_test 模块设计
如图所示,用户运行 easy_data_test 工具后,可以通过 ./easy_data_test --help 命令查看所有非交互式命令,使用 stdin.readline() 来获取用户输入的语句。
如果没有指定 -f 或者 -e 就会进入交互式命令行模式。进入交互式模式后,程序通过 raw_input 函数获取用户输入的命令,并根据命令的首个关键字执行对应的函数。函数中封装了一条或多条 SQL 语句,通过 Presto 读取 Hive 元数据,或通过 pyHive 的 Hive 模块连接 Hive。
部分执行结果展示在终端页面,并存储在查询历史命令及结果文件中。部分命令执行完毕后会生成 url,通过浏览器可以查看相应命令的执行结果。
不同的首个关键字对应不同的功能模块,通常每个功能模块包含多个执行函数。
技术选型
业内常用的 Python 连接 Hive 的工具有 Presto、pyHive、impala 及 pyhs2 等。设计人员在经过执行效率及公司现有环境综合比较后,最终选择了 Presto 作为查询主要工具。
Presto 是由 Facebook 公司开发的、一个运行在多台服务器上的分布式查询引擎。本身虽然并不存储数据,但是可以接入多种数据源(Hive、HBase、Oracle、MySQL、Kafka、Redis 等),并且支持跨数据源的级联查询。
Presto 所使用的执行模式与 Hive 有根本的不同,大部分场景下 Presto 比 Hive 快一个数量级。Presto 接受请求后,立即执行,全内存并行计算;Hive 需要用 Yarn 做资源调度,为了接受查询,需要先申请资源,启动进程,并且采用 MapReduce 计算模型,中间结果会保存在磁盘上,所以速度就相对较慢。
使用 easy_data_test 过程中,有时会发现 Presto 存在部分 HiveQL 不兼容问题,例如,show tables like a* 命令无法执行,表结构查询与预期不符,执行切换库操作报错时不抛出异常等。
考虑到 Presto 部分功能缺失带来的问题,于是设计人员选择 pyHive 作为功能弥补工具,在执行特定 SQL 语句时会切换到 pyHive 去连接 Hive 执行。
区别于 Hive,需要格外注意的是,Presto 不支持隐式转换。例如,Hive 会成功执行以下语句:
select count(1) from sample_label where label <> ";
但是使用 Presto 执行就会报告以下错误;
PrestoUserError(type=USER_ERROR, name=SYNTAX_ERROR, message="line 1:83: '<>' cannot be applied to integer, varchar(0)", query_id=20191106_024551_ 01370_8ukjc)
报错原因是,label 列定义的类型为 integer,在使用 Presto 时直接将该列与空字符做比较,Presto 不支持隐式转换。对于该类问题,使用时只需将 label 显式转换为 string 或者 varchar 类型即可解决。
select count(1) from sample_label where cast(label as string) <> ";
从以上内容已经不难看出研发人员的匠心,最后我们直接来看一看 easy_data_test 的模块代码。
模块代码
入口函数如下:
1 def main(options, hostname, port):
2 setup_cqlruleset(options.cqlmodule)
3 setup_cqldocs(options.cqlmodule)
4 # 初始化历史执行命令及结果文件
5 init_history()
6 if options.file is None:
7 stdin = None
8 else:
9 try:
10 encoding, bom_size = get_file_encoding_bomsize(options.file)
11 stdin = codecs.open(options.file, 'r', encoding)
12 stdin.seek(bom_size)
13 except IOError, e:
14 sys.exit("Can't open %r: %s" % (options.file, e))
15
16 try:
17 # 初始化Shell,该类继承自cmd.Cmd
18 shell = Shell(hostname,
19 port,
20 database=options.database,
21 username=options.username,
22 password=options.password,
23 stdin=stdin,
24 tty=options.tty,
25 completekey=options.completekey,
26 single_statement=options.execute,
27 connect_timeout=DEFAULT_CONNECT_TIMEOUT_SECONDS)
28 except KeyboardInterrupt:
29 sys.exit('Connection aborted.')
30 except Exception, e:
31 sys.exit('Connection error: %s' % (e,))
32 if options.debug:
33 shell.debug = True
34
35 # 通过交互式命令循环处理
36 shell.cmdloop()
37 batch_mode = options.file or options.execute
38 if batch_mode and shell.statement_error:
39 sys.exit(2)
40
41
42 if __name__ == '__main__':
43 main(*read_options(sys.argv[1:], os.environ))
通过 Presto 连接 Hive 的代码如下:
1 import prestodb
2 conn=prestodb.dbapi.connect(
3 host= ip,
4 port=8443,
5 user='username',
6 catalog='hive',
7 schema='default',
8 http_scheme='https',
9 auth=prestodb.auth.BasicAuthentication("username", "username的密码"),
10 )
11 conn._http_session.verify = './presto.pem' #身份认证相关文件
12 cur = conn.cursor()
13 cur.execute('SELECT * FROM system.runtime.nodes')
14 rows = cur.fetchall()
15 print rows
为了使用 Hive 查询全表数据量,需要执行 SQL 语句 select count(*) from tablename。使用工具代码封装后,查询表数据只需要使用 count tablename 即可实现,且查询效率比使用原生 Hive 快一个数量级。查询结果保存在历史文件中,可以使用相关命令查看。
关于单表模块的命令有多个,count 命令的代码如下:
1 class SigleTableAnalysis(cmd.Cmd):
2 # count table,查询表数据量,支持传入where条件
3 @classmethod
4 def do_count(self, parsed, print_command=True, print_res=True):
5 try:
6 table_name = parsed.split(' ')[1].strip(';')
7 statement = 'select count(1) from %s' % table_name
8 if len(parsed.split(' ')) >=3 and parsed.split(' ')[2].strip() == 'where': 9 wherecondition = ' '.join(parsed.split(' ')[3:])
10 statement = statement + ' where ' + wherecondition
11 status, res = perform_simple_statement(statement, detail=False, print_
command=print_command, print_res=print_res)
12 if not print_res:
13 return status, res
14 except IndexError as e:
15 print('please check whether your command is right')
16 except Exception as e:
17 import traceback
18 print('%s detail: %s' % (str(e), traceback.format_exc()))
其他模块的代码与 count 命令的代码相似,双表查询模块、拉链表测试模块、数据质量分析模块会在单表模块的基础上进行封装,所以设计会更复杂一些,由于篇幅有限,异步君没法在这里为大家更多地展示了。想要深入了解的小伙伴,推荐阅读《机器学习测试入门与实践》。
机器学习测试入门与实践
作者:艾辉
内容简介:
本书全面且系统地介绍了机器学习测试技术与质量体系建设,能够帮助读者了解机器学习是如何工作的,了解机器学习的质量保障是如何进行的。
工程开发人员和测试工程师通过阅读本书,可以系统化地了解大数据测试、特征测试及模型评估等知识;算法工程师通过阅读本书,可以学习模型评测的方法和拓宽模型工程实践的思路;技术专家和技术管理者通过阅读本书,可以了解机器学习质量保障与工程效能的建设方案。
家好,我是DD,已经是封闭在家的第51天了!
最近一直在更新Java新特性(https://www.didispace.com/java-features/)和IDEA Tips(https://www.didispace.com/idea-tips/)两个原创专栏,其他方向内容的动态关注少了。昨天天晚上刷推的时候,瞄到了这个神奇的东西,觉得挺cool的,拿出来分享下:
相信你看到图,不用我说,你也猜到是啥了吧?html里可以跑python代码了!
看到好多Python公众号已经开始猛吹未来了,但乍看怎么觉得有点像JSP?或者一些模版引擎?是进步还是倒退呢?与其瞎想,不如仔细看看这个东东的能力吧!
根据官方介绍,这个名为PyScript的框架,其核心目标是为开发者提供在标准HTML中嵌入Python代码的能力,使用 Python调用JavaScript函数库,并以此实现利用Python创建Web应用的功能。
看到介绍里提到了调用JavaScript函数库的能力,看来跟JSP或者模版引擎还是有区别的。
官方给了一个例子,可以帮助我们观的感受这个开发框架的能力,不妨跟着DD看看,它能做啥吧!
第一个案例,hello world
代码很简单,就下面这几行。你只需要创建一个html文件,然后复制进去就可以了。
|
保存好之后,在浏览器里打开就能看到这样的页面了:
回头再看看这个html里的内容,三个核心内容:
如果你懒得自己敲代码的话,本文的两个案例代码我打包放在公众号了,需要的朋友可以关注公众号“程序猿DD”,回复:pyscript 获取。
第二个案例,数据定义 + 数据展示
先创建一个data.py文件,然后加入前面的代码。功能很简单,就是随机生成(x,y)的坐标
|
再创建一个html文件,加入下面的代码
|
这里就稍微复杂一些了,除了hello world中的几个要点外,这里还有这几个要关注的地方:
这个页面的执行效果是这样的:
是不是很神奇呢?整个过程中都没有大家熟悉的cs、js内容,就完成了这样一个图的页面实现。
最后,谈谈在整个尝试过程中,给我的几个感受:
这个开发框架目前还只是alpha版本,未来一定还会有更多特性与优化出来,总体上我觉得这个框架还是非常cool的,尤其对于刚学会Python,或者只会Python,但又想快速开发Web应用的小伙伴来说,可能将会是个不错的选择,那你觉得这个框架如何?未来会不会火?留言区聊聊吧!
小新 编译自 Insight Data Blog
量子位 出品 | 公众号 QbitAI
写个网页能有多麻烦?在大多数公司里,这项工作分为三步:
1. 产品经理完成用户调研任务后,列出一系列技术要求;
2. 设计师根据这些要求来设计低保真原型,逐渐修改得到高保真原型和UI设计图;
3. 工程师将这些设计图实现为代码,最终变成用户使用的产品。
这么多环节,任何地方出一点问题,都会拉长开发周期。因此,不少公司,比如Airbnb已经开始用机器学习来提高这个过程的效率。
△ Airbnb内部的AI工具,从图纸到代码一步到位
看起来很美好,但Airbnb还没公开该模型中端到端训练的细节,以及手工设计的图像特征对该模型的贡献度。这是该公司特有的闭源解决方案专利,可能不会进行公开。
好在,一个叫Ashwin Kumar的程序员创建了一个开源版本,让开发者/设计师的工作变得更简单。
以下内容翻译自他的博客:
理想上,这个模型可以根据网站设计的简单手绘原型,很快地生成一个可用的HTML网站:
△ SketchCode模型利用手绘线框图来生成HTML网站
事实上,上面例子就是利用训练好的模型在测试集上生成的一个实际网站,代码请访问:https://github.com/ashnkumar/sketch-code。
目前要解决的问题属于一种更广泛的任务,叫做程序综合(program synthesis),即自动生成工作源代码。尽管很多程序综合研究通过自然语言规范或执行追踪法来生成代码,但在当前任务中,我会充分利用源图像,即给出的手绘线框图来展开工作。
在机器学习中有一个十分热门的研究领域,称为图像标注(image caption),目的是构建一种把图像和文本连接在一起的模型,特别是用于生成源图像内容的描述。
△ 图像标注模型生成源图像的文本描述
我从一篇pix2code论文和另一个应用这种方法的相关项目中获得灵感,决定把我的任务按照图像标注方式来实现,把绘制的网站线框图作为输入图像,并将其相应的HTML代码作为其输出内容。
注:上段提到的两个参考项目分别是
pix2code论文:https://arxiv.org/abs/1705.07962
floydhub教程:https://blog.floydhub.com/turning-design-mockups-into-code-with-deep-learning/?source=techstories.org
确定图像标注方法后,理想中使用的训练数据集会包含成千上万对手绘线框图和对应的HTML输出代码。但是,目前还没有我想要的相关数据集,我只好为这个任务来创建数据集。
最开始,我尝试了pix2code论文给出的开源数据集,该数据集由1750张综合生成网站的截图及其相应源代码组成。
△ pix2code数据集中的生成网站图片和源代码
这是一个很好的数据集,有几个有趣的地方:
该数据集中的每个生成网站都包含几个简单的辅助程序元素,如按钮、文本框和DIV对象。尽管这意味着这个模型受限于将这些少数元素作为它的输出内容,但是这些元素可通过选择生成网络来修改和扩展。这种方法应该很容易地推广到更大的元素词汇表。
每个样本的源代码都是由领域专用语言(DSL)的令牌组成,这是该论文作者为该任务所创建的。每个令牌对应于HTML和CSS的一个片段,且加入编译器把DSL转换为运行的HTML代码。
为了修改我的任务数据集,我要让网站图像看起来像手工绘制出的。我尝试使用Python中的OpenCV库和PIL库等工具对每张图像进行修改,包括灰度转换和轮廓检测。
最终,我决定直接修改原始网站的CSS样式表,通过执行以下操作:
1. 更改页面上元素的边框半径来平滑按钮和DIV对象的边缘;
2. 模仿绘制的草图来调整边框的粗细,并添加阴影;
3. 将原有字体更改为类似手写的字体;
最终实现的流程中还增加了一个步骤,通过添加倾斜、移动和旋转来实现图像增强,来模拟实际绘制草图中的变化。
现在,我已经处理好数据集,接下来是构建模型。
我利用了图像标注中使用的模型架构,该架构由三个主要部分组成:
1. 一种使用卷积神经网络(CNN)的计算机视觉模型,从源图像提取图像特征;
2. 一种包含门控单元GRU的语言模型,对源代码令牌序列进行编码;
3. 一个解码器模型,也属于GRU单元,把前两个步骤的输出作为输入,并预测序列中的下一个令牌。
△ 以令牌序列为输入来训练模型
为了训练模型,我将源代码拆分为令牌序列。模型的输入为单个部分序列及它的源图像,其标签是文本中的下一个令牌。该模型使用交叉熵函数作为损失函数,将模型的下个预测令牌与实际的下个令牌进行比较。
在模型从头开始生成代码的过程中,该推理方式稍有不同。图像仍然通过CNN网络进行处理,但文本处理开始时仅采用一个启动序列。在每个步骤中,模型对序列中输出的下个预测令牌将会添加到当前输入序列,并作为新的输入序列送到模型中;重复此操作直到模型的预测令牌为,或该过程达到每个文本中令牌数目的预定义值。
当模型生成一组预测令牌后,编译器就会将DSL令牌转换为HTML代码,这些HTML代码可以在任何浏览器中运行。
我决定使用BLEU分数来评估模型。这是机器翻译任务中常用的一种度量标准,通过在给定相同输入的情况下,衡量机器生成的文本与人类可能产生内容的近似程度。
实际上,BLEU通过比较生成文本和参考文本的N元序列,以创建修改后的准确版本。它非常适用于这个项目,因为它会影响生成HTML代码中的实际元素,以及它们之间的相互关系。
最棒的是,我还可以通过检查生成的网站来比较当前的实际BLEU分数。
△ 观察BLEU分数
当BLEU分数为1.0时,则说明给定源图像后该模型能在正确位置设置合适的元素,而较低的BLEU分数这说明模型预测了错误元素或是把它们放在相对不合适的位置。我们最终模型在评估数据集上的BLEU分数为0.76。
后来,我还想到,由于该模型只生成当前页面的框架,即文本的令牌,因此我可以在编译过程中添加一个定制的CSS层,并立刻得到不同风格的生成网站。
△ 一个手绘图生成多种风格的网页
把风格定制和模型生成两个过程分开,在使用模型时带来了很多好处:
1.如果想要将SketchCode模型应用到自己公司的产品中,前端工程师可以直接使用该模型,只需更改一个CSS文件来匹配该公司的网页设计风格;
2. 该模型内置的可扩展性,即通过单一源图像,模型可以迅速编译出多种不同的预定义风格,因此用户可以设想出多种可能的网站风格,并在浏览器中浏览这些生成网页。
受到图像标注研究的启发,SketchCode模型能够在几秒钟内将手绘网站线框图转换为可用的HTML网站。
但是,该模型还存在一些问题,这也是我接下来可能的工作方向:
1. 由于这个模型只使用了16个元素进行训练,所以它不能预测这些数据以外的令牌。下一步方向可能是使用更多元素来生成更多的网站样本,包括网站图片,下拉菜单和窗体,可参考启动程序组件(https://getbootstrap.com/docs/4.0/components/buttons/)来获得思路;
2. 在实际网站构建中,存在很多变化。创建一个能更好反映这种变化的训练集,是提高生成效果的一种好方法,可以通过获取更多网站的HTML/CSS代码以及内容截图来提高;
3. 手绘图纸也存在很多CSS修改技巧无法捕捉到的变化。解决这个问题的一种好方法是使用生成对抗网络GAN来创建更逼真的绘制网站图像。
代码:https://github.com/ashnkumar/sketch-code
原文:https://blog.insightdatascience.com/automated-front-end-development-using-deep-learning-3169dd086e82
— 完 —
诚挚招聘
量子位正在招募编辑/记者,工作地点在北京中关村。期待有才气、有热情的同学加入我们!相关细节,请在量子位公众号(QbitAI)对话界面,回复“招聘”两个字。
量子位 QbitAI · 头条号签约作者
վ'ᴗ' ի 追踪AI技术和产品新动态
*请认真填写需求信息,我们会在24小时内与您取得联系。