Python vs. R: Magia de Açúcar Sintática

Publicados: 2022-07-22

Meu paladar de desenvolvimento se expandiu desde que aprendi a apreciar a doçura encontrada em Python e R. A ciência de dados é uma arte que pode ser abordada de vários ângulos, mas requer um equilíbrio cuidadoso de linguagem, bibliotecas e experiência. Os recursos expansivos de Python e R fornecem açúcar sintático: sintaxe que facilita nosso trabalho e nos permite abordar problemas complexos com soluções curtas e elegantes.

Essas linguagens nos fornecem maneiras exclusivas de explorar nosso espaço de soluções. Cada idioma tem seus próprios pontos fortes e fracos. O truque para usar cada uma de forma eficaz é reconhecer quais tipos de problemas se beneficiam de cada ferramenta e decidir como queremos comunicar nossas descobertas. O açúcar sintático em cada idioma nos permite trabalhar com mais eficiência.

R e Python funcionam como interfaces interativas sobre o código de nível inferior, permitindo que os cientistas de dados usem a linguagem escolhida para exploração, visualização e modelagem de dados. Essa interatividade nos permite evitar o loop incessante de edição e compilação de código, o que complica desnecessariamente nosso trabalho.

Essas linguagens de alto nível nos permitem trabalhar com o mínimo de atrito e fazer mais com menos código. O açúcar sintático de cada linguagem nos permite testar rapidamente nossas ideias em um REPL (read-evaluate-print loop), uma interface interativa onde o código pode ser executado em tempo real. Essa abordagem iterativa é um componente-chave no ciclo de processo de dados moderno.

R vs. Python: expressivo e especializado

O poder do R e do Python está em sua expressividade e flexibilidade. Cada linguagem tem casos de uso específicos nos quais é mais poderosa que a outra. Além disso, cada linguagem resolve problemas ao longo de diferentes vetores e com diferentes tipos de saída. Esses estilos tendem a ter diferentes comunidades de desenvolvedores onde um idioma é o preferido. À medida que cada comunidade cresce organicamente, seu idioma e recursos preferidos definem a tendência para estilos de açúcar sintático exclusivos que reduzem o volume de código necessário para resolver problemas. E à medida que a comunidade e o idioma amadurecem, o açúcar sintático do idioma geralmente fica ainda mais doce.

Embora cada linguagem ofereça um poderoso conjunto de ferramentas para resolver problemas de dados, devemos abordar esses problemas de maneiras que explorem os pontos fortes específicos das ferramentas. O R nasceu como uma linguagem de computação estatística e possui um amplo conjunto de ferramentas disponíveis para realizar análises estatísticas e explicar os dados. Python e suas abordagens de aprendizado de máquina resolvem problemas semelhantes, mas apenas aqueles que se encaixam em um modelo de aprendizado de máquina. Pense na computação estatística e no aprendizado de máquina como duas escolas para modelagem de dados: embora essas escolas sejam altamente interconectadas, suas origens e paradigmas para modelagem de dados são diferentes.

R adora estatísticas

O R evoluiu para uma oferta de pacote rica para análise estatística, modelagem linear e visualização. Como esses pacotes fazem parte do ecossistema R há décadas, eles são maduros, eficientes e bem documentados. Quando um problema exige uma abordagem de computação estatística, R é a ferramenta certa para o trabalho.

As principais razões pelas quais R é amado por sua comunidade se resumem a:

  • Manipulação discreta de dados, computação e métodos de filtragem.
  • Operadores de encadeamento flexíveis para conectar esses métodos.
  • Um açúcar sintático sucinto que permite aos desenvolvedores resolver problemas complexos usando métodos estatísticos e de visualização confortáveis.

Um modelo linear simples com R

Para ver o quão sucinto R pode ser, vamos criar um exemplo que prevê preços de diamantes. Primeiro, precisamos de dados. Usaremos o conjunto de dados padrão dos diamonds , que é instalado com R e contém atributos como cor e corte.

Também demonstraremos o operador pipe do R ( %>% ), o equivalente ao operador pipe da linha de comando do Unix ( | ). Esta parte popular do recurso de açúcar sintático do R é disponibilizada pelo pacote de pacotes arrumado. Este operador e o estilo de código resultante é um divisor de águas em R porque permite o encadeamento de verbos R (ou seja, funções R) para dividir e conquistar uma variedade de problemas.

