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

Chapter 4

chapter4.livemd

Chapter 4

Mix.install([
  {:nx, "~> 0.6.4"}
])

Data

data =
  (__DIR__ <> "/data/pizza_3_vars.txt")
  |> Path.expand()
  |> File.read!()
  |> String.split()
  |> Enum.drop(4)
  |> Enum.map(&amp;String.to_integer/1)
  |> Enum.chunk_every(4)
  |> Nx.tensor()

Multiple Variables

defmodule MultiLinearRegression do
  import Nx.Defn

  defn predict(x, w) do
    Nx.dot(x, w)
  end

  defn loss(x, y, w) do
    (predict(x, w) - y)
    |> Nx.pow(2)
    |> Nx.mean()
  end

  defn gradient(x, y, w) do
    (predict(x, w) - y)
    |> Nx.dot(x)
    |> Nx.divide(Nx.axis_size(x, 0))
    |> Nx.multiply(2)
  end

  def train(x, y, iterations, lr) do
    Enum.reduce(1..iterations, Nx.broadcast(0.0, {Nx.axis_size(x, 1)}), fn i, w ->
      IO.puts("Iteration #{i}, loss #{Nx.to_number(loss(x, y, w))}")
      Nx.subtract(w, Nx.multiply(gradient(x, y, w), lr))
    end)
  end
end

Prediction

x = data[[.., 0..2]]
y = data[[.., 3]]
w = MultiLinearRegression.train(x, y, 10000, 0.001)
MultiLinearRegression.predict(x, w)

Adding a bias

x = Nx.pad(data[[.., 0..2]], 1, [{0, 0, 0}, {1, 0, 0}])
y = data[[.., 3]]
w = MultiLinearRegression.train(x, y, 125_000, 0.001)
Nx.to_list(y)
|> Enum.with_index()
|> Enum.each(fn {y, i} ->
  IO.puts("#{i}: y=#{y} prediction=#{Nx.to_number(MultiLinearRegression.predict(x[i], w))}")
end)

Field statistician

data =
  (__DIR__ <> "/data/life-expectancy-without-country-names.txt")
  |> Path.expand()
  |> File.read!()
  |> String.split()
  |> Enum.drop(4)
  |> Enum.map(&amp;Float.parse/1)
  |> Enum.map(&amp;elem(&amp;1, 0))
  |> Enum.chunk_every(4)
  |> Nx.tensor()
x = Nx.pad(data[[.., 0..2]], 1, [{0, 0, 0}, {1, 0, 0}])
y = data[[.., 3]]

w = MultiLinearRegression.train(x, y, 1_000_000, 0.0001)
Nx.to_list(y)
|> Enum.with_index()
|> Enum.each(fn {y, i} ->
  IO.puts("#{i}: y=#{y} prediction=#{Nx.to_number(MultiLinearRegression.predict(x[i], w))}")
end)