高斯拟合 vc++代码_双重高斯分布拟合

高斯分布在自然界非常常见,中心极限定理很好的说明了它,但事情往往不是那么地纯粹,很多时候我们得到的结果里面会混入两个截然不同的样本数据集,虽然它们各自都是高斯分布,但是它们的均值和方差都不一样,如果拿到的是它们的混合数据,就不能简单的使用一个高斯拟合来处理它了。

如果我们有比较强的背景知识,或者看了如下分布的条形图,会下意识的猜想出是两个高斯分布的混合,但是想从数据的角度来探索,两个独立的高斯分布各自独立的均值和方差该如何推测出来呢?

41dcc9e0e6958f68eb48907e318967ee.png

这个难题早在四年前我处理免疫组库数据就遇到了,那个时候功力很浅,全网搜索各自资料也没有解决,后来换工作了,这个项目也就不了了之,最近看文献比较多,其中一个文章的描述了一个R包可以做:

The bimodal distribution was approximated by the ‘normalmixEM’ function in the ‘mixtools’ package of R.

生成测试数据

生成两个高斯分布,它们有各自独立的均值和方差

a=rnorm(1000)
b=rnorm(1000,mean = 1,sd=1.4)
par(mfrow=c(1,2))
hist(a);hist(b)

可视化如下:

97b6ed0099fca7d175c416d508bf2913.png

使用mixtools包的normalmixEM函数

首先加载安装好的包:

> library(mixtools)
mixtools package, version 1.1.0, Released 2017-03-10
This package is based upon work supported by the National Science Foundation under Grant No. SES-0518772.

先看帮助文档的代码,

data(faithful)
attach(faithful)
set.seed(100)
system.time(out<-normalmixEM(waiting, arbvar = FALSE, epsilon = 1e-03))
out
hist(waiting)
plot(out,2)

可以看到,很简单一个函数,就可以把faithful这个数据框里面的waiting列的数据进行双重高斯分布拟合

b25a9df8e18d0f66895f9fe445fbab83.png

在我们的数据上面是使用

前面我们根据R包说明书进行了示例数据分析,那么理所当然就学会了它,然后就应该是应用于自己的数据,我们测试数据是两个高斯分布的向量,如果要使用mixtools包的normalmixEM函数处理它,就应该是需要把两个向量合并.

d=c(a,b)
out<-normalmixEM(d, arbvar = FALSE, epsilon = 1e-03)
hist(d);plot(out,2)

可以看到,其实这个函数并不是把我们生成的两个高斯分布完成拆解开来,前面我们模拟的是平均值分别是0和1的两个分布,但是函数拟合后是0和2的两个高斯分布,如下:

317c8ce14f567bbef4c58143c91c7aa8.png

这个时候,有两种解决方案,首先你可以继续花时间去攻克这个R包的详细文档,看看有没有什么参数可以调整,其次你可以去看看其它R包或者算法。

因为这个不是我的课题了,仅仅是想分享给生信技能树的粉丝,符合你们的需求,所以接下来靠你们自己花费时间去摸索哈,比如 http://exploringdatablog.blogspot.com/2011/08/fitting-mixture-distributions-with-r.html

bea1076aad0ac795fbd0ea22d075c863.png

后记

其实这个R包早在2009就发表了,不知道为什么我四年前没有搜索到它,那个时候还没有生信技能树公众号呢

Benaglia, T., Chauveau, D., Hunter, D. R., and Young, D. mixtools: An R package for analyzing finite mixture models. Journal of Statistical Software, 32(6):1-29, 2009.

最后,跟大家互动一下,说到双重高斯分布,大家首先想到的是什么呢?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用`scipy`库中的`curve_fit`函数来对一维直方图进行高斯拟合。下面是一个简单的示例代码: ```python import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # 生成随机数据 data = np.random.randn(1000) # 绘制直方图 hist, bin_edges = np.histogram(data, bins=50, density=True) bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2 plt.bar(bin_centers, hist, width=0.05) # 高斯分布函数 def gaussian(x, a, b, c): return a * np.exp(-(x - b) ** 2 / (2 * c ** 2)) # 初始参数猜测值 p0 = [1, 0, 1] # 使用curve_fit进行高斯拟合 popt, pcov = curve_fit(gaussian, bin_centers, hist, p0=p0) # 绘制拟合曲线 x = np.linspace(bin_centers[0], bin_centers[-1], 100) plt.plot(x, gaussian(x, *popt), 'r', linewidth=2) # 显示图像 plt.show() ``` 在上述代码中,首先生成了一组随机数据,并使用`np.histogram()`函数计算了直方图和对应的bin_centers。然后,定义了高斯分布函数`gaussian()`和初始参数猜测值`p0`。接下来,使用`curve_fit()`函数进行高斯拟合,并得到了拟合参数`popt`和协方差矩阵`pcov`。最后,使用`plt.plot()`函数绘制了拟合曲线,并显示了图像。 需要注意的是,`curve_fit()`函数需要提供拟合函数、自变量和因变量,其中拟合函数需要是一个函数句柄,用于计算拟合值。在本例中,拟合函数为`gaussian()`,自变量为`bin_centers`,因变量为`hist`。`p0`是初始参数猜测值,可以根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值