如何由小样本(100-200之间)求概率分布
如何由小样本(100-200之间)求概率函数、概率分布函数。不能使用频次代替概率。请给出理论与实现方法。
[ 本帖最后由 assist 于 2007-10-26 11:20 编辑 ] 使用概率统计工具箱的函数可以实现 谁有做过这样问题的 经验。帮忙解释一下!
回复 #3 assist 的帖子
我昨天发了一个统计工具箱的介绍,里边讲得还算详细。仔细读会找到答案的
--------------------------------------------------
ksdensity函数可以估计概率密度函数
概率分布,应该再进行积分就可以了
---------------------------------------------------
[ 本帖最后由 花如月 于 2007-10-27 09:31 编辑 ] 花如月,谢谢你,我还想问ksdensity使用的是什么算法。我想使用C++实现它。
回复 #5 assist 的帖子
这个我也不太清楚,如果需要了解其原理。edit ksdensity看看它的源码,或许对你有帮助 谢谢,源码倒是不长,如果能知道使用的是什么原理就好办很多。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 编辑 ] 原帖由 assist 于 2007-10-29 08:34 发表 http://www.chinavib.com/forum/images/common/back.gif
花如月,谢谢哦,我已经使用C++实现了ksdensity的正态分布密度功能。
人家 花如月 是版主,你应该称呼 花版主 才对:lol
ksdensity函数,其支持理论是什么?
ksdensity函数其支持理论是什么?[ 本帖最后由 eight 于 2007-10-30 10:36 编辑 ]
回复 #11 assist 的帖子
这个我也不清楚,是统计工具箱里的函数。不过你既然都能用c++来实现,难道搞不清他的原理?至少在概率论里应该可以找到些痕迹 直方图是最简单的非参数密度估计方式,因而其使用也最为广泛。为了创建直方图,将数据值所覆盖的区间等分为若干子区间。每次,一个数据值落入某个唯一的子区间,并将其在平行于横坐标的方向上延拓成单位宽度的线段。当创建一个直方图时,必须考虑两个关键点:子区间的始点、终点。如果选取在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直方图密度估计1
图5.2直方图密度估计2
图5.3两边延拓直方图密度估计
上图说明密度是双峰的。这种可以被称作线框核密度的估计方法仍然是不连续的,这是因为在对数据进行延拓时采用了一种不连续的中心延拓方式。如果在估计过程中使用一种平滑的数据延拓方式,那么将得到一条平滑的密度估计曲线。但是,这种方式仍然无法取消对带宽(相当于直方图中子区间的宽度)对于数据曲线的影响。
选择最适当的带宽是很重要的,值太小或太大都是不能用的。如果使用标准的(高斯)带宽,那么,所得到的核密度估计则不够平滑,这是因为所选带宽过小,见图5.4。
图5.4窄带宽核密度估计
可以通过增加核的带宽到0.5来消除这种由于人为处理数据不当而带来的影响。只采用一种方式获得表面上看起来更为平滑的估计曲线。但是,这种情形认为它过于平滑,因为在这种估计方式中,所采用的带宽过大,这样就使得很多数据的细节变的模糊。见图5.5。
那么,如何选择最理想的带宽呢? 最普遍的方法是使用最优化标准带宽—渐进的均方值误差AMISE(Asymptotic Mean Integrated Squared Error)最小。一般而言,AMISE需要从样本数据中去估计,也就是意味着带宽选择是渐进逼近的一种估计。核密度估计的特性与直方图比较的优点是光滑、没有终点、取决于带宽。
图5.5 宽带宽核密度估计
参考文献:
Adrian W, Bowman,Adelchi Azzalini.Applied Smoothing Techniques for Data Analysis.London:
Oxford University Press,1997
Tarn Duong.An introduction to kernel density estimation .(2001-5-24)http:// www .maths .uwa.edu.au/~duongt/seminars/intro2kde/
[ 本帖最后由 assist 于 2008-1-7 11:09 编辑 ]
回复 13楼 的帖子
厉害,相当佩服你的编程能力请问花版主
看到你的帖子ksdensity函数可以估计概率密度函数
概率分布,应该再进行积分就可以了
用ksdensity计算出的不是解析式,而是一组概率密度函数值,Matlab的什么函数可以积分出这组数的分布函数?这个操作是能实现的吗?
[ 本帖最后由 serenityz 于 2010-1-24 04:53 编辑 ] ksdensity可以直接求核分布估计,不需要做积分。
页:
[1]