Python vs. R: Syntaktische Zuckermagie

Veröffentlicht: 2022-07-22

Mein Entwicklungsgeschmack hat sich erweitert, seit ich gelernt habe, die Süße von Python und R zu schätzen. Data Science ist eine Kunst, die aus verschiedenen Blickwinkeln angegangen werden kann, aber eine sorgfältige Balance von Sprache, Bibliotheken und Fachwissen erfordert. Die umfangreichen Möglichkeiten von Python und R bieten syntaktischen Zucker: eine Syntax, die unsere Arbeit erleichtert und es uns ermöglicht, komplexe Probleme mit kurzen, eleganten Lösungen anzugehen.

Diese Sprachen bieten uns einzigartige Möglichkeiten, unseren Lösungsraum zu erkunden. Jede Sprache hat ihre eigenen Stärken und Schwächen. Der Trick, um jedes Tool effektiv zu nutzen, besteht darin, zu erkennen, welche Problemtypen von jedem Tool profitieren, und zu entscheiden, wie wir unsere Ergebnisse kommunizieren möchten. Der syntaktische Zucker in jeder Sprache ermöglicht es uns, effizienter zu arbeiten.

R und Python fungieren als interaktive Schnittstellen auf untergeordnetem Code, sodass Data Scientists ihre gewählte Sprache für die Datenexploration, Visualisierung und Modellierung verwenden können. Diese Interaktivität ermöglicht es uns, die unaufhörliche Schleife des Bearbeitens und Kompilierens von Code zu vermeiden, was unsere Arbeit unnötig erschwert.

Diese Hochsprachen ermöglichen es uns, mit minimaler Reibung zu arbeiten und mit weniger Code mehr zu erreichen. Der syntaktische Zucker jeder Sprache ermöglicht es uns, unsere Ideen schnell in einer REPL (Read-Evaluate-Print-Schleife) zu testen, einer interaktiven Schnittstelle, wo Code in Echtzeit ausgeführt werden kann. Dieser iterative Ansatz ist eine Schlüsselkomponente im modernen Datenverarbeitungszyklus.

R vs. Python: Ausdrucksstark und spezialisiert

Die Stärke von R und Python liegt in ihrer Ausdruckskraft und Flexibilität. Jede Sprache hat spezifische Anwendungsfälle, in denen sie leistungsfähiger ist als die andere. Darüber hinaus löst jede Sprache Probleme entlang unterschiedlicher Vektoren und mit sehr unterschiedlichen Ausgabetypen. Diese Stile haben in der Regel unterschiedliche Entwicklergemeinschaften, in denen eine Sprache bevorzugt wird. Da jede Community organisch wächst, tendieren ihre bevorzugte Sprache und Feature-Sets zu einzigartigen syntaktischen Zuckerstilen, die das zur Lösung von Problemen erforderliche Codevolumen reduzieren. Und wenn die Gemeinschaft und die Sprache reifen, wird der syntaktische Zucker der Sprache oft noch süßer.

Obwohl jede Sprache ein leistungsstarkes Toolset zum Lösen von Datenproblemen bietet, müssen wir diese Probleme so angehen, dass die besonderen Stärken der Tools ausgenutzt werden. R wurde als statistische Computersprache geboren und verfügt über eine breite Palette von Werkzeugen, um statistische Analysen durchzuführen und die Daten zu erklären. Python und seine maschinellen Lernansätze lösen ähnliche Probleme, aber nur solche, die in ein maschinelles Lernmodell passen. Stellen Sie sich statistisches Rechnen und maschinelles Lernen als zwei Schulen für die Datenmodellierung vor: Obwohl diese Schulen eng miteinander verbunden sind, sind ihre Ursprünge und Paradigmen für die Datenmodellierung unterschiedlich.

R liebt Statistiken

R hat sich zu einem umfangreichen Paketangebot für statistische Analysen, lineare Modellierung und Visualisierung entwickelt. Da diese Pakete seit Jahrzehnten Teil des R-Ökosystems sind, sind sie ausgereift, effizient und gut dokumentiert. Wenn ein Problem einen statistischen Rechenansatz erfordert, ist R das richtige Werkzeug für den Job.

Die Hauptgründe, warum R von seiner Community geliebt wird, laufen auf Folgendes hinaus:

  • Diskrete Datenmanipulations-, Berechnungs- und Filtermethoden.
  • Flexible Verkettungsoperatoren zum Verbinden dieser Methoden.
  • Ein prägnanter syntaktischer Zucker, der es Entwicklern ermöglicht, komplexe Probleme mit komfortablen statistischen und Visualisierungsmethoden zu lösen.

Ein einfaches lineares Modell mit R

Um zu sehen, wie prägnant R sein kann, erstellen wir ein Beispiel, das Diamantpreise vorhersagt. Zuerst brauchen wir Daten. Wir verwenden den Standarddatensatz für diamonds , der mit R installiert wird und Attribute wie Farbe und Schliff enthält.

Wir werden auch den Pipe-Operator ( %>% ) von R demonstrieren, das Äquivalent zum Unix-Befehlszeilen-Pipe-Operator ( | ). Dieses beliebte Stück der syntaktischen Zuckerfunktion von R wird von der tidyverse-Paketsuite zur Verfügung gestellt. Dieser Operator und der daraus resultierende Codestil sind ein Game Changer in R, da er die Verkettung von R-Verben (dh R-Funktionen) ermöglicht, um eine Vielzahl von Problemen zu teilen und zu überwinden.

