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

可以看到,我们直接对均方误差进行开根,便得到了均方根误差,这样就避免了量纲的问题。其实这两个衡量标准本质上比较类似,因为均方误差大,那么均方根误差也会跟着大,只是均方根误差更具有统计学上的意义

3. 平均绝对误差(Mean Absolute Error,MAE)

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

这个衡量标准非常的直白,就是每一个样本的真实值和预测值之差的绝对值之和,这便是平均绝对误差。之前我们说过,在训练的时候,不建议使用这个模型,因为这不是一个处处可导的函数,但是在预测的时候,我们是完全可以使用这个指标的。也就是说,我们在评价一个算法所使用的指标和训练模型所使用的目标函数是可以不一致的。

使用程序来实现三个指标

这次我们使用sklearn中的真实数据集,波士顿房产数据。但由于我们这里还是简单线性回归,而波士顿房产数据有多个特征,因此我们这里只选择一个特征,选择房子的房间数。

from sklearn.datasets import load_boston boston = load_boston() x = boston.data[:, 5] # 选择房屋的房间数 y = boston.target trace0 = go.Scatter(x=x, y=y, mode="markers", marker={"size": 10}) figure = go.Figure(data=[trace0], layout={"showlegend": False, "template": "plotly_dark"}) figure.show()

线性回归算法原理与总结

数据集大致长这样,但是会发现有些奇怪的点,对,就是纵轴为50的位置。之所以出现这种情况,是因为在实际生活中,没有进行更仔细的分类,比如价格超过50万美元,就按照50万美元来统计了。比如我们经常看到的统计月薪,最下面的选项是2000及以下,最上面的是40000及以上等等。 因此我们可以将最大值给去掉:

x = boston.data[:, 5] y = boston.target x = x[y < np.max(y)] y = y[y < np.max(y)] trace0 = go.Scatter(x=x, y=y, mode="markers", marker={"size": 10}) figure = go.Figure(data=[trace0], layout={"showlegend": False, "template": "plotly_dark"}) figure.show()

线性回归算法原理与总结

如此一来,我们便把最大值给去掉了。

from sklearn.model_selection import train_test_split class SimpleLinearRegression: def __init__(self): self.a_ = None self.b_ = None def fit(self, x_train: np.ndarray, y_train: np.ndarray): 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 return self def predict(self, x_predict): 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_}" boston = load_boston() x = boston.data[:, 5] # 选择房屋的房间数 y = boston.target x = x[y < np.max(y)] y = y[y < np.max(y)] x_train, x_test, y_train, y_test = train_test_split(x, y) print(x_train.shape) # (367,) print(x_test.shape) # (123,) linear = SimpleLinearRegression() linear.fit(x_train, y_train) print(linear.a_) # 7.920613164194192 print(linear.b_) # -27.860720801665288

我们将得到的直线绘制出来:

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

线性回归算法原理与总结

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

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