Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting orthogonal polynomial coefficients from R's poly() function?

Tags:

r

R's poly() function produces orthogonal polynomials for data fitting. However, I would like to use the results of the regression outside of R (say in C++), and there doesn't seem to be a way to get the coefficients for each orthogonal polynomial.

Note 1: I don't mean the regression coefficients, but the coefficients of the orthogonal polynomials themselves), e.g. the p_i(x) in

y = a0 + a1*p_1(x) + a2*p_2(x) + ...

Note 2: I know poly(x, n, raw=T) forces poly to return non-orthogonal polynomials, but I want to regress against orthogonal polynomials, so that's what I'm looking for.

like image 346
Gilead Avatar asked Nov 04 '14 05:11

Gilead


People also ask

How to generate orthogonal polynomials in R?

We can say that orthogonal is a synonym of perpendicular. If the inner product (inner product is generalization of dot product) of two polynomials is zero then we call them orthogonal polynomials. In R, we can find the orthogonal product by using poly function as shown in the below examples.

Should I use raw or orthogonal polynomials?

Both, the manual coding (Example 1) and the application of the poly function with raw = TRUE (Example 2) use raw polynomials. However, depending on your situation you might prefer to use orthogonal (i.e. uncorrelated) polynomials.

How to evaluate orthogonal polynomials?

The orthogonal polynomial is summarized by the coefficients, which can be used to evaluate it via the three-term recursion given in Kennedy & Gentle (1980, pp.343--4), and used in the predict part of the code. poly using … is just a convenience wrapper for polym: coef is ignored.

Are the original powers of X and orthognonal polynomials correlated?

Hence they are correlated and the regression parameters could be unstable, but it is not automatically the case that they are unreliable. Conversion to orthognonal polynomials may be more reliable. But what makes the coefficient of the original powers of x any more interpretable than the coefficients of the orthogonal polynomials?


1 Answers

The polynomials are defined recursively using the alpha and norm2 coefficients of the poly object you've created. Let's look at an example:

z <- poly(1:10, 3)
attributes(z)$coefs
# $alpha
# [1] 5.5 5.5 5.5
# $norm2
# [1]    1.0   10.0   82.5  528.0 3088.8

For notation, let's call a_d the element in index d of alpha and let's call n_d the element in index d of norm2. F_d(x) will be the orthogonal polynomial of degree d that is generated. For some base cases we have:

F_0(x) = 1 / sqrt(n_2)
F_1(x) = (x-a_1) / sqrt(n_3)

The rest of the polynomials are recursively defined:

F_d(x) = [(x-a_d) * sqrt(n_{d+1}) * F_{d-1}(x) - n_{d+1} / sqrt(n_d) * F_{d-2}(x)] / sqrt(n_{d+2})

To confirm with x=2.1:

x <- 2.1
predict(z, newdata=x)
#               1         2         3
# [1,] -0.3743277 0.1440493 0.1890351
# ...

a <- attributes(z)$coefs$alpha
n <- attributes(z)$coefs$norm2
f0 <- 1 / sqrt(n[2])
(f1 <- (x-a[1]) / sqrt(n[3]))
# [1] -0.3743277
(f2 <- ((x-a[2]) * sqrt(n[3]) * f1 - n[3] / sqrt(n[2]) * f0) / sqrt(n[4]))
# [1] 0.1440493
(f3 <- ((x-a[3]) * sqrt(n[4]) * f2 - n[4] / sqrt(n[3]) * f1) / sqrt(n[5]))
# [1] 0.1890351

The most compact way to export your polynomials to your C++ code would probably be to export attributes(z)$coefs$alpha and attributes(z)$coefs$norm2 and then use the recursive formula in C++ to evaluate your polynomials.

like image 65
josliber Avatar answered Dec 13 '22 11:12

josliber