Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中计算最小范数解或伪逆解的最精确方法是什么?_Python_Numpy_Precision_Linear Algebra_Linear Regression - Fatal编程技术网

python中计算最小范数解或伪逆解的最精确方法是什么?

python中计算最小范数解或伪逆解的最精确方法是什么?,python,numpy,precision,linear-algebra,linear-regression,Python,Numpy,Precision,Linear Algebra,Linear Regression,我的目标是解决: Kc=y 使用伪逆(即最小范数解): 这样模型(希望)是高次多项式模型f(x)=sum_i c_i x^i。我特别感兴趣的是欠定情况,在这种情况下,多项式特征比数据多(很少方程,变量/未知数太多)columns=deg+1>N=rows。注K是多项式特征的范德模矩阵 我最初使用的是python函数,但后来我注意到了一些奇怪的事情,正如我在这里指出的那样:。在这个问题中,我使用一个平方矩阵来学习区间[-1.+1]上的函数和高次多项式。那里的答案建议我降低多项式的次数和/或增加区

我的目标是解决:

Kc=y
使用伪逆(即最小范数解):

这样模型(希望)是高次多项式模型
f(x)=sum_i c_i x^i
。我特别感兴趣的是欠定情况,在这种情况下,多项式特征比数据多(很少方程,变量/未知数太多)
columns=deg+1>N=rows
。注
K
是多项式特征的范德模矩阵

