6 R Interop & Plot
(ns assignment.r-interop
(:require
[assignment.generate-data :refer [data]]
[assignment.lda :refer [lda-pipe-fn models]]
[clojisr.v1.applications.plotting
:refer [plot->svg]]
[clojisr.v1.r :refer [r+]]
[clojisr.v1.require :refer [require-r]]
[scicloj.kindly.v4.kind :as kind]
[scicloj.ml.core :as ml]
[scicloj.ml.dataset :as ds]
[scicloj.ml.dataset :as ds]))6.1 Load the required R libraries
(require-r '[base :refer [summary]]
'[ggplot2 :refer [ggplot aes geom_point
geom_contour theme_bw]])nil(summary data) x1 x2 group
Min. :-5.96223 Min. :-30.5006 Length:600
1st Qu.:-0.03666 1st Qu.: -5.0922 Class :character
Median : 3.25954 Median : -0.9309 Mode :character
Mean : 3.07651 Mean : 0.2922
3rd Qu.: 6.04087 3rd Qu.: 5.5367
Max. :12.26393 Max. : 19.8487
6.2 Setup dataset
Clojure does a nice job constructing cartesian products with the for function. As an illustration:
(def letters ["A" "B"])(def numbers [1 2 3])(for [x letters
y numbers]
[x y])(["A" 1] ["A" 2] ["A" 3] ["B" 1] ["B" 2] ["B" 3])In other words, cartesian product takes each element of sequence x (in illustration, letters) and pairs them with each element of sequence y (in illustration, numbers) to create a new set of ordered pairs.
(def dat (for [x (range -5 12 0.1)
y (range -14 20 0.2)]
{:x1 x :x2 y :group nil}))Using the cartesian product, I can create a nil prediction dataset with :x1 and :x2 values from x in [-5, 12] to y in [-14, 20].
(def contour-data
(ds/dataset dat))(def predictions
(-> contour-data
(ml/transform-pipe
lda-pipe-fn
(-> models second :fit-ctx))
:metamorph/data
:group
vec))(def lda-predict
(ds/add-or-replace-column contour-data :group predictions))Predictions variable is collecting the estimated :group based on the lda-pipe-fn plus the best model described in the last chapter. LDA-predict is putting those predictions in the contour-data set.
6.3 Plot LDA
^kind/hiccup
(-> (ggplot :data data (aes :x 'x1 :y 'x2 :color 'group))
(r+ (geom_point))
(r+ (geom_contour :data lda-predict (aes :x 'x1 :y 'x2 :z 'group) :col "black"))
(r+ (theme_bw))
plot->svg)(comment ;reverse process
(def dat
(for [minx (Math/floor (apply min (:x1 data)))
maxx (Math/floor (apply max (:x1 data)))
miny (Math/floor (apply min (:x2 data)))
maxy (Math/floor (apply max (:x2 data)))
x (range (int minx) (int maxx) 0.1)
y (range (int miny) (int maxy) 0.2)]
{:x1 x :x2 y :group nil}))
(def lookup-table
(-> models second :fit-ctx :model
:target-categorical-maps :group :lookup-table))
(def lookup-table-invert
(clojure.set/map-invert lookup-table))
(def lda-predict
(-> lda-pred-pre-transform
(ds/add-or-replace-column
:group (map #(get lookup-table-invert %)
(map int (:group lda-predict)))))))source: src/assignment/r_interop.clj