R使用什么类型的正交多项式?

Cha*_*ker 25 python r machine-learning polynomial-math gradient-descent

我试图在R中的以下代码中匹配正交多项式:

X <- cbind(1, poly(x = x, degree = 9))
Run Code Online (Sandbox Code Playgroud)

但是在python中.

为此,我实现了自己的方法来给出正交多项式:

def get_hermite_poly(x,degree):
    #scipy.special.hermite()
    N, = x.shape
    ##
    X = np.zeros( (N,degree+1) )
    for n in range(N):
        for deg in range(degree+1):
            X[n,deg] = hermite( n=deg, z=float(x[deg]) )
    return X
Run Code Online (Sandbox Code Playgroud)

虽然它似乎不匹配它.有人知道它使用的正交多项式的类型吗?我尝试在文档中搜索但没有说.


为了给出一些上下文,我试图在python中实现以下R代码(https://stats.stackexchange.com/questions/313265/issue-with-convergence-with-sgd-with-function-approximation-using-polynomial- lin/315185#comment602020_315185):

set.seed(1234)

N <- 10
x <- seq(from = 0, to = 1, length = N)
mu <- sin(2 * pi * x * 4)
y <- mu
plot(x,y)

X <- cbind(1, poly(x = x, degree = 9))
# X <- sapply(0:9, function(i) x^i)
w <- rnorm(10)

learning_rate <- function(t) .1 / t^(.6)

n_samp <- 2
for(t in 1:100000) {
  mu_hat <- X %*% w
  idx <- sample(1:N, n_samp)
  X_batch <- X[idx,]
  y_batch <- y[idx]
  score_vec <- t(X_batch) %*% (y_batch - X_batch %*% w)

  change <- score_vec * learning_rate(t)
  w <- w + change
}

plot(mu_hat, ylim = c(-1, 1))
lines(mu)
fit_exact <- predict(lm(y ~ X - 1))
lines(fit_exact, col = 'red')
abs(w - coef(lm(y ~ X - 1)))
Run Code Online (Sandbox Code Playgroud)

因为它似乎是唯一一个使用具有多项式特征的线性回归的梯度下降.

我觉得任何正交多项式(或至少是正交)都应该工作并给出条件号为1的粗体,但我似乎无法使它在python中工作.相关问题:如何使用具有随机梯度下降(SGD)的Hermite多项式?

dww*_*dww 17

poly使用QR分解,如本答案中的一些细节所述.

我认为你真正想要的是如何poly使用python 复制R的输出.

在这里,我已经编写了一个基于R实现的功能.我还添加了一些注释,以便您可以看到R中的等效语句:

import numpy as np

def poly(x, degree):
    xbar = np.mean(x)
    x = x - xbar

    # R: outer(x, 0L:degree, "^")
    X = x[:, None] ** np.arange(0, degree+1)

    #R: qr(X)$qr
    q, r = np.linalg.qr(X)

    #R: r * (row(r) == col(r))
    z = np.diag((np.diagonal(r)))  

    # R: Z = qr.qy(QR, z)
    Zq, Zr = np.linalg.qr(q)
    Z = np.matmul(Zq, z)

    # R: colSums(Z^2)
    norm1 = (Z**2).sum(0)

    #R: (colSums(x * Z^2)/norm2 + xbar)[1L:degree]
    alpha = ((x[:, None] * (Z**2)).sum(0) / norm1 +xbar)[0:degree]

    # R: c(1, norm2)
    norm2 = np.append(1, norm1)

    # R: Z/rep(sqrt(norm1), each = length(x))
    Z = Z / np.reshape(np.repeat(norm1**(1/2.0), repeats = x.size), (-1, x.size), order='F')

    #R: Z[, -1]
    Z = np.delete(Z, 0, axis=1)
    return [Z, alpha, norm2];
Run Code Online (Sandbox Code Playgroud)

检查这是否有效:

x = np.arange(10) + 1
degree = 9
poly(x, degree)
Run Code Online (Sandbox Code Playgroud)

返回矩阵的第一行是

[-0.49543369,  0.52223297, -0.45342519,  0.33658092, -0.21483446,
  0.11677484, -0.05269379,  0.01869894, -0.00453516],
Run Code Online (Sandbox Code Playgroud)

与R中的相同操作相比

poly(1:10, 9)
# [1] -0.495433694  0.522232968 -0.453425193  0.336580916 -0.214834462
# [6]  0.116774842 -0.052693786  0.018698940 -0.004535159
Run Code Online (Sandbox Code Playgroud)

  • 我不建议您*应该*使用哪种特定方法.你的问题是"在R中使用什么方法`poly`"和"我如何在Python中获得相同的东西"?我试图表明.R的算法可以比数据更多吗?试试`poly(1:10,degree = 11)`并亲自看看.有关哪种方法最适合您的特定应用程序的相关(但不同)问题的更详细建议,您将在交叉验证方面获得更多好运.这个网站对于问题的编程方面更好,但是对于数学的基本问题,你会得到更多专业知识的关注. (5认同)
  • 你不能拥有比数据更多的学位.不确定我真的明白你的用例需要它.但这可能是一个更适合在https://stats.stackexchange.com/上讨论的问题. (3认同)
  • 你的意思是什么不可以?你当然可以.只需选择更高次多项式.我不是要求你评估它的统计稳健性.我问你建议的方法是否会影响我使用的单项式数.谢谢你的时间顺便一下!:) (3认同)
  • 哦,哇,这是你链接的长篇文章.就像一个简单的问题,我认为使用像`qr`这样的因子分解会人为地降低我的多项式的程度.我记得当我有更多学位而不是数据时进行因式分解,它将我的数据矩阵"X"减少到数据点的数量.你的方法也这样做吗?我真的不希望它这样做,它确定我知道我有太多度数,我是故意这样做的,但即使我有太多的度/参数我想要多项式仍然是正交的(不改变我的数字)单项式是至关重要的). (2认同)