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.
Em seguida, selecione um dos seus modelos, (que não precisa estar registrado ou publicado), e exporte o código de escoragem.
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).
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! O 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.
# 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")
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"
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)
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.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!