Machine Learning para Vertica

Anotação


Neste artigo, quero compartilhar minha própria experiência com o aprendizado de máquina em um data warehouse da Vertica.

Francamente, eu não sou um analista especialista que será capaz de descrever em detalhes toda a variedade de métodos de pesquisa e algoritmos de previsão de dados. Ainda assim, sendo um especialista em Vertica e tendo uma experiência básica com ML, tentarei falar sobre maneiras de trabalhar com a análise preditiva no Vertica usando a funcionalidade interna do servidor e a linguagem R.

Biblioteca de aprendizado de máquina Vertica


A partir da versão 7, o Vertica foi expandido com a biblioteca Machine Learning, com a qual você pode:

  • Prepare exemplos de dados para aprendizado de máquina
  • treinar modelos de aprendizado de máquina com dados preparados;
  • realizar análises preditivas de dados de armazenamento em modelos de aprendizado de máquina salvos.

A biblioteca vem imediatamente completa com a instalação do Vertica para todas as versões, incluindo a Comunidade gratuita. O trabalho com ele é estruturado na forma de uma chamada para funções do SQL, descritas em detalhes na documentação com exemplos de uso em dados de demonstração preparados.

Um exemplo de trabalho com ML no Vertica


Como um exemplo simples de como o ML funciona, usei os dados de demonstração mtcars que fazem parte do exemplo de dados do ML para a Vertica. Esses dados incluem duas tabelas:

  • mtcars_train - dados preparados para o treinamento de modelos de aprendizado de máquina
  • mtcars - dados para análise

Vejamos os dados para treinamento:

=>SELECT * FROM mtcars_train; 



No conjunto de dados dos modelos de carros, suas características são descritas. Vamos tentar treinar o aprendizado de máquina para que, de acordo com as características dos carros, seja possível prever qual tipo de caixa de velocidades está envolvida no carro - uma caixa manual ou uma caixa de velocidades automática. Para fazer isso, precisamos construir um modelo de regressão logística com os dados preparados, encontrando a dependência do tipo de caixa do campo "am" e os campos de peso do veículo "wt", o número de cilindros "cyl" e o número de velocidades na caixa "gear":

 =>SELECT LOGISTIC_REG('logistic_reg_mtcars', 'mtcars_train', 'am', 'cyl, wt, gear'); Finished in 19 iterations 

A função chamada analisou a relação entre am e os campos cyl, wt, gear, revelou a fórmula da dependência e escreveu o resultado da simulação da dependência no banco de dados Vertica no modelo "logistic_reg_mtcars". Usando este modelo salvo, agora você pode analisar dados sobre carros e prever a disponibilidade de caixas de velocidades automáticas.

Informações sobre o modelo podem ser visualizadas:

 =>SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='logistic_reg_mtcars'); 



Agora usamos o modelo nos dados para carros, salvando o resultado em uma nova tabela:

 =>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 ); 

E comparando os valores reais de am com os obtidos na previsão de previsão:

 =>SELECT * FROM mtcars_predict_results; 



Nesse caso, a previsão para 100% coincidiu com o tipo real de caixa nos modelos apresentados. No caso de preparar novos dados para treinamento, você precisará excluir e salvar novamente o modelo.

Funcionalidade de ML no Vertica


A biblioteca Vertica ML suporta os seguintes tipos de análise preditiva:

  • Previsão:
    • Regressão linear
    • Floresta aleatória para regressão
    • SVM (Support Vector Machine) para regressão
  • Classificação:
    • Regressão logística
    • Bayes ingênuos
    • Floresta aleatória para classificação
    • SVM (Support Vector Machine) para classificação
  • Agrupamento:
    • k-significa

Para preparar os dados para o treinamento, a seguinte funcionalidade é apresentada:

  • Balanceamento de dados
  • Limpeza de emissões
  • Codificando valores de coluna categóricos (textuais)
  • Substituindo dados ausentes
  • Normalização de dados
  • Análise de componentes principais
  • Amostragem de dados
  • Decomposição de valor singular

