2017-09-23 21 views
2

我有一組我手動(我想這手動)配有僞逆參數使用PolynomialFeatures如何按照字典順序組織PolynomialFeatures的係數,使它們與多元多項式的sympy匹配?

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函數表示它返回列法定單中的非零係數。因此,我只是想知道如何才能使PolynomialFeatures的順序與上面的匹配,以便我可以逐項比較係數,如果需要的話。

有人知道如何匹配二者的順序,以便這樣的比較是可能的嗎?


我知道什麼字典順序從尋找一個mathematica documentation,我認爲具有直觀意義對我來說(基本上是字典順序由單項的程度,使XY X^2和y^2都做了指相同的順序並且比任何一個像x或y這樣的術語「更大」)。但是,我認爲它的細節是找出sympy vs PolynomialFeatures如何排序。 Sympy說它按照字典順序排列,但是當我檢查我的多項式時,它似乎並不服從我所期望的順序(而PolyFeatures確實服從某些順序,但是當它具有多個相同順序的項時, x^2y,xy^2,y^2)。因此,這是出來的時候我檢查sympy:

(Pdb) s_expr 
Poly(-4.92243832500572e-13*x1**3 - 3.86418002630562e-13*x1**2*x2 - 284.848327636719*x1**2 - 1.97301728991142e-13*x1*x2**2 - 11.1939144134521*x1*x2 + 66.1333587984857*x1 - 1.35329085177577e-13*x2**3 - 108.171173095703*x2**2 + 28.227414137076*x2 - 11.0110442095318, x1, x2, domain='RR') 
(Pdb) s_expr.coeffs() 
[-4.92243832500572e-13, -3.86418002630562e-13, -284.848327636719, -1.97301728991142e-13, -11.1939144134521, 66.1333587984857, -1.35329085177577e-13, -108.171173095703, 28.2274141370760, -11.0110442095318] 
(Pdb) s_expr.coeffs()[::-1] 
[-11.0110442095318, 28.2274141370760, -108.171173095703, -1.35329085177577e-13, 66.1333587984857, -11.1939144134521, -1.97301728991142e-13, -284.848327636719, -3.86418002630562e-13, -4.92243832500572e-13] 

,這是什麼出來的時候我檢查PolynomailFeatures:

>>> 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正在使用grevlex,grlex之一,如果任何人有任何想法如何使它,我會很樂意聽到它。我將多項式匹配的係數作爲該單項值應該是多少,如果輸入爲[x3,x2,x1] = [5,3,2],例如x3**2的係數具有係數25x2*x3**2的係數爲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) 

回答

2

因此,單項的PolynomialFeatures順序如下:

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。

首先要認識到的是,這不是一個詞典順序,但分級(可能反轉?)詞典順序(請參閱Wikipedia上的Monomial order)。也就是說,首先將單項式按其總度分開(即分級),然後在每個組中應用詞典順序。

SymPy的方法coeffs支持命令'lex'(詞典,默認),'grlex'(分級詞典)和grevlex(反分級詞典)。然而,爲了產生結果,我們希望它是必要作出兩項調整:

  • 構建多項式時,聲明的變量(x2, x1)使用聚構造函數的第二個參數的順序。
  • coeffs反轉系數列表。

這兩個調整的組合效果是先放小總度,同時保持相同總度的單項之間的順序。

實施例:

q = Poly(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, (x2, x1)) 
c = q.coeffs(order='grevlex')[::-1] 
print(c) 

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

重要:grlex和grevlex 1個2個變量一致。由於你的例子有兩個變量,我不知道'grevlex'或'grlex'是否正確;我在預感上使用了'grevlex',但你應該用一個多於2個變量的多項式來測試它。

+0

爲什麼'(X2,X1)''VS(X1,X2)'有關係嗎? –

+0

因爲要應用任何前述的單項式命令,所以必須首先命令_variables_。詞典中的字典順序依賴於被排序的字母:A在B之前,B在C之前。這就是(x2,x1)所說的:x2在x1之前。 – FTP

+0

出於好奇,爲什麼我們不能通過查看一維和二維輸入來判斷正確的輸入? –

0

似乎正確的答案是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) 
相關問題