排序后的数据未在正确的数据点中绘制

时间:2018-12-22 12:36:41

标签: python matplotlib scikit-learn

这似乎是一个sklearn问题,但不是(至少不是直接)。我只是在这里使用sklearn来获取数据点,因为这将完全重现我的问题。一些背景

我使用sklearn在很小的间隔内预测一些点。首先,我用2d向量(矩阵中的行)构建一个合成域X

然后,我使用这些行y= x_1 + x_2 + noise计算一些图像点x=(x_1, x_2)和一些噪声以尝试复制一些真实数据。

要进行回归(aka插值),作为方法的一部分,我使用命令X从域train_test_split中随机选取向量/点(这里是矩阵形式的行),我将跳过细节,但是结果数组是该空间的随机子集(紧凑支持中所有(x_1, x_2, y)的空间为(x_1, x_2)

然后我使用sklearn进行回归,到目前为止效果很好。一切都按预期进行。而且我得到y_pred_test_sine的预测,并且它们运行良好。但是,由于该方法从域中选择随机点作为测试集,因此该预测被完全打乱了。

问题来了……

由于我想绘制为连续函数(由matplotlib进行插值,所以可以,以后我将进行自己的插值测试)。我做两件事:

  1. 使用来自测试X_test_sort的排序的预测图像点创建新矢量
  2. 使用测试中已排序的域点创建一个新的向量。 y_pred_test_sine_sort

这些(1)和(2)匹配(至少应该匹配)预测模型中的每个数据点(这些排序仅是为了便于使用plt.plot行而不是标记进行绘制)

然后我将它们绘制出来,它们与我的解决方案空间中的预期点根本不匹配。

enter image description here

在这里,我们可以看到全黑线(排序的预测线)不跟随橙色点(预测点)。那根本不是我所期望的。

请按照以下代码重现该问题。

import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

plt.close('all')

rng = np.random.RandomState(42)
regressor = LinearRegression()

# Synthetic dataset
x_1 = np.linspace(-3, 3, 300)
x_2 = np.sin(4*x_1)
noise = rng.uniform(size=len(x_1))
y = x_1 + x_2 + noise
X = np.vstack((x_1, x_2)).T

# Data splitting
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)

# Regression 2 features data
fit_sine = regressor.fit(X_train, y_train)
y_pred_test_sine = regressor.predict(X_test)

# Here I have sorted the X values and its image points Y = f(x)
# Why those are not correctly placed over the 'prediction' points
X_test_sort = np.sort(X_test[:,0].ravel())
y_pred_test_sine_sort = np.sort(y_pred_test_sine.ravel())

# DO THE PLOTTING
plt.plot(X_test[:,0], y_test, 'o', alpha=.5, label='data')
plt.plot(X_test[:,0], y_pred_test_sine, 'o', alpha=.5, label='prediction')
plt.plot(X_test_sort, y_pred_test_sine_sort, 'k', label='prediction line')
plt.plot(x, np.sin(4*x)+x+.5, 'k:', alpha=0.3, label='trend')
plt.legend()

1 个答案:

答案 0 :(得分:1)

正如您在注释中提到的那样,通过对y进行排序,可以按位置破坏Xy之间的连接。相反,请使用use argsort获取X的排序顺序,然后使用以下顺序对X_test和y进行排序:

argsort_X_test = np.argsort((X_test[:,0].ravel()))
X_test_sort = X_test[argsort_X_test, 0]
y_pred_test_sine_sort = y_pred_test_sine[argsort_X_test]

这将为您提供所需的图形

enter image description here