注解
在本文中,我想分享我在Vertica上的数据仓库中的机器学习经验。
坦白说,我不是专家分析师,他将能够详细描述所有研究方法和数据预测算法。 但是,作为Vertica的专家并拥有ML的基本经验,我将尝试谈论使用内置服务器功能和R语言在Vertica中进行预测分析的方法。
机器学习库Vertica
从版本7开始,Vertica已使用机器学习库进行了扩展,您可以使用该库:
- 准备用于机器学习的数据示例
- 在准备好的数据上训练机器学习模型;
- 对保存的机器学习模型上的存储数据进行预测分析。
该库随所有版本的Vertica安装一起提供,包括免费的Community。 它的使用以从SQL调用函数的形式进行构造,在文档中对此进行了详细说明,并提供了示例数据的用法示例。
在Vertica中使用ML的示例
作为有关ML工作原理的简单示例,我采用了mtcars演示数据,该数据是Vertica的ML数据示例的一部分。 该数据包括两个表:
- mtcars_train-为训练机器学习模型准备的数据
- mtcars-分析数据
让我们看一下训练数据:
=>SELECT * FROM mtcars_train;

在有关汽车模型的数据集中,描述了它们的特性。 让我们尝试训练机器学习,以便根据汽车的特性来预测汽车所涉及的变速箱类型-手动变速箱还是自动变速箱。 为此,我们需要在准备的数据上构建逻辑回归模型,找到字段“ am”的框类型和车辆“ wt”的重量字段,气缸“ cyl”的数量以及框“ gear”中的速度数量的相关性:
=>SELECT LOGISTIC_REG('logistic_reg_mtcars', 'mtcars_train', 'am', 'cyl, wt, gear'); Finished in 19 iterations
所调用的函数分析了am与cyl,wt,gear字段之间的关系,揭示了依赖关系公式,并将依赖关系的模拟结果写入模型“ logistic_reg_mtcars”中的Vertica数据库中。 使用此保存的模型,您现在可以分析汽车上的数据并预测自动变速箱的可用性。
可以查看有关模型的信息:
=>SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='logistic_reg_mtcars');

现在,我们将模型用于汽车数据,将结果保存在新表中:
=>CREATE TABLE mtcars_predict_results AS ( SELECT car_model, am, PREDICT_LOGISTIC_REG(cyl, wt, gear USING PARAMETERS model_name='logistic_reg_mtcars') AS prediction FROM mtcars );
并将am的实际值与预测预测中获得的值进行比较:
=>SELECT * FROM mtcars_predict_results;

