10
votes

Trouver une courbe pour correspondre aux données

Je recherche une routine de raccord de courbe non linéaire (probablement la plus susceptible d'être trouvée dans R ou Python, mais je suis ouvert à d'autres langues) qui prendraient des données x, y et leur adapter une courbe.

Je devrais être capable de spécifier comme une chaîne le type d'expression que je veux vous adapter.

exemples: xxx

Qu'est-ce que je sortirais de cela est au moins les valeurs pour les constantes (A, B, C, etc.) et espérons que des statistiques sur la forme physique du match.

Il y a des programmes commerciaux pour le faire, mais je m'attendais à être capable de trouver quelque chose d'aussi courant que d'être adapté à une expression souhaitée dans une bibliothèque de langue de nos jours. Je soupçonne que les trucs d'optimisation de Scipy pourraient être capables de le faire, mais je ne vois pas que cela me permet de définir une équation. De même, je ne peux pas sembler trouver exactement ce que je veux dans R.

est ce que je cherche là-bas ou dois-je avoir la mienne? Je déteste le faire si c'est là et j'ai juste du mal à le trouver.


Edit: je veux le faire pour un peu plus de contrôle sur le processus que je ne reçois de laboratoire. Le laboratoire Fit Ui est terrible. J'aimerais également pouvoir casser la plage en plusieurs morceaux et avoir différentes courbes représentent les différentes pièces de la gamme. En fin de compte, le résultat doit être capable de battre (sagesse) battre une lut avec une interpolation linéaire ou je ne suis pas intéressé.

dans mon ensemble actuel de problèmes, j'ai des fonctions de trig ou d'exp. ) Et je dois les exécuter 352 800 fois par seconde en temps réel (et n'utilisez qu'une fraction de la CPU). Donc, je trace la courbe et utilisez les données pour conduire l'ampleur de la courbe pour obtenir des approximations moins chères. Dans les vieux jours, les luttes étaient presque toujours la solution, mais de nos jours sauter les recherches de la mémoire et une approximation est parfois plus rapide.


2 commentaires

Est-ce que vous réalisez que c'est une très mauvaise idée, statistiquement parlant? Si vous voulez juste un ajustement flexible à vos données, utilisez un modèle flexible comme des modèles d'additifs, de splines ou d'additifs généralisés.


Même la rupture de la fourchette dans des gammes plus petites est un coût que je dois faire attention. J'ai accès à toutes sortes d'excellents interpolateurs pour les données audio, mais ils sont généralement trop intenses de calcul pour moi. Généralement, une fois que je dois commencer à briser la portée, je suis mieux avec une lutte. Les approximations des courbes sont toujours assez utiles dans les applications DSP.


6 Réponses :


1
votes

Consultez gnu octave - entre son polyfit () et le Contraintes non linéaires SOLVER Il devrait être possible de construire quelque chose qui convient à votre problème.


1 commentaires

J'utilise effectivement octave parfois. Je vais voir ce que je peux comprendre.



8
votes

Votre premier modèle est en fait linéaire em> dans les trois paramètres et peut être adapté à R à l'aide de

 fit <- lm(y ~ x + I(x^2), data=X)


1 commentaires

Bien que vous soyez mieux avec y ~ poly (x, 2) ou y ~ ns (x, 2)



1
votes

Vous n'allez probablement pas trouver une seule routine avec la flexibilité impliquée dans vos exemples (polynômes et fonctions rationnelles à l'aide de la même routine), sans parler d'une chaîne pour déterminer le type d'équation.

