如何将多项式特征的系数按字典顺序组织起来,以便它们与多元多项式的symphy相匹配?

2024-10-06 12:27:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我用PolynomialFeatures手动(我想要手动)装配伪逆的一组参数:

poly_feat = PolynomialFeatures(degree=Degree_mdl)
Kern_train = poly_feat.fit_transform(X_train)
c_pinv = np.dot(np.linalg.pinv( Kern_train ),Y_train)

然后我得到了一些多元多项式,在sympy的帮助下,通过使用poly类和coeffs()函数对其进行了简化。不过,coeffs函数表示它以lex顺序返回非零coefs。因此,我只想知道如何得到多项式特征的阶数来匹配上述特征,以便在需要时逐项比较系数。在

有没有人知道如何匹配两者的顺序,以便进行这种比较?在


我确实知道字典序是什么意思,我认为这对我来说很直观(基本上,字典序是由单项式的阶数来完成的,所以xy x^2和y^2都有相同的顺序,比x或y之类的任何阶数都要大)。然而,我认为它总结起来的细节是找出交响和多项式特征是如何排序的。Sympy说它是按字典顺序排列的,但当我检查我的多项式时,它似乎不符合我预期的顺序(虽然PolyFeatures确实遵循某种顺序,但是当它有多个相同顺序的项,比如x^2y,xy^2,y^2)时,breaks会以某种未知的方式消亡。这就是我在考察辛普森的时候得出的结论:

^{pr2}$

这是我在考察多项式特征时得出的结论:

>>> xx
array([[2, 3]])
>>> poly_feat.fit_transform(xx)
array([[  1.,   2.,   3.,   4.,   6.,   9.,   8.,  12.,  18.,  27.]])
# maps to the following ordering:
## [1,x1,x2,x1^2,x1x2,x2^2,x1^3,x1^2x2,x1x2^2,x2^3]

所以现在我正在研究这些,想知道如何使它们具有完全相同的顺序,包括当单项式具有相同的顺序时。任何想法都会很有帮助。在

我已经看了他们的源代码,但我不能完全消化它来理解发生了什么(特别是在sympy方面)。感谢任何帮助!在

我只处理了3度和2度输入维的例子,但它适合于任意输入和度。在


赏金部分:用3度制作三维空间(我希望是3级以上)

我试着使系数与维3和度3的系数匹配,但由于某些原因它们不匹配。看起来PolyFeatures并没有使用grevlexgrlex如果有人知道如何制作它,我很乐意听听。我让polinonial的系数与这个单项式的值相匹配,如果[x3,x2,x1] = [5,3,2]的输入是x3**2的系数是25,或者{}的系数是75。结果是:

    x_poly_feat_list =  [1, 2, 3, 5, 4, 6, 10, 9, 15, 25, 8, 12, 20, 18, 30, 50, 27, 45, 75, 125]
    poly =  Poly(125*x3**3 + 75*x3**2*x2 + 50*x3**2*x1 + 25*x3**2 + 45*x3*x2**2 + 30*x3*x2*x1 + 15*x3*x2 + 20*x3*x1**2 + 10*x3*x1 + 5*x3 + 27*x2**3 + 18*x2**2*x1 + 9*x2**2 + 12*x2*x1**2 + 6*x2*x1 + 3*x2 + 8*x1**3 + 4*x1**2 + 2*x1 + 1, x3, x2, x1, domain='ZZ')
    c_grevlex =  [1, 2, 3, 5, 4, 6, 10, 9, 15, 25, 8, 12, 20, 18, 30, 50, 27, 45, 75, 125]
    c_grlex =  [1, 2, 3, 5, 4, 6, 9, 10, 15, 25, 8, 12, 18, 27, 20, 30, 45, 50, 75, 125]
    len(c_grlex) 20
    len(c_grevlex) 20
    len(x_poly_feat_list) 20
    all_match_grlex =  False
    all_match_grevlex =  False

也就是说它不匹配。在

完整代码:

from sklearn.preprocessing import PolynomialFeatures
import numpy as np
from sympy import *

# nb monomials (n+d,d), d=degree, n=# of inputs

def check(n,d,user_array=None):
    if user_array is None:
        x = np.arange(2,2+n).reshape(1,n) # e.g. array([[2, 3]])
    else:
        x = user_array.reshape(1,n)
    #x = np.arange(2,2+n).reshape(1,n) # e.g. array([[2, 3]])
    print('x = ', x)
    ##
    poly_feat = PolynomialFeatures(d)
    x_poly_feat = poly_feat.fit_transform(x)
    ##
    x_poly_feat_list = [ int(i) for i in x_poly_feat[0]]
    #print('x_poly_feat = ', x_poly_feat)
    #print('x_poly_feat = ', list(x_poly_feat[0]))
    print('x_poly_feat_list = ', x_poly_feat_list)
    return x_poly_feat_list

def check_sympy_degree():
    x3,x2,x1 = symbols('x3 x2 x1')
    poly = Poly( 125*x3**3 + 75*x2*x3**2 + 45*x2**2*x3 + 27*x2**3 + 50*x1*x3**2 + 30*x1*x2*x3 + 18*x1*x2**2 + 20*x1**2*x3 + 12*x1**2*x2
        + 8*x1**3 + 25*x3**2 + 15*x2*x3 + 9*x2**2 + 10*x1*x3 + 6*x1*x2 + 4*x1**2 + 2*x1 + 3*x2 + 5*x3 + 1,(x3,x2,x1) )
    c_grevlex = poly.coeffs(order='grevlex')
    c_grlex = poly.coeffs(order='grlex')
    print('poly = ',poly)
    print('c_grevlex = ', c_grevlex[::-1])
    print('c_grlex = ', c_grlex[::-1])
    return c_grlex, c_grevlex