在这种情况下,对100%的预测与所提出模型中的实际盒子类型一致。 在准备用于训练的新数据时,您将需要删除并重新保存模型。
Vertica中的ML功能
Vertica ML库支持以下类型的预测分析:
- 预测:
- 分类:
- 逻辑回归
- 朴素的贝叶斯
- 分类随机森林
- 支持向量机(SVM)用于分类
- 聚类:
为了准备训练数据,需要提供以下功能:
- 资料平衡
- 排放清洁
- 编码分类(文本)列值
- 替换丢失的数据
- 数据标准化
- 主成分分析
- 资料取样
- 奇异值分解
考虑到Vertica中的ML功能,我们可以说内置库使我们能够解决相当多的问题,但没有积压来研究数据的模式和依存关系。 有准备用于机器学习的数据的功能,但是没有以图表的形式可视化数据的分布,只有具有分析数据专家知识的分析专家才能“准备”此类数据并在其上训练学习模型。
带Vertica的R Studio
对于更彻底和交互式的预测数据分析,R语言非常适合,它具有用于处理R Studio数据的可视环境。 将R与Vertica一起使用的明显优势将是:
- 环境的交互性,可以保存状态以在下一次运行后进行进一步分析;
- 以表格和图表的形式直观地查看数据;
- R语言处理数据集的能力;
- 与Vertica ML中提供的算法相似的各种预测分析算法。
使用R处理大数据的缺点是对RAM的要求,处理大数据阵列的速度以及导入和导出Vertica数据的需求。 这些缺点被嵌入书面R函数以直接在Vertica中的群集上执行的能力所弥补,这将在下面进行描述。
R的简要介绍
我们将使用R在Vertica数据上重现对自动包装盒的预测。为了不吓走不熟悉这种语言的程序员,我将进行一门年轻的R战斗机的短期课程。
因此,R语言与具有对象,类和函数的过程语言相同。
一个对象可以是数据集(向量,列表,数据集...),值(文本,数字,日期,时间...)或函数。 对于值,支持数字,字符串,布尔值和日期时间类型。 对于数据集,数组编号从1开始,而不是0。
传统上,使用赋值运算符“ <-”代替R中的“ =”。 尽管不禁止在另一侧使用“->”,甚至是通常的“ =”。 调用函数以指定命名参数时,使用运算符“ =”本身。
代替“。” “ $”用于访问数据集的字段。 点不是关键字,而是用于对象名称中以提高其可读性。 因此,“ my.data $ field”将从数据集“ my.data”中解密为字段“ field”的记录数组。
您可以使用单引号或双引号将文本框起来。
最重要的是: R致力于处理数据集。 即使代码说“ a <-1”,也要确保R内部本身认为“ a”是1个元素的数组。 语言设计使您可以像处理普通变量一样使用数据集:加和减,连接和断开连接,按度量过滤。 创建列出其元素的数组的最简单方法是调用函数“ c(用逗号分隔的数组元素)”。 名称“ c”显然是Collection的缩写,但我不确定。
将数据从DBMS加载到R中
要通过ODBC for R使用RDBMS,必须安装RODBC软件包。 可以将其安装在R Studio的“程序包”选项卡上,或使用R命令安装:
install.packages('RODBC') library('RODBC')
现在我们可以使用Vertica。 我们为服务器创建ODBC别名,并获取汽车的测试数据和完整数据集:
# Vertica con <- odbcConnect(dsn='VerticaDSN') # mtcars_train mtcars.train <- sqlQuery(con, "SELECT * FROM public.mtcars_train") # mtcars</b> mtcars.data <- sqlQuery(con, "SELECT * FROM public.mtcars") # odbcClose(con)
当从源R加载文本类型和日期时间字段的数据时,将自动确定其属于因素。 “ am”字段是数字类型,R被认为是数字指示符,而不是因素,这将不允许进行逻辑回归。 因此,我们将此字段转换为数值因子:
mtcars.data$am = factor(mtcars.data$am) mtcars.train$am = factor(mtcars.train$am)
在R Studio中,可以方便地交互地观看数据,构建预测分析图以及在R中使用提示编写代码:

