1.6.14 Data sources
Source: "glmnet/examples/13-data-sources.rkt"
This section fits one model to one dataset, which arrives through each data source of Data in turn: R’s glmnet(as.matrix(mtcars[, c("wt", "hp", "qsec")]), mtcars$mpg), the lasso path of fuel economy on a car’s weight, horsepower and quarter-mile time. The data are R’s mtcars, which glmnet/datasets ships as a CSV file and provides as a table. Every source holds the same doubles and every fit keeps them, so each gives the same path, R’s.
1.6.14.1 A table
A table names the response column, and #:predictors the predictor columns. The path has R’s sequence of λ, and R’s coef(fit, s = 0.5):
> (require glmnet/datasets) > (define predictors '("wt" "hp" "qsec")) > (define from-table (elnet-path mtcars "mpg" #:predictors predictors)) > (vector-length (glmnet-path-lambda from-table)) 58
> (coef from-table #:lambda 0.5)
'#(33.16562014425745
-3.6829279730390896
-0.02385276160227977
0.12733703169896884)
1.6.14.2 Lists and vectors
The table’s columns are vectors. A vector of rows and the response column are unnamed data:
> (define mpg (dict-ref mtcars "mpg")) > (define columns (map (λ (name) (dict-ref mtcars name)) predictors)) > (define rows (apply vector-map vector columns)) > (vector-take rows 3) '#(#(2.62 110.0 16.46) #(2.875 110.0 17.02) #(2.32 93.0 18.61))
> (equal? (elnet-path rows mpg) from-table) #t
1.6.14.3 A CSV file
csv-file->table reads the file into a table of vector columns:
> (require glmnet/data/csv) > (define file (collection-file-path "mtcars.csv" "glmnet" "datasets")) > (define cars (csv-file->table file)) > (equal? (elnet-path cars "mpg" #:predictors predictors) from-table) #t
1.6.14.4 A matrix
A math/matrix matrix has the observations as its rows, and the response can be a column matrix:
> (require (only-in math/matrix ->col-matrix matrix-shape vector*->matrix)) > (define M (vector*->matrix rows)) > (matrix-shape M)
32
3
> (equal? (elnet-path M (->col-matrix mpg)) from-table) #t
1.6.14.5 A Polars dataframe
Polars reads the file itself, and the predictors leave it in one copy:
> (require (only-in polars read-csv)) > (define df (read-csv file)) > (equal? (elnet-path df "mpg" #:predictors predictors) from-table) #t
1.6.14.6 Formulas
The table, the CSV table and the dataframe name their columns, so each also fits the path as a formula model, whose coef names the coefficients:
> (define (formula-fit data) (formula-path (mpg . ~ . wt + hp + qsec) data)) > (define formula-from-table (formula-fit mtcars)) > (define formula-from-csv (formula-fit cars)) > (define formula-from-polars (formula-fit df)) > (coef formula-from-table #:lambda 0.5)
'(("(Intercept)" . 33.16562014425745)
("wt" . -3.6829279730390896)
("hp" . -0.02385276160227977)
("qsec" . 0.12733703169896884))
> (equal? (coef formula-from-csv #:lambda 0.5) (coef formula-from-table #:lambda 0.5)) #t
> (equal? (coef formula-from-polars #:lambda 0.5) (coef formula-from-table #:lambda 0.5)) #t
1.6.14.7 A design matrix, and back
Converting to a design matrix once checks the data once, for many fits (see The explicit route), and fits the same path:
> (require glmnet/data/nested glmnet/data/math glmnet/data/polars) > (define design (table->design-matrix mtcars predictors)) > (equal? (elnet-path design mpg) from-table) #t
The design matrix converts back to each source, and table->csv writes it as CSV:
> (define first-cars (design-matrix-select-rows design '(0 1 2))) > (design-matrix->nested first-cars) '((2.62 110.0 16.46) (2.875 110.0 17.02) (2.32 93.0 18.61))
> (design-matrix->matrix first-cars) (flarray #[#[2.62 110.0 16.46] #[2.875 110.0 17.02] #[2.32 93.0 18.61]])
> (design-matrix->polars first-cars)
shape: (3, 3)
┌───────┬───────┬───────┐
│ wt ┆ hp ┆ qsec │
│ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 │
╞═══════╪═══════╪═══════╡
│ 2.62 ┆ 110.0 ┆ 16.46 │
│ 2.875 ┆ 110.0 ┆ 17.02 │
│ 2.32 ┆ 93.0 ┆ 18.61 │
└───────┴───────┴───────┘
> (table->csv first-cars)
wt,hp,qsec
2.62,110,16.46
2.875,110,17.02
2.32,93,18.61