Интерполяция: восстанавливаем значения между точками

У нас есть значения функции в нескольких точках — а нужно значение между ними. Это задача интерполяции.

Интерполяция — построение функции, которая проходит ровно через заданные точки и позволяет оценить значение между ними.

Зачем это нужно

Измерения почти всегда дискретны: температура раз в час, курс раз в день, датчик раз в миллисекунду. А вопросы возникают про промежуток: «какая была температура в 14:30, если меряли в 14:00 и 15:00?». Интерполяция отвечает на это, проводя гладкую кривую через известные точки. Важно не путать с экстраполяцией (выход за пределы данных — гораздо рискованнее) и с аппроксимацией (приближение, которое НЕ обязано проходить через точки).

Линейная интерполяция: простейший случай

Между двумя соседними точками (x0, y0) и (x1, y1) проводим прямую. Значение в точке x внутри отрезка:

y = y0 + (y1 - y0) * (x - x0) / (x1 - x0)

Геометрически — «доля пути» от x0 к x1 определяет, насколько y ушёл от y0 к y1.

Реализация на чистом Python

Найдём нужный отрезок и применим формулу — всё на stdlib, реально работает:

xs = [0.0, 1.0, 2.0, 3.0]
ys = [0.0, 1.0, 4.0, 9.0]   # это y = x^2 в узлах

def interp(x):
    # ищем отрезок [xs[i], xs[i+1]], содержащий x
    for i in range(len(xs) - 1):
        if xs[i] <= x <= xs[i + 1]:
            x0, x1 = xs[i], xs[i + 1]
            y0, y1 = ys[i], ys[i + 1]
            return y0 + (y1 - y0) * (x - x0) / (x1 - x0)
    raise ValueError("x вне диапазона")

print("Точно  x^2 при 1.5 =", 1.5 ** 2)
print("Линейная оценка    =", interp(1.5))

Вывод:

Точно  x^2 при 1.5 = 2.25
Линейная оценка    = 2.5

Заметьте: линейная интерполяция дала 2.5 вместо точного 2.25 — прямая «срезает» кривизну параболы. Чем гуще узлы, тем меньше ошибка.

Сплайны: гладко, как лекало

Линейная интерполяция даёт «ломаную» с изломами в узлах. Чтобы было гладко, используют кубические сплайны: между каждой парой точек проводят кубический многочлен, причём так, чтобы в узлах совпадали не только значения, но и первая и вторая производные. Результат — кривая без изломов, как если бы вы гнули гибкое лекало (само слово spline — гибкая чертёжная рейка).

МетодГладкостьЦена
Линейнаяизломы в узлахдёшево, просто
Кубический сплайнгладкая, без изломовчуть дороже, нужно решить систему

А в SciPy — одна строка

SciPy умеет и линейную, и сплайны (код для чтения, не запускается):

import numpy as np
from scipy.interpolate import interp1d, CubicSpline

xs = np.array([0, 1, 2, 3])
ys = xs ** 2

f_lin = interp1d(xs, ys, kind="linear")
f_cub = CubicSpline(xs, ys)

print(f_lin(1.5))   # 2.5  — как у нас руками
print(f_cub(1.5))   # 2.25 — сплайн точно ложится на параболу

Как работает под капотом

Кубический сплайн требует решить систему уравнений: на N узлах — N−1 кубических кусков, у каждого 4 коэффициента, итого много неизвестных. Условия (значения в узлах + непрерывность первой и второй производных + краевые условия) дают ровно столько же уравнений. Получается трёхдиагональная система — её решают за O(N), очень быстро. Вот почему сплайн «чуть дороже» линейной интерполяции, но всё равно практически мгновенный даже на тысячах точек.

Частые ошибки

  • Путать интерполяцию с экстраполяцией. За пределами данных кубический сплайн может «выстрелить» в абсурдные значения.
  • Интерполировать шумные данные. Если в y есть шум, интерполяция честно протащит кривую через каждую помеху — лучше аппроксимация (сглаживание).
  • Неотсортированные узлы. И наш код, и SciPy ждут возрастающие xs.

Итог

  • Интерполяция строит функцию, проходящую через заданные точки.
  • Линейная проста, но даёт изломы; кубический сплайн — гладкий, ценой решения системы.
  • «Руками» легко делается линейная; сплайны и прочее — scipy.interpolate.
  • Не путайте с экстраполяцией (рискованно) и аппроксимацией (не проходит через точки).
Проверьте себя
1. Чем интерполяция отличается от аппроксимации?
AНичем
BИнтерполяция проходит РОВНО через заданные точки, аппроксимация лишь приближает их (может не проходить)
CАппроксимация точнее всегда
DИнтерполяция работает только для прямых
2. Почему кубический сплайн глаже линейной интерполяции?
AОн использует прямые отрезки
BВ узлах он согласует значения, первую и вторую производные — поэтому нет изломов
CОн игнорирует часть точек
DОн экстраполирует данные
3. Что опасно делать с кубическим сплайном?
AИнтерполировать гладкие данные
BЭкстраполировать за пределы узлов — кривая может уйти в абсурдные значения
CИспользовать возрастающие xs
DПрименять к параболе