Erreur de gradient singulier en nls avec des valeurs de départ correctes

19

J'essaie d'adapter une ligne + une courbe exponentielle à certaines données. Pour commencer, j'ai essayé de le faire sur certaines données artificielles. La fonction est: Il s'agit en fait d'une courbe exponentielle avec une section linéaire, ainsi que d'un paramètre de décalage horizontal supplémentaire ( m ). Cependant, lorsque j'utilise la fonction de R, j'obtiens l' erreur redoutée de " matrice de gradient singulier aux estimations de paramètres initiales ", même si j'utilise les mêmes paramètres que ceux que j'ai utilisés pour générer les données en premier lieu. J'ai essayé les différents algorithmes, différentes valeurs de départ et essayé d'utiliser

y=une+br(X-m)+cX
nls()
optimpour minimiser la somme résiduelle des carrés, tout cela en vain. J'ai lu qu'une raison possible à cela pourrait être une paramétrisation excessive de la formule, mais je ne pense pas que ce soit (n'est-ce pas?)
Quelqu'un a-t-il une suggestion pour ce problème? Ou est-ce juste un modèle maladroit?

Un petit exemple:

#parameters used to generate the data
reala=-3
realb=5
realc=0.5
realr=0.7
realm=1
x=1:11 #x values - I have 11 timepoint data
#linear+exponential function
y=reala + realb*realr^(x-realm) + realc*x
#add a bit of noise to avoid zero-residual data
jitter_y = jitter(y,amount=0.2)
testdat=data.frame(x,jitter_y)

#try the regression with similar starting values to the the real parameters
linexp=nls(jitter_y~a+b*r^(x-m)+c*x, data=testdat, start=list(a=-3, b=5, c=0.5, r=0.7, m=1), trace=T)

Merci!

Steiny
la source
2
Astuce: regardez le coefficient de (pour un r fixe ) et notez que b r - m = constante a une famille de solutions unidimensionnelle ( b , m ) avec b = r mconstante . rXrbr-m=constant(b,m)b=rmconstant
whuber
1
Ce n'est pas un modèle identifié, à moins que ou r ne soient en quelque sorte contraints. Je pense que l'exigence du r ( 0 , 1 ) ferait l'affaire. brr(0,1)
Macro

Réponses:

16

Je me suis mordu récemment. Mes intentions étaient les mêmes, faire un modèle artificiel et le tester. La raison principale est celle donnée par @whuber et @marco. Un tel modèle n'est pas identifié. Pour voir cela, n'oubliez pas que NLS minimise la fonction:

je=1n(yje-une-brXje-m-cXje)2

Disons qu'il est minimisé par l'ensemble de paramètres (une,b,m,r,c) . Il n'est pas difficile de voir que l'ensemble des paramètres (une,br-m,0,r,c) donnera la même valeur de la fonction à minimiser. Le modèle n'est donc pas identifié, c'est-à-dire qu'il n'y a pas de solution unique.

Il n'est pas difficile non plus de comprendre pourquoi le gradient est singulier. Dénoter

F(une,b,r,m,c,X)=une+brX-m+cX

alors

Fb=rX-m

fm=blnrrxm

et nous obtenons cela pour tout X

blnrfb+fm=0.

D'où la matrice

(F(X1)F(Xn))

ne sera pas de rang complet et c'est pourquoi nlsdonnera le message de gradient singulier.

J'ai passé plus d'une semaine à chercher des bogues dans mon code ailleurs jusqu'à ce que je remarque que le bogue principal était dans le modèle :)

mpiktas
la source
2
C'est vieux, je sais, mais je me demande simplement si cela signifie que les nls ne peuvent pas être utilisés sur des modèles qui ne sont pas identifiables. Par exemple, un réseau neuronal?
Count Zero
grosse chance, je sais, mais pourriez-vous décomposer cela pour les gens qui se souviennent moins de calc? :). aussi, quelle est la solution au problème du PO, alors? Abandonnez et rentrez chez vous?
theforestecologist
2
brxmβrxmββ=brm
@CountZero, fondamentalement oui, les méthodes d'optimisation habituelles échoueraient si les paramètres n'étaient pas identifiés. Les réseaux de neurones contournent cependant ce problème, en ajoutant des contraintes supplémentaires et en utilisant d'autres astuces intéressantes.
mpiktas
Fm=-blnr rX-m
17

Les réponses ci-dessus sont bien sûr correctes. Pour ce que cela vaut, en plus des explications données, si vous essayez cela sur un ensemble de données artificielles, selon la page d'aide nls disponible à l' adresse : http://stat.ethz.ch/R-manual/R-patched/ bibliothèque / stats / html / nls.html

Les nls de R ne pourront pas le gérer. La page d'aide indique spécifiquement:

avertissement

N'utilisez pas nls sur des données artificielles "zéro résiduel".

La fonction nls utilise un critère de convergence à décalage relatif qui compare l'imprécision numérique aux estimations des paramètres actuels à la somme des carrés résiduels. Cela fonctionne bien sur les données du formulaire

y = f (x, θ) + eps

(avec var (eps)> 0). Il n'indique pas la convergence sur les données du formulaire

y = f (x, θ)

car le critère revient à comparer deux composantes de l'erreur d'arrondi. Si vous souhaitez tester nls sur des données artificielles, veuillez ajouter un composant de bruit, comme indiqué dans l'exemple ci-dessous.

Donc, pas de bruit == pas bon pour les nls de R.

B_D_Dubbya
la source
Bienvenue sur le site, @B_D_Dubbya. J'ai pris la liberté de formater votre réponse, j'espère que cela ne vous dérange pas. Vous pouvez trouver plus d'informations sur la modification de vos réponses sur CV ici .
gung - Rétablir Monica
1
Je suis au courant de ce problème - d'où l'utilisation de la fonction "gigue" pour ajouter du bruit
steiny