在R中建立模型
我们将针对与Vertica中相同的维度,在准备好的数据集上构建逻辑回归模型:
mtcars.model <- glm(formula = am ~ cyl + wt + gear, family = binomial(), data = mtcars.train)
说明:在R语言中,预测分析公式表示为:
< >~< >
R中的模型数据分析
我们初始化结果数据集,从mtcars中获取所有必填字段的记录:
mtcars.result <- data.frame(car_model = mtcars.data$car_model, am = mtcars.data$am, predict = 0)
现在,基于构造的模型,您可以对数据本身进行分析:
mtcars.result$predict <- predict.glm(mtcars.model, newdata = subset(mtcars.data, select = c('cyl', 'wt', 'gear')), type = 'response' )
分析结果作为预测概率的百分比返回到预测字段。 通过与Vertica的类比简化为0或1,考虑到预测为正数且概率大于50%:
mtcars.result$predict <- ifelse(mtcars.result$predict > 0.5, 1, 0)
我们计算预测预测字段与am中的实际值不匹配的记录总数:
nrow(mtcars[mtcars.result$am != mtcars.result$predict, ])
R返回零。 因此,与Vertica的ML一样,该预测也适用于所有汽车模型。
请注意:来自mtcars的记录由过滤器(方括号中的第一个参数)返回所有列(方括号中的逗号后省略第二个参数)返回。
在R中本地保存和加载数据
退出R后,工作室会保存所有对象的状态,以便在重新启动后继续工作。 如果由于某种原因需要保存然后恢复单个对象的状态,R中提供了此特殊功能:
# save(mtcars.model, file = 'mtcars.model') # load('mtcars.model')
将数据从R保存到Vertica
如果使用R Studio为训练ML Vertica模型准备数据,或者直接在其中进行分析(然后在Vertica数据库中使用),则可以将R数据集写入Vertica表。
由于R的ODBC库是为OLTP RDBMS设计的,因此它无法正确生成Vertica的表创建查询。 因此,要成功记录数据,您将需要使用SQL在Vertica中手动创建必要的表,其字段和类型的集合与可记录的数据集R一致。
此外,录制过程本身看起来很简单(不要忘记打开然后关闭连接):
sqlSave(con, mtcars.result, tablename = 'public.mtcars_result', append = TRUE, rownames = FALSE, colnames = FALSE)
将Vertica与R结合使用
R Studio中的数据交互工作非常适合研究和准备数据的模式。 但是它完全不适合在自动模式下分析数据流和大型阵列。 Vertica的混合R预测分析方案的一种选择是准备用于R的学习数据并确定构建模型的依存关系。 然后,使用Vertica内置的ML函数,考虑到已识别的变量依存关系,对R上准备的数据的预测模型进行训练。
如果直接在Vertica中使用R语言的所有功能,则有一个更灵活的选择。 为此,Vertica以插件库的形式开发了R发行版,使您可以在SQL查询中使用直接用R语言编写的转换函数。文档详细描述了Vertica的R支持的安装以及操作所需的其他R软件包(如果有)。
在Vertica中保存Model R
要使用R Studio先前在Vertica下运行的R函数中准备的分析模型,您需要将其保存在Vertica服务器上。 使用文件在集群的每个服务器上本地保存既不方便也不可靠,可以将新服务器添加到集群,并且在更改模型时,您将需要记住再次重写所有文件。
最方便的方法是将R模型序列化为文本并将Vertica函数另存为UDF,这会将此文本作为常量返回(不要忘记打开然后关闭con连接):
# mtcars.model.text <- rawToChar( serialize(mtcars.model, connection = NULL, ascii = TRUE)) # Vertica # ( ) mtcars.func <- paste0( "CREATE OR REPLACE FUNCTION public.MtCarsAnalizeModel() RETURN varchar(65000) AS BEGIN RETURN '", gsub("'", "''", mtcars.model.text), "'; END; GRANT EXECUTE ON FUNCTION public.MtCarsAnalizeModel() TO public;" ) # Vertica sqlQuery(con, mtcars.func)
所提出的方法允许在变换函数中绕开Vertica对传输参数的限制,在变换函数中,仅需要常量或常量的表达式的传递。 Vertica UDF SQL不会以函数形式而是以计算表达式的形式进行编译,也就是说,当传递参数而不是调用函数时,其文本(在这种情况下为常量)将被传输,并保存在上面的代码中。
如果更改模型,则需要在Vertica中重新创建其功能。 将此代码包装在通用函数中是有意义的,该通用函数在Vertica中使用传递的模型中的指定名称生成函数。
Vertica的R函数
为了将R函数连接到Vertica,您需要在Vertica中编写数据分析和注册函数。
从Vertica本身处理数据的功能应具有两个参数:结果数据集(如data.frame)和工作参数(如list):
MtCarsAnalize <- function(data, parameters) { if ( is.null(parameters[['model']]) ) { stop("NULL value for model! Model cannot be NULL.") } else { model <- unserialize(charToRaw(parameters[['model']])) } names(data) <- c('car_model', 'cyl', 'wt', 'gear') result <- data.frame(car_model = data$car_model, predict = 0) result$predict <- predict.glm(model, newdata = subset(data, select = c('cyl', 'wt', 'gear')), type = 'response' ) result$predict <- ifelse(result$predict > 0.5, TRUE, FALSE) return(result) }
在函数的主体中,检查是否传递了模型参数,该模型参数的文本转换为二进制形式,然后反序列化为分析模型的对象。 由于Vertica将其自己的字段名称传输到该功能的数据集,因此将显式字段名称设置为该数据集。 基于获得的数据,使用机器模型的名称和零预测来构造结果集。 接下来,仅使用从获得的数据集中进行分析所需的字段来构建预测。 结果集的预测字段设置为布尔值(用于更改而不是数字值),结果从函数返回。
现在剩下要描述此功能在Vertica中的注册:
MtCarsAnalizeFactory <- function() { list(name = MtCarsAnalize, udxtype = c("transform"), intype = c("varchar", "int", "float", "int"), outtype = c("varchar", "boolean"), outnames = c("car_model", "predict"), parametertypecallback=MtCarsAnalizeParameters) } MtCarsAnalizeParameters <- function() { parameters <- list(datatype = c("varchar"), length = 65000, scale = c("NA"), name = c("model")) return(parameters) }
MtCarsAnalizeFactory函数描述用于操作的函数的名称,传入和传出数据集的字段,第二个函数描述传递的参数“ model”。 字段类型是Vertica数据类型。 在传输和返回数据时,Vertica会自动将值转换为R语言所需的数据类型,您可以在Vertica文档中看到类型兼容性表。
您可以在上传到R studio的数据上测试Vertica书面功能的运行情况:
test.data = subset(mtcars.data, select = c('car_model', 'cyl', 'wt', 'gear')) test.params = list(model = mtcars.model.text) test.result = MtCarsAnalize(test.data, test.params)
将功能库连接到Vertica
我们将以上所有功能保存在一个文件“ mtcars_func.r”中,并将此文件从“ / home / dbadmin”中的Vertica群集上传到其中一台服务器。
要点:在R Studio中,您需要设置选项以Posix(LF)模式将行的转换保存在文件中。 这可以在全局选项的“代码”部分的“保存”选项卡中完成。 如果您在Windows上工作,则默认情况下,文件将与回车符一起保存,并且无法上载到Vertica。
我们从Vertica群集连接到服务器,在该服务器上保存了文件并加载了库:
CREATE LIBRARY MtCarsLibs AS '/home/dbadmin/mtcars_func.r' LANGUAGE 'R';
现在,您可以从该库中注册R函数:
CREATE TRANSFORM FUNCTION public.MtCarsAnalize AS LANGUAGE 'R' NAME 'MtCarsAnalizeFactory' LIBRARY MtCarsLibs; GRANT EXECUTE ON TRANSFORM FUNCTION public.MtCarsAnalize(varchar, int, float, int) TO public;
Vertica中的Call R函数
我们调用R函数,并向其传递模型文本,该文本先前已保存为UDF函数:
SELECT MtCarsAnalize(car_model, cyl, wt, gear USING PARAMETERS model = public.MtCarsAnalizeModel()) OVER() FROM public.mtcars;

