Интерполяция полиномов и сплайнов

Machine LearningMachine LearningBeginner
Практиковаться сейчас

This tutorial is from open-source community. Access the source code

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии мы научимся приближать функцию полиномами до определенной степени с использованием регрессии с регуляризацией. Мы покажем два различных способа сделать это для n_samples 1D точек x_i:

  1. PolynomialFeatures: генерирует все одночлены до заданной степени. Это дает нам матрицу Вандермонда с n_samples строками и degree + 1 столбцами.
  2. SplineTransformer: генерирует базисные функции B-сплайна. Базисная функция B-сплайна - это кусочно-полиномиальная функция степени degree, которая не равна нулю только между degree+1 последовательными узлами.

Мы будем использовать функцию make_pipeline для добавления нелинейных признаков и покажем, насколько эти трансформеры хорошо подходят для моделирования нелинейных эффектов с использованием линейной модели. Мы построим график функции, тренировочные точки и интерполяцию с использованием полиномиальных признаков и B-сплайнов. Мы также построим все столбцы обоих трансформеров отдельно и покажем узлы сплайна. Наконец, мы продемонстрируем использование периодических сплайнов.

Советы по работе с ВМ

После запуска ВМ нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь задавать вопросы Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills ml/sklearn -.-> lab-49248{{"Интерполяция полиномов и сплайнов"}} end

Подготовка данных

Начнем с определения функции, которую мы собираемся аппроксимировать, и подготовки ее для построения графика.

def f(x):
    """Функция, которая будет аппроксимироваться полиномиальной интерполяцией."""
    return x * np.sin(x)

## весь диапазон, который мы хотим построить
x_plot = np.linspace(-1, 11, 100)

## Чтобы сделать это интереснее, мы даем только небольшую подмножество точек для обучения.
x_train = np.linspace(0, 10, 100)
rng = np.random.RandomState(0)
x_train = np.sort(rng.choice(x_train, size=20, replace=False))
y_train = f(x_train)

## создаем 2D-массивные версии этих массивов, чтобы передать их в трансформеры
X_train = x_train[:, np.newaxis]
X_plot = x_plot[:, np.newaxis]

Интерполяция с полиномиальными признаками

Мы будем использовать PolynomialFeatures для генерации полиномиальных признаков и подгонки модели регрессии с регуляризацией к тренировочным данным. Затем построим график функции, тренировочных точек и интерполяцию с использованием полиномиальных признаков.

## plot function
lw = 2
fig, ax = plt.subplots()
ax.set_prop_cycle(
    color=["black", "teal", "yellowgreen", "gold", "darkorange", "tomato"]
)
ax.plot(x_plot, f(x_plot), linewidth=lw, label="ground truth")

## plot training points
ax.scatter(x_train, y_train, label="training points")

## polynomial features
for degree in [3, 4, 5]:
    model = make_pipeline(PolynomialFeatures(degree), Ridge(alpha=1e-3))
    model.fit(X_train, y_train)
    y_plot = model.predict(X_plot)
    ax.plot(x_plot, y_plot, label=f"degree {degree}")

ax.legend(loc="lower center")
ax.set_ylim(-20, 10)
plt.show()

Интерполяция B-сплайнами

Мы будем использовать SplineTransformer для генерации базисных функций B-сплайна и подгонки модели регрессии с регуляризацией к тренировочным данным. Затем построим график функции, тренировочных точек и интерполяцию с использованием B-сплайнов.

## B-сплайн с 4 + 3 - 1 = 6 базисными функциями
model = make_pipeline(SplineTransformer(n_knots=4, degree=3), Ridge(alpha=1e-3))
model.fit(X_train, y_train)

y_plot = model.predict(X_plot)
ax.plot(x_plot, y_plot, label="B-spline")
ax.legend(loc="lower center")
ax.set_ylim(-20, 10)
plt.show()

Построение графиков трансформеров

Мы отдельно строим все столбцы обоих трансформеров, чтобы получить более глубокое понимание сгенерированных баз признаков.

fig, axes = plt.subplots(ncols=2, figsize=(16, 5))
pft = PolynomialFeatures(degree=3).fit(X_train)
axes[0].plot(x_plot, pft.transform(X_plot))
axes[0].legend(axes[0].lines, [f"степень {n}" for n in range(4)])
axes[0].set_title("PolynomialFeatures")

splt = SplineTransformer(n_knots=4, degree=3).fit(X_train)
axes[1].plot(x_plot, splt.transform(X_plot))
axes[1].legend(axes[1].lines, [f"сплайн {n}" for n in range(6)])
axes[1].set_title("SplineTransformer")

## строим узлы сплайна
knots = splt.bsplines_[0].t
axes[1].vlines(knots[3:-3], ymin=0, ymax=0.8, linestyles="пунктирный")
plt.show()

Периодические сплайны

Мы демонстрируем использование периодических сплайнов с помощью SplineTransformer и ручного указания узлов. Мы подгоняем модель регрессии с регуляризацией к тренировочным данным и строим график функции, тренировочных точек и интерполяцию с использованием периодических сплайнов.

def g(x):
    """Функция, которая будет аппроксимироваться периодической интерполяцией сплайнов."""
    return np.sin(x) - 0.7 * np.cos(x * 3)


y_train = g(x_train)

## Продлеваем тестовые данные в будущее:
x_plot_ext = np.linspace(-1, 21, 200)
X_plot_ext = x_plot_ext[:, np.newaxis]

lw = 2
fig, ax = plt.subplots()
ax.set_prop_cycle(color=["black", "tomato", "teal"])
ax.plot(x_plot_ext, g(x_plot_ext), linewidth=lw, label="исходная функция")
ax.scatter(x_train, y_train, label="тренировочные точки")

for transformer, label in [
    (SplineTransformer(degree=3, n_knots=10), "сплайн"),
    (
        SplineTransformer(
            degree=3,
            knots=np.linspace(0, 2 * np.pi, 10)[:, None],
            extrapolation="periodic",
        ),
        "периодический сплайн",
    ),
]:
    model = make_pipeline(transformer, Ridge(alpha=1e-3))
    model.fit(X_train, y_train)
    y_plot_ext = model.predict(X_plot_ext)
    ax.plot(x_plot_ext, y_plot_ext, label=label)

ax.legend()
fig.show()

Резюме

В этом практическом занятии мы узнали, как приближать функцию полиномами до определенной степени с использованием регрессии с регуляризацией. Мы показали два различных способа сделать это для n_samples одномерных точек x_i. Мы использовали функцию make_pipeline для добавления нелинейных признаков и показали, насколько эти трансформеры хорошо подходят для моделирования нелинейных эффектов с использованием линейной модели. Мы построили график функции, тренировочных точек и интерполяцию с использованием полиномиальных признаков и B-сплайнов. Мы также построили все столбцы обоих трансформеров отдельно и показали узлы сплайна. Наконец, мы демонстрировали использование периодических сплайнов.