Considerando a funcionalidade de ML no Vertica, podemos dizer que a biblioteca interna nos permite resolver uma gama bastante ampla de problemas, mas não possui o backlog para estudar os padrões e dependências nos dados. Existem funções para preparar dados para aprendizado de máquina, mas sem visualizar a distribuição de dados na forma de gráficos, apenas os gurus da análise com conhecimento especializado dos dados analisados ​​podem "preparar" esses dados e treinar modelos de aprendizado.

R Studio com Vertica


Para uma análise preditiva de dados mais completa e interativa, a linguagem R é ideal, que possui um ambiente visual para trabalhar com dados do R Studio. As vantagens tangíveis do uso de R com o Vertica serão:

  • interatividade do ambiente com a capacidade de salvar o estado para análises posteriores após a próxima execução;
  • visualização visual de dados sob a forma de tabelas e gráficos;
  • Poder da linguagem R para trabalhar com conjuntos de dados;
  • uma variedade de algoritmos de análise preditiva semelhantes aos apresentados no Vertica ML.

As desvantagens de trabalhar com R com big data são os requisitos de RAM, a velocidade de trabalho com grandes matrizes de dados e a necessidade de importar e exportar dados da Vertica. Essas deficiências são cobertas pela capacidade de incorporar funções R escritas para execução direta em um cluster no Vertica, que será descrito abaixo.

Uma pequena introdução ao R


Vamos reproduzir a previsão de caixas automáticas nos dados da Vertica usando R. Para não assustar os programadores que não estão familiarizados com esse idioma, realizarei um curso breve de um jovem lutador R.

Portanto, a linguagem R é a mesma linguagem processual que possui objetos, classes e funções.
Um objeto pode ser um conjunto de dados (vetor, lista, conjunto de dados ...), valor (texto, número, data, hora ...) ou uma função. Para valores, os tipos numérico, sequência, booleano e data e hora são suportados. Para conjuntos de dados, a numeração da matriz começa em 1, não em 0.

Classicamente, em vez de "=" em R, o operador de atribuição "<-" é usado. Embora não seja proibido usar a atribuição para o outro lado "->" e até o habitual "=". O operador "=" é usado ao chamar funções para especificar parâmetros nomeados.

Em vez de "." "$" é usado para acessar os campos dos conjuntos de dados. Um ponto não é uma palavra-chave e é usado nos nomes de objetos para aumentar sua legibilidade. Assim, "my.data $ field" será descriptografado como uma matriz de registros do campo "field" do conjunto de dados "my.data".

Você pode usar aspas simples ou duplas para enquadrar textos.

Mais importante: R é voltado para trabalhar com conjuntos de dados. Mesmo que o código diga "a <-1", verifique se R dentro de si acredita que "a" é uma matriz de 1 elemento. O design do idioma permite trabalhar com conjuntos de dados como com variáveis ​​comuns: adicionar e subtrair, conectar e desconectar, filtrar por medições. A maneira mais fácil de criar uma matriz listando seus elementos é chamar a função "c (elementos da matriz separados por vírgulas)". O nome "c" parece ser uma abreviação curta de Collection, mas não vou dizer com certeza.

Carregando dados de um DBMS no R


Para usar RDBMS através do ODBC para R, você deve instalar o pacote RODBC. Ele pode ser instalado no R Studio na guia packages ou usando o comando R:

 install.packages('RODBC') library('RODBC') 


Agora podemos trabalhar com a Vertica. Criamos um alias ODBC para o servidor e obtemos os dados de teste e o conjunto completo de dados para o carro:

 #    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) 

Ao carregar dados das fontes R para campos de tipos de texto e data e hora, sua pertença a fatores é automaticamente estabelecida. O campo "am" é do tipo numérico e R é percebido como um indicador numérico e não como um fator que não permitirá uma regressão logística. Portanto, convertemos esse campo em um fator numérico:

 mtcars.data$am = factor(mtcars.data$am) mtcars.train$am = factor(mtcars.train$am) 

