1. 最小二乘直线拟合(曲线拟合)
【问题描述】根据N个数据点构造最小二乘拟合直线y=ax+b。
【输入形式】在屏幕上依次输入数据点的个数N,和N对数据点的x和y坐标。
【输出形式】输出最小二乘拟合直线y=ax+b和误差(N对数据点的y坐标,与由拟合直线得到的对应N个x坐标的y值,之间的欧式距离)。
【样例1输入】
8
-1 10
0 9
1 7
2 5
3 4
4 3
5 0
6 -1
【样例1输出】
y=-1.6071429x+8.6428571
1.1801937
【样例1说明】输入:有8对数据点,后续每行是一对数据点的x和y坐标。输出:最小二乘拟合直线为y=-1.6071429x+8.6428571,误差(norm2范数,即欧式距离)为1.1801937(保留小数点后7位有效数字)
【评分标准】根据输入得到的输出准确
import numpy as np
# 最小二乘拟合直线
def f(n, x, y):
# 求x,y的平均值
xm = np.mean(x)
ym = np.mean(y)
# 求C
sumx = (x - xm) @ (x - xm)
# 求A
sumxy = (y - ym) @ (x - xm)
a = sumxy / sumx
# 求B
b = ym - a * xm
print("y=%.7fx+%.7f" % (a, b))
# 求误差
f_y = np.poly1d([a, b])
f_x = np.polyval(f_y, x)
norm2 = np.linalg.norm(f_x - y)
print('%.7f' %norm2)
"""
sum = 0
z = x * a + b - y
for i in range(n):
sum += z[i] ** 2
ans = np.sqrt(sum)
print('%.7f' % ans)
"""
def main():
n = int(input())
x = np.zeros(n, dtype=np.int)
y = np.zeros(n, dtype=np.int)
for i in range(n):
xx,yy = input().split()
x[i] = xx
y[i] = yy
f(n, x, y)
if __name__ == '__main__':
main()
2. 最小二乘多项式拟合(曲线拟合)
【问题描述】根据N个数据点构造最小二乘多项式拟合。
【输入形式】在屏幕上依次输入多项式的次数m,数据点的个数N,和N对数据点的x和y坐标。
【输出形式】输出最小二乘多项式和误差。
【样例1输入】
2
4
-3 3
0 1
2 1
4 3
【样例1输出】
[ 0.17846248 -0.19249542 0.85051861]
0.2445252
【样例1说明】输入:多项式的次数m为2,有4对数据点,后续每行是一对数据点的x和y坐标。
输出:最小二乘多项式为y=0.17846248x**2-0.19249542x+0.85051861,误差(norm2范数,即欧式距离)为0.2445252(保留小数点后7位有效数字)
【评分标准】根据输入得到的输出准确
import numpy as np
def nihe(m, n, x, y):
f = np.zeros((n, m+1), dtype=np.double)
# b = np.zeros((1, m+1), dtype=np.double)
# 一列一列的赋值
for k in range(m+1):
f[:, k] = x ** k
# 矩阵的转置np.transpose(f)
a = np.transpose(f) @ f
b = np.transpose(f) @ y
# a @ c = b
c = np.linalg.inv(a) @ b
# c为c1——c(m+1),为了对应多项式计算,需用np.flipud(c)翻转
c = np.flipud(c)
print(c)
# 求误差
f_x = np.polyval(c, x)
norm2 = np.linalg.norm(f_x - y)
print('%.7f' % norm2)
def main():
# m为次数,有0——m,即m+1列
m = int(input())
# n为点数,有0——n-1,即n行
n = int(input())
x = np.zeros(n, dtype=np.double)
y = np.zeros(n, dtype=np.double)
for i in range(n):
xx, yy = map(float, input().split())
x[i] = xx
y[i] = yy
nihe(m, n, x, y)
if __name__ == '__main__':
main()