FindFit 与 Mathematica 中的 BinCounts 或直方图

发布于 2024-12-01 12:04:41 字数 983 浏览 2 评论 0原文

daList={62.8347, 88.5806, 74.8825, 61.1739, 66.1062, 42.4912, 62.7023, 
        39.0254, 48.3332, 48.5521, 51.5432, 69.4951, 60.0677, 48.4408, 
        59.273, 30.0093, 94.6293, 43.904, 59.6066, 58.7394, 68.6183, 83.0942, 
        73.1526, 47.7382, 75.6227, 58.7549, 59.2727, 26.7627, 89.493, 
        49.3775, 79.9154, 73.2187, 49.5929, 84.4546, 28.3952, 75.7541, 
        72.5095, 60.5712, 53.2651, 33.5062, 80.4114, 63.7094, 90.2438, 
        55.2248, 44.437, 28.1884, 4.77477, 36.8398, 70.3579, 28.1913, 
        43.9001, 23.8907, 12.7823, 22.3473, 57.6724, 49.0148}

以上是我正在处理的实际数据示例。 我使用 BinCounts,但这只是为了直观地说明直方图应该这样做:我想适应该直方图的形状

Histogram@data

enter image这里的描述

我知道如何拟合数据点本身,例如:

model = 0.2659615202676218` E^(-0.2222222222222222` (x - \[Mu])^2)
FindFit[data, model, \[Mu], x]

这与我想要做的相距甚远:如何在 Mathematica 中拟合 bin 计数/直方图?

daList={62.8347, 88.5806, 74.8825, 61.1739, 66.1062, 42.4912, 62.7023, 
        39.0254, 48.3332, 48.5521, 51.5432, 69.4951, 60.0677, 48.4408, 
        59.273, 30.0093, 94.6293, 43.904, 59.6066, 58.7394, 68.6183, 83.0942, 
        73.1526, 47.7382, 75.6227, 58.7549, 59.2727, 26.7627, 89.493, 
        49.3775, 79.9154, 73.2187, 49.5929, 84.4546, 28.3952, 75.7541, 
        72.5095, 60.5712, 53.2651, 33.5062, 80.4114, 63.7094, 90.2438, 
        55.2248, 44.437, 28.1884, 4.77477, 36.8398, 70.3579, 28.1913, 
        43.9001, 23.8907, 12.7823, 22.3473, 57.6724, 49.0148}

The above are a sample of actual data I am dealing with.
I use BinCounts, but this is just to illustrate visually histogram should do it : I would like to fit the shape of that histogram

Histogram@data

enter image description here

I know how to fit datapoints themselves like :

model = 0.2659615202676218` E^(-0.2222222222222222` (x - \[Mu])^2)
FindFit[data, model, \[Mu], x]

Which is far from what I wan to do : How can I fit bin-counts/histograms in Mathematica ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趁微风不噪 2024-12-08 12:04:41

如果您有 MMA V8,您可以使用新的 DistributionFitTest

disFitObj = DistributionFitTest[daList, NormalDistribution[a, b],"HypothesisTestData"];

Show[
   SmoothHistogram[daList], 
   Plot[PDF[disFitObj["FittedDistribution"], x], {x, 0, 120}, 
        PlotStyle -> Red
   ], 
   PlotRange -> All
]

在此处输入图像描述

disFitObj["FittedDistributionParameters"]

(* ==> {a -> 55.8115, b -> 20.3259} *)

disFitObj["FittedDistribution"]

(* ==> NormalDistribution[55.8115, 20.3259] *)

它可以适合其他分布也是如此。


另一个有用的 V8 函数是 HistogramList,它为您提供 Histogram 的分箱数据。它也需要直方图的所有选项。

{bins, counts} = HistogramList[daList]

(* ==> {{0, 20, 40, 60, 80, 100}, {2, 10, 20, 17, 7}} *)

centers = MovingAverage[bins, 2]

(* ==> {10, 30, 50, 70, 90} *)

model = s E^(-((x - \[Mu])^2/\[Sigma]^2));

pars = FindFit[{centers, counts}\[Transpose], 
                     model, {{\[Mu], 50}, {s, 20}, {\[Sigma], 10}}, x]

(* ==> {\[Mu] -> 56.7075, s -> 20.7153, \[Sigma] -> 31.3521} *)

