(一)求解正规方程来计算3个点的最佳拟合
一、问题描述
假设平面上3个点:(-1.0,-1.2) , (0.0,1.0), (1.0,2.8)。
(1)请写出相应的正规方程。
(2)并通过求解正规方程来计算这3个点的最佳拟合。
二、实验目的
1理解线性回归算法中目标函数的几何与统计意义;
2理解线性回归的优化算法——正规方程;
3理解多项式回归和线性回归的关系;
三、实验内容
Step1:首先对数据进行特征处理;
Step2:然后求出正规方程的最优解;
Step3:通过最优解预测数据;
正规方程算法:
1.linear_regression.py
import numpy as np
class LinearRegression:
def fit(self, X, y):
self.w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
return
def predict(self, X):
return X.dot(self.w)
def mean_squared_error(y_true, y_pred):
return np.average((y_true - y_pred)**2, axis=0)
def r2_score(y_true, y_pred):
numerator = (y_true - y_pred)**2
denominator = (y_true - np.average(y_true, axis=0))**2
return 1- numerator.sum(axis=0) / denominator.sum(axis=0)
|
2.normalEquation.py
import numpy as np
import matplotlib.pyplot as plt
import linear_regression as lib
def mean_squared_error(y_true, y_pred): # h的均方误差
return np.average((y_true - y_pred) ** 2, axis=0)# axis = 0 按列计算
def r2_score(y_true, y_pred): # R^2的决定系数
numerator = (y_true - y_pred) ** 2
denominator = (y_true - np.average(y_true, axis=0)) ** 2
return 1 - numerator.sum(axis=0) / denominator.sum(axis=0) # 按列计算
def process_features(X): # 特征处理
m, n = X.shape
X = np.c_[np.ones((m, 1)), X] # 按行连接,(1,x)
return X
plt.figure(1)
x = np.mat([[-1.0], [0.0], [1.0]])
y = np.mat([[-1.2], [1.0], [2.8]])
plt.plot(x[:, 0], y[:, 0], "bs", ms=3)
x_train = process_features(x)
model = lib.LinearRegression()
model.fit(x_train, y)
print('最优解:',model.w)
y_pred = model.predict(x_train)
plt.plot(x, y_pred)
plt.show()
|
运行结果:

四、实验结果及分析
- 正规方程是2XTXw-2XTy=0,正规方程的最优解是 [[0.86666667] [2.]]。
- 在XTX可逆时,w=(XTX)-1XTy。
五、遇到的问题及解决办法
(1)当XTX不可逆的时候,就需要涉及广义逆矩阵等较为复杂的线性代数方法,而且最优解也没有简单形式。
(2)对n阶方阵求逆算法的时间复杂度是O(n3),可以说算法效率比较低。
(二)多项式拟合3个点及线性回归拟合
一、问题描述
考察平面上3个点: (0,1) , (1,1), (2,3)。
(1)请计算能够完美拟合这3个点的2次多项式。
(2)在线性模型假设 H={hw,b=wx + b: w∈ℝ, b∈ℝ} ,假定损失是例2.2中的平方损失函数,请写出在训练数据集S={(0,1),(1,1),(2,3)}上经验损失最小化算法中的目标函数,并计算出最优的线性模型参数。
二、实验目的
- 理解线性回归算法中目标函数的几何与统计意义;
- 理解线性回归的优化算法——正规方程;
- 理解多项式回归和线性回归的关系;
三、实验内容
- 使用scipy提供的最小二乘法函数得到最佳的拟合参数;
- 找到数据集,这里的数据集是平面上的三个点(0,1),(1,1),(2,3);
- 定义拟合函数:h<w,x>=w0+w1*x+w2*x*x;
- 代码求解该2次多项式:
import numpy as np
from scipy.optimize import leastsq
# 拟合数据集,平面上3个点:(0,1),(1,1),(2,3)
x=[0,1,2]
y=[1,1,3]
def fun(p, x):
"""
定义想要拟合的函数
"""
w0,w1,w2 = p # 从参数p获得拟合的参数
# 二次多项式则:w0,w1,w2 = p ;return w0 + w1*x + w2*x*x
return w0 + w1*x + w2*x*x
def err(p, x, y):
"""
定义误差函数
"""
return fun(p, x) - y
# 定义起始的参数 即从 y = 1*x*x+1*x+1 开始,其实这个值可以随便设,只不过会影响到找到最优解的时间
p0 = [1, 1, 1] # p0 = [1,1,1] w系数的个数[w0,w1,w2...]
# 将list类型转换为 numpy.array 类型
x1 = np.array(x)
y1 = np.array(y)
coefficient = leastsq(err, p0, args=(x1, y1))
#打印出系数矩阵coefficient[0]
print("系数矩阵是:",coefficient[0])
w0,w1,w2=coefficient[0]
print("w0的值为:",w0)
print("w1的值为:",w1)
print("w2的值为:",w2)
# coefficient[0],即为获得的参数
|
运行结果如下:


因此,该2次多项式是h<w,x>=1-x+x*x;
- 答:目标函数是h<w,b>=(b-1)2+[w+b-1]2+(2w+b-3)2;
参数w=1,b=0.667
代码实现:
from sklearn import linear_model
import matplotlib.pyplot as plt
import numpy as np
diabetes_x_train = [[0],[1],[2]]
diabetes_y_train = [[1],[1],[3]]
# 回归训练及预测
clf = linear_model.LinearRegression()
clf.fit(diabetes_x_train, diabetes_y_train) #用训练器数据拟合分类器模型
print('系数 :\n', clf.coef_)#打印出参数的值
print("观测值与拟合值之间的差距: %.2f" % np.mean((clf.predict(diabetes_x_train) - diabetes_y_train) ** 2))
print("方差: %.2f" % clf.score(diabetes_x_train, diabetes_y_train))
# 绘图,点的准确位置
plt.scatter(diabetes_x_train, diabetes_y_train, color='red')
# 预测结果 直线表示
plt.plot(diabetes_x_train, clf.predict(diabetes_x_train), color='blue', linewidth=1)#给新数据对其预测
plt.show()
|
运行结果:

四、实验结果及分析
(1)在该题目中,我们可以明显地看出,y=1-x+x^2能够完美拟合平面上的这三个点,这说明特征与标签不是简单的线性关系,而是呈现多项式的关系;
(2)但是,我们可以用线性回归的思想去拟合多项式,将1,x,x^2均看成特征,进而将该多项式看成线性模型,用y=w*x+b去拟合这三个点,进而找到平均拟合误差最小的那条直线。
五、遇到的问题及解决办法
多项式回归可以用线性回归来解决问题。