线性回归算法原理与总结 (3)

线性回归算法原理与总结

可以看到数据绘制出来,大致长上面这样,下面就来按照公式推导我们的 \(a\)\(b\)

a = np.sum( (x - np.mean(x)) * (y - np.mean(y)) ) / np.sum( (x - np.mean(x)) ** 2 ) b = np.mean(y) - a * np.mean(x) print(a, b) # 0.8 0.39999999999999947

此时 \(a\)\(b\) 便被计算了出来,那么我们就将这条直线给绘制出来吧。

y_hat = a * x + b trace0 = go.Scatter(x=x, y=y, mode="markers", marker={"size": 10}) trace1 = go.Scatter(x=x, y=y_hat, mode="lines", marker={"size": 10}) figure = go.Figure(data=[trace0, trace1], layout={"showlegend": False, "template": "plotly_dark"}) figure.show()

线性回归算法原理与总结

然后我们进行预测。

x_predict = 6 y_predict = a * x_predict + b print(y_predict) # 5.2

肿么样,似不似灰常简单呢?那么下面我们就按照sklearn的模式,来封装这个简单线性回归算法。

import numpy as np class SimpleLinearRegression: def __init__(self): """ 关于变量后面加上一个下划线这种命名方式在sklearn中是有约定的 表示这种变量不是由用户传来的,而是一开始就有的,具体是什么值则是由用户传来的样本进行训练之后得到的 并且还可以提供给用户使用,这种类型的变量都会在后面加上一个下划线 """ self.a_ = None self.b_ = None def fit(self, x_train: np.ndarray, y_train: np.ndarray): """通过x_train和y_train训练模型""" assert x_train.ndim == 1, "简单线性回归只支持一个具有一个特征的训练集" assert len(x_train) == len(y_train), "样本数必须和标签数保持一致" x_mean = np.mean(x_train) y_mean = np.mean(y_train) self.a_ = np.sum((x_train - x_mean) * (y_train - y_mean)) / np.sum((x_train - x_mean) ** 2) self.b_ = y_mean - self.a_ * x_mean # 按照sklearn的标准,我们要将这个实例进行返回 return self def predict(self, x_predict): """对传来的x进行预测""" assert self.a_ is not None, "预测(predict)之前要先拟合(fit)" if isinstance(x_predict, list): x_predict = np.array(x_predict) return self.a_ * x_predict + self.b_ def __str__(self): return f"<SimpleLinearRegression>:a_={self.a_},b_={self.b_}" def __repr__(self): return f"<SimpleLinearRegression>:a_={self.a_},b_={self.b_}" x = np.array([1, 2, 3, 4, 5]) y = np.array([1, 3, 2, 3, 5]) sim_linear_reg = SimpleLinearRegression() sim_linear_reg.fit(x, y) print(sim_linear_reg.a_) # 0.8 print(sim_linear_reg.b_) # 0.39999999999999947 x_predict = [1, 3, 4, 6] print(sim_linear_reg.predict(x_predict)) # [1.2 2.8 3.6 5.2]

可以看到,计算的结果是一致的。此时我们便通过sklearn的方式实现了一个简单线性回归

衡量线性回归的指标

在knn中,我们将数据集分为训练集合测试集,训练集用于训练模型,然后对测试集进行预测,通过预测出来的标签和真实标签进行对比,得到一个分类的准确度。

但是对于回归算法来说,我们如何评价一个算法呢?其实对于回归算法来说,我们仍然需要将数据集分为训练集和测试集,而我们的目的就是找到一个a和b,使得在训练集中,预测值和真实值之间差距尽可能的小。

所以我们的目标就变成了,找到 \(a\) 和 \(b\) ,使得 \(\displaystyle\sum^{m}_{i=1}(y^{i}_{train} - ax^{i}_{train} - b)^{2}\) 尽可能的小;然后对预测集进行预测,得到的误差 \(\displaystyle\sum^{m}_{i=1}(y^{i}_{test} - ax^{i}_{test} - b)^{2}\) 便是我们的评价指标,越小代表模型越好。

但是这样又出现了一个问题,那就是我们的预测结果是和样本个数m有关的。如果A预测10000个样本,误差是1000,而B预测10个样本误差就达到800了,难道说B的算法比A好吗?显然是不能的,那么我们可以改进一下。

那么下面就产生了三个指标:

1. 均方误差(Mean Squared Error,MSE)

\(\frac{1}{m} \displaystyle\sum_{i=1}^{m}(y_{test}^{i} - \hat y_{test}^{i})^{2}\)

让衡量标准与我们的样本数无关,这便是均方误差。但是呢?这个均方误差还有一个潜在的问题,那就是如果我们预测房产数据单位是万元,那么得到的单位就是万元的平方,会造成量纲上的问题。 由此产生了下面一个衡量标准

2. 均方根误差(Root Mean Squared Error,RMSE)

\(\sqrt{\frac{1}{m} \displaystyle\sum_{i=1}^{m}(y_{test}^{i} - \hat y_{test}^{i})^{2}} = \sqrt{MSE_{text}}\)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsxyz.html