声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 4861|回复: 14

[综合讨论] 如何由小样本(100-200之间)求概率分布

[复制链接]
发表于 2007-10-26 11:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
如何由小样本(100-200之间)求概率函数、概率分布函数。不能使用频次代替概率。


请给出理论与实现方法。

[ 本帖最后由 assist 于 2007-10-26 11:20 编辑 ]
回复
分享到:

使用道具 举报

发表于 2007-10-26 11:10 | 显示全部楼层
使用概率统计工具箱的函数可以实现
 楼主| 发表于 2007-10-27 09:08 | 显示全部楼层
谁有做过这样问题的 经验。帮忙解释一下!
发表于 2007-10-27 09:13 | 显示全部楼层

回复 #3 assist 的帖子

我昨天发了一个统计工具箱的介绍,里边讲得还算详细。
仔细读会找到答案的

--------------------------------------------------
ksdensity函数可以估计概率密度函数
概率分布,应该再进行积分就可以了
---------------------------------------------------

[ 本帖最后由 花如月 于 2007-10-27 09:31 编辑 ]
 楼主| 发表于 2007-10-27 14:23 | 显示全部楼层
花如月,谢谢你,我还想问ksdensity使用的是什么算法。我想使用C++实现它。
发表于 2007-10-27 14:37 | 显示全部楼层

回复 #5 assist 的帖子

这个我也不太清楚,如果需要了解其原理。edit ksdensity看看它的源码,或许对你有帮助
 楼主| 发表于 2007-10-27 14:50 | 显示全部楼层
谢谢,源码倒是不长,如果能知道使用的是什么原理就好办很多。
 楼主| 发表于 2007-10-29 09:19 | 显示全部楼层

matlab的ksdensity的C++实现

花如月,谢谢哦,我已经使用C++实现了ksdensity的正态分布密度功能。


此为matlab的ksdensity的C++实现,只考虑了正态分布
// density.h: interface for the Cdensity class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DENSITY_H__DF52D4E3_8E9D_45AE_8BD8_97062CCEB182__INCLUDED_)
#define AFX_DENSITY_H__DF52D4E3_8E9D_45AE_8BD8_97062CCEB182__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MATRIX.h"
class Cdensity  
{
public:
CMatrix normal(CMatrix z);
CMatrix linspace(double ,double ,int m=100);
void ksdensity(CMatrix y,int m,CMatrix &x,CMatrix &f);
Cdensity();
virtual ~Cdensity();
};
#endif // !defined(AFX_DENSITY_H__DF52D4E3_8E9D_45AE_8BD8_97062CCEB182__INCLUDED_)





// density.cpp: implementation of the Cdensity class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "density.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//#define SefeDeleteArray(ps)  if(ps!=NULL) { delete []ps;ps=NULL;}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Cdensity::Cdensity()
{
}
Cdensity::~Cdensity()
{
}
//y 必须是列向量,x是返回区间,f是返回密度函数
void Cdensity::ksdensity(/*in*/CMatrix y,/*in*/int m,/*out*/CMatrix &x,/*out*/CMatrix &f)
{
//y 必须是列向量
double n;
int size;
if(1==y.GetColumnNum()&&1!=y.GetRowNum())
{
  size=y.GetRowNum();
  n=y.GetRowNum();
  double ymin,ymax;
  ymin=y.Min();
  ymax=y.Max();
  //中值,先排序再取中值
  double sig;
  double u;
  sig=y.median2()/0.6745;
  if(sig<=0)
  {
   sig=ymax-ymin;
  }
  if(sig>0)
  {
   u=sig * pow((4/(3*n)),0.2);
  }
  else
  {
   u=1;
  }
//  double m=100; //也可以使用传递数值,随时变更
  //产生100个线性数
  if(m<=2)
  {
   m=100;
  }
  x=linspace(ymin-2*u,ymax+2*u,m);
  CMatrix z,z1,z2;
  //第一项按行,第二项按列
  z1=z1.repmat(size,x,true);
  z2=z2.repmat(m,y);
  z=(z1-z2)/u;
  z1=normal(z);
  f=z1.Sum(1);
  f=f/(n*u);
}
}
CMatrix Cdensity::linspace(double min,double max,int m)//返回行向量
{
CMatrix result;
result.Init(1,m);
double step;
int i;
step=(max-min)/(m-1);
for (i=0;i<m-1;++i)
{
  result.SetElement(0,i,min+i*step);
}
result.SetElement(0,m-1,max);
return result;
}
CMatrix Cdensity::normal(CMatrix z)
{
int row,col;
row=z.GetRowNum();
col=z.GetColumnNum();
int i,j;
double ftemp;
CMatrix f;
f.Init(row,col);
for(i=0;i<row;++i)
{
  for (j=0;j<col;++j)
  {
   ftemp = exp(-0.5 * z.GetElement(i,j)*z.GetElement(i,j))/ sqrt(2*3.1415926);
   f.SetElement(i,j,ftemp);
  }
}
return f;
}


CMatrix CMatrix::repmat(int m,CMatrix A,bool flag)
{
CMatrix result;
int row,col,i,j;
row=A.GetRowNum();
col=A.GetColumnNum();
result.Init();
if (flag)//表示为行向量
{
  if(1!=row)
  {
   return result;
  }
  result.Init(m,col);
  for (i=0;i<m;++i)
  {
   for(j=0;j<col;j++)
   {
    result.SetElement(i,j,A.GetElement(0,j));
   }
  }
}
else//表示为列向量
{
  if(1!=col)
  {
   return result;
  }
  result.Init(row,m);
  for (i=0;i<m;++i)
  {
   for(j=0;j<row;j++)
   {
    result.SetElement(j,i,A.GetElement(j,0));
   }
  }
}
return result;
}