O código a seguir carrega as bibliotecas necessárias, processa nossos dados e gera um modelo linear:

 library(tidyverse) library(ggplot2) mode <- function(data) { freq <- unique(data) freq[which.max(tabulate(match(data, freq)))] } data <- diamonds %>% mutate(across(where(is.numeric), ~ replace_na(., median(., na.rm = TRUE)))) %>% mutate(across(where(is.numeric), scale)) %>% mutate(across(where(negate(is.numeric)), ~ replace_na(.x, mode(.x)))) model <- lm(price~., data=data) model <- step(model) summary(model)
 Call: lm(formula = price ~ carat + cut + color + clarity + depth + table + x + z, data = data) Residuals: Min 1Q Median 3Q Max -5.3588 -0.1485 -0.0460 0.0943 2.6806 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -0.140019 0.002461 -56.892 < 2e-16 *** carat 1.337607 0.005775 231.630 < 2e-16 *** cut.L 0.146537 0.005634 26.010 < 2e-16 *** cut.Q -0.075753 0.004508 -16.805 < 2e-16 *** cut.C 0.037210 0.003876 9.601 < 2e-16 *** cut^4 -0.005168 0.003101 -1.667 0.09559 . color.L -0.489337 0.004347 -112.572 < 2e-16 *** color.Q -0.168463 0.003955 -42.599 < 2e-16 *** color.C -0.041429 0.003691 -11.224 < 2e-16 *** color^4 0.009574 0.003391 2.824 0.00475 ** color^5 -0.024008 0.003202 -7.497 6.64e-14 *** color^6 -0.012145 0.002911 -4.172 3.02e-05 *** clarity.L 1.027115 0.007584 135.431 < 2e-16 *** clarity.Q -0.482557 0.007075 -68.205 < 2e-16 *** clarity.C 0.246230 0.006054 40.676 < 2e-16 *** clarity^4 -0.091485 0.004834 -18.926 < 2e-16 *** clarity^5 0.058563 0.003948 14.833 < 2e-16 *** clarity^6 0.001722 0.003438 0.501 0.61640 clarity^7 0.022716 0.003034 7.487 7.13e-14 *** depth -0.022984 0.001622 -14.168 < 2e-16 *** table -0.014843 0.001631 -9.103 < 2e-16 *** x -0.281282 0.008097 -34.740 < 2e-16 *** z -0.008478 0.005872 -1.444 0.14880 --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 0.2833 on 53917 degrees of freedom Multiple R-squared: 0.9198, Adjusted R-squared: 0.9198 F-statistic: 2.81e+04 on 22 and 53917 DF, p-value: < 2.2e-16

R torna essa equação linear simples de programar e entender com seu açúcar sintático. Agora, vamos mudar nossa atenção para onde o Python é rei.

Python é melhor para aprendizado de máquina

Python é uma linguagem poderosa e de uso geral, com uma de suas principais comunidades de usuários focada em aprendizado de máquina, aproveitando bibliotecas populares como scikit-learn, desequilibrada-learn e Optuna. Muitos dos kits de ferramentas de aprendizado de máquina mais influentes, como TensorFlow, PyTorch e Jax, são escritos principalmente para Python.

O açúcar sintático do Python é a mágica que os especialistas em aprendizado de máquina adoram, incluindo a sintaxe sucinta do pipeline de dados, bem como o padrão fit-transform-predict do scikit-learn:

  1. Transforme dados para prepará-los para o modelo.
  2. Construa um modelo (implícito ou explícito).
  3. Encaixe o modelo.
  4. Preveja novos dados (modelo supervisionado) ou transforme os dados (não supervisionado).
    • Para modelos supervisionados, calcule uma métrica de erro para os novos pontos de dados.

A biblioteca scikit-learn encapsula a funcionalidade que corresponde a esse padrão enquanto simplifica a programação para exploração e visualização. Há também muitos recursos correspondentes a cada etapa do ciclo de aprendizado de máquina, fornecendo validação cruzada, ajuste de hiperparâmetros e pipelines.

Um modelo de aprendizado de máquina Diamond

Agora vamos nos concentrar em um exemplo simples de aprendizado de máquina usando Python, que não tem comparação direta em R. Usaremos o mesmo conjunto de dados e destacaremos o padrão fit-transform-predict em um pedaço de código muito compacto.