Un petit-gitter polynomial des moindres carrés serait approprié pour votre premier exemple. (C'est à vous de voir quel degré polynomial à utiliser - quadradique, cubique, quartique, etc.). Pour une fonction rationnelle comme votre deuxième exemple, vous devrez peut-être "roulant le vôtre" si vous ne trouvez pas une bibliothèque appropriée. Gardez également à l'esprit qu'un polynôme de degré suffisamment degré peut être utilisé pour se rapprocher de votre fonction «réelle», tant que vous n'avez pas besoin d'extrapoler au-delà des limites du jeu de données que vous correspondez.

Comme d'autres l'ont noté, il existe d'autres algorithmes d'estimation de paramètres plus généralisés qui pourraient également s'avérer utiles. Mais ces algorithmes ne sont pas assez «plug and play»: ils vous obligent généralement à écrire quelques routines d'assistance et fournissez une liste de valeurs initiales pour les paramètres de modèle. Il est possible que ces types d'algorithmes divergent ou sont bloqués dans un minimum local ou maximum pour un choix malchanceux d'estimations de paramètres initiaux.


3 commentaires

Lorsque j'utilise les produits commerciaux, j'ai généralement aucune idée Qu'est-ce qui fonctionnera mieux. Labor Fit essaiera plusieurs centaines d'équations pour voir ce qui correspond aux données les mieux dans la plage que je spécifie.


Je n'avais pas examiné ce cas d'utilisation - si vous avez des premiers stades d'essayer de caractériser un ensemble de données, il est logique d'essayer plusieurs familles de fonctions (linéaire, polynôme, loi de puissance, périodique ...) à Voyez à quoi une bonne ajustement pourrait ressembler. Je vais éditer ma réponse en conséquence.


"Il est possible que ces sortes d'algorithmes deviennent divergentes ..." Ouais, je suppose que les programmes commerciaux juste cautionnés lorsque cela se produit pendant la vérification de tous les choix. Ils vous permettent de jouer avec des valeurs initiales lorsque vous choisissez une expression à la fois.



1
votes

in r, c'est assez facile.

La méthode intégrée est appelée Optim (). Il faut comme argument un vecteur de départ de paramètres potentiels, puis une fonction. Vous devez créer votre propre fonction d'erreur, mais c'est vraiment simple.

alors vous l'appelez comme out = Optim (1, ERR_FN)

où ERR_FN est < Pré> xxx

Cela suppose simplement que vous avez un vecteur de valeurs x et y dans eckses et données. Changez la ligne Model_Y comme vous le voyez, ajoutez encore plus de paramètres.

Il fonctionne simplement sur une fine non linéaire, je l'utilise pour quatre courbes de e ^ x dimensionnelles et il est très rapide. Les données de sortie comprennent la valeur d'erreur à la fin du raccord, qui est une mesure de la manière dont elle convient, étant donné comme une somme de différences carrées (dans mon err_fn).

EDIT: Si vous devez prendre le modèle sous forme de chaîne, vous pouvez avoir votre interface utilisateur construire tout ce processus de montage de modèle en tant que script R et le charger pour exécuter. R peut prendre du texte de STDIN ou à partir d'un fichier, il ne devrait donc pas être trop difficile d'élaborer l'équivalent de la chaîne de cette fonction et de l'avoir exécuté automatiquement.


2 commentaires

Je n'utilise pas de NLS pour deux raisons, premièrement, j'aime pouvoir remettre à la main la fonction d'erreur pour être optimisée, et deuxièmement, je ne suis pas réellement expérimenté avec R. SO NLS () ne fait que ce que j'ai écrit là-bas? Soigné.


Mon objectif ultime est de lui remettre une liste de chaînes et de faire les essayer de trouver le meilleur ajustement.



1
votes

Si vous avez des contraintes sur vos coefficients et que vous savez qu'il existe un type de fonction spécifique que vous souhaitez adapter à vos données et que la fonction est désordonnée, où les méthodes de régression standard ou d'autres méthodes de raccord de courbe ne seront pas. travailler, avez-vous considéré des algorithmes génétiques?

Ce ne sont pas mon premier choix, mais si vous essayez de trouver les coefficients de la deuxième fonction que vous avez mentionnés, le gaz fonctionnerait peut-être, surtout si vous utilisez des métriques non standard pour évaluer le meilleur ajustement. Par exemple, si vous vouliez trouver les coefficients de "(A + BX + CX ^ 2) / (dx + ex ^ 2)" de telle sorte que la somme des différences carrées entre votre fonction et vos données est minimale et qu'il y ait une certaine contrainte sur l'Arclength de la fonction résultante, un algorithme stochastique pourrait être un bon moyen d'aborder cela.

Certaines réserves: 1) Les algorithmes stochastiques ne garantissent pas la solution meilleure , mais elles seront souvent très proches. 2) Vous devez faire attention à la stabilité de l'algorithme.

sur une note plus longue, si vous êtes au stade où vous souhaitez trouver une fonction de certains espaces correspondant au mieux à vos données (par exemple, vous n'allez pas imposer, disons, le deuxième modèle de vos données) , alors les techniques de programmation génétique peuvent également aider.


3 commentaires

C'est une idée intéressante. Je vais y penser. De toute évidence, ce serait lent. Les programmes commerciaux traversent des centaines de formes d'équation en quelques secondes.


Oui, un autre inconvénient est que les algorithmes stochastiques peuvent être lents. À l'envers, il est possible d'obtenir un formulaire d'équation en dehors de l'ensemble des programmes commerciaux. En permettant un programme génétique de rechercher des classes de fonctions (avec des opérations sur ces fonctions) telles que, des fonctions d'alimentation, des exponentielles, des logarithmes, des fonctions de Trig, des PDF / CDFS, etc. Il est possible de trouver une solution non donné par un ensemble fixe de formulaires d'équation. Mais encore une fois sur l'inconvénient, cela nécessite un effort de codage avant raisonnable qui pourrait ne pas valoir sa peine.


Je suis toujours prêt pour une aventure quixotique.



8
votes

Pour répondre à votre question dans un sens général (concernant l'estimation des paramètres dans R) sans envisager les spécificités des équations que vous avez signalées, je pense que vous recherchez NLS () ou OPTI () ... 'NLS' est mon Premier choix car il fournit des estimations d'erreur pour chaque paramètre estimé et lorsqu'il échoue, j'utilise 'optim'. Si vous avez vos variables X, Y:

summary(out)$parameters


3 commentaires

Puis-je nourrir la formule en tant que chaînes?


Oui - quelque chose comme AS.Formula (Coller ("Y", "A + B X + C X ^ 2", Sep = "~")) devrait le faire.


C'était dans l'affaire NLS, en optimal quelque chose comme Eval (parse (Text = Sprintf ("SUM (((Y-% S) ^ 2)", "A + B x + C x ^ 2 "))) devrait fonctionner (la construction Sprintf est montrée afin que vous puissiez insérer la formule que vous désirez).