Skip to main content

Modeling in Python

Published

2026-11-06

The model-basic-py.qmd file creates a model using Python’s palmerpenguins, numpy, pandas, and scikit-learn libraries.

View model-basic-py.qmd


---
title: "Model"
format:
  html:
    code-fold: true
---

```{python}
from palmerpenguins import penguins
from pandas import get_dummies
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn import preprocessing
```

## Get Data

```{python}
df = penguins.load_penguins().dropna()

df.head(3)
```

## Define Model and Fit

```{python}
X = get_dummies(df[['bill_length_mm', 'species', 'sex']], drop_first = True)
y = df['body_mass_g']

model = LinearRegression().fit(X, y)
```

## Get some information

```{python}
print(f"R^2 {model.score(X,y)}")
print(f"Intercept {model.intercept_}")
print(f"Columns {X.columns}")
print(f"Coefficients {model.coef_}")
```

Because this book renders with knitr, I’ve added the reticulate code below to supply the Python environment for the chunks that follow.

library(reticulate)
use_virtualenv("myenv", required = TRUE)
virtualenv_install(
  envname = "myenv", 
  packages = c("palmerpenguins", "pandas", "numpy", 
               "scikit-learn", "jupyter"))

The first Python chunk imports the penguins data, get_dummies() from pandas, numpy, and the scikit-learn modules for the model:

from palmerpenguins import penguins
from pandas import get_dummies
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn import preprocessing

Next, we load the penguins data, drop the rows with missing values, and view the first three rows:

df = penguins.load_penguins().dropna()

df.head(3)
  species     island  bill_length_mm  ...  body_mass_g     sex  year
0  Adelie  Torgersen            39.1  ...       3750.0    male  2007
1  Adelie  Torgersen            39.5  ...       3800.0  female  2007
2  Adelie  Torgersen            40.3  ...       3250.0  female  2007

[3 rows x 8 columns]

We encode species and sex as indicator columns with get_dummies(), then fit a LinearRegression() model that predicts body_mass_g:

X = get_dummies(df[['bill_length_mm', 'species', 'sex']], drop_first = True)
y = df['body_mass_g']

model = LinearRegression().fit(X, y)

Finally, we print the model’s R², intercept, column names, and coefficients:

print(f"R^2 {model.score(X,y)}")
R^2 0.8555368759537614
print(f"Intercept {model.intercept_}")
Intercept 2169.2697209393996
print(f"Columns {X.columns}")
Columns Index(['bill_length_mm', 'species_Chinstrap', 'species_Gentoo', 'sex_male'],
      dtype='str')
print(f"Coefficients {model.coef_}")
Coefficients [  32.53688677 -298.76553447 1094.86739145  547.36692408]

Recap

  1. Running Python inside this Quarto book relies on reticulate: use_virtualenv() points to the myenv environment, and virtualenv_install() installs palmerpenguins, pandas, numpy, scikit-learn, and jupyter into it.

  2. The model predicts body_mass_g from bill_length_mm, species, and sex with LinearRegression(). get_dummies() with drop_first = True converts the categorical columns into indicator columns, so female Adelie penguins are the baseline.

  3. The R² of about 0.86 means these three variables explain most of the variation in body mass. Holding the other variables constant, each extra millimeter of bill length adds roughly 33 grams, Gentoo penguins are about 1,095 grams heavier than Adelie (Chinstrap are about 299 grams lighter), and males are about 547 grams heavier than females.

Next, EDA in R explores the same palmerpenguins data with dplyr and ggplot2.