5

x、y 点のセットがあり、SciPy を使用して線がすべての点の下になるように最適な線を見つけたいと思います。これに leastsq を使用しようとしていますが、最適な線ではなく、すべての点の下になるように線を調整する方法がわかりません。最適な線の係数は、次の方法で生成できます。

def linreg(x, y):

    fit = lambda params, x: params[0] * x - params[1]
    err = lambda p, x, y: (y - fit(p, x))**2 

    # initial slope/intercept
    init_p = np.array((1, 0))

    p, _ = leastsq(err, init_p.copy(), args=(x, y))

    return p

xs = sp.array([1, 2, 3, 4, 5])  
ys = sp.array([10, 20, 30, 40, 50])

print linreg(xs, ys)

出力は、最適な直線の係数です。

array([  9.99999997e+00,  -1.68071668e-15])

すべてのポイントの下にある最適なラインの係数を取得するにはどうすればよいですか?

4

1 に答える 1

6

可能なアルゴリズムは次のとおりです。

  1. 軸を移動して、すべてのデータをx軸の正の半分に配置します。

  2. 近似がの形式y = a * x + bである場合、与えられbた最適な近似は、点と各点をa結ぶ勾配の最小値になります。(0, b)(x, y)

  3. 次に、のみの関数である近似誤差を計算しb、を使用scipy.optimize.minimizeして。の最適な値を見つけることができますb

  4. 残っているのはa、そのためのb計算bと軸の元の位置の計算だけです。

以下は、最小化が不思議なエラーで失敗した場合を除いて、ほとんどの場合それを行います。

from __future__ import division
import numpy as np
import scipy.optimize
import matplotlib.pyplot as plt

def fit_below(x, y) :
    idx = np.argsort(x)
    x = x[idx]
    y = y[idx]
    x0, y0 = x[0] - 1, y[0]
    x -= x0
    y -= y0

    def error_function_2(b, x, y) :
        a = np.min((y - b) / x)
        return np.sum((y - a * x - b)**2)

    b = scipy.optimize.minimize(error_function_2, [0], args=(x, y)).x[0]

    a = np.min((y - b) / x)

    return a, b - a * x0 + y0

x = np.arange(10).astype(float)
y = x * 2 + 3 + 3 * np.random.rand(len(x))

a, b = fit_below(x, y)

plt.plot(x, y, 'o')
plt.plot(x, a*x + b, '-')
plt.show()

そして、TheodrosZellekeが賢明に予測したように、凸包の一部である2つのポイントを通過します。

ここに画像の説明を入力してください

于 2013-01-24T00:35:52.777 に答える