Show[Histogram[daList],Plot[model /. pars // Evaluate, {x, 0, 120}]]

在此处输入图像描述

您也可以尝试使用 NonlinearModeFit 进行拟合。在这两种情况下,最好有自己的初始参数值,这样才有可能最终获得全局最佳拟合。


在 V7 中没有 HistogramList 但您可以使用 这个

Histogram[data,bspec,fh] 中的函数 fh 应用于两个
参数:bin 列表 {{Subscript[b, 1],Subscript[b,
2]},{下标[b, 2],下标[b, 3]},[省略号]},以及相应的
计数列表 {Subscript[c, 1],Subscript[c, 2],[Ellipsis]}。这
函数应返回要用于每个的高度列表
下标[c, i]。

可以按如下方式使用(来自我之前的回答):

Reap[Histogram[daList, Automatic, (Sow[{#1, #2}]; #2) &]][[2]]

(* ==> {{{{{0, 20}, {20, 40}, {40, 60}, {60, 80}, {80, 100}}, {2, 
    10, 20, 17, 7}}}} *)

当然,您仍然可以使用BinCounts,但您会错过 MMA 的自动分箱算法。您必须提供自己的分箱:

counts = BinCounts[daList, {0, Ceiling[Max[daList], 10], 10}]

(* ==>  {1, 1, 6, 4, 11, 9, 9, 8, 5, 2} *)

centers = Table[c + 5, {c, 0, Ceiling[Max[daList] - 10, 10], 10}]

(* ==>  {5, 15, 25, 35, 45, 55, 65, 75, 85, 95} *)

pars = FindFit[{centers, counts}\[Transpose],
                model, {{\[Mu], 50}, {s, 20}, {\[Sigma], 10}}, x]

(* ==> \[Mu] -> 56.6575, s -> 10.0184, \[Sigma] -> 32.8779} *)

Show[
   Histogram[daList, {0, Ceiling[Max[daList], 10], 10}], 
   Plot[model /. pars // Evaluate, {x, 0, 120}]
]

在此处输入图像描述

如您所见,拟合参数可能在很大程度上取决于关于您的分箱选择。特别是我称为 s 的参数主要取决于 bin 的数量。 bin 越多,单个 bin 计数越少,s 的值也越低。

If you have MMA V8 you could use the new DistributionFitTest

disFitObj = DistributionFitTest[daList, NormalDistribution[a, b],"HypothesisTestData"];

Show[
   SmoothHistogram[daList], 
   Plot[PDF[disFitObj["FittedDistribution"], x], {x, 0, 120}, 
        PlotStyle -> Red
   ], 
   PlotRange -> All
]

enter image description here

disFitObj["FittedDistributionParameters"]

(* ==> {a -> 55.8115, b -> 20.3259} *)

disFitObj["FittedDistribution"]

(* ==> NormalDistribution[55.8115, 20.3259] *)

It can fit other distributions too.


Another useful V8 function is HistogramList, which provides you with Histogram's binning data. It takes about all of Histogram's options too.

{bins, counts} = HistogramList[daList]

(* ==> {{0, 20, 40, 60, 80, 100}, {2, 10, 20, 17, 7}} *)

centers = MovingAverage[bins, 2]

(* ==> {10, 30, 50, 70, 90} *)

model = s E^(-((x - \[Mu])^2/\[Sigma]^2));

pars = FindFit[{centers, counts}\[Transpose], 
                     model, {{\[Mu], 50}, {s, 20}, {\[Sigma], 10}}, x]

(* ==> {\[Mu] -> 56.7075, s -> 20.7153, \[Sigma] -> 31.3521} *)

Show[Histogram[daList],Plot[model /. pars // Evaluate, {x, 0, 120}]]

enter image description here

You could also try NonlinearModeFit for fitting. In both cases it is good to come with your own initial parameter values to have the best chances that you end up with a globally optimal fit.


In V7 there is no HistogramList but you could get the same list using this:

The function fh in Histogram[data,bspec,fh] is applied to two
arguments: a list of bins {{Subscript[b, 1],Subscript[b,
2]},{Subscript[b, 2],Subscript[b, 3]},[Ellipsis]}, and corresponding
list of counts {Subscript[c, 1],Subscript[c, 2],[Ellipsis]}. The
function should return a list of heights to be used for each of the
Subscript[c, i].

This can be used as follows (from my earlier answer):

Reap[Histogram[daList, Automatic, (Sow[{#1, #2}]; #2) &]][[2]]

(* ==> {{{{{0, 20}, {20, 40}, {40, 60}, {60, 80}, {80, 100}}, {2, 
    10, 20, 17, 7}}}} *)

Of course, you can still use BinCounts but the you miss MMA's automatic binning algorithms. You have to provide a binning of your own:

counts = BinCounts[daList, {0, Ceiling[Max[daList], 10], 10}]

(* ==>  {1, 1, 6, 4, 11, 9, 9, 8, 5, 2} *)

centers = Table[c + 5, {c, 0, Ceiling[Max[daList] - 10, 10], 10}]

(* ==>  {5, 15, 25, 35, 45, 55, 65, 75, 85, 95} *)

pars = FindFit[{centers, counts}\[Transpose],
                model, {{\[Mu], 50}, {s, 20}, {\[Sigma], 10}}, x]

(* ==> \[Mu] -> 56.6575, s -> 10.0184, \[Sigma] -> 32.8779} *)

Show[
   Histogram[daList, {0, Ceiling[Max[daList], 10], 10}], 
   Plot[model /. pars // Evaluate, {x, 0, 120}]
]

enter image description here

As you can see the fit parameters may depend quite a bit on your binning choice. Particularly the parameter I called s depends critically on the amount of bins. The more bins, the lower the individual bin counts and the lower the value of s will be.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文