绘制多元线性回归

数据挖掘 机器学习 Python 线性回归 可视化 matplotlib
2022-02-02 00:08:48

为了练习线性回归,我正在生成一些合成数据样本,如下所示。

首先,它生成 2000 个具有 3 个特征的样本(用 表示x_data)。然后它y_data通过一个小模拟生成(结果为真实的 y)。即通过假设一个线性依赖模型:虚构权重(由 表示w_real)、偏差(由 表示b_real),并添加一些噪声。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


#create some test data and simulate results
x_data = np.random.randn(2000,3)
w_real = [0.3,0.5,0.1]
b_real = -0.2

noise = np.random.randn(1,2000)*0.1
y_data = np.matmul(w_real,x_data.T) + b_real + noise

print(len(x_data))
print(len(y_data[0]))

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x1 = x_data[:,0]
x2 = x_data[:,1]
x3 = x_data[:,2]
ax.scatter3D(x1, x2, x3, c=x3, cmap='Greens');

plt.show()

#actual implementation of liner regression
#compute y_pred, compare with y_data above etc etc
#assume more code here

exit() 

我正在尝试使用 matplotlib可视化上面的模拟样本(x_data和)。y_data我能够绘制 x_data 如下图所示。我还想y_data在这个图上可视化模拟结果(),可能是不同的颜色。其背后的动机是可视化 x 和 y 之间的关系。我怎么能这样绘制它?

数据维度:

  • x_data2000×3
  • y_data2000×1

以下是上述示例显示示例数据的方式,

合成数据样本

这是我想要实现的一个例子。该图像显示了用直线表示的两个不同假设,在我的情况下,我想画一条表示y_data.

来自网络的示例

1个回答

如果有两个以上的变量,就会出现维度问题。在这里,有 3 个变量和一个输出,您需要一个 4 维图,除非您使用一些技巧,否则这是不可能的。

1. 减少问题的维度

一般来说,如果你需要观察一个维度太大的问题,你可能想要减少它的维度。只观察一个或两个变量的关系。当然,这意味着您将难以观察更复杂的关系。

例如,这意味着为 (X1,X2)、(X2,X3) 和 (X1,X3) 独立绘图:

ax.scatter(x1, x2, y_data[0], c=y_data[0], cmap='viridis');

在此处输入图像描述

老实说,这并不理想,因为某些点可能会恢复其他点。这可以通过为点添加一些透明度(参数 alpha)来解决,但它并没有改善可视化效果。我建议从一维图开始(y 对另一个变量),以真正了解正在发生的事情:

plt.scatter(x1, y_data[0], c=y_data[0], cmap='viridis');

在此处输入图像描述

2.使用颜色并使图形具有交互性

向图形添加第四维的一种方法是使用颜色。它有一些限制(您需要一个良好的色标:如果以黑白打印仍会呈现,一种对色盲友好)。事实上,它不适用于超过 3 个变量。

例如,这意味着:

ax.scatter3D(x1, x2, x3, c=y_data[0], cmap='viridis');

在此处输入图像描述

这面临着上面的可读性问题(但我发现它更好,因为颜色带来了一些信息,而不是重复垂直轴上的内容)。

一种选择是使图形具有交互性,例如 plotly。(更多信息:https ://plot.ly/python/3d-scatter-plots/ )

3.使用等高线

为图形添加维度的另一种方法是绘制等高线曲线,它表示给出相同 y) 的 X 值的集合。请注意,您不会得到任何“代表 y_data 的单行”。一般来说,我很确定这不会在 3D 中很好地渲染(绘制 3D 曲线的集合),除了你的线性回归问题(你会得到一个 3D 平面的集合)。同样,主要选项是绘制问题的简化版本,即带有 2D 轮廓曲线的 2D 绘图。

这种方法的一个主要要求是您需要提供 X 和 y 之间的关系,这是未知的。因此,您必须建立一个模型并使其适应您想要绘制的内容。

对于线性回归,你会得到类似的东西:

获取估计模型:

w_est = [0.29,0.51,0.09]
b_est = -0.19

def output_X1_X2(X1, X2):
    return X1*w_est[0] + X2*w_est[1] + 0 * w_est[2] + b_est 

设置绘图值:

x1_plot = np.linspace(-3, 3, 50)
x2_plot = np.linspace(-3, 3, 50)

X1_plot, X2_plot = np.meshgrid(x1_plot, x2_plot)
Y = output_X1_X2(X1_plot, X2_plot)

绘制输出和相关的轮廓:

contours = plt.contour(X1_plot, X2_plot, Y, 20, colors='black')
plt.clabel(contours, inline=True, fontsize=8)
plt.imshow(Y, extent=[0, 3, 0, 3], origin='lower',
           cmap='viridis')
plt.colorbar();

在此处输入图像描述

您会得到一个 X1 和 X2 的 y 值不同的图形。主要缺点是:您看不到与 X3 的交互,您必须设置给定的 X3(此处为 0)。这意味着您必须使用 (X2,X3) 和 (X1,X3) 绘制类似的图表,而且您必须使预留变量移动到 0 以外的值。即使这可以自动化,它也会很快成为一个痛苦有很多变数。