我最初使用的是python函数,但后来我注意到了一些奇怪的事情,正如我在这里指出的那样:。在这个问题中,我使用一个平方矩阵来学习区间
[-1.+1]
上的函数和高次多项式。那里的答案建议我降低多项式的次数和/或增加区间大小。主要的问题是,在事情变得不可靠之前,我不清楚如何选择间隔或最大度。我认为我的主要问题是,选择这样一个数值稳定的范围取决于我可能使用的方法。最后我真正关心的是

  • 我使用的方法与多项式拟合问题的伪逆方法非常接近
  • 它在数值上是稳定的
  • 理想情况下,我想尝试一个高次多项式,但这可能会受到我的机器精度的限制。是否有可能通过使用比浮子更精确的东西来提高机器的数值精度

    另外,我真正关心的是,无论我使用python中的什么函数,它都提供了最接近伪逆的答案(希望它在数值上是稳定的,所以我可以实际使用它)。为了检查伪逆的哪个答案,我编写了以下脚本:

    import numpy as np
    from sklearn.preprocessing import PolynomialFeatures
    
    def l2_loss(y,y_):
        N = y.shape[0]
        return (1/N)*np.linalg.norm(y-y_)
    
    ## some parameters
    lb,ub = -200,200
    N=100
    D0=1
    degree_mdl = 120
    ## target function
    freq_cos = 2
    f_target = lambda x: np.cos(freq_cos*2*np.pi*x)
    ## evaluate target_f on x_points
    X = np.linspace(lb,ub,N) # [N,]
    Y = f_target(X) # [N,]
    # get pinv solution
    poly_feat = PolynomialFeatures(degree=degree_mdl)
    Kern = poly_feat.fit_transform( X.reshape(N,D0) ) # low degrees first [1,x,x**2,...]
    c_pinv = np.dot(np.linalg.pinv( Kern ), Y)
    ## get polyfit solution
    c_polyfit = np.polyfit(X,Y,degree_mdl)[::-1] # need to reverse to get low degrees first [1,x,x**2,...]
    ##
    c_lstsq,_,_,_ = np.linalg.lstsq(Kern,Y.reshape(N,1))
    ##
    print('lb,ub = {} '.format((lb,ub)))
    print('differences with c_pinv')
    print( '||c_pinv-c_pinv||^2 = {}'.format( np.linalg.norm(c_pinv-c_pinv) ))
    print( '||c_pinv-c_polyfit||^2 = {}'.format( np.linalg.norm(c_pinv-c_polyfit) ))
    print( '||c_pinv-c_lstsq||^2 = {}'.format( np.linalg.norm(c_pinv-c_lstsq) ))
    ##
    print('differences with c_polyfit')
    print( '||c_polyfit-c_pinv||^2 = {}'.format( np.linalg.norm(c_polyfit-c_pinv) ))
    print( '||c_polyfit-c_polyfit||^2 = {}'.format( np.linalg.norm(c_polyfit-c_polyfit) ))
    print( '||c_polyfit-c_lstsq||^2 = {}'.format( np.linalg.norm(c_polyfit-c_lstsq) ))
    ##
    print('differences with c_lstsq')
    print( '||c_lstsq-c_pinv||^2 = {}'.format( np.linalg.norm(c_lstsq-c_pinv) ))
    print( '||c_lstsq-c_polyfit||^2 = {}'.format( np.linalg.norm(c_lstsq-c_polyfit) ))
    print( '||c_lstsq-c_lstsq||^2 = {}'.format( np.linalg.norm(c_lstsq-c_lstsq) ))
    ##
    print('Data set errors')
    y_polyfit = np.dot(Kern,c_polyfit)
    print( 'J_data(c_polyfit) = {}'.format( l2_loss(y_polyfit,Y) ) )
    y_pinv = np.dot(Kern,c_pinv)
    print( 'J_data(c_pinv) = {}'.format( l2_loss(y_pinv,Y) ) )
    y_lstsq = np.dot(Kern,c_lstsq)
    print( 'J_data(c_lstsq) = {}'.format( l2_loss(y_lstsq,Y) ) )
    
    使用它,我注意到
    polyfit
    很少与
    pinv
    使用的参数匹配。我知道pinv最终返回伪逆,所以我想如果我的主要目标是“确保我使用伪逆”,那么使用
    np.pinv
    是个好主意。然而,我在数学上也知道,无论怎样,伪逆总是最小化最小二乘误差
    J(c)=| | Kc-y | | ^2
    (证明定理11.1.2第446页)。因此,也许我的目标应该是使用python函数,该函数返回最小的最小二乘误差
    J
    。因此,我(在未确定的情况下)比较了三种方法

  • Polygit,
    np.polyfit
  • 伪逆,
    np.linalg.pinv
  • 最小二乘法,
    np.linalg.lstsq
  • 并比较了他们给我的数据的最小二乘误差:

    然后我检查了函数似乎经历的奇怪的下降(顺便说一句,如果算法不是随机的,为什么会有下降,这似乎是一个完全的谜),对于polyfit,数字通常较小,例如:

    lb,ub = (-100, 100)
    Data set errors
    J_data(c_polyfit) = 5.329753025633029e-12
    J_data(c_pinv) = 0.06670557822873546
    J_data(c_lstsq) = 0.7479733306782645
    
    鉴于这些结果以及伪逆是最小二乘法的极小值,似乎最好忽略
    np.pinv
    。这是最好的办法吗?还是我遗漏了一些明显的东西


    作为一个额外的注意事项,我去看看到底是什么使得它具有更好的最小二乘误差(我现在用它来表示它是伪逆的最佳近似值),它似乎有一些奇怪的条件/数值稳定性代码:

    # scale lhs to improve condition number and solve
    scale = NX.sqrt((lhs*lhs).sum(axis=0))
    lhs /= scale
    c, resids, rank, s = lstsq(lhs, rhs, rcond)
    c = (c.T/scale).T  # broadcast scale coefficients
    
    我想,是什么给polyfit带来了
    pinv
    所没有的额外稳定性

    在我的高次多项式线性系统近似任务中使用
    polyfit
    是正确的决定吗


    此外,在这一点上,我愿意使用其他软件,如matlab,如果它为我提供了正确的伪逆和更多的数值稳定性(对于大多数度和任何边界)


    我刚才的另一个随机想法是,也许有一种很好的方法对函数进行采样,这样伪逆的稳定性就好了。我的猜测是,用多项式近似余弦需要某种类型的样本数或样本之间的距离(如奈奎斯特-香农采样定理所说,如果基函数是正弦函数…)


    应该指出的是,很可能先反转(或伪反转),然后再相乘是个坏主意。见:

    那个只讨论逆,但我假设它也扩展到伪逆


    现在我的困惑是,通常我们不想显式地计算伪逆,而是做
    A^+y=x_min_norm
    来获得最小范数解。然而,我本以为
    np.lstsq
    会得到我想要的答案,但它的错误也与另一个大不相同。我发现这非常令人困惑……让我觉得我使用了错误的方法来获得python中的最小范数解决方案



    我不想得到一个正规化的解决方案。我试图得到最小范数解,而不是别的,尽可能精确地计算数值。

    我的研究领域涉及一种基本上被称为傅里叶扩展的压缩算法。什么是最准确的?它高度依赖于向量,我相信这是由于平滑的特性。在夏天,我用了一种叫做。有相当稳定和精确的数值滤波方法。然而,我的顾问有一种相对快速且数值稳定的方法。该区域称为傅立叶延拓或延拓。怎么用?我不知道我是否被允许发布它,这里是如果我相信我可能已经在这个夏天发布在这里的python部分

    这与python无关,因为python使用与大多数数字编码方案相同的底层库,即BLAS和LAPACK。是在线的

    还有许多其他类似的fast和numeri
    # scale lhs to improve condition number and solve
    scale = NX.sqrt((lhs*lhs).sum(axis=0))
    lhs /= scale
    c, resids, rank, s = lstsq(lhs, rhs, rcond)
    c = (c.T/scale).T  # broadcast scale coefficients
    
    v = (1:.5:6);
    
    V = vander(v);
    
    c1 = cond(V)
    
    v2 = (1:.5:12);
    c2 = cond(vander(v2));
    display(c1)
    display(c2)
    
    function B = lowapprox(A)
    % Takes a matrix A
    % Returns a low rank approx of it
    % utilizing the SVD
    chi = 1e-10;
    [U,S,V]  = svd(A,0);
    
    DS = diag(S);
    aa = find(DS > chi);
    s= S(aa,aa);
    k = length(aa);
    Un = U(:,1:k);
    Vn = V(:,1:k)';
    
    B = Un*s*Vn;
    
    end
    
    
    V2  = vander(v2);
    r2 = rank(V2);
    c2=cond(V2);
    B = lowapprox(V2);
    c3 = cond(B);
    display(c3)
    c2 =
    
       9.3987e+32
    
    
    c3 =
    
       3.7837e+32
    
    t= (0:.01:pi)';
    f = cos(t);
    data = [t,f];
    f1 = barylag(data,t)
    display(err =norm(f1-f1))
    err =
    
         0