Der folgende Code lädt die erforderlichen Bibliotheken, verarbeitet unsere Daten und generiert ein lineares Modell:

 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 macht diese lineare Gleichung mit ihrem syntaktischen Zucker einfach zu programmieren und zu verstehen. Lassen Sie uns nun unsere Aufmerksamkeit darauf lenken, wo Python König ist.

Python eignet sich am besten für maschinelles Lernen

Python ist eine leistungsstarke Allzwecksprache, wobei sich eine ihrer primären Benutzergemeinschaften auf maschinelles Lernen konzentriert und beliebte Bibliotheken wie scikit-learn, imbalanced-learn und Optuna nutzt. Viele der einflussreichsten Toolkits für maschinelles Lernen, wie TensorFlow, PyTorch und Jax, wurden hauptsächlich für Python geschrieben.

Pythons syntaktischer Zucker ist die Magie, die Experten für maschinelles Lernen lieben, einschließlich der prägnanten Datenpipeline-Syntax sowie des Fit-Transform-Predict-Musters von scikit-learn:

  1. Transformieren Sie Daten, um sie für das Modell vorzubereiten.
  2. Konstruieren Sie ein Modell (implizit oder explizit).
  3. Passen Sie das Modell an.
  4. Prognostizieren Sie neue Daten (überwachtes Modell) oder transformieren Sie die Daten (unüberwacht).
    • Berechnen Sie für überwachte Modelle eine Fehlermetrik für die neuen Datenpunkte.

Die scikit-learn-Bibliothek kapselt Funktionen, die diesem Muster entsprechen, und vereinfacht gleichzeitig die Programmierung für Exploration und Visualisierung. Es gibt auch viele Funktionen, die jedem Schritt des maschinellen Lernzyklus entsprechen und Kreuzvalidierung, Hyperparameter-Tuning und Pipelines bieten.

Ein Diamond Machine Learning-Modell

Wir konzentrieren uns jetzt auf ein einfaches Beispiel für maschinelles Lernen mit Python, für das es keinen direkten Vergleich in R gibt. Wir verwenden denselben Datensatz und heben das Fit-Transform-Predict-Muster in einem sehr engen Codeabschnitt hervor.

Nach einem maschinellen Lernansatz teilen wir die Daten in Trainings- und Testpartitionen auf. Wir wenden die gleichen Transformationen auf jede Partition an und verketten die enthaltenen Operationen mit einer Pipeline. Die Methoden (Fit und Score) sind Schlüsselbeispiele für leistungsstarke Methoden des maschinellen Lernens, die in scikit-learn enthalten sind:

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

Wir können sehen, wie rationalisiert der maschinelle Lernprozess in Python ist. Darüber hinaus helfen die sklearn -Klassen von Python Entwicklern, Lecks und Probleme im Zusammenhang mit der Weitergabe von Daten durch unser Modell zu vermeiden und gleichzeitig strukturierten Code auf Produktionsebene zu generieren.

Was können R und Python sonst noch?

Abgesehen von der Lösung statistischer Anwendungen und der Erstellung von Modellen für maschinelles Lernen zeichnen sich R und Python durch Berichterstellung, APIs, interaktive Dashboards und die einfache Einbeziehung externer Low-Level-Codebibliotheken aus.

Entwickler können interaktive Berichte sowohl in R als auch in Python generieren, aber es ist viel einfacher, sie in R zu entwickeln. R unterstützt auch den Export dieser Berichte in PDF und HTML.

Beide Sprachen ermöglichen es Data Scientists, interaktive Datenanwendungen zu erstellen. R und Python verwenden die Bibliotheken Shiny bzw. Streamlit, um diese Anwendungen zu erstellen.

Schließlich unterstützen R und Python beide externe Bindungen an Low-Level-Code. Dies wird normalerweise verwendet, um hochleistungsfähige Operationen in eine Bibliothek einzufügen und diese Funktionen dann in der Sprache Ihrer Wahl aufzurufen. R verwendet das Rcpp-Paket, während Python das pybind11-Paket verwendet, um dies zu erreichen.

Python und R: Jeden Tag süßer werden

In meiner Arbeit als Data Scientist verwende ich regelmäßig sowohl R als auch Python. Der Schlüssel liegt darin, zu verstehen, wo jede Sprache am stärksten ist, und dann ein Problem so anzupassen, dass es in eine elegant codierte Lösung passt.

Bei der Kommunikation mit Kunden möchten Datenwissenschaftler dies in der Sprache tun, die am leichtesten zu verstehen ist. Daher müssen wir abwägen, ob eine statistische oder maschinell lernende Darstellung effektiver ist und dann die am besten geeignete Programmiersprache verwenden.

Python und R bieten jeweils eine ständig wachsende Sammlung von syntaktischem Zucker, die sowohl unsere Arbeit als Datenwissenschaftler vereinfachen als auch die Verständlichkeit für andere erleichtern. Je ausgefeilter unsere Syntax, desto einfacher ist es, unsere bevorzugten Sprachen zu automatisieren und mit ihnen zu interagieren. Ich mag meine datenwissenschaftliche Sprache süß, und die eleganten Lösungen, die daraus resultieren, sind noch süßer.

Weiterführende Literatur im Toptal Engineering Blog:

  • Eine Einführung in die Theorie des maschinellen Lernens und ihre Anwendungen: Ein visuelles Tutorial mit Beispielen
  • Python-Entwurfsmuster: Für eleganten und modischen Code
  • Social Network Analysis in R und Gephi: Graben in Twitter
  • Erforschung überwachter Algorithmen für maschinelles Lernen
  • Gewährleistung von sauberem Code: Ein Blick auf Python, parametrisiert