Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Visualizing your Data With VegaLite

notebooks/vegalite.livemd

Visualizing your Data With VegaLite

Mix.install([
  {:scholar, "~> 0.1"},
  {:explorer, "~> 0.5.6"},
  {:exla, "~> 0.5.2"},
  {:req, "~> 0.3.6"},
  {:kino_vega_lite, "~> 0.1.8"},
  {:kino, "~> 0.9.0"},
  {:kino_explorer, "~> 0.1.6"}
])
:ok

Generating Data

We are going to visualize data that should fit the formula $y = 2x + 1$ using VegaLite (via Kino plugin)

alias VegaLite, as: Vl
require Explorer.DataFrame, as: DF
require Explorer.Series, as: S
Nx.global_default_backend(EXLA.Backend)

{x, y} = {
  Nx.tensor([[1], [2], [3], [5], [10], [15], [20]]),
  Nx.tensor([3, 5, 7, 11, 20, 32, 41])
}

df = DF.new(x: x, y: y)

Visualize Data

Vl.new(
  title: [
    text: "Scatterplot of 2x + 1 Approximation",
    offset: 20
  ],
  width: 630,
  height: 630
)
|> Vl.data_from_values(df)
|> Vl.mark(:circle, size: 500)
|> Vl.encode_field(:x, "x",
  type: :quantitative,
  scale: [domain: [0, 20]],
  axis: [grid: false]
)
|> Vl.encode_field(:y, "y", type: :quantitative, scale: [domain: [0, 50]], axis: [grid: false])

Create Model

For a regression task, we will use the Scholar.Linear.LinearRegression module.

model = Scholar.Linear.LinearRegression.fit(x, y)
%Scholar.Linear.LinearRegression{
  coefficients: #Nx.Tensor<
    f32[1]
    EXLA.Backend
    [2.015822410583496]
  >,
  intercept: #Nx.Tensor<
    f32
    EXLA.Backend
    0.8734207153320312
  >
}

As we can see, the coefficient is almost 2.0, and the intercept is nearly 1.0. Let’s plot the result of linear regression.

[intercept] = Nx.to_flat_list(model.intercept)
[coefficients] = Nx.to_flat_list(model.coefficients)
x_1 = 0
x_2 = 20

line = %{
  x: [x_1, x_2],
  y: [x_1 * coefficients + intercept, x_2 * coefficients + intercept]
}

Vl.new(
  title: [
    text: "Scatterplot of Generated Data",
    offset: 20
  ],
  width: 630,
  height: 630
)
|> Vl.layers([
  Vl.new()
  |> Vl.data_from_values(df)
  |> Vl.mark(:circle, size: 500)
  |> Vl.encode_field(:x, "x",
    type: :quantitative,
    scale: [domain: [0, 20]],
    axis: [grid: false]
  )
  |> Vl.encode_field(:y, "y",
    type: :quantitative,
    scale: [domain: [0, 50]],
    axis: [grid: false]
  ),
  Vl.new()
  |> Vl.data_from_values(line)
  |> Vl.mark(:line, color: :green)
  |> Vl.encode_field(:x, "x", type: :quantitative, scale: [domain: [0, 20]])
  |> Vl.encode_field(:y, "y", type: :quantitative, scale: [domain: [0, 50]])
])
x_prediction = Nx.tensor([[9]])

[y_prediction] =
  model
  |> Scholar.Linear.LinearRegression.predict(x_prediction)
  |> Nx.to_flat_list()

[x_prediction] = Nx.to_flat_list(x_prediction)
{x_prediction, y_prediction}
{9, 19.015823364257812}