BookmarkSubscribeRSS Feed
ehellas
SAS Employee

Olá pessoal,

 

Modelos anlíticos vem em vários formatos, tamanhos e, complexidades. Um uso comum do software do SAS é utilizá-lo para para manejar o ciclo de vidas de modelos. Entretanto, reconhecemos que nem sempre este é o caso. Você pode precisar utilizar as saídas do SAS fora do SAS. Seja criando modelos em Python ou R e colocando em produção no SAS ou criando modelos no SAS e utilizá-los em outro lugar.

Para ajudar no último caso, estou aqui para apresentá-los aos mais novos pacotes Open Source para Python, sas-scoring-translator-python (pysct), e para o R, sas-scoring-translator-r (rsct), que traduz os "scoring codes" do SAS para estas linguagens. Isso facilita o uso de modelos SAS na sua aplicação (ou caso você queira aprender um pouco mais como o pacote  SWAT funciona). Estas ferramentas estão disponíveis no sassoftware GitHub.

 

Obtendo o código de escoragem SAS

A essa altura vocês já devem saber que o SAS possui várias interfaces que ajudam a criar modelos (que podem até serem feitos para você através do Auto ML). E, claro, depois de criar seus fabulosos modelos, você quer utilizá-los, o que você poderia fazer então? Exportar o código de escoragem, é claro.

 

Primeiramente, no Model Studio (SAS Viya), vá até "Pipeline Comparison", como pode assinala a imagem abaixo.

 

ehellas_0-1628112063250.png

 

Em seguida, selecione um dos seus modelos, (que não precisa estar registrado ou publicado), e exporte o código de escoragem.

 

ehellas_1-1628112153522.png

 

 

Você irá baixar um arquivo zip com o seu código de escoragem SAS (guarde o nome dmcas_epsscorecode.sas por enquanto, vamos utilizá-lo mais tarde).

 

ehellas_4-1628112310660.png

 

Você não precisas descompactar o arquivo (unzip), mas, se você olhar o que tem dentro vai encontrar alguns arquivos .sas parecido com o exemplo abaixo, que vai depender do modelo que você vai utilizar.

 

/*
* This score code file references one or more analytic stores that are located in the caslib "Models".
* This score code file references the following analytic-store tables:
* _28LWD4IVTS9I294A6F893FNBY_ast
*/
/*----------------------------------------------------------------------------------*/
/* Product: Visual Data Mining and Machine Learning */
/* Release Version: V2021.1.1 */
/* Component Version: V2020.1.5 */
/* CAS Version: V.04.00M0P05162021 */
/* SAS Version: V.04.00M0P051621 */
/* Site Number: 70180938 */
/* Host: sas-cas-server-default-client */
/* Encoding: utf-8 */
/* Java Encoding: UTF8 */
/* Locale: en_US */
/* Project GUID: f8b37e46-c893-4cf5-8183-0802c729b1b0 */
/* Node GUID: 25d24897-fad4-4e1d-bc94-1a7d93340ade */
/* Node Id: 28LWD4IVTS9I294A6F893FNBY */
/* Algorithm: Gradient Boosting */
/* Generated by: sasdemo */
/* Date: 26JUL2021:19:12:08 */
/*----------------------------------------------------------------------------------*/
data sasep.out;
dcl package score _28LWD4IVTS9I294A6F893FNBY();
dcl double "P_BAD1" having label n'Predicted: BAD=1';
dcl double "P_BAD0" having label n'Predicted: BAD=0';
dcl nchar(32) "I_BAD" having label n'Into: BAD';
dcl nchar(4) "_WARN_" having label n'Warnings';
dcl double EM_EVENTPROBABILITY;
dcl nchar(12) EM_CLASSIFICATION;
dcl double EM_PROBABILITY;
varlist allvars [_all_];

method init();
_28LWD4IVTS9I294A6F893FNBY.setvars(allvars);
_28LWD4IVTS9I294A6F893FNBY.setkey(n'C08002467175AC235F1C68321869975F6170F229');
end;

method post_28LWD4IVTS9I294A6F893FNBY();
dcl double _P_;