Seguindo uma abordagem de aprendizado de máquina, dividiremos os dados em partições de treinamento e teste. Vamos aplicar as mesmas transformações em cada partição e encadear as operações contidas com um pipeline. Os métodos (ajuste e pontuação) são exemplos importantes de métodos poderosos de aprendizado de máquina contidos no scikit-learn:

 import numpy as np import pandas as pd from sklearn.linear_model LinearRegression from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import OneHotEncoder from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer from pandas.api.types import is_numeric_dtype diamonds = sns.load_dataset('diamonds') diamonds = diamonds.dropna() x_train,x_test,y_train,y_test = train_test_split(diamonds.drop("price", axis=1), diamonds["price"], test_size=0.2, random_state=0) num_idx = x_train.apply(lambda x: is_numeric_dtype(x)).values num_cols = x_train.columns[num_idx].values cat_cols = x_train.columns[~num_idx].values num_pipeline = Pipeline(steps=[("imputer", SimpleImputer(strategy="median")), ("scaler", StandardScaler())]) cat_steps = Pipeline(steps=[("imputer", SimpleImputer(strategy="constant", fill_value="missing")), ("onehot", OneHotEncoder(drop="first", sparse=False))]) # data transformation and model constructor preprocessor = ColumnTransformer(transformers=[("num", num_pipeline, num_cols), ("cat", cat_steps, cat_cols)]) mod = Pipeline(steps=[("preprocessor", preprocessor), ("linear", LinearRegression())]) # .fit() calls .fit_transform() in turn mod.fit(x_train, y_train) # .predict() calls .transform() in turn mod.predict(x_test) print(f"R squared score: {mod.score(x_test, y_test):.3f}")

Podemos ver como o processo de aprendizado de máquina é simplificado em Python. Além disso, as classes sklearn do Python ajudam os desenvolvedores a evitar vazamentos e problemas relacionados à passagem de dados pelo nosso modelo, além de gerar código estruturado e em nível de produção.

O que mais R e Python podem fazer?

Além de resolver aplicativos estatísticos e criar modelos de aprendizado de máquina, R e Python se destacam em relatórios, APIs, painéis interativos e simples inclusão de bibliotecas externas de código de baixo nível.

Os desenvolvedores podem gerar relatórios interativos em R e Python, mas é muito mais simples desenvolvê-los em R. R também suporta a exportação desses relatórios para PDF e HTML.

Ambas as linguagens permitem que os cientistas de dados criem aplicativos de dados interativos. R e Python usam as bibliotecas Shiny e Streamlit, respectivamente, para criar esses aplicativos.

Por fim, R e Python suportam ligações externas para código de baixo nível. Isso normalmente é usado para injetar operações de alto desempenho em uma biblioteca e, em seguida, chamar essas funções de dentro da linguagem de escolha. R usa o pacote Rcpp, enquanto Python usa o pacote pybind11 para fazer isso.

Python e R: ficando mais doce a cada dia

Em meu trabalho como cientista de dados, uso R e Python regularmente. A chave é entender onde cada idioma é mais forte e, em seguida, ajustar um problema para caber em uma solução elegantemente codificada.

Ao se comunicar com os clientes, os cientistas de dados desejam fazê-lo na linguagem mais facilmente compreendida. Portanto, devemos ponderar se uma apresentação estatística ou de aprendizado de máquina é mais eficaz e, em seguida, usar a linguagem de programação mais adequada.

Python e R fornecem uma coleção cada vez maior de açúcar sintático, o que simplifica nosso trabalho como cientistas de dados e facilita sua compreensão para os outros. Quanto mais refinada for nossa sintaxe, mais fácil será automatizar e interagir com nossos idiomas preferidos. Eu gosto da minha linguagem de ciência de dados doce, e as soluções elegantes que resultam são ainda mais doces.

Leitura adicional no Blog da Toptal Engineering:

  • Uma introdução à teoria do aprendizado de máquina e suas aplicações: um tutorial visual com exemplos
  • Padrões de design Python: para código elegante e moderno
  • Análise de redes sociais em R e Gephi: explorando o Twitter
  • Explorando algoritmos de aprendizado de máquina supervisionado
  • Garantindo um código limpo: uma visão do Python, parametrizado