题目

假设平面上3个点: (-1.0,-1.2) , (0.0,1.0), (1.0,2.8)。
(1)请写出相应的正规方程。
(2)并通过求解正规方程来计算这3个点的最佳直线拟合。
要求:
画出原始数据的散点图;
画出拟合的直线。

求解思路

思路题目已经给出来了,先求正规方程,再求拟合直线。

求解步骤

输入坐标X,Y

dots = np.array([[-1.0, -1.2],
                 [0.0, 1.0],
                 [1.0, 2.8]])  # 点坐标
X = dots[:, [0]]  # 取出每个坐标X轴的值
Y = dots[:, [1]]  # 取出每个坐标Y轴的值

X首位置1

m, n = X.shape  # 求X矩阵的行数和列数
X_1 = np.c_[np.ones((m, 1)), X]  # 将m行1列的矩阵与X拼接

求正规方程
正规方程法求解点的拟合直线

# w*=(XT⦁X)-1⦁X⦁y  # 求解正规方程
theta = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
print("theta:{}".format(theta))

使用模型预测X对应Y的值
Y_pred = X_1 ⦁ w*

Y_pred = X_1.dot(theta)  # 求Y的预测值

求模型的均方误差
均方误差MSE是反映估计量与被估计量之间差异程度的一种度量。
MSE的值越小,说明预测模型描述实验数据具有更好的精确度。

正规方程法求解点的拟合直线

mse = np.average((Y - Y_pred)**2, axis=0)
print("mse = {}".format(mse))

求决定系数
决定系数越接近于1,说明模型拟合的效果越好。

正规方程法求解点的拟合直线

numerator = (Y - Y_pred)**2
denominator = (Y - np.average(Y, axis=0))**2
r2 = 1- numerator.sum(axis=0) / denominator.sum(axis=0)
print("r2 = {}".format(r2))

绘图

plt.figure()
plt.title("Scatter Fitting")
plt.plot(X, Y, "bs", ms=3)  # 画散点
plt.plot(X, Y_pred, color='red')  # 打印直线
plt.show()

整合起来

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)  # w*=(XT⦁X)-1⦁X⦁y
        return self.w

    def predict(self, X):  # 预测X对应的Y值
        return X.dot(self.w)  # Y_pred = X ⦁ 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)

scatter_fitting.py

import numpy as np
import matplotlib.pyplot as plt
import machine_learning.linear_regression.lib.linear_regression as lib


def process_features(X):
    m, n = X.shape  # 求X矩阵的行数和列数
    X = np.c_[np.ones((m, 1)), X]  # 将m行1列的矩阵与X拼接
    return X


dots = np.array([[-1.0, -1.2],
                 [0.0, 1.0],
                 [1.0, 2.8]])  # 点坐标
X = dots[:, [0]]  # 取出每个坐标X轴的值
Y = dots[:, [1]]  # 取出每个坐标Y轴的值
X_1 = process_features(X)  # 首位置1
model = lib.LinearRegression()  # 生成回归模型
theta = model.fit(X_1, Y)  # 求解正规方程
print("theta:{}".format(theta))
Y_pred = model.predict(X_1)  # 求解X的预测值
plt.figure()
plt.title("Scatter Fitting")
plt.plot(X, Y, "bs", ms=3)  # 画散点
plt.plot(X, Y_pred, color='red')  # 打印直线
plt.show()
mse = lib.mean_squared_error(Y, Y_pred)  # 求均方误差
r2 = lib.r2_score(Y, Y_pred)  # 求决定系数
print("mse = {}".format(mse))
print("r2 = {}".format(r2))

预测结果

theta = [[0.86666667][2.]]
mse = [0.00888889]
r2 = [0.99667774]
正规方程法求解点的拟合直线


我一直在开辟我的天空