4 Clojure with Scikit Learn Algorithm
(ns assignment.sklearn
(:require
[assignment.eda :refer [liver-disease]]
[assignment.scicloj :refer [col-order]]
[calc-metric.patch] ;eval from milliseconds to nanoseconds
[fastmath.stats :as stats]
[scicloj.ml.core :as ml]
[scicloj.ml.dataset :as ds]
[scicloj.ml.metamorph :as mm]
[scicloj.sklearn-clj.ml]
[utils.helpful-extracts
:refer [best-models evaluate-pipe extract-params model->ds]]))Define regressor and response
(def response :drinks)(def regressors
(remove #(= response %) (ds/column-names liver-disease)))4.1 Build pipelines
(def pipeline-fn
(ml/pipeline
(mm/remove-column :selector)
(mm/std-scale regressors {})
(mm/set-inference-target response)))In scikit.learn’s implementation of elastic net, it takes an alpha value, where \(alpha = 0\) is a ridge regression model, \(alpha = 1\) is a lasso regression model, and \(0 < alpha < 1\) is strictly an elastic net model that combines the loss functions of both ridge and lasso regression models at differing strengths. Closer to 0 means ridge regression loss function has a heavier consideration and alpha closer to 1 meaning the lasso loss function has a heavier consideration. (This is in general, there is an optional l1-ratio parameter that will change the above interpretation.)
(defn sklearn-pipe-fn [params]
(ml/pipeline
pipeline-fn
{:metamorph/id :model}
(mm/model (merge {:model-type :sklearn.regression/elastic-net
:predict-proba? false}
params))))4.2 Partition data
(def ds-split ;:split-names [:train-val :test]
(ds/split->seq liver-disease :kfold {:seed 123 :k 5 :ratio [0.8 0.2]}))(def train-val-splits
(ds/split->seq
(:train (first ds-split))
:kfold {:seed 123 :k 5}))4.3 Evaluate pipelines
(def sklearn-pipelines
(->>
(ml/sobol-gridsearch {:alpha (ml/linear 0 1 250)}) ;doesnt like l1-ratio, why??
(map sklearn-pipe-fn)))(def evaluations-sklearn
(ml/evaluate-pipelines
sklearn-pipelines
train-val-splits
stats/omega-sq
:accuracy
{:other-metrices [{:name :mae :metric-fn ml/mae}
{:name :rmse :metric-fn ml/rmse}]
:return-best-pipeline-only false
:return-best-crossvalidation-only true}))4.4 Extract models
(def models-sklearn-vals
(->> (best-models evaluations-sklearn)
reverse))(-> models-sklearn-vals first :metric)0.3641237206779405(-> models-sklearn-vals first :params){:model-type :sklearn.regression/elastic-net,
:predict-proba? false,
:alpha 1.0}(-> models-sklearn-vals first :fit-ctx :model :model-data :attributes :intercept_)3.567873303167421(-> models-sklearn-vals first :fit-ctx :model :model-data :attributes :coef_)[0.23816559 0. 0. 0.16579044 0.25591104](-> (model->ds models-sklearn-vals 5)
(ds/reorder-columns col-order))_unnamed [5 7]:
| :model-type | :compute-time-ns | :alpha | :adj-r2 | :mae | :rmse | :predict-proba? |
|---|---|---|---|---|---|---|
| :sklearn.regression/elastic-net | 6331770 | 1.00000000 | 0.36412372 | 2.77538202 | 3.27570429 | false |
| :sklearn.regression/elastic-net | 4065197 | 0.99598394 | 0.36409472 | 2.77449564 | 3.27469312 | false |
| :sklearn.regression/elastic-net | 3652424 | 0.99196787 | 0.36406587 | 2.77360744 | 3.27368066 | false |
| :sklearn.regression/elastic-net | 3245103 | 0.98795181 | 0.36403717 | 2.77271740 | 3.27266689 | false |
| :sklearn.regression/elastic-net | 4218376 | 0.98393574 | 0.36400862 | 2.77182552 | 3.27165183 | false |
(-> (model->ds models-sklearn-vals 5)
(ds/reorder-columns col-order)
(ds/order-by :adj-r2 :desc))_unnamed [5 7]:
| :model-type | :compute-time-ns | :alpha | :adj-r2 | :mae | :rmse | :predict-proba? |
|---|---|---|---|---|---|---|
| :sklearn.regression/elastic-net | 6331770 | 1.00000000 | 0.36412372 | 2.77538202 | 3.27570429 | false |
| :sklearn.regression/elastic-net | 4065197 | 0.99598394 | 0.36409472 | 2.77449564 | 3.27469312 | false |
| :sklearn.regression/elastic-net | 3652424 | 0.99196787 | 0.36406587 | 2.77360744 | 3.27368066 | false |
| :sklearn.regression/elastic-net | 3245103 | 0.98795181 | 0.36403717 | 2.77271740 | 3.27266689 | false |
| :sklearn.regression/elastic-net | 4218376 | 0.98393574 | 0.36400862 | 2.77182552 | 3.27165183 | false |
4.5 Build final models for evaluation
(def eval-sklearn
(evaluate-pipe
(->> (extract-params models-sklearn-vals 5) ;use best 3 alphas
(map sklearn-pipe-fn))
ds-split))(def models-sklearn
(->> (best-models eval-sklearn)
reverse))(def top-sklearn
(-> (model->ds models-sklearn 5)
(ds/reorder-columns col-order)
(ds/order-by :adj-r2 :desc)
(ds/drop-columns :predict-proba?)))top-sklearn_unnamed [5 6]:
| :model-type | :compute-time-ns | :alpha | :adj-r2 | :mae | :rmse |
|---|---|---|---|---|---|
| :sklearn.regression/elastic-net | 3434387 | 0.98393574 | 0.26161668 | 2.30607905 | 3.04582307 |
| :sklearn.regression/elastic-net | 3545495 | 0.98795181 | 0.26159480 | 2.30679512 | 3.04693277 |
| :sklearn.regression/elastic-net | 3777292 | 0.99196787 | 0.26157229 | 2.30750974 | 3.04804261 |
| :sklearn.regression/elastic-net | 5455140 | 0.99598394 | 0.26154913 | 2.30822291 | 3.04915259 |
| :sklearn.regression/elastic-net | 4709301 | 1.00000000 | 0.26152532 | 2.30893464 | 3.05026269 |
source: src/assignment/sklearn.clj