Это кажется склеарнским вопросом, но это не так (по крайней мере, не напрямую). Я просто использую здесь sklearn для получения точек данных, так как это сможет полностью воспроизвести мою проблему. Некоторый фон
Я использую sklearn
чтобы предсказать некоторые точки в небольшом интервале. Сначала я строю синтетический домен X
с 2d векторами (строки в матрице).
Затем я вычисляю некоторые точки изображения y= x_1 + x_2 + noise
используя эти строки x=(x_1, x_2)
и некоторый шум, чтобы попытаться воспроизвести некоторые реальные данные.
Чтобы выполнить регрессию (или интерполяцию), в рамках метода, который я выбираю случайным образом, выбираем векторы/точки (здесь в матричной форме они являются строками) из домена X
с помощью команды train_test_split
, я train_test_split
детали, но массивы результатов случайные подмножества пространства (пространство (x_1, x_2, y)
для всех (x_1, x_2)
в моей компактной поддержке.
Затем я делаю регрессию, используя sklearn, пока все хорошо. все работает как положено. И я получаю в y_pred_test_sine
прогнозы, и они хорошо работают. Но прогноз полностью перемешан, так как метод выбирает случайные точки из области в качестве тестового набора.
Здесь возникает проблема...
Так как я хочу построить непрерывную функцию (будучи интерполированной с помощью matplotlib, и это нормально, я позже поиграю с собственными тестами интерполяции). Я делаю две вещи:
X_test_sort
y_pred_test_sine_sort
Они (1) и (2) соответствуют (по крайней мере, должны) каждой точке данных в прогнозируемой модели (они сортируются только для того, чтобы их можно было легко построить с использованием линий plt.plot
, а не маркеров)
Затем я строю их, и они не соответствуют (ВСЕМ) ожидаемым точкам в моем пространстве решений.
Здесь мы видим, что полная черная линия (отсортированная предсказанная линия) не следует за оранжевыми точками (предсказанные точки). И это было совсем не то, что я ожидал.
Здесь следуйте коду, чтобы воспроизвести проблему.
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()
Как вы упомянули в своих комментариях, сортируя y
, вы разрушаете связь между X
и y
по месту. Вместо этого используйте 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]
Это даст вам желаемый график
X_test[:,0]
иy_pred_test_sine
одновременно, используя первый в качестве руководства. Я думаю, что это исправит. Есть идеи как это сделать.np.argsort()
мне как-то поможет.