Установка неизвестной кривой
Есть некоторые связанные вопросы, которые я встретил (например 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)]
- но это просто догадка.