if "P_BAD0" = . then "P_BAD0" = 0.8005033557;
if "P_BAD1" = . then "P_BAD1" = 0.1994966443;
if MISSING("I_BAD") then do ;
_P_ = 0.0;
if "P_BAD1" > _P_ then do ;
_P_ = "P_BAD1";
"I_BAD" = ' 1';
end;
if "P_BAD0" > _P_ then do ;
_P_ = "P_BAD0";
"I_BAD" = ' 0';
end;
end;
EM_EVENTPROBABILITY = "P_BAD1";
EM_CLASSIFICATION = "I_BAD";
EM_PROBABILITY = MAX("P_BAD1", "P_BAD0");

end;

method run();
set SASEP.IN;
_28LWD4IVTS9I294A6F893FNBY.scoreRecord();
post_28LWD4IVTS9I294A6F893FNBY();
end;

method term();
end;

enddata;

 

Até então tudo certo, desde que você saiba utilizar códigos SAS. Entretanto, se você não souber, ou caso queira escorar tabelas utilizando todo o poder de processamento distribuído do SAS Viya através do R ou Python, um código SAS apenas não te ajuda exatamente. Claro, você poderia usar o SWAT  e fazer toda a tradução manualmente, mas isso não seria nada eficiente. E é para isso que estamos aqui!pysct - Python Scoring Code Translator (e rsct) vão te ajudar. Ele vai ler o arquivo zip e traduzir para você, vamos dar uma olhada.

 

Vamos começar com Python, mas caso esteja interessado apenas em R, sinta-se a vontade para pular até a sessão do R.

 

Python Scoring Code Translator

 

Primeiramente, vamos instalar o pacote a partir do GitHub do SAS:

 

## Instale direto do github caso ainda não o tenha
pip install git+https://github.com/sassoftware/sas-scoring-translator-python.git

 

A ferramenta é bem direta e fácil de utilizar. Olhe a tabela de referência, de onde seu modelo veio e o tipo do cógido de escoragem. No nosso exemplo nos fizemos um modelo através do Model Studio, e, o tipo de código de escoragem é o nome que destaquei mais cedo, dmcas_epscorecode.sas. Com isso, a função que utilizaremos é a EPS_translate(). Outras combinações de modelos e tipo de código de escoragem estão definidos na tabela a seguir:

 

Interface Code Type Base File Name Translation Function
Model Studio DataStep dmcas_scorecode.sas pysct.DS_translate()
Model Studio DS2 dmcas_epscorecode.sas pysct.EPS_translate()
Visual Text Analytics Sentiment - CAS Procedure scoreCode.sas pysct.nlp_sentiment_translate()
Visual Text Analytics Categories - CAS Procedure scoreCode.sas pysct.nlp_category_translate()
Visual Text Analytics Topics - CAS Procedure AstoreScoreCode.sas pysct.nlp_topics_translate()
Visual Text Analytics Concepts - CAS Procedure ScoreCode.sas pysct.nlp_concepts_translate()

 

E, com apena a código a seguir, você já terá tudo o que precisa. No nosso exemplo, veja o código:

 

# importando a biblioteca
import pysct