if __name__ == '__main__':
    #check(n=2,d=3)
    ##
    x_poly_feat_list = check(n=3,d=3,user_array=np.array([2,3,5]))
    ##
    c_grlex, c_grevlex = check_sympy_degree()
    print('len(c_grlex)',len(c_grlex))
    print('len(c_grevlex)',len(c_grevlex))
    print('len(x_poly_feat_list)',len(x_poly_feat_list))
    all_match_grlex = all( c_grlex[i] == x_poly_feat_list for i in range(len(x_poly_feat_list)) )
    all_match_grevlex = all( c_grevlex[i] == x_poly_feat_list for i in range(len(x_poly_feat_list)) )
    print('all_match_grlex = ',all_match_grlex)
    print('all_match_grevlex = ',all_match_grevlex)

Tags: len顺序matchnpallarraylistprint
2条回答

因此,单项式的多项式特征顺序如下:

1 + 2*x1 + 3*x2 + 4*x1**2 + 5*x1*x2 + 6*x2**2 + 7*x1**3 + 8*x1**2*x2 + 9*x1*x2**2 + 10*x2**3

我们希望SymPy按如下顺序返回系数:1..10。在

首先要认识到的是,这不是一个字典序,而是分级的(可能相反吗?)字典顺序(见维基百科上的Monomial order)。也就是说,首先根据单项式的总程度将其分开(即分级),然后在每组中应用字典序。在

SymPy的方法coeffs支持“lex”(词典学,默认)、“grlex”(分级词典)和grevlex(反向分级词典)的顺序。但是,为了产生我们想要的结果,有必要进行两项调整:

  • 构造多项式时,使用Poly constructor的第二个参数将变量的顺序声明为(x2, x1)。在
  • coeffs反转系数列表。在

这两种调整的综合效果是将较小的总度放在首位,同时保持相同总度的单项之间的顺序。在

示例:

^{pr2}$

打印[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

重要提示:grlex和grevlex对于1和2变量是一致的。因为你的例子是在2个变量中,我不知道一般来说“grevlex”还是“grlex”是正确的;我在直觉上使用了“grevlex”,但是你应该用一个超过2个变量的多项式来测试这个问题。在

根据我生成的代码,似乎正确的答案是grevlex。希望它能帮助人们。在

代码:

from sklearn.preprocessing import PolynomialFeatures
import numpy as np
from sympy import *

import pdb

# nb monomials (n+d,d), d=degree, n=# of inputs

def check(n,d,user_array=None):
    if user_array is None:
        x = np.arange(2,2+n).reshape(1,n) # e.g. array([[2, 3]])
    else:
        x = user_array.reshape(1,n)
    #x = np.arange(2,2+n).reshape(1,n) # e.g. array([[2, 3]])
    print('x = ', x)
    ##
    poly_feat = PolynomialFeatures(d)
    x_poly_feat = poly_feat.fit_transform(x)
    ##
    x_poly_feat_list = [ int(i) for i in x_poly_feat[0]]
    #print('x_poly_feat = ', x_poly_feat)
    #print('x_poly_feat = ', list(x_poly_feat[0]))
    print('x_poly_feat_list = ', x_poly_feat_list)
    return x_poly_feat_list

def check_sympy_degree():
    x3,x2,x1 = symbols('x3 x2 x1')
    poly = Poly( 125*x3**3 + 75*x2*x3**2 + 45*x2**2*x3 + 27*x2**3 + 50*x1*x3**2 + 30*x1*x2*x3 + 18*x1*x2**2 + 20*x1**2*x3 + 12*x1**2*x2
        + 8*x1**3 + 25*x3**2 + 15*x2*x3 + 9*x2**2 + 10*x1*x3 + 6*x1*x2 + 4*x1**2 + 2*x1 + 3*x2 + 5*x3 + 1,(x3,x2,x1) )
    c_grevlex = poly.coeffs(order='grevlex')[::-1]
    c_grlex = poly.coeffs(order='grlex')[::-1]
    print('poly = ',poly)
    return c_grevlex, c_grlex


if __name__ == '__main__':
    #check(n=2,d=3)
    ##
    x_poly_feat_list = check(n=3,d=3,user_array=np.array([2,3,5]))
    ##
    c_grevlex, c_grlex = check_sympy_degree()
    #c_grevlex = len(c_grevlex)*[-1]

    print('c_grevlex = ', c_grevlex)
    print('c_grlex = ', c_grlex)

    print('len(c_grevlex)',len(c_grevlex))
    print('len(c_grlex)',len(c_grlex))
    print('len(x_poly_feat_list)',len(x_poly_feat_list))

    match_grevlex_list = [ c_grevlex[i] == x_poly_feat_list[i] for i in range(len(x_poly_feat_list)) ]
    match_grlex_list = [ c_grlex[i] == x_poly_feat_list[i] for i in range(len(x_poly_feat_list)) ]

    all_match_grevlex = all( match_grevlex_list )
    all_match_grlex = all( match_grlex_list )

    print('match_grevlex_list = ',match_grevlex_list)
    print('match_grlex_list =',match_grlex_list)

    print('all_match_grevlex = ',all_match_grevlex)
    print('all_match_grlex = ',all_match_grlex)

相关问题 更多 >