Установка неизвестной кривой

Есть некоторые связанные вопросы, которые я встретил (например this, , this и this), но все они касаются подбора данных к известной кривой. Есть ли способ подгонять данные к неизвестной кривой? Под этим я имею в виду, что с учетом некоторых данных алгоритм даст мне подгонку, которая является одной функцией или суммой функций. Я программирую на C, но я полностью потеряю, как использовать gsl для этого. Я открыт для использования всего, что может (в идеале) быть передано через C. Но любая помощь в каком направлении я должен смотреть, будет с благодарностью.

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

Ответ 1

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

В полиномиальной интерполяции - заданный набор точек (x, y) - вы пытаетесь найти лучший полином, который подходит для этих точек. Один из способов сделать это - использовать интерполяцию Ньютона, которую довольно легко запрограммировать.

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

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


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

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


Простая полиномиальная интерполяция пример:

Скажем, мы имеем (0,1),(1,2),(3,10) как наши данные.

В таблице 1 мы используем метод newton:

0  | 1 |                 |
1  | 2 | (2-1)/(1-0)=1   |
3  | 9 | (10-2)/(3-1)=4  | (4-1)/(3-0)=1

Теперь полином, который мы получаем, является "диагональю", которая заканчивается последним элементом:

1 + 1*(x-0) + 1*(x-0)(x-1) = 1 + x + x^2 - x = x^2 +1 

(и это идеально подходит для данных, которые мы использовали)


(1) Таблица рекурсивно создана: первые 2 столбца представляют собой значения x, y - и каждый следующий столбец основан на предыдущем. Это действительно легко реализовать, как только вы его получите, полное объяснение находится на странице wikipedia для интерполяции newton.

Ответ 2

Возможно, вы захотите использовать (Fast) Преобразования Фурье для преобразования данных в частотную область.

В результате преобразования (набора амплитуд и фаз и частот) даже самый скрученный набор данных может быть представлен несколькими функциями (гармоники) формы:

r * cos(f * t - p)

где r - гармоническая амплитуда, f - частота a p - фаза.

Наконец, неопределенная кривая данных представляет собой сумму всех гармоник.

Я сделал это в R (у вас есть некоторые примеры), но я считаю, что C имеет достаточно инструментов для управления им. Также возможно конвейер C и R, но он мало знает об этом. Это может помочь.

Этот метод действительно хорош для больших фрагментов данных, поскольку он имеет сложности:

1) разлагать данные с помощью быстрых преобразований Фурье (FTT) = O (n log n)

2) построил функцию с результирующими компонентами = O (n)

Ответ 3

Другой альтернативой является линейная регрессия, но многомерная.. p >

Трюк здесь - искусственно генерировать дополнительные размеры. Вы можете сделать это, просто подразумевая некоторые функции в исходном наборе данных. Обычное использование делает это для генерации полиномов для соответствия данным, поэтому здесь вы подразумеваете f(x) = x^i для всех i < k (где k - степень полинома, которую вы хотите получить).

Например, набор данных (0,2),(2,3) с k = 3 вы получите дополнительные 2 уменьшения, и ваш набор данных будет: (0,2,4,8),(2,3,9,27).

Алгоритм линейной регрессии найдет значения a_0,a_1,...,a_k для полинома p(x) = a_0 + a_1*x + ... + a_k * x^k, которые минимизируют ошибку для каждой точки данных по сравнению с предсказанной моделью (значение p (x)).

Теперь проблема заключается в том, что когда вы начинаете увеличивать размерность, вы переходите от недофинансирования (линейной линейной регрессии) к переобучению (когда k==n, вы эффективно получаете полиномиальную интерполяцию).

Чтобы "выбрать", что является лучшим значением k, вы можете использовать cross-validation, и выбрал k, который минимизировал ошибку в соответствии с вашей перекрестной проверкой.

Обратите внимание, что этот процесс может быть полностью автоматизирован, все, что вам нужно, это итеративно проверить все значения k в требуемом диапазоне 1 и выбрать модель с помощью k, который минимизировал ошибку в соответствии с перекрестной проверкой.


(1) Диапазон может быть [1,n] - хотя он, вероятно, будет слишком трудоемким, я бы пошел на [1,sqrt(n)] или даже [1,log(n)] - но это просто догадка.