私は正方形の線形システムXc=y
を解決しようとしていました。これを解決するために、私が知っている方法がある:それは私の知る限り、これらのドン」を言うことができるように思わ擬似逆 PythonでXc = yを解決するためのさまざまな方法が、なぜそうしてはいけないときに異なる解決策を与えるのですか?
を使用してガウスの消去
c=<X^-1,y>
- 私は地面の真実と思ったものにマッチする。
- まず、周波数30の余弦に次数30の多項式を当てはめることによって、真理値パラメータを生成します。だから私は
y_truth = X*c_truth
を持っています。上記の3つの方法が、私はそれを試してみましたが、方法が一致していないようだし、それはケースであるべき理由を私は見ていない真実に
と一致した場合
- まず、周波数30の余弦に次数30の多項式を当てはめることによって、真理値パラメータを生成します。だから私は
- は、それから私は確認してください。
私は完全に実行可能な再現性のあるコードを生成:
import numpy as np from sklearn.preprocessing import PolynomialFeatures ## some parameters degree_target = 25 N_train = degree_target+1 lb,ub = -2000,2000 x = np.linspace(lb,ub,N_train) ## generate target polynomial model freq_cos = 5 y_cos = np.cos(2*np.pi*freq_cos*x) c_polyfit = np.polyfit(x,y_cos,degree_target)[::-1] ## needs to me reverse to get highest power last ## generate kernel matrix poly_feat = PolynomialFeatures(degree=degree_target) K = poly_feat.fit_transform(x.reshape(N_train,1)) # generates degree 0 first ## get target samples of the function y = np.dot(K,c_polyfit) ## get pinv approximation of c_polyfit c_pinv = np.dot(np.linalg.pinv(K), y) ## get Gaussian-Elminiation approximation of c_polyfit c_GE = np.linalg.solve(K,y) ## get inverse matrix approximation of c_polyfit i = np.linalg.inv(K) c_mdl_i = np.dot(i,y) ## check rank to see if its truly invertible print('rank(K) = {}'.format(np.linalg.matrix_rank(K))) ## comapre parameters print('--c_polyfit') print('||c_polyfit-c_GE||^2 = {}'.format(np.linalg.norm(c_polyfit-c_GE))) print('||c_polyfit-c_pinv||^2 = {}'.format(np.linalg.norm(c_polyfit-c_pinv))) print('||c_polyfit-c_mdl_i||^2 = {}'.format(np.linalg.norm(c_polyfit-c_mdl_i))) print('||c_polyfit-c_polyfit||^2 = {}'.format(np.linalg.norm(c_polyfit-c_polyfit))) ## print('--c_GE') print('||c_GE-c_GE||^2 = {}'.format(np.linalg.norm(c_GE-c_GE))) print('||c_GE-c_pinv||^2 = {}'.format(np.linalg.norm(c_GE-c_pinv))) print('||c_GE-c_mdl_i||^2 = {}'.format(np.linalg.norm(c_GE-c_mdl_i))) print('||c_GE-c_polyfit||^2 = {}'.format(np.linalg.norm(c_GE-c_polyfit))) ## print('--c_pinv') print('||c_pinv-c_GE||^2 = {}'.format(np.linalg.norm(c_pinv-c_GE))) print('||c_pinv-c_pinv||^2 = {}'.format(np.linalg.norm(c_pinv-c_pinv))) print('||c_pinv-c_mdl_i||^2 = {}'.format(np.linalg.norm(c_pinv-c_mdl_i))) print('||c_pinv-c_polyfit||^2 = {}'.format(np.linalg.norm(c_pinv-c_polyfit))) ## print('--c_mdl_i') print('||c_mdl_i-c_GE||^2 = {}'.format(np.linalg.norm(c_mdl_i-c_GE))) print('||c_mdl_i-c_pinv||^2 = {}'.format(np.linalg.norm(c_mdl_i-c_pinv))) print('||c_mdl_i-c_mdl_i||^2 = {}'.format(np.linalg.norm(c_mdl_i-c_mdl_i))) print('||c_mdl_i-c_polyfit||^2 = {}'.format(np.linalg.norm(c_mdl_i-c_polyfit)))
を、私は結果を得る:
rank(K) = 4 --c_polyfit ||c_polyfit-c_GE||^2 = 4.44089220304006e-16 ||c_polyfit-c_pinv||^2 = 1.000000000000001 ||c_polyfit-c_mdl_i||^2 = 1.1316233165135605e-06 ||c_polyfit-c_polyfit||^2 = 0.0 --c_GE ||c_GE-c_GE||^2 = 0.0 ||c_GE-c_pinv||^2 = 1.0000000000000007 ||c_GE-c_mdl_i||^2 = 1.1316233160694804e-06 ||c_GE-c_polyfit||^2 = 4.44089220304006e-16 --c_pinv ||c_pinv-c_GE||^2 = 1.0000000000000007 ||c_pinv-c_pinv||^2 = 0.0 ||c_pinv-c_mdl_i||^2 = 0.9999988683985006 ||c_pinv-c_polyfit||^2 = 1.000000000000001 --c_mdl_i ||c_mdl_i-c_GE||^2 = 1.1316233160694804e-06 ||c_mdl_i-c_pinv||^2 = 0.9999988683985006 ||c_mdl_i-c_mdl_i||^2 = 0.0 ||c_mdl_i-c_polyfit||^2 = 1.1316233165135605e-06
なぜそれがあるの?それは機械の精密なものですか?それとも、度が大きい(1より大きい)ときに誤差が累積する(たくさん)ためですか?正直なところ私は知らないけど、これらの仮説はすべて私にはばかげているようだ。誰かが私の間違いを見つけられる場合は、それを指摘してください。そうでなければ、私は線形代数や何かを理解していないかもしれません...より多くの心配です。
また、私はこれがうまくいくための提案を得ることができれば、非常に感謝します。 Do I:
- 間隔のサイズを1より大きくしないでください(大きさで)。
- 私が使用できる多項式の最大次数はどれくらいですか?
- 異なる言語...?または精度を上げる?
どのような提案もありがとうございます!
GDやSGDを使って多項式モデルを訓練すると、モデルを '[-1,1]'に制限すると同じ数値エラーが発生するか、これはちょうど特別なものです行列を(疑似)反転させるか? – Pinocchio
別のフォローアップの質問。私は '[-5,5]'と言うように間隔を変更するだけで何度も提案されてきました。しかし、今私の質問は、なぜ反対の問題が起きるのではなく、 '1.0 + eps = 1.0'の代わりに' 1.0 + big_number = NaN'が得られるのでしょうか? 'big_number = number^30'ならば?なぜ、数が1未満の数の30の威力に持ち上げると、数値問題はより敏感に見えるのですか? – Pinocchio