python使用最小二乘法求拟合曲线

1.最小二乘法
2.假设4个数据点为:(1, 6),(2, 5),(3, 7),(4, 10),求最佳匹配直线。

import numpy as np
x = [1, 2, 3, 4]
y = [6, 5, 7, 10]
r = np.polyfit(x, y, deg=1) # 对(x,y)拟合多项式p(x) = p[0] * x**deg + ... + p[deg]
f = np.poly1d(r) #f为拟合函数

求出的拟合直线为$ y = r[0]x+r[1] $, $y = 1.4x+3.5 $
3.画出拟合直线和数据点

import matplotlib.pyplot as plt
fig = plt.subplots()
plt.plot(1,6,'*-')
plt.plot(2,5,'*-')
plt.plot(3,7,'*-')
plt.plot(4,10,'*-')
f = lambda x: 1.4*x + 3.5
x = [1, 2, 3, 4]
y = [f(e) for e in x]
plt.plot(x,y)
plt.show()

image


使用scikit-learn

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression


x = np.array([ 6,  8, 10, 14, 18])
y = np.array([ 7. ,  9. , 13. , 17.5, 18. ])

plt.plot(x, y, 'k.')
plt.axis([0, 25, 0, 25])


model = LinearRegression()
model.fit(x.reshape(-1,1),y.reshape(-1,1))

e = [item[0] for item in model.predict(x.reshape(-1,1))]


X = list(zip(x,x))
Y = list(zip(y,e))
for i in range(len(X)):
    plt.plot(X[i],Y[i],'r')

plt.title("Linear regression use least square method")
plt.xlabel(r'$x$', horizontalalignment='right', x=1.0)
plt.ylabel(r'$y$', horizontalalignment='right', y=1.0, rotation=0)

plt.plot(x, e)
plt.grid(True)
plt.show()

代码


选择最小二乘的原因:
1.平方能将正残差与负残差都变成正数
2.平方相当于给残差赋予了一个权重,越大的残差(绝对值)被赋予的权重越大。但是并不是所有情况下大的残差都应该被赋予大的权重,因为这样拟合方程就很容易受到异常值的影响
3.在残差服从均值为0,方差为$ \sigma ^2 $ (未知,但为常数)的正态分布,且在残差与x独立的假设下,参数的最小二乘估计结果与极大似然估计量相同。
4.最小二乘估计的计算简单 在数理统计中,残差是指实际观察值与估计值(拟合值)之间的差。


Ref:
1.Think Stats Probability and Statistics for Programmers
2.numpy
3.scikit-learn