Как взвесить точки на участке рассеяния для подгонки? - программирование
Подтвердить что ты не робот

Как взвесить точки на участке рассеяния для подгонки?

Итак, я искал информацию о параметре весов в функции polyfit (numpy.polynomial.polynomial.polyfit) в Python и кажется, что он имеет какое-то отношение к ошибке, связанной с отдельными точками. (Как включить ошибки измерения в numpy.polyfit)

Однако то, что я пытаюсь сделать, не имеет ничего общего с ошибкой, но весами. У меня есть изображение в виде массива numpy, который указывает количество заряда, депонированного в детекторе. Я конвертирую это изображение в график рассеяния, а затем делаю приступ. Но я хочу, чтобы это пригодилось, чтобы придать больше очков тем, у кого больше денег, и меньше, чем те, у которых меньше заряда. Это то, что для параметра весов?

Вот пример изображения: image of the shower Здесь мой код:

def get_best_fit(image_array, fixedX, fixedY):
    weights = np.array(image_array)
    x = np.where(weights>0)[1]
    y = np.where(weights>0)[0]
    size = len(image_array) * len(image_array[0])
    y = np.zeros((len(image_array), len(image_array[0])))
    for i in range(len(np.where(weights>0)[0])):
        y[np.where(weights>0)[0][i]][np.where(weights>0)[1][i]] = np.where(weights>0)[0][i]
    y = y.reshape(size)
    x = np.array(range(len(image_array)) * len(image_array[0]))
    weights = weights.reshape((size))
    b, m = polyfit(x, y, 1, w=weights)
    angle = math.atan(m) * 180/math.pi
    return b, m, angle

Позвольте мне объяснить вам код:

Первая строка назначает заряженную, депонированную в переменной, называемой весом. Следующие две линии получают точки, в которых осажденный заряд составляет> 0, поэтому некоторые заряды осаждаются для захвата координат для графика рассеяния. Затем я получаю размер всего изображения для последующего преобразования в одномерный массив для построения графика. Затем я просматриваю изображение и пытаюсь получить координаты точек, где наложен некоторый заряд (помните, что сумма заряда хранится в переменных weights). Затем я изменяю координаты y, чтобы получить одномерный массив, и получить координаты x для всех соответствующих координат y из изображения, а затем изменить форму весов, чтобы быть только одномерным.

Edit: если есть способ сделать это с np.linalg.lstsq функции np.linalg.lstsq, это было бы идеально, так как я также пытаюсь получить соответствие, чтобы пройти через вершину сюжета. Я мог бы просто переместить сюжет так, чтобы вершина была в нуле, а затем использовала np.linalg.lstsq, но это не позволило бы мне использовать веса.

4b9b3361

Ответ 1

Вы можете использовать sklearn.linear_model.LinearRegression. Это позволяет вам не подходить к перехвату (т.е. линия проходит через начало координат или, с некоторым финишем, точка по вашему выбору). Он также касается взвешенных данных.

например (в основном украдены бесстыдно от ответа @Hiho)

import numpy as np
import matplotlib.pyplot as plt
import sklearn.linear_model

y = np.array([1.0, 3.3, 2.2, 4.25, 4.8, 5.1, 6.3, 7.5])
x = np.arange(y.shape[0]).reshape((-1,1))
w = np.linspace(1,5,y.shape[0])

model = sklearn.linear_model.LinearRegression(fit_intercept=False)
model.fit(x, y, sample_weight=w)

line_x = np.linspace(min(x), max(x), 100).reshape((-1,1))
pred = model.predict(line_x)

plt.scatter(x, y)
plt.plot(line_x, pred)

plt.show()

Ответ 2

Поэтому я мог бы неправильно понять проблему, но я просто попытался поместить прямую линию в график рассеяния, а затем изменить соответствие, чтобы определить приоритеты определенных точек, используя параметр весов.
Я пробовал это с помощью np.polyfit и np.polynomial.polynomial.polyfit, я бы ожидал, что они оба будут вести себя так же, как они сводят к минимуму квадрат ошибки (по крайней мере, это мое понимание).
Однако приступы были совсем другими, см. Ниже. Не совсем уверен, что с этим делать.

Код

import numpy as np
import matplotlib.pyplot as plt

def func(p1, p2, x):
    return  p1 * x + p2

y = np.array([1.0, 3.3, 2.2, 4.25, 4.8, 5.1, 6.3, 7.5])
x = np.arange(y.shape[0])

plt.scatter(x, y)

w = np.ones(x.shape[0])
w[1] = 12
# p1, p2 = np.polyfit(x, y, 1, w=w)
p1, p2 = np.polynomial.polynomial.polyfit(x, y, 1, w=w)
print(p1, p2, w)

plt.plot(x, func(p1, p2, x))

plt.show()

np.polyfit

Без весов (или всего набора 1)

No weights

При весе 2-й точки, установленной на 12, все остальные веса равны 1

enter image description here

np.polynomial.polynomial.polyfit

Нет весов enter image description here

При весе 2-й точки, установленной на 12, все остальные веса равны 1

enter image description here

Так что np.polyfit ведет себя так, как я ожидал бы, но я действительно не знаю, что происходит с np.polynomial.polynomial.polyfit, даже пригонка без каких-либо весов не имеет для меня никакого смысла.
Но я думаю, что np.polyfit делает то, что вам нужно? Изменение параметра веса явно дает больший вес более высоким взвешенным точкам.