No R Studio, é conveniente assistir dados interativamente, criar gráficos de análise preditiva e escrever código em R com dicas:



Construindo um modelo em R


Construiremos um modelo de regressão logística sobre o conjunto de dados preparado para as mesmas dimensões do Vertica:

 mtcars.model <- glm(formula = am ~ cyl + wt + gear, family = binomial(), data = mtcars.train) 

Explicação: na linguagem R, a fórmula de análise preditiva é indicada como:

 <  >~<   > 

Análise de dados do modelo em R


Inicializamos o conjunto de dados resultante, retirando do mtcars todos os registros para os campos obrigatórios:

 mtcars.result <- data.frame(car_model = mtcars.data$car_model, am = mtcars.data$am, predict = 0) 

Agora, com base no modelo construído, você pode executar a análise dos próprios dados:

 mtcars.result$predict <- predict.glm(mtcars.model, newdata = subset(mtcars.data, select = c('cyl', 'wt', 'gear')), type = 'response' ) 

O resultado da análise é retornado ao campo de previsão como uma porcentagem da probabilidade da previsão. Simplifique por analogia com a Vertica os valores 0 ou 1, considerando a previsão positiva com uma probabilidade superior a 50%:

 mtcars.result$predict <- ifelse(mtcars.result$predict > 0.5, 1, 0) 

Calculamos o número total de registros para os quais o campo de previsão previsto não corresponde ao valor real em am:

 nrow(mtcars[mtcars.result$am != mtcars.result$predict, ]) 

R retornou zero. Assim, a previsão convergiu em todos os modelos de carros, como no ML da Vertica.

Observação: os registros dos mtcars foram retornados pelo filtro (o primeiro parâmetro entre colchetes) com todas as colunas (o segundo parâmetro foi omitido após a vírgula entre colchetes).

Salvando e carregando dados localmente no R


Ao sair do R, o estúdio oferece salvar o estado de todos os objetos para continuar trabalhando após uma reinicialização. Se, por algum motivo, você precisar salvar e restaurar o estado de objetos individuais, essas funções especiais são fornecidas em R:

 #      save(mtcars.model, file = 'mtcars.model') #      load('mtcars.model') 

Salvando dados do R no Vertica


Se o R Studio foi usado para preparar dados para o treinamento dos modelos ML Vertica, ou se foram analisados ​​diretamente nele, que serão usados ​​no banco de dados Vertica, os conjuntos de dados R poderão ser gravados na tabela Vertica.

Como a biblioteca ODBC para R foi projetada para RDBMSs OLTP, ela não pode gerar corretamente consultas de criação de tabela para o Vertica. Portanto, para registrar dados com êxito, você precisará criar manualmente a tabela necessária no Vertica usando SQL, cujo conjunto de campos e tipos coincide com o conjunto de dados graváveis ​​R.

Além disso, o próprio processo de gravação parece simples (não esqueça de abrir e fechar a conexão contra):

 sqlSave(con, mtcars.result, tablename = 'public.mtcars_result', append = TRUE, rownames = FALSE, colnames = FALSE) 

Usando o Vertica com R


O trabalho interativo com dados no R Studio é adequado para o modo de pesquisa e preparação de dados. Mas é completamente inadequado para a análise de fluxos de dados e grandes matrizes no modo automático. Uma das opções para o esquema de análise preditiva híbrida R com a Vertica é a preparação de dados para aprender sobre R e identificar dependências para a construção de modelos. Em seguida, usando as funções de ML incorporadas ao Vertica, os modelos de previsão para dados preparados em R são treinados levando em consideração as dependências identificadas das variáveis.

