2013-04-08 137 views
3

我需要做一些穩健的數據擬合操作。R:將數據點穩健地擬合成高斯函數

我有一堆(x,y)數據,我想適合Gaussian(又名普通)函數。 重點是,我想要刪除的老闆。正如人們在下面的示例圖中可以看到的那樣,還有另一個數據分佈會污染我的右邊的數據,我不想將它考慮在內來進行擬合(即找到\ sigma,\ mu和整體比例參數)。 sample data plot

[R似乎是這個職位的合適的工具,我發現了一些包(robustrobustbaseMASS例如),它們與強大的配件。

但是,他們認爲用戶已經對R有很強的瞭解,這不是我的情況,文檔僅作爲參考手冊提供,不提供任何教程或同等內容。我的統計背景相當低,我試圖讀reference material on fitting with R,但它並沒有真正幫助(我甚至不確定這是否是正確的方法)。 但我覺得這實際上是一個非常簡單的操作。

我檢查了這個related question(和鏈接的),然而他們把一個單一的向量值作爲輸入,我有一個向量對,所以我不知道如何轉置。

任何幫助如何做到這一點,將不勝感激。

+0

我認爲相關的問題是將分佈擬合爲一維數據的密度。你得到的是data {x,f(x)},你想要擬合f(x)的參數,而不是估計分佈的參數。 – Spacedman 2013-04-08 15:04:35

+0

你想刪除異常值或只適合高斯? – Nishanth 2013-04-08 15:10:26

+0

我也很擔心你的數據點看起來不像他們有獨立的錯誤 - 似乎是四個或五個單獨的系列。你應該在你的方法中考慮這一點... – Spacedman 2013-04-08 15:13:50

回答

6

擬合高斯曲線的數據,原則是儘量擬合曲線和數據之間的平方差之和,所以我們定義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) 

enter image description here

但是我會警惕你的函數參數的統計推斷...

產生的警告消息可能是由於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 

正如指出的那樣,對初始值的敏感性總是帶着這樣的曲線擬合的東西有問題。

+0

太棒了!這給我正在尋找什麼(甚至更多,因爲它也給出了「噪音」參數)。我不完全理解所有「R」步驟,但我會詳細研究,非常感謝您提供了這樣一個清晰準確的答案!我懷疑我會在幾周之前完成這項工作,也非常感謝。 – kebs 2013-04-08 22:25:41

+0

另外一點(對於未來的讀者),這種方法對給出的初始值非常明智,因此必須搜索初步的近似值。 – kebs 2013-04-09 09:27:49

4

擬合高斯:

# your data 
set.seed(0) 
data <- c(rnorm(100,0,1), 10, 11) 

# find & remove outliers 
outliers <- boxplot(data)$out 
data <- setdiff(data, outliers) 

# fitting a Gaussian 
mu <- mean(data) 
sigma <- sd(data) 

# testing the fit, check the p-value 
reference.data <- rnorm(length(data), mu, sigma) 
ks.test(reference.data, data) 
+0

感謝您的回答,我會研究。 – kebs 2013-04-08 22:32:12