Подгонка полиномов к данным

Есть ли способ, учитывая набор значений (x,f(x)), найти полином заданной степени, который лучше всего соответствует данным?

Я знаю полиномиальная интерполяция, который предназначен для поиска полинома степени n с учетом точек данных n+1, но здесь есть большое количество значений, и мы хотим найти полином низкой степени (найти наилучшее линейное соответствие, наилучшее квадратичное, наилучшее кубическое и т. д.). Это может быть связано с наименьших квадратов ...

В более общем плане, я хотел бы знать ответ, когда у нас есть многомерная функция - например, точки типа (x,y,f(x,y)) - и мы хотим найти лучший полином (p(x,y)) заданной степени в переменных. (В частности, полином, а не сплайны или ряд Фурье.)

И теория, и код / ​​библиотеки (желательно на Python, но подойдет любой язык) были бы полезны.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
50
0
52 459
9

Ответы 9

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

Лучше всего начать с Числовые рецепты.

р бесплатен и будет делать все, что вы хотите, и даже больше, но для этого потребуется большая кривая обучения.

Если у вас есть доступ к системе Mathematica, вы можете использовать функцию Fit, чтобы выполнить аппроксимацию по методу наименьших квадратов. Я полагаю, что Matlab и его аналог Octave с открытым исходным кодом имеют аналогичную функцию.

Это полезно, но знаете ли вы, какие из них подходят для многомерной подгонки?

ShreevatsaR 20.12.2008 01:11

Метод наименьших квадратов может быть многомерным. «Введение в прикладную математику» Гила Стрэнга содержит очень приятное и удобочитаемое обсуждение.

duffymo 28.12.2008 18:55

Да, спасибо ... когда я спросил этот комментарий о многомерной подгонке, я не знал достаточно о наименьших квадратах :-)

ShreevatsaR 01.01.2009 02:14

Для случая (x, f (x)):

import numpy

x = numpy.arange(10)
y = x**2

coeffs = numpy.polyfit(x, y, deg=2)
poly = numpy.poly1d(coeffs)
print poly
yp = numpy.polyval(poly, x)
print (yp-y)

Если вы хотите подогнать (xi, f (xi)) к полиному степени п, тогда вы должны настроить линейную задачу наименьших квадратов с данными (1, xi, xi, xi ^ 2, ..., xi ^ n, f (xi)). Это вернет набор коэффициентов (c0, c1, ..., сп), так что наилучшим подходящим полиномом будет * y = c0 + c1 * x + c2 * x ^ 2 + ... + cn * x ^ n. *

Вы можете обобщить эти две более чем одной зависимой переменной, включив в задачу степени y и комбинации Икс и y.

полином Лагранжа в некотором смысле является «простейшим» интерполирующим полиномом, который соответствует заданному набору точек данных.

Иногда это проблематично, потому что оно может сильно различаться между точками данных.

Кроме того, многочлен Лагранжа имеет степень n-1 с n точками - это то, что я написал в вопросе о полиномиальной интерполяции - он не дает наиболее подходящий многочлен для данной степени.

ShreevatsaR 20.12.2008 00:43

Полиномы Лагранжа (как опубликовано в @j w) дают вам точное соответствие в указанных вами точках, но с полиномами степени выше, чем, скажем, 5 или 6, вы можете столкнуться с числовой нестабильностью.

Метод наименьших квадратов дает вам полином «наилучшего соответствия» с ошибкой, определяемой как сумма квадратов отдельных ошибок. (возьмите расстояние по оси Y между точками, которые у вас есть, и полученной функцией, возведите их в квадрат и просуммируйте) Функция MATLAB polyfit делает это, и с несколькими возвращаемыми аргументами вы можете автоматически позаботиться о масштабировании / смещение (например, если у вас есть 100 точек между x = 312,1 и 312,3, и вам нужен полином 6-й степени, вам нужно будет вычислить u = (x-312.2) /0.1, чтобы значения u были распределены от -1 до + =).

ПРИМЕЧАНИЕ, что результаты аппроксимации методом наименьших квадратов являются сильно под влиянием распределения значений оси x. Если значения x расположены на одинаковом расстоянии, на концах будут большие ошибки. Если у вас есть случай, когда вы можете выберите значения x, и вы заботитесь о максимальном отклонении от вашей известной функции и интерполирующего полинома, то использование Полиномы Чебышева даст вам что-то, что близко к идеальному минимаксному полиному (что очень сложно вычислять). Это подробно обсуждается в «Числовых рецептах».

Редактировать: Насколько я понимаю, все это хорошо работает для функций одной переменной. Для многомерных функций это, вероятно, будет намного сложнее, если степень будет больше, скажем, 2. Я нашел ссылка на Google Книги.

Спасибо за ссылку, кстати. Соответствующий материал будет несколькими страницами позже; 4.10.4 на стр. 231. То же самое работает и с многомерными многочленами более высокой степени без особого труда, хотя существует проблема «переобучения».

ShreevatsaR 21.12.2008 19:17