可以证明,与以前的情况一样,该预测与实际情况是100%一致的:
SELECT c.*, p.predict, p.predict = c.am::int AS valid FROM public.mtcars c INNER JOIN ( SELECT MtCarsAnalize(car_model, cyl, wt, gear USING PARAMETERS model = public.MtCarsAnalizeModel()) OVER() FROM public.mtcars ) p ON c.car_model = p.car_model
请注意: Vertica中的转换函数从函数中定义的字段和记录中返回它们自己的数据集,但是如果将它们包装在子查询中,则可以在查询中使用它们。
连接R函数后,Vertica会将源代码复制到其安装中,然后将其编译为机器代码。 连接到库之后,上传到服务器的源R文件不需要进一步的工作。 考虑二进制编译的函数速度足够高,可以处理大型数据阵列,但是,值得记住的是,所有R操作都在内存中执行,并且如果缺少OS内存来满足Vertica和R一起工作的需求,则存在交换风险。
如果在PARTITION BY中为OVER指定的数据分区上调用了该函数,则Vertica会并行化集群服务器上每个分区的执行。 因此,如果除了机器型号之外,数据集中还存在制造商,则可以在PARTITION BY中指定它,并并行化每个制造商的分析。
其他Vertica机器学习机会
除R外,Vertica可以使用C,Java和Python开发其自己的转换函数。 每种语言都有其自己的细微差别,并且具有编写和连接到Vertica的功能。 连同其自己的ML,所有这些都为Vertica提供了进行预测数据分析的良好储备。
谢谢和链接
我要衷心感谢来自彼尔姆的朋友和同事Vlad Malofeev,他向我介绍了R,并帮助我在我们的一个联合项目中弄清楚了这一点。
最初,在一个使用过去一年的数据对未来的困难条件进行预测的项目中,开发人员尝试使用SQL和Java。 考虑到这些来源的质量,这造成了很大的困难,并大大减缓了该项目的开发。 弗拉德(Vlad)与R一起带来了这个项目,我们将R连接到了Vertica,他将数据带到录音棚,一切都旋转并立即旋转。 从字面上看,数周之久的所有工作都被抽空了,从而使该项目免于复杂的代码。
可以从GIT存储库下载有关汽车的示例数据:
git clone https://github.com/vertica/Machine-Learning-Examples
并上传到Vertica:
/opt/vertica/bin/vsql -d <name of your database> -f load_ml_data.sql
如果您想更深入地学习ML并学习如何使用R,我建议您用俄语写一本书
“ R in action”。 以R语言对数据进行分析和可视化 。
” 它以一种简单易用的人类语言编写,适合以前从未接触过机器学习的初学者。
在这里,您可以看到有关将R库连接到Vertica的信息。
对于已经开始在Python中学习和使用ML的人来说,值得关注IDE Rodeo,它是R Studio的类似产品,因为没有交互式质量分析是不可能的。 我认为,本文在R下以类似方式描述的所有内容都可以用Python开发,包括将模型保存在UDF函数中以及为Vertica开发分析函数。 如果您进行检查,请不要忘记在评论中退订结果,我将不胜感激。
感谢您的宝贵时间,我希望我能够证明R和Vertica共生的简单性和令人难以置信的功能。