擬合高斯曲線的數據,原則是儘量擬合曲線和數據之間的平方差之和,所以我們定義f
我們的目標函數和運行optim
它:
fitG =
function(x,y,mu,sig,scale){
f = function(p){
d = p[3]*dnorm(x,mean=p[1],sd=p[2])
sum((d-y)^2)
}
optim(c(mu,sig,scale),f)
}
現在,擴展這一兩個高斯:
fit2G <- function(x,y,mu1,sig1,scale1,mu2,sig2,scale2,...){
f = function(p){
d = p[3]*dnorm(x,mean=p[1],sd=p[2]) + p[6]*dnorm(x,mean=p[4],sd=p[5])
sum((d-y)^2)
}
optim(c(mu1,sig1,scale1,mu2,sig2,scale2),f,...)
}
從第一個擬合擬合初始參數,第二個峯值的猜測。需要增加最大迭代:
> fit2P = fit2G(data$V3,data$V6,6,.6,.02,8.3,0.10,.002,control=list(maxit=10000))
Warning messages:
1: In dnorm(x, mean = p[1], sd = p[2]) : NaNs produced
2: In dnorm(x, mean = p[4], sd = p[5]) : NaNs produced
3: In dnorm(x, mean = p[4], sd = p[5]) : NaNs produced
> fit2P
$par
[1] 6.035610393 0.653149616 0.023744876 8.317215066 0.107767881 0.002055287
這個什麼都什麼樣子的?
> plot(data$V3,data$V6)
> p = fit2P$par
> lines(data$V3,p[3]*dnorm(data$V3,p[1],p[2]))
> lines(data$V3,p[6]*dnorm(data$V3,p[4],p[5]),col=2)
但是我會警惕你的函數參數的統計推斷...
產生的警告消息可能是由於SD參數變負。你可以解決這個問題,並通過使用L-BFGS-B和設置下限更快地得到收斂:
> fit2P = fit2G(data$V3,data$V6,6,.6,.02,8.3,0.10,.002,control=list(maxit=10000),method="L-BFGS-B",lower=c(0,0,0,0,0,0))
> fit2P
$par
[1] 6.03564202 0.65302676 0.02374196 8.31424025 0.11117534 0.00208724
正如指出的那樣,對初始值的敏感性總是帶着這樣的曲線擬合的東西有問題。
我認爲相關的問題是將分佈擬合爲一維數據的密度。你得到的是data {x,f(x)},你想要擬合f(x)的參數,而不是估計分佈的參數。 – Spacedman 2013-04-08 15:04:35
你想刪除異常值或只適合高斯? – Nishanth 2013-04-08 15:10:26
我也很擔心你的數據點看起來不像他們有獨立的錯誤 - 似乎是四個或五個單獨的系列。你應該在你的方法中考慮這一點... – Spacedman 2013-04-08 15:13:50