本人在求小样本数据的概率密度曲线,困扰了好几天,前天在花如月建议下使用ksdensity函数,在仔细分析了ksdensity的代码后,改用C++实现。以上为核心代码。

[ 本帖最后由 ChaChing 于 2010-1-24 11:18 编辑 ]

评分

1

查看全部评分

发表于 2007-10-29 09:42 | 显示全部楼层
 楼主| 发表于 2007-10-30 10:00 | 显示全部楼层

ksdensity函数,其支持理论是什么?

ksdensity函数其支持理论是什么?

[ 本帖最后由 eight 于 2007-10-30 10:36 编辑 ]
发表于 2007-10-30 13:04 | 显示全部楼层

回复 #11 assist 的帖子

这个我也不清楚,是统计工具箱里的函数。不过你既然都能用c++来实现,难道搞不清他的原理?至少在概率论里应该可以找到些痕迹
 楼主| 发表于 2008-1-7 11:07 | 显示全部楼层
直方图是最简单的非参数密度估计方式,因而其使用也最为广泛。为了创建直方图,将数据值所覆盖的区间等分为若干子区间。每次,一个数据值落入某个唯一的子区间,并将其在平行于横坐标的方向上延拓成单位宽度的线段。当创建一个直方图时,必须考虑两个关键点:子区间的始点、终点。如果选取在0到0.5这个区间内,也就是区间宽度0.5时,得到的直方图见图5.1。
为了方便分析,使用示例数据:2,22,42,62,82,102,122,142,162,182,202和222。数据点用十字标在X轴上。根据直方图,可以看出数据密度具有单峰特性且向右边偏斜。
断点的选取对直方图具有尤其特殊的影响。例如如果使用同样的区间宽度,但起始点和终点调整到0.25和0.75,作出的直方图见图5.2。
这时,发现图5.1的密度估计和图5.2的密度估计结果完全不同,现在看起具有双峰特性。用以上这两个例子来说明直方图的属性:不光滑,图形取决于子区间的端点,即区间宽度。
可以使用核密度估计的方法减少由于前两个问题所带来的误差。为了消除区间的端点带来的影响,以各个数据点的中心向两边延拓取代固定延拓终点的延拓方式。
在上述的直方图中,根据已有12个数据点,设置延拓方式为:宽度为1和高度为1/12(虚线框),然后把他们加起来。这个密度估计(连续曲线)的精确度相比其它直方图要高,可以提取一些更加微细结构变化,见图5.3。
图5.1.JPG
图5.1  直方图密度估计1
图5.2.JPG
图5.2  直方图密度估计2
图5.3.JPG
图5.3  两边延拓直方图密度估计
上图说明密度是双峰的。这种可以被称作线框核密度的估计方法仍然是不连续的,这是因为在对数据进行延拓时采用了一种不连续的中心延拓方式。如果在估计过程中使用一种平滑的数据延拓方式,那么将得到一条平滑的密度估计曲线。但是,这种方式仍然无法取消对带宽(相当于直方图中子区间的宽度)对于数据曲线的影响。
选择最适当的带宽是很重要的,值太小或太大都是不能用的。如果使用标准的(高斯)带宽,那么,所得到的核密度估计则不够平滑,这是因为所选带宽过小,见图5.4。
图5.4.JPG
图5.4  窄带宽核密度估计
可以通过增加核的带宽到0.5来消除这种由于人为处理数据不当而带来的影响。只采用一种方式获得表面上看起来更为平滑的估计曲线。但是,这种情形认为它过于平滑,因为在这种估计方式中,所采用的带宽过大,这样就使得很多数据的细节变的模糊。见图5.5。
那么,如何选择最理想的带宽呢? 最普遍的方法是使用最优化标准带宽—渐进的均方值误差AMISE(Asymptotic Mean Integrated Squared Error)最小。一般而言,AMISE需要从样本数据中去估计,也就是意味着带宽选择是渐进逼近的一种估计。核密度估计的特性与直方图比较的优点是光滑、没有终点、取决于带宽。
图5.5.JPG
图5.5 宽带宽核密度估计

参考文献:

Adrian W, Bowman,Adelchi Azzalini.Applied Smoothing Techniques for Data Analysis[M].London:

Oxford University Press,1997

Tarn Duong.An introduction to kernel density estimation [EB/OL].(2001-5-24)http:// www .maths .uwa.edu.au/~duongt/seminars/intro2kde/

[ 本帖最后由 assist 于 2008-1-7 11:09 编辑 ]
发表于 2008-1-17 10:11 | 显示全部楼层

回复 13楼 的帖子

厉害,相当佩服你的编程能力
发表于 2010-1-24 04:50 | 显示全部楼层

请问花版主

看到你的帖子

ksdensity函数可以估计概率密度函数
概率分布,应该再进行积分就可以了


用ksdensity计算出的不是解析式,而是一组概率密度函数值,Matlab的什么函数可以积分出这组数的分布函数?这个操作是能实现的吗?

[ 本帖最后由 serenityz 于 2010-1-24 04:53 编辑 ]
发表于 2010-1-24 19:22 | 显示全部楼层
ksdensity可以直接求核分布估计,不需要做积分。
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-9-22 01:18 , Processed in 0.070274 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表