I'm trying to reproduce the following example from David Ruppert's "Statistics and Data Analysis for Financial Engineering", which fits Students t-distribution to historical risk free rate:
library(MASS)
data(Capm, package = "Ecdat")
x <- Capm$rf
fitt <- fitdistr(x,"t", start = list(m=mean(x),s=sd(x)), df=3)
as.numeric(fitt$estimate)
0.437310595161651 0.152205764779349
The output is accompanied by the following Warnings message:
Warning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs producedWarning message:
In log(s): NaNs produced
It appears from the R's help file that MASS::fitdistr
uses maximum-likelihood for finding optimal parameters. However, when I do optimization manually (same book), all goes smoothly and there is no warnings:
library(fGarch)
loglik_t <- function(beta) {sum( - dt((x - beta[1]) / beta[2],
beta[3], log = TRUE) + log(beta[2]) )}
start <- c(mean(x), sd(x), 5)
lower <- c(-1, 0.001, 1)
fit_t <- optim(start, loglik_t, hessian = T, method = "L-BFGS-B", lower = lower)
fit_t$par
0.44232633269102 0.163306955396773 4.12343777572566
The fitted parameters are within acceptable standard errors, and, in addition to mean and sd I have gotten df
.
Can somebody advise me please:
MASS::fitdistr
produces warnings whereas optimization via fGarch::optim
succeeds without a warning?df
in MASS::fitdistr
output?MASS:fitdistr
on this data without a warning and get df
?Disclaimer:
a similar question was asked couple of times without an answer here and here
You are not passing the lower
argument to the function fitdistr
which leads it to make a search in positive and negative domain. By passing the lower
argument to function
fitt <- fitdistr(x,"t", start = list(m=mean(x),s=sd(x)), df=3, lower=c(-1, 0.001))
you get no NaNs -as you did in your manual optimisation.
EDIT:
fitt <- fitdistr(x,"t", start = list(m=mean(x),s=sd(x),df=3),lower=c(-1, 0.001,1))
returns non-integer degrees of freedom result. However, I guess, the rounded value of it, which is round(fitt$estimate['df'],0)
can be used for fitted degrees of freedom parameter.