lstsq
достаточно для этого;веса могут быть применены к уравнениям.То есть, если в переопределенной системе
3*a + 2*b = 9
2*a + 3*b = 4
5*a - 4*b = 2
вы заботитесь о первом уравнении больше, чем о других, умножьте его на некоторое число, большее 1. Например, на 5:
15*a + 10*b = 45
2*a + 3*b = 4
5*a - 4*b = 2
Математически система такая же, но решение наименьших квадратов будет другим, потому что оно минимизирует сумму квадратов невязок, а остаток 1-го уравнения умножается на 5.
Здесьпример на основе вашего кода (с небольшими изменениями, чтобы сделать его более NumPythonic).Во-первых, невзвешенная подгонка:
import numpy as np
x, y = np.meshgrid(np.arange(0, 3), np.arange(0, 3))
x = x.ravel()
y = y.ravel()
values = np.sqrt(x+y+2) # some values to fit
functions = np.stack([np.ones_like(y), y, x, x**2, y**2], axis=1)
coeff_r = np.linalg.lstsq(functions, values, rcond=None)[0]
values_r = functions.dot(coeff_r)
print(values_r - values)
Это отображает остатки как
[ 0.03885814 -0.00502763 -0.03383051 -0.00502763 0.00097465 0.00405298
-0.03383051 0.00405298 0.02977753]
Теперь я придаю 1-й точке данных больший вес.
weights = np.ones_like(x)
weights[0] = 5
coeff_r = np.linalg.lstsq(functions*weights[:, None], values*weights, rcond=None)[0]
values_r = functions.dot(coeff_r)
print(values_r - values)
Остатки:
[ 0.00271103 -0.01948647 -0.04828936 -0.01948647 0.00820407 0.0112824
-0.04828936 0.0112824 0.03700695]
Первый остаток теперь на порядок меньше, разумеется за счет других остатков.