拟合方法——np.polyfit、np.poly1d
今天来介绍一下np.polyfit、np.poly1d
1. np.polyfit
1. 概念
np.polyfit使用的是最小二乘法进行多项式拟合
先看看np.polyfit的参数:
numpy.polyfit(x,y,deg,rcond = None,full = False,w = None,cov = False )
参数:
x: 类数组,形状(M,),表示M个采样点的x坐标
y: 类似array_,形状为(M,)或(M,K), 表示采样点的y坐标。通过传递每列包含一个数据集的2D数组,可以一次拟合多个共享相同x坐标的采样点数据集
deg: 度:整数, 表示拟合多项式的度
cov: cov:布尔值,可选。返回估算值和估算值的协方差矩阵。如果full为True,则不返回cov
返回值:
p: ndarray,形状(deg + 1,)或(deg + 1,K)。项式系数,最高幂优先。
简单介绍几个常用的参数,其他的参数如果想要了解,可以去官网看看: np.polyfit官网
2. 使用
x = np.array([ 0.0 , 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ])
y = np.array([ 0.0 , 0.8 , 0.9 , 0.1 , - 0.8 , - 1.0 ])
z = np.polyfit(x, y, 3)
print(z)
结果:
array([0.08703704, -0.81349206, 1.69312169, -0.03968254])
即: 0.08703704为最高次
x
3
x^3
x3的系数,-0.81349206为
x
2
x^2
x2的系数,1.69312169为
x
x
x的系数,-0.03968254为常数项
2. np.poly1d
1. 概念
np.poly1d的参数:
numpy.poly1d(c_or_r,r = False,变量= None )
参数:
c_or_r: 数组array,代表多项式的系数,以幂次递减,或者如果第二个参数的值为True,则为多项式的根(多项式求值为0的值)。
r bool(可选): 如果为True,则c_or_r指定多项式的根。默认值为False。
可变str(可选): 将打印p时使用的变量从x更改为variable 。
返回值: 相应的多项式
2. 使用
- 构造多项式
x
2
+
2
x
+
3
x^2+2x+3
x2+2x+3
coff = np.array([1, 2, 3]) p = np.pyly1d(coff) print(p) 结果为: 2 1 X + 2 X + 3
- 给定x的值,求出多项式的值(比如给出x=0.5)
print(p(0.5)) 结果为: 4.5
- 显示多项式系数
print(p.c) 结果为: array([1, 2, 3])
- 显示多项式中的第k次幂的系数
print(p[2]) print(p[1]) print(p[0]) 结果为: 1 2 3
- 多项式可以相加,相减,相乘和相除(返回商和余数):
print(p * p) print(p**2) print(np.square(p)) 结果为: poly1d([ 1, 4, 10, 12, 9]) poly1d([ 1, 4, 10, 12, 9]) array([1, 4, 9])
- 可以使用参数variable修改p的字符串表示形式中使用的变量:
c= np.poly1d([1,2,3], variable='z') print(c) 结果为: 2 1 z + 2 x + 3
- 当第二个参数r为True时, 传入的数组中的数为多项式的根:
print(poly1d([1, 2, 3], True)) 结果为: 3 2 1 x - 6 x + 11 x - 6
x
3
−
6
x
2
+
11
x
−
6
x^3-6x^2+11x-6
x3−6x2+11x−6=
(
x
−
1
)
(
x
−
2
)
(
x
−
3
)
(x-1)(x-2)(x-3)
(x−1)(x−2)(x−3)
3. 使用np.polyfit、np.poly1d进行拟合
先说明一下,以下代码中使用的拟合优度计算方法以及代码在我的上一篇博客中可以找到:
数学建模方法—【03】拟合优度的计算(python计算)
使用np.polyfit、np.poly1d进行1-5阶的拟合:
拟合数据集
x = np.array([4, 8, 10, 12, 25, 32, 43, 58, 63, 69, 79])
y = np.array([20, 33, 50, 56, 42, 31, 33, 46, 65, 75, 78])
一阶拟合:
figure1 = plt.figure(figsize=(8, 6))
# coeff 为系数,poly_fit 拟合函数
# 1. 先拟合获取系数
coeff_1 = np.polyfit(x, y, 1)
print("一阶拟合系数为:", coeff_1)
# 2. 根据系数得到多项式
poly_fit_1 = np.poly1d(coeff_1)
print("一阶多项式为:", poly_fit_1)
# 3. 输入变量(单个值或者变量数组),得到拟合结果(数组)
y_fit_1 = poly_fit_1(x)
print("拟合得到的数据为L", y_fit_1)
# 4. 根据结果作图
plt.plot(x, y_fit_1, 'green',label="一阶拟合")
# 5. 根据原始数据以及拟合数据得到拟合优度
rr1 = goodness_of_fit(y_fit_1, y)
print("拟合优度为%.5f" % rr1)
输出结果为:
一阶拟合系数为: [ 0.5000123 29.77227674]
一阶多项式为:
0.5 x + 29.77
一阶拟合得到的数据为: [31.77232593 33.77237512 34.77239971 35.77242431 42.27258418 45.77267026
51.27280553 58.77298999 61.27305148 64.27312526 69.27324824]
一阶拟合优度为0.52079
二阶拟合:
## 二阶拟合
coeff_2 = np.polyfit(x, y, 2)
print("二阶拟合系数为:", coeff_2)
poly_fit_2 = np.poly1d(coeff_2)
print("二阶多项式为:", poly_fit_2)
y_fit_2 = poly_fit_2(x)
print("二阶拟合得到的数据为: ", y_fit_2)
plt.plot(x, y_fit_2, 'orange',label="二阶拟合")
rr2 = goodness_of_fit(y_fit_2, y)
print("拟合优度为%.5f" % rr2)
结果为:
二阶拟合系数为: [ 1.31325973e-02 -5.41278736e-01 4.14687611e+01]
二阶多项式为: 2
0.01313 x - 0.5413 x + 41.47
二阶拟合得到的数据为: [39.51376772 37.97901745 37.36923348 36.86451029 36.14466602 37.59562119
42.47594787 54.25265174 59.49147943 66.64482408 80.66828073]
二阶拟合优度为0.64095
三阶拟合:
## 三阶拟合
coeff_3 = np.polyfit(x, y, 3)
print("三阶拟合系数为:", coeff_3)
poly_fit_3 = np.poly1d(coeff_3)
print("三阶多项式为:", poly_fit_3)
y_fit_3 = poly_fit_3(x)
print("三阶拟合得到的数据为: ", y_fit_3)
plt.plot(x, y_fit_3, 'skyblue',label="三阶拟合")
rr3 = goodness_of_fit(y_fit_3, y)
print("拟合优度为%.5f" % rr3)
结果为:
三阶拟合系数为: [ 3.52702455e-04 -3.04653592e-02 8.94352257e-01 3.18682147e+01]
三阶多项式为: 3 2
0.0003527 x - 0.03047 x + 0.8944 x + 31.87
三阶拟合得到的数据为: [34.98075096 37.25383345 38.11790383 38.82289993 40.69714753 40.84831321
42.03722677 50.07165879 55.48758714 64.39887624 86.28380214]
三阶拟合优度为0.67675
四阶拟合:
## 四阶拟合
coeff_4 = np.polyfit(x, y, 4)
print("四阶拟合系数为:", coeff_4)
poly_fit_4 = np.poly1d(coeff_4)
print("四阶多项式为:", poly_fit_4)
y_fit_4 = poly_fit_4(x)
print("四阶拟合得到的数据为: ", y_fit_4)
plt.plot(x, y_fit_4, 'blue',label="四阶拟合")
rr4 = goodness_of_fit(y_fit_4, y)
print("拟合优度为%5f" % rr4)
结果为:
四阶拟合系数为: [-5.20382218e-05 9.18774157e-03 -5.17764921e-01 1.03856517e+01
-1.43837752e+01]
四阶多项式为: 4 3 2
-5.204e-05 x + 0.009188 x - 0.5178 x + 10.39 x - 14.38
四阶拟合得到的数据为: [19.44928636 40.05545822 46.36360859 50.48324889 44.88547204 34.26368367
27.43335073 49.97112982 62.51444419 75.84652392 77.73379358]
四阶拟合优度为0.953101
五阶拟合:
## 五阶拟合
coeff_5 = np.polyfit(x, y, 5)
print("五阶拟合系数为:", coeff_5)
poly_fit_5 = np.poly1d(coeff_5)
print("五阶多项式为:", poly_fit_5)
y_fit_5 = poly_fit_5(x)
print("五阶拟合得到的数据为: ", y_fit_5)
plt.plot(x, y_fit_5, 'red', label="五阶拟合")
rr5 = goodness_of_fit(y_fit_5, y)
print("拟合优度为%.5f" % rr5)
结果为:
五阶拟合系数为: [ 2.92948996e-07 -1.11412559e-04 1.34633715e-02 -6.48604067e-01
1.19810057e+01 -2.01221591e+01]
五阶多项式为: 5 4 3 2
2.929e-07 x - 0.0001114 x + 0.01346 x - 0.6486 x + 11.98 x - 20.12
五阶拟合得到的数据为: [18.25763258 40.66172555 47.20603154 51.2782733 43.7309192 33.27241619
28.39304966 51.21670562 62.50290083 74.18143391 78.29891163]
五阶拟合优度为0.95620
作图:
plt.scatter(x, y, color='black', label="原始数据")
plt.title("1~5阶拟合曲线图")
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.legend(loc=2)
plt.show()
结果为:
所有代码:
# 拟合数据集
x = np.array([4, 8, 10, 12, 25, 32, 43, 58, 63, 69, 79])
y = np.array([20, 33, 50, 56, 42, 31, 33, 46, 65, 75, 78])
figure1 = plt.figure(figsize=(8, 6))
# coeff 为系数,poly_fit 拟合函数
# 1. 先拟合获取系数
coeff_1 = np.polyfit(x_arr, y_arr, 1)
print("一阶拟合系数为:", coeff_1)
# 2. 根据系数得到多项式
poly_fit_1 = np.poly1d(coeff_1)
print("一阶多项式为:", poly_fit_1)
# 3. 输入变量(单个值或者变量数组),得到拟合结果(数组)
y_fit_1 = poly_fit_1(x_arr)
print("一阶拟合得到的数据为: ", y_fit_1)
# 4. 根据结果作图
plt.plot(x_arr, y_fit_1, 'green',label="一阶拟合")
# 5. 根据原始数据以及拟合数据得到拟合优度
rr1 = goodness_of_fit(y_fit_1, y_arr)
print("一阶拟合优度为%.5f" % rr1)
#
coeff_2 = np.polyfit(x_arr, y_arr, 2)
print("二阶拟合系数为:", coeff_2)
poly_fit_2 = np.poly1d(coeff_2)
print("二阶多项式为:", poly_fit_2)
y_fit_2 = poly_fit_2(x_arr)
print("二阶拟合得到的数据为: ", y_fit_2)
plt.plot(x_arr, y_fit_2, 'orange',label="二阶拟合")
rr2 = goodness_of_fit(y_fit_2, y_arr)
print("二阶拟合优度为%.5f" % rr2)
# #
coeff_3 = np.polyfit(x_arr, y_arr, 3)
print("三阶拟合系数为:", coeff_3)
poly_fit_3 = np.poly1d(coeff_3)
print("三阶多项式为:", poly_fit_3)
y_fit_3 = poly_fit_3(x_arr)
print("三阶拟合得到的数据为: ", y_fit_3)
plt.plot(x_arr, poly_fit_3(x_arr), 'skyblue',label="三阶拟合")
rr3 = goodness_of_fit(y_fit_3, y_arr)
print("三阶拟合优度为%.5f" % rr3)
# #
coeff_4 = np.polyfit(x_arr, y_arr, 4)
print("四阶拟合系数为:", coeff_4)
poly_fit_4 = np.poly1d(coeff_4)
print("四阶多项式为:", poly_fit_4)
y_fit_4 = poly_fit_4(x_arr)
print("四阶拟合得到的数据为: ", y_fit_4)
plt.plot(x, y_fit_4, 'blue',label="四阶拟合")
rr4 = goodness_of_fit(y_fit_4, y_arr)
print("四阶拟合优度为%5f" % rr4)
#
coeff_5 = np.polyfit(x_arr, y_arr, 5)
print("五阶拟合系数为:", coeff_5)
poly_fit_5 = np.poly1d(coeff_5)
print("五阶多项式为:", poly_fit_5)
y_fit_5 = poly_fit_5(x_arr)
print("五阶拟合得到的数据为: ", y_fit_5)
plt.plot(x_arr, y_fit_5, 'red', label="五阶拟合")
rr5 = goodness_of_fit(y_fit_5, y_arr)
print("五阶拟合优度为%.5f" % rr5)
plt.scatter(x, y, color='black', label="原始数据")
plt.title("1~5阶拟合曲线图")
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.legend(loc=2)
plt.show()