Linear Polynomial Regression
This tutorial show how to use the P4ML package to perform a naive polynomial regression. This is not really the intended use-case of the package, but it serves to illustrate some basic usage and functionality.
using Polynomials4ML, LinearAlgebra, StaticArrays
Example 1: Univariate Polynomial Regression
First, we specify a target function, which we will try to approximate.
f1(x) = 1 / (1 + 10 * x^2);
Suppose we are given data in the form of argument, function value pairs, with arguments sampled uniformly from the interval [-1, 1].
N = 1_000
Xtrain = 2 * rand(N) .- 1
Ytrain = f1.(Xtrain);
We want to solve the least squares problem
\[ \min_p \sum_{i = 1}^{N} | y_i - p(x_i) |^2\]
for a polynomial $p$. Because $f_1$ is analytic, we use a degree approximately $\sqrt{N}$. Since the distribution of the samples is uniform, the Legrendre polynomials are likely a good choice.
basis = legendre_basis(ceil(Int, sqrt(N)))
c = basis(Xtrain) \ Ytrain
p = x -> sum(c .* basis(x));
A quick statistical test error
Xtest = 2 * rand(N) .- 1
Ytest = f1.(Xtest)
println("Test RMSE: ", norm(Ytest - p.(Xtest)) / sqrt(N))
Test RMSE: 3.0329984403230623e-5
Example 2: Polynomial Regression on the Sphere
As a second example we consider a function defined on the unit sphere,
f2(x) = 1 / (1 + 10 * norm(x - SA[1.0,0.0,0.0])^2);
where x
is now an SVector{3, Float64}
with norm(x) == 1
. We generate again uniform samples on the sphere.
N = 1_000
X = [ (x = randn(SVector{3, Float64}); x/norm(x)) for i = 1:N ]
Y = f2.(X);
In this case, spherical harmonics are natural basis functions. P4ML implements both real and complex spherical harmonics. Since the target function is real, we choose the real basis.
basis = real_sphericalharmonics(9)
@show length(basis);
length(basis) = 100
We see that we now have far more basis functions per degree and therefore cannot use as high a degree as before (unless we give ourselves more data). Otherwise we can proceed exactly as above.
c = basis(X) \ Y
p = x -> sum(c .* basis(x));
We can test the RMSE again.
Xtest = [ (x = randn(SVector{3, Float64}); x/norm(x)) for i = 1:N ]
Ytest = f2.(Xtest)
println("Test RMSE: ", norm(Ytest - p.(Xtest)) / sqrt(N));
Test RMSE: 0.00970364646742417
This page was generated using Literate.jl.