研一第一学期刚学习完数值分析,赶上期末复习,复习的时候正好复习到最小二乘法,把离散的点拟合为线性函数,就顺便用python实现一下。正好准备学习机器学习算法这方面,就当是预热吧,我知道机器学习的算法肯定比这个难很多,我还是个新手,不当之处还请大神指点,轻喷。
首先上一下公式:
因为书上记笔记画的很乱就不拍书了,直接百度也能搜到最小二乘法的公式:
解方程组得到的解(a0,a1......an)就是拟合函数的系数。这里是简单的一次线性函数,因此只要求a0,a1即可。
读取的数据是读取的csv文件里的x与y
下载地址:https://download.youkuaiyun.com/download/qq_32194791/89402478
下面是代码:
#离散型数据利用最小二乘法拟合为一次线性函数
import csv
import numpy as np
from numpy.linalg import *
import matplotlib.pyplot as plt
'''
#手动输入数据使用
i=0;X=[];Y=[]
m=int(input('请输入x的个数:'))
while i<m:
x,y=map(float,input('请输入x%d,y%d:'%(i,i)).split(','))
X.append(x)
Y.append(y)
i=i+1
print('x:',X)
print('y:',Y)
'''
#直接读取csv文件的数据
X=[];Y=[]
file=csv.reader(open('F:/data.csv','r'))
for each in file:
if 'x' not in each:
X.append(float(each[0]))
Y.append(float(each[1]))
#print(X)
#print(Y)
a11=0;a12=0;a21=0;a22=0;b1=0;b2=0
for i in range(len(X)):
#系数矩阵A部分
a11=a11+X[i]**0
a12=a12+X[i]**1
a21=a21+X[i]**1
a22=a22+X[i]**2
#b部分
b1=b1+Y[i]
b2=b2+X[i]*Y[i]
A=np.array([[a11,a12], #法方程组的系数矩阵
[a21,a22]])
b=np.array([[b1], #常数项所构成的列向量
[b2]])
print('A:',A)
print('b:',b)
#求解部分
ans=np.dot(inv(A),b)#这里np.dot才能是矩阵乘法,否则只是对应元素相乘
#print(ans)
#ans1=solve(A,b)没有求逆相乘精确
#若设P(x)=ax+c,
print('Ab:',ans)#ans是一个2行1列的矩阵
c=ans[0,0]#第一行的是截距
a=ans[1,0]#第二行的是斜率
if c<0:
print('拟合的线性函数P(x)=%.5fx%.5f'%(a,c))
elif c==0:
print('拟合的线性函数P(x)=%.5fx'%a)
else:
print('拟合的线性函数P(x)=%.5fx+%.5f'%(a,c))
def P(x):
return a*x+c
#画图部分
Y_=[]#用来存放拟合的y_
for each in X:
y_=P(each)
Y_.append(y_)
plt.figure()
plt.plot(X,Y_,color='blue')
plt.scatter(X,Y,marker='.',color='red')#等价于plt.plot(X,Y,'r.')
plt.xlabel('x',fontproperties='SimHei',fontsize=14)
plt.ylabel('y',fontproperties='SimHei',fontsize=14)
plt.title('Least square linear regression',fontproperties='SimHei',fontsize=20)
plt.show()
运行效果图:
菜鸟一枚,望大神轻喷,欢迎评论,谢谢!