Existe uma opção mais flexível quando todo o poder da linguagem R é usado diretamente no Vertica. Para isso, a Vertica desenvolveu a distribuição R na forma de uma biblioteca de plug-ins que permite usar funções de transformação escritas diretamente na linguagem R. em consultas SQL. A documentação descreve em detalhes a instalação do suporte R para Vertica e os pacotes R adicionais necessários para a operação, se houver.

Salvando o Modelo R no Vertica


Para usar o modelo de análise preparado anteriormente pelo R Studio nas funções R em execução no Vertica, é necessário salvá-lo nos servidores Vertica. Salvar localmente em cada servidor do cluster com um arquivo não é conveniente nem confiável, novos servidores podem ser adicionados ao cluster e, ao alterar o modelo, será necessário lembrar de reescrever todos os arquivos novamente.

A maneira mais conveniente é serializar o modelo R em texto e salvar a função Vertica como UDF, que retornará esse texto como uma constante (não esqueça de abrir e fechar a conexão):

 #     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) 

O método proposto permite contornar a restrição do Vertica nos parâmetros transmitidos na função de transformação, onde apenas a transferência de constantes ou expressões das constantes é necessária. O Vertica UDF SQL compila não como funções, mas como expressões calculadas, ou seja, ao passar um parâmetro, em vez de chamar a função, seu texto (nesse caso, uma constante) será transferido, que foi salvo no código acima.

Se você alterar o modelo, será necessário recriar sua função no Vertica. Faz sentido agrupar esse código em uma função universal que gera uma função no Vertica com o nome especificado do modelo passado.

Funções R para Vertica


Para conectar funções R ao Vertica, você precisa gravar funções de análise e registro de dados no Vertica.

A função de trabalhar com dados do próprio Vertica deve ter dois parâmetros: o conjunto de dados resultante (como data.frame) e os parâmetros de trabalho (como lista):

 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) } 

No corpo da função, é verificado que o parâmetro do modelo é passado, cujo texto é traduzido para a forma binária e desserializado para o objeto do modelo de análise. Como a Vertica transfere seus próprios nomes de campo para o conjunto de dados da função, nomes de campo explícitos são definidos para o conjunto de dados. Com base nos dados obtidos, um conjunto de resultados é construído com o nome do modelo da máquina e previsão zero. Em seguida, uma previsão é construída usando apenas os campos necessários para a análise do conjunto de dados obtido. O campo de previsão do conjunto de resultados é definido como valores booleanos (para uma alteração em vez de valores numéricos) e o resultado é retornado da função.

Agora resta descrever o registro dessa função no 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) } 

A função MtCarsAnalizeFactory descreve o nome da função usada para a operação, o campo para o conjunto de dados de entrada e saída e a segunda função descreve o parâmetro passado "modelo". Tipos de campo são tipos de dados Vertica. Ao transferir e retornar dados, o Vertica converte automaticamente os valores nos tipos de dados necessários para o idioma R. Você pode ver a tabela de compatibilidade de tipos na documentação do Vertica.

Você pode testar a operação da função gravada do Vertica nos dados carregados no R studio:

 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) 

Conecte a biblioteca de recursos ao Vertica


Salvamos todas as funções acima em um arquivo "mtcars_func.r" e carregamos esse arquivo em um dos servidores do cluster Vertica em "/ home / dbadmin".

Um ponto importante: no R Studio, você precisa definir a opção de salvar a tradução de linhas em arquivos no modo Posix (LF). Isso pode ser feito nas opções globais, seção Código, guia Salvar. Se você estiver trabalhando no Windows, por padrão, o arquivo será salvo com um retorno de carro e não poderá ser carregado no Vertica.

Nós nos conectamos ao servidor do cluster Vertica, no qual salvamos o arquivo e carregamos a biblioteca:

 CREATE LIBRARY MtCarsLibs AS '/home/dbadmin/mtcars_func.r' LANGUAGE 'R'; 

Agora, nesta biblioteca, você pode registrar a função 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; 

Chamar funções R no Vertica