out = pysct.EPS_translate(
            in_file = "C:/score_code_Gradient Boosting.zip",  ## caminho do seu .zip (sim, .zip compactado, não precisa se preocupar)
            out_caslib = "casuser",                           ## Nome da caslib da tabela de saída (depois dos dados escorados)
            out_castable = "hmeq",                            ## Nome da tabela de saida (depois dos dados escorados)
            in_caslib = "public",                             ## Nome da caslib onde a tabela a ser escorada está
            in_castable = "hmeq",                             ## Nome da tabela a ser escorada
            copyVars="ALL",                                   ## por padrão, o SAS retorna apenas o resultados, utilize "ALL" caso queira copiar todas as variáveis, ou omita caso contrário
            out_file="gradientBoosting.py"                    ## caminho de saída do arquivo python)

out.keys()

 

Exemplo do output:

The file was successfully written to gradientBoosting.py

dict_keys(['ds2_raw', 'py_code', 'out_caslib', 'out_castable', 'out_file'])

 

Por padrão, o pysct escreve o arquivo no seu diretório atual. Todo o código pode ser encontrado no objeto out no caso de querer mais detalhes. Mas agora vamos dar uma olhada no código gerado, o gradientBoosting.py.

 

## SWAT package needed to run the codes, below the packages in pip and conda
# documentation: https://github.com/sassoftware/python-swat/
# pip install swat
# conda install -c sas-institute swat

import swat

## Defining tables and models variables
in_caslib = "public"
in_castable = "hmeq"
out_caslib = "casuser"
out_castable = "hmeq"
astore_name = "_28LWD4IVTS9I294A6F893FNBY_ast"
astore_file_name = "_28LWD4IVTS9I294A6F893FNBY_ast.sashdat"

## Connecting to SAS Viya
conn = swat.CAS(hostname = "myserver.com", ## change if needed
                port = 8777,
                protocol='http',  ## change protocol to cas and port to 5570 if using binary connection (unix)
                username='username', ## use your own credentials
                password='password') ## we encorage using .authinfo 


## Loading model to memory
## assuming the model is already inside the viya server

conn.table.loadTable(caslib= "Models",
                      path = astore_file_name, #case sensitive
                      casOut = {"name": astore_name,
                                "caslib": "Models"}
                                )

score_table = conn.CASTable(name = in_castable,
                            caslib = in_caslib
                                )

column_names = score_table.columns.tolist()


## loading astore actionset and scoring
conn.loadActionSet("astore")

conn.astore.score(table = {"caslib": in_caslib, "name": in_castable},
                   out = {"caslib": out_caslib, "name": out_castable, "replace": True},
                   copyVars = column_names,
                   rstore = {"name": astore_name, "caslib": "Models"}
              )

## Obtaining output/results table
scored_table = conn.CASTable(name = out_castable,
                              caslib = out_caslib)
                              
scored_table.head()

 

E a mágica está feita, você precisa apenas editar a conexão (swat.CAS) com as suas credencias e do seu servidor, e o seu código está pronto para ser usado no Python.

Apesar de utilizar alguns valores padrões (ou copiar do código SAS original), você pode alterar para ajustar ao seu caso, mas agora você já tem uma boa ideia de como começar a criar ótimas integrações.

 

R Scoring Code Translator

Se você leu a sessão do Python, não há muitas mudanças, apenas na sintaxe. Preparem suas <- !
 
Primeiramente, vamos instalar o pacote do GitHub do SAS (não está disponível no CRAN).
 
# Como o pacote não está disponível no CRAN, você deve instalá-lo a partir do git 
# recomendamos utilizar o pacote remotes
# install.packages("remotes") # descomente em caso não o tenha instalado

remotes::install_github("sassoftware/sas-scoring-translator-r")  
 
Para saber exatamente qual função utilizar, utilize a tabela de referência para comparar de onde tirou seu modelo, e qual é o tipo do código de escorage. No nosso exemplo, o modelo foi feito no Model Studio, e o tipo do código é o que pedi para guardarem mais cedo, dmcas_epscorecode.sas . Assim, basta utilizar a função EPS_translate(). Outras combinações estão descritas na tabela a seguir.
 
Interface Code Type Base File Name Translation Function
Model Studio DataStep dmcas_scorecode.sas DS_translate()
Model Studio DS2 dmcas_epscorecode.sas EPS_translate()
Visual Text Analytics Sentiment - CAS Procedure scoreCode.sas nlp_sentiment_translate()
Visual Text Analytics Categories - CAS Procedure scoreCode.sas nlp_category_translate()
Visual Text Analytics Topics - CAS Procedure AstoreScoreCode.sas nlp_topics_translate()
Visual Text Analytics Concepts - CAS Procedure ScoreCode.sas nlp_concepts_translate()

 

E, com algumas linhas, conseguimos traduzir o nosso código, sem nem precisar descompactá-lo.

 

## Carregando o pacote
library("rsct")

output_infos <- EPS_translate(in_file = "C:/score_code_Gradient Boosting.zip",  ## caminho do seu .zip (sim, .zip compactado, não precisa se preocupar)
                              out_caslib = "casuser",                     ## Nome da caslib da tabela de saída (depois dos dados escorados)
                              out_castable = "hmeq_scored",               ## Nome da tabela de saida (depois dos dados escorados)
                              in_caslib = "public",                       ## Nome da caslib onde a tabela a ser escorada está
                              in_castable = "hmeq",                       ## Nome da tabela que a ser escorarada
                              copyVars = "ALL",                           ## por padrão, o SAS retorna apenas o resultados, utilize "ALL" caso queira copiar todas as variáveis, ou omita caso contrário
                              out_file = "gb_translated.R"                ## caminho de saída do arquivo R
)

names(output_infos)

 

Exemplo do output:

File successfully written to gb_translated.R

[1] "r_code"       "out_file"     "out_caslib"   "out_castable"

 

O arquivo gb_translated.R foi salvo no diretório padrão de sua sessão, mas você poderia também utilizar um caminho completo. O objeto output_infos é uma lista com detalhes da tradução, caso você precise utilizar em outro lugar. E esse é o código gerado:
 
## install swat package from github if needed, uncomment OS version
# install.packages('https://github.com/sassoftware/R-swat/releases/download/v1.6.1/R-swat-1.6.1-linux64.tar.gz',repos=NULL, type='file') ## linux
# install.packages('https://github.com/sassoftware/R-swat/releases/download/v1.6.1/R-swat-1.6.1-win64.tar.gz',repos=NULL, type='file') ## windows
# install.packages('https://github.com/sassoftware/R-swat/releases/download/v1.6.1/R-swat-1.6.1-REST-only-osx64.tar.gz',repos=NULL, type='file') ## osx

## Load library
library("swat")

## Defining tables and models variables
in_caslib <- "public"
in_castable <- "hmeq"
out_caslib <- "casuser"
out_castable <- "hmeq_scored"
astore_name <- "_28LWD4IVTS9I294A6F893FNBY_ast"
astore_file_name <- "_28LWD4IVTS9I294A6F893FNBY_ast.sashdat"

## Connecting to SAS Viya
conn <- CAS(hostname = "myserver.com", ## change if needed
						port = 8777,
						protocol='http',  ## change protocol to cas and port to 5570 if using binary connection (unix)
						username='sasusername', ## use your own credentials
						password='password') ## we encorage using  .authinfo

## Loading model to memory
cas.table.loadTable(conn,
                      caslib= "Models",
                      path = astore_file_name , #case sensitive
                      casOut = list(name = astore_name,
                                    caslib = "Models")
              )

## Defining scoring table obtaining column names
score_table <- defCasTable(conn,
                             tablename = in_castable,
                             caslib = in_caslib)

column_names <- names(score_table)

## loading astore actionset and scoring
loadActionSet(conn, "astore")

cas.astore.score(conn,
                   table = list(caslib= in_caslib, name = in_castable),
                   out = list(caslib = out_caslib, name = out_castable, replace = TRUE),
                   copyVars = column_names,
                   rstore = list(name = astore_name, caslib = "Models")
              )

## Obtaining output/results table
scored_table <- defCasTable(conn,
                            tablename = out_castable,
                            caslib = out_caslib)

head(scored_table)
 
Como você pode notar, está quase pronto para ser utilizado, só falta editar a conexão com o CAS (usando CAS) com suas credencias e do seu servidor, e seu código está pronto para ser usado diretamente no R. Você pode fazer as alterações que precisar, mas é uma ótima maneira de começar a entender como SAS e Open Source podem trabalhar juntos.

 

Conclusão
 
Quanto antes concordarmos que não é uma questão de Python, R ou SAS, mas sim com SAS, mais rápido podemos criar soluções integradas. Eu realmente espero que essas ferramentas possam ser úteis e interessantes para vocês. E é claro, vamos continuar melhorando estes pacotes e criando mais, especialmente se soubermos que vocês estão utilizando. Qualquer report de bug ou pedidos podem ser feitos no GitHub. Vamos continuar melhorando todas as formas de integração.
1 REPLY 1
diegoserodio
SAS Employee
Projeto incrível! Parabéns pelo trabalho!!