2017-08-02 3 views
0

J'ai deux grands ensembles de données dans R, l'un des mesures réelles et l'une des prédictions que j'ai faites pour ces mesures. J'ai trouvé que les tendances de mes prédictions étaient exactes, mais l'amplitude était éteinte. Je me demande s'il existe un moyen de trouver une constante dans R qui, lorsque les prédictions sont multipliées par la constante, minimise l'erreur entre les réels et les prédictions.Comment puis-je minimiser l'erreur entre les estimations et les données réelles en multipliant par une constante (en R)?

Par exemple:

predictions <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 
actuals <- c(2, 4, 6, 8, 10, 12, 14, 16, 18, 20) 

La constante Je veux générer dans ce cas serait 2.

J'ai regardé en utilisant la fonction optim(), mais le message d'avertissement " l'optimisation unidimensionnelle par Nelder-Mead n'est pas fiable: utilisez 'Brent' ou optimize() directement. " Je ne suis pas familier avec l'optimisation, il est donc probable que j'aborde ce problème de la mauvaise façon. J'apprécie l'aide!

Répondre

1

Tout d'abord nous allons définir une fonction d'erreur pour minimiser:

MultError <- function(constant, predictions, actuals) { 

    return(sum((constant*predictions - actuals)^2)) 

} 

C'est la somme des carrés des erreurs ... vous pouvez utiliser un autre!

optimize() attend une fonction, un intervalle de recherche (que vous pourriez obtenir en inspectant les min et max de predictions/actuals), et tous les paramètres supplémentaires. Il minimisera par défaut

optimize(MultError, interval=c(0, 5), predictions=predictions, actuals=actuals) 

Ce retour

$minimum 
[1] 2 

$objective 
[1] 0 

Quelle est la valeur du minimum et la valeur de la fonction d'erreur, respectivement.

On peut supposer que votre match n'est pas parfait, donc j'ai aussi essayé avec le bruit artificiel

set.seed(1) 
actuals <- rnorm(length(predictions), 2, 0.4) * predictions 

Ensuite, il retourne

$minimum 
[1] 2.087324 

$objective 
[1] 22.21434 

Très bon!

EDIT:

je répondu à cette question à l'aide d'optimiser à cause du titre et la direction de l'OP était allé, mais en pensant plus dur, il semblait que cela pourrait surpuissance. Quel est le problème avec simplement prendre mean(actuals/predictions)?

donc j'ai décidé de les tester à la fois ...

set.seed(1) 
arithmetic <- opt <- numeric(10000) 

for (trial in 1:10000) { 

    actuals <- rnorm(length(predictions), 2, 0.4) * predictions 
    arithmetic[trial] <- mean(actuals/predictions) 
    opt[trial] <- optimize(MultError, interval=c(0, 5), predictions=predictions, actuals=actuals)$minimum 

} 

Pour 10.000 ensembles de données possibles, nous avons récupéré la constante en utilisant la somme moyenne et en réduisant au minimum des erreurs au carré. Quelle est la moyenne et la variance de nos estimateurs?

> mean(arithmetic) 
[1] 1.999102 
> mean(opt) 
[1] 1.998695 

Les deux font assez bien en moyenne.

> var(arithmetic) 
[1] 0.0159136 
> var(opt) 
[1] 0.02724814 

L'estimateur arithmétique moyen a cependant un écart plus étroit. Donc, je dirais que vous devriez simplement prendre la moyenne!

0

Vous pouvez obtenir une assez bonne approximation en utilisant la régression linéaire, la fonction lm().

m = lm(actuals ~ predictions)

m est l'objet où le modèle de régression linéaire sera enregistrée.

coef(m) vous donnera la constante à multiplier avec plus un décalage.

+1

Si vous ajoutez '+ 0' à la formule, il ne correspondra pas à une interception, donc il n'y aura qu'un seul coefficient multipliant les 'prédictions' (c'est-à-dire ce que l'OP a demandé). – Gregor

+0

Bon point, OP a mis cela comme une condition préalable. (J'utilise -1 pour me débarrasser de l'interception, je ne savais pas que +0 a réalisé la même chose). Notez que vous pouvez jouer avec la formule, par exemple, reals ~ predictions + predictions^2). Essentiellement, vous essayez de deviner la relation mathématique. – rdodhia