Помните, что полином более высокой степени ВСЕГДА лучше соответствует данным. Полиномы более высокой степени обычно приводят к очень маловероятным функциям (см. Бритва Оккама), хотя (переоснащение). Вы хотите найти баланс между простотой (степенью полинома) и соответствием (например, ошибкой наименьших квадратов). Количественно для этого существуют тесты Информационный критерий Акаике или Байесовский информационный критерий. Эти тесты дают оценку, какой модели следует отдать предпочтение.

Верно, через некоторое время я понял, что, как вы сказали, существует некоторый компромисс между удобством и простотой. Спасибо за информацию о критериях.

ShreevatsaR 20.12.2008 19:39

Помните, есть большая разница между полиномом приблизительный и поиском полинома точный.

Например, если я дам вам 4 балла, вы можете

  1. Составьте приблизительную линию с помощью метода наименьших квадратов
  2. Приближаем параболу методом наименьших квадратов
  3. Найдите кубическую функцию точный через эти четыре точки.

Обязательно выберите метод, который подходит именно вам!

Да, я знаю :-) Вот почему я упомянул в вопросе «полиномиальную интерполяцию», которая предназначена для нахождения точной кубики по четырем точкам или точного полинома n-й степени по n + 1 точкам.

ShreevatsaR 21.12.2008 20:17

Довольно легко напугать быстрого подбора, используя матричные функции Excel, если вы знаете, как представить задачу наименьших квадратов как задачу линейной алгебры. (Это зависит от того, насколько надежен, по вашему мнению, Excel как решатель линейной алгебры.)

в колледже у нас была эта книга, которую я до сих пор считаю чрезвычайно полезной: Conte, de Boor; элементарный численный анализ; Макроу Хилл. Соответствующий абзац - 6.2: Data Fitting.
. Пример кода представлен на ФОРТРАНЕ, и листинги тоже не очень читабельны, но в то же время объяснения глубокие и ясные. в конечном итоге вы понимаете, что делаете, а не просто делаете это (как мой опыт работы с числовыми рецептами). Обычно я начинаю с числовых рецептов, но для подобных вещей мне быстро приходится брать Конте-де-Бура.

может быть, лучше опубликовать какой-нибудь код ... он немного урезан, но там есть самые важные части. очевидно, он полагается на numpy!

def Tn(n, x):
  if n==0:
    return 1.0
  elif n==1:
    return float(x)
  else:
    return (2.0 * x * Tn(n - 1, x)) - Tn(n - 2, x)

class ChebyshevFit:

  def __init__(self):
    self.Tn = Memoize(Tn)

  def fit(self, data, degree=None):
    """fit the data by a 'minimal squares' linear combination of chebyshev polinomials.

    cfr: Conte, de Boor; elementary numerical analysis; Mc Grow Hill (6.2: Data Fitting)
    """

    if degree is None:
      degree = 5

    data = sorted(data)
    self.range = start, end = (min(data)[0], max(data)[0])
    self.halfwidth = (end - start) / 2.0
    vec_x = [(x - start - self.halfwidth)/self.halfwidth for (x, y) in data]
    vec_f = [y for (x, y) in data]

    mat_phi = [numpy.array([self.Tn(i, x) for x in vec_x]) for i in range(degree+1)]
    mat_A = numpy.inner(mat_phi, mat_phi)
    vec_b = numpy.inner(vec_f, mat_phi)

    self.coefficients = numpy.linalg.solve(mat_A, vec_b)
    self.degree = degree

  def evaluate(self, x):
    """use Clenshaw algorithm

    http://en.wikipedia.org/wiki/Clenshaw_algorithm
    """

    x = (x-self.range[0]-self.halfwidth) / self.halfwidth

    b_2 = float(self.coefficients[self.degree])
    b_1 = 2 * x * b_2 + float(self.coefficients[self.degree - 1])

    for i in range(2, self.degree):
      b_1, b_2 = 2.0 * x * b_1 + self.coefficients[self.degree - i] - b_2, b_1
    else:
      b_0 = x*b_1 + self.coefficients[0] - b_2

    return b_0

Еще раз спасибо; это совершенно ясно. Почему полезно нормализовать диапазон до (-1,1), BTW?

ShreevatsaR 28.07.2009 16:52

потому что это диапазон, в котором многочлены Чебышева хорошо себя ведут. фактически внутри этого диапазона их можно охарактеризовать следующим образом: T_n (x) = cos (n * acos (x)). эта формула не имеет значения для x не в (-1, 1).

mariotomo 28.07.2009 18:39

Я протестировал свой модуль на numpy.polyfit (только этот единственный пример со страницы, на которую вы указываете), и был немного удивлен, увидев, что моя подгонка соответствует numpy.polyfit (даже для экстраполяции) до 15-й цифры. Я должен попробовать больше плохих условных случаев ... если они все еще совпадают, то, возможно, numpy использует полиномы Чебышева за кулисами и возвращает соответствующие мономиальные коэффициенты ...

mariotomo 28.07.2009 18:45

Другие вопросы по теме