Chamamos a função R, passando o texto do modelo, que foi salvo anteriormente como uma função UDF:

 SELECT MtCarsAnalize(car_model, cyl, wt, gear USING PARAMETERS model = public.MtCarsAnalizeModel()) OVER() FROM public.mtcars; 



Pode-se verificar que, assim como nos casos anteriores, a previsão é 100% consistente com o estado real das coisas:

 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 

Observe: as funções de transformação no Vertica retornam seu próprio conjunto de dados dos campos e registros definidos nas funções; no entanto, elas podem ser usadas em consultas se agrupadas em uma subconsulta.

Quando as funções R são conectadas, a Vertica copia o código-fonte para sua instalação, que é compilado no código da máquina. O arquivo R de origem carregado no servidor após a conexão com a biblioteca não é necessário para trabalho adicional. A velocidade das funções que levam em consideração a compilação binária é alta o suficiente para trabalhar com grandes matrizes de dados; no entanto, vale lembrar que todas as operações R são executadas na memória e existe o risco de troca, se houver falta de memória do SO para atender às necessidades da Vertica e R trabalhando juntas. .

Se a função for chamada na partição dos dados especificados em PARTITION BY for OVER, o Vertica paraleliza a execução de cada partição nos servidores de cluster. Portanto, se um fabricante ainda estivesse presente no conjunto de dados, além do modelo da máquina, você poderia especificá-lo em PARTITION BY e paralelizar a análise para cada fabricante.

Outras oportunidades de aprendizado de máquina da Vertica


Além do R, a Vertica pode desenvolver suas próprias funções de transformação em C, Java e Python. Cada idioma possui suas próprias nuances e recursos para escrever e se conectar ao Vertica. Juntamente com seu próprio ML, tudo isso confere à Vertica uma boa reserva para análise preditiva de dados.

Obrigado e links


Quero sinceramente agradecer ao meu amigo e colega Vlad Malofeev, da Perm, que me apresentou a R e me ajudou a descobrir isso em um de nossos projetos conjuntos.

Inicialmente, em um projeto em que uma previsão foi feita em condições difíceis para o futuro usando dados do ano passado, os desenvolvedores tentaram usar SQL e Java. Isso causou grandes dificuldades, levando em consideração a qualidade dessas fontes e atrasou bastante o desenvolvimento do projeto. Vlad veio ao projeto com R, conectamos R à Vertica, ele dirigiu os dados para o estúdio e tudo girou e virou lindamente imediatamente. Literalmente em semanas, tudo o que durou meses foi varrido, salvando o projeto de códigos complexos.

Os dados de exemplo com carros podem ser baixados do repositório GIT:

 git clone https://github.com/vertica/Machine-Learning-Examples 

e faça o upload para o Vertica:

 /opt/vertica/bin/vsql -d <name of your database> -f load_ml_data.sql 

Se você deseja aprofundar-se no ML e aprender a trabalhar com R, recomendo um livro em russo "R em ação". Análise e visualização de dados na linguagem R. ” Ele foi escrito em uma linguagem humana simples e acessível e é adequado para iniciantes que ainda não encontraram o aprendizado de máquina.

Aqui você pode ver informações sobre como conectar a biblioteca R ao Vertica.

Para quem já começou a aprender e usar o ML em Python, vale a pena prestar atenção no IDE Rodeo, este é um análogo do R Studio, porque sem a análise interativa da qualidade é impossível. Penso que tudo o que é descrito neste artigo no R de maneira semelhante pode ser desenvolvido em Python, incluindo salvar o modelo em funções UDF e desenvolver funções de análise para o Vertica. Se você marcar, não se esqueça de cancelar a inscrição sobre os resultados nos comentários, serei grato pelas informações.

Obrigado pelo seu tempo e espero poder demonstrar a simplicidade e os incríveis recursos da simbiose de R e Vertica.

Source: https://habr.com/ru/post/pt436306/


All Articles