Подгонка квадратичной функции в python без nimpy polyfit - PullRequest
6 голосов
/ 17 мая 2019

Я пытаюсь приспособить квадратичную функцию к некоторым данным, и я пытаюсь сделать это без использования функции полифита numpy.

Математически я пытался следить за этим сайтом https://neutrium.net/mathematics/least-squares-fitting-of-a-polynomial/, но почему-то я не думаю, что я делаю это правильно. Если бы кто-нибудь мог мне помочь, это было бы замечательно, или если бы вы могли предложить другой способ сделать это, это также было бы здорово.

Что я пробовал до сих пор:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

ones = np.ones(3)
A = np.array( ((0,1),(1,1),(2,1)))
xfeature = A.T[0]
squaredfeature = A.T[0] ** 2
b = np.array( (1,2,0), ndmin=2 ).T
b = b.reshape(3)

features = np.concatenate((np.vstack(ones), np.vstack(xfeature), np.vstack(squaredfeature)), axis = 1)
featuresc = features.copy()
print(features)
m_det = np.linalg.det(features)
print(m_det)
determinants = []
for i in range(3):
    featuresc.T[i] = b
    print(featuresc)
    det = np.linalg.det(featuresc)
    determinants.append(det)
    print(det)
    featuresc = features.copy()

determinants = determinants / m_det
print(determinants)
plt.scatter(A.T[0],b)
u = np.linspace(0,3,100)
plt.plot(u, u**2*determinants[2] + u*determinants[1] + determinants[0] )
p2 = np.polyfit(A.T[0],b,2)
plt.plot(u, np.polyval(p2,u), 'b--')
plt.show()

Как вы видите, моя кривая не очень хорошо сравнивается с полифитовой кривой nnumpy. plot


Обновление: Я просмотрел свой код и удалил все глупые ошибки, и теперь он работает, когда я пытаюсь уместить его в 3 балла, но я понятия не имею, как вписать более трех баллов. updated

Это новый код:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

ones = np.ones(3)
A = np.array( ((0,1),(1,1),(2,1)))
xfeature = A.T[0]
squaredfeature = A.T[0] ** 2
b = np.array( (1,2,0), ndmin=2 ).T
b = b.reshape(3)

features = np.concatenate((np.vstack(ones), np.vstack(xfeature), np.vstack(squaredfeature)), axis = 1)
featuresc = features.copy()
print(features)
m_det = np.linalg.det(features)
print(m_det)
determinants = []
for i in range(3):
    featuresc.T[i] = b
    print(featuresc)
    det = np.linalg.det(featuresc)
    determinants.append(det)
    print(det)
    featuresc = features.copy()

determinants = determinants / m_det
print(determinants)
plt.scatter(A.T[0],b)
u = np.linspace(0,3,100)
plt.plot(u, u**2*determinants[2] + u*determinants[1] + determinants[0] )
p2 = np.polyfit(A.T[0],b,2)
plt.plot(u, np.polyval(p2,u), 'r--')
plt.show()

1 Ответ

6 голосов
/ 17 мая 2019

Вместо использования правила Крамера, на самом деле решите систему, используя наименьшие квадраты.Помните, что Правило Крамера будет работать только в том случае, если общее количество набранных вами очков равно желаемому порядку полинома плюс 1. Если у вас его нет, Правило Крамера не будет работать, поскольку вы пытаетесь найти точное решение дляпроблема.Если у вас есть больше точек, метод не подходит, так как мы создадим переопределенную систему уравнений.

Чтобы адаптировать это к большему количеству точек, numpy.linalg.lstsq будет лучше подходить, поскольку он решаетрешение Ax = b путем вычисления вектора x , который минимизирует евклидову норму, используя матрицу A .Поэтому удалите значения y из последнего столбца матрицы признаков и решите для коэффициентов и используйте numpy.linalg.lstsq для решения для коэффициентов:

import numpy as np
import matplotlib.pyplot as plt


ones = np.ones(4)
xfeature = np.asarray([0,1,2,3])
squaredfeature = xfeature ** 2
b = np.asarray([1,2,0,3])

features = np.concatenate((np.vstack(ones),np.vstack(xfeature),np.vstack(squaredfeature)), axis = 1) # Change - remove the y values

determinants = np.linalg.lstsq(features, b)[0] # Change - use least squares
plt.scatter(xfeature,b)
u = np.linspace(0,3,100)
plt.plot(u, u**2*determinants[2] + u*determinants[1] + determinants[0] )
plt.show()

Теперь я получаю этот график, который соответствует тому, чтопунктирная кривая на вашем графике также соответствует тому, что дает numpy.polyfit:

least squares fit

...