我正在尝试将二次函数拟合到某些数据,并且在不使用numpy的polyfit函数的情况下尝试这样做。
从数学上讲,我试图关注该网站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的polyfit曲线无法很好地比较。
更新: 我遍历了代码并删除了所有愚蠢的错误,现在,当我尝试使其超过3分时,它可以工作,但是我不知道如何超过3分。
这是新代码:
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()
答案 0 :(得分:6)
实际上使用最小二乘法来求解系统,而不是使用Cramer规则。请记住,只有当您拥有的点总数等于多项式的期望阶数加1时,克莱默法则才有效。 如果您没有这个,那么Cramer规则将不起作用,因为您正试图找到问题的确切解决方案。如果您有更多点,则该方法不合适,因为我们将创建一个超定方程组。
要将其调整为更多点,numpy.linalg.lstsq
会更合适,因为它可以通过计算向量 x 来解决 Ax = b 的解决方案使用矩阵 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
所提供的匹配: