1

Python で 3 次スプラインをノイズの多い x、y データに当てはめ、各区間のスプライン係数を抽出したい (つまり、各区間で 4 つのスプライン係数を取得することが期待される)

これまでのところ、私は試しました(すべてscipy.interpolateから):

1) CubicSpline ですが、この方法ではスプラインを滑らかにすることができず、非現実的で不安定な係数データが​​生成されます。

2) splrep と splev の組み合わせ。

tck = splrep(x, y, k=3, s=1e25)

ここで、次を使用して係数/ノットを抽出します

F = PPoly.from_spline(tck)
coeffs = F.c
knots = F.x

ただし、平滑化パラメーター s を非常に大きな数値に増やしても、x 範囲全体で滑らかな係数を見つけることができません (0 に近い値と 1e23 の間でジャンプします。これは非物理的です)。ノット数は s とともに減少します。適切なパラメータ s とノット数を同時に見つけることができないようです。

3) UnivariateSpline(x, y, k=3, s=0.03) を使用しました。ここでは、s の変更に対する感度が高いことがわかりましたが、対応する get_coeffs() メソッドは、各間隔に対して 4 つの係数を提供するのではなく、1 つのみを提供します。理解していない。

4) 3 次多項式を使用した区分的リッジ型線形回帰も試しましたが、この方法ではフィットのパーセンテージ エラーが大きすぎるため、標準のスプライン法の 1 つを機能させることができれば素晴らしいと思います。

私は何が欠けていますか?誰か助けてくれませんか?

4

1 に答える 1

3

ここで目にする具体的な問題はUnivariateSpline、補間スプラインで x のさまざまな累乗の代数係数が得られないことです。これは、プライベート_dataプロパティに保持され、get_coeffsメソッドで返される係数が一種のB スプライン係数であるためです。これらの係数は冗長性のないスプラインを表します (自由度 N のスプラインには N 個必要です) が、それらが接続されている基底スプラインはいくぶん複雑です。

derivativesしかし、スプライン オブジェクトのメソッドを使用して、必要な種類の係数を取得できます。これは、特定の点 x における 4 つの導関数すべてを返します。そこから、その点におけるテイラー係数を簡単に見つけることができます。x を補間の結び目とし、右端のものを除くこの方法を使用するのが自然です。得られた係数は、その結び目から次の結び目まで有効です。これは、「派手な」フォーマットの出力を備えた例です。

import numpy as np
from scipy.interpolate import UnivariateSpline
spl = UnivariateSpline(np.arange(6), np.array([3, 1, 4, 1, 5, 9]), s=0)
kn = spl.get_knots()
for i in range(len(kn)-1):
    cf = [1, 1, 1/2, 1/6] * spl.derivatives(kn[i])
    print("For {0} <= x <= {1}, p(x) = {5}*(x-{0})^3 + {4}*(x-{0})^2 + {3}*(x-{0}) + {2}".format(kn[i], kn[i+1], *cf))

この例では、ノットは 0、2、3、5 です。出力は次のとおりです。

For 0.0 <= x <= 2.0, p(x) = -3.1222222222222222*(x-0.0)^3 + 11.866666666666667*(x-0.0)^2 + -10.744444444444445*(x-0.0) + 3.000000000000001
For 2.0 <= x <= 3.0, p(x) = 4.611111111111111*(x-2.0)^3 + -6.866666666666667*(x-2.0)^2 + -0.7444444444444436*(x-2.0) + 4.000000000000001
For 3.0 <= x <= 5.0, p(x) = -2.322222222222221*(x-3.0)^3 + 6.966666666666665*(x-3.0)^2 + -0.6444444444444457*(x-3.0) + 1.0000000000000016

各部分についてcf、最小次数から始まる係数を保持するため、文字列をフォーマットするときに順序が逆になることに注意してください。

(もちろん、これらの係数を使って別のことをしたいと思うでしょう)

式が正しいことを確認するために、プロット用にコピーして貼り付けました。

スプライン

于 2017-05-05T22:38:37.833 に答える