R语言中dnorm, pnorm, qnorm与rnorm以及随机数

Python09

R语言中dnorm, pnorm, qnorm与rnorm以及随机数,第1张

-- title: R语言中dnorm, pnorm, qnorm与rnorm以及随机数 date: 2018-09-07 12:02:00 type: "tags" tags: 在R语言中,与正态分布(或者说其它分布)有关的函数有四个,分别为dnorm,pnorm,qnorm和rnorm,其中,dnorm表示密度函数,pnorm表示分布函数,qnorm表示分位数函数,rnorm表示生成随机数的函数。在R中与之类似的函数还有很多,具体的可以通过 help(Distributions) 命令去查看,对于分位数或百分位数的一些介绍可以看这篇笔记 《分位数及其应用》 ,关于正态分布的知识可以看这篇笔记 《正态分布笔记》 。 现在这篇笔记就介绍一下这些函数的区别。 R提供了多种随机数生成器(random number generators, RNG),默认采用的是Mersenne twister方法产生的随机数,该方法是由Makoto Matsumoto和Takuji Nishimura于1997年提出来的,其循环周期是 。R里面还提供了了Wichmann-Hill、Marsaglia-Multicarry、Super-Duper、Knuth-TAOCP-2002、Knuth-TAOCP和L'Ecuyer-CMRG等几种随机数生成方法,可以通过 RNGkind() 函数进行更改,例如,如果要改为WIchmann-Hill方法,就使用如下语句: 在R中使用随机数函数,例如 rnorm() 函数来生成的随机数是不一样的,有时我们在做模拟时,为了比较不同的方法,就需要生成的随机数都一样,即重复生成相同的随机数,此时就可以使用 set.seed() 来设置随机数种子,其参数为整数,如下所示:dnorm 中的 d 表示 density , norm 表示正态贫,这个函数是正态分布的 概率密度(probability density)函数 。 正态分布的公式如下所示:给定x,μ和σ后, dnorm() 这个函数返回的就是会返回上面的这个公式的值,这个值就是Z-score,如果是标准正态分布,那么上述的公式就变成了这个样子,如下所示:现在看一个案例,如下所示:dnorm(0,mean=0,sd=1) 由于是标准正态分布函数的概率密度,这个命令其实可以直接写为 dnorm(0) 即可,如下所示: 再看一个非标准正态分布的案例,如下所示: 虽然在 dnorm() 中,x是一个概率密度函数(PDF,Probability Density Function)的独立变量,但它也能看作是一组经过Z转换后的一组变量,现在我们看一下使用 dnorm 来绘制一个正态分布的概率密度函数曲线,如下所示: 现在使用 dnorm() 函数计算一下Z_scores的概率密度,如下所示: 现在绘图,如下所示: 从上面的结果可以看出,在每个Z-score处, dnorm 可以绘制出这个Z-score对应的正态分布的pdf的高度。pnorm 函数中的 p 表示Probability,它的功能是,在正态分布的PDF曲线上,返回从负无穷到 q 的积分,其中这个 q 指的是一个Z-score。现在我们大概就可以猜测出 pnorm(0) 的值是0.5,因为在标准正态分布曲线上,当Z-score等于0时,这个点正好在标准正态分布曲线的正中间,那么从负无穷到0之间的曲线面积就是整个标准正态分布曲线下面积的一半,如下所示:pnorm 函数还能使用 lower.tail 参数,如果 lower.tail 设置为 FALSE ,那么 pnorm() 函数返回的积分就是从 q 到正无穷区间的PDF下的曲线面积,因此我们就知道了, pnorm(q) 与 1-pnorm(q,lower.tail=FALSE) 的结果是一样的,如下所示: 在计算机出现之前的时代里,统计学家们使用正态分布进行统计时,通常是要查正态分布表的,但是,在计算机时代,通常都不使用正态分布表了,在R中, pnorm() 这个函数完全可以取代正态分布表了,现在我们使用一个Z-scores的向量来计算一下相应的累积概率,如下所示: 以上就是标准正态分布的 累积分布函数(CDF,Cumulative Distribution Function) 曲线。 简单来说, qnorm 是正态分布 累积分布函数(CDF,Cumulative Distribution Function) 的反函数,也就是说它可以视为 pnorm 的反函数,这里的 q 指的是quantile,即分位数。 使用 qnorm 这个函数可以回答这个问题:正态分布中的第p个分位数的Z-score是多少? 现在我们来计算一下,在正态分布分布中,第50百分位数的Z-score是多少,如下所示: 再来看一个案例:在正态分布中,第96个百分位的Z-score是多少,如下所示: 再来看一个案例:在正态分布中,第99个百分位的Z-score是多少,如下所示: 再来看一下 pnorm() 这个函数,如下所示: 从上面我们可以看到, pnorm 这个函数的功能是,我们知道某个Z-score是多少,它位于哪个分位数上。 接着我们进一步举例来说明一下 qnorm 和 pnorm 的具体功能,如下所示: 现在进行绘图,如下所示:rnomr() 函数的功能用于生成一组符合正态分布的随机数,在学习各种统计学方法时, rnorm 这个函数应该是最常用的,它的参数有 n , mean , sd ,其中n表示生成的随机数,mean与sd分别表示正态分布的均值与标准差,现在举个例子,如下所示: 现在我们绘制一下上面的几个向量的直方图,看一下它们的均值是否在70附近,如下所示: 在R语言中,生成不同分布的各种类型的函数都是以d,p,q,r开头的,使用原理跟上面的正态分布都一样。sample() 函数是一个用于生成随机数的重要的核心函数,如果仅传递一个数值n给它,就会返回一个从1到n的自然数的排列,如果传递是 n:m 就是生成从n到m的随机数,如是是 7,5 ,则会生成5个小于7的随机数,如下所示: 从上面的结果可以看出来,这些数字都是不同的,也就是说,sample函数默认情况下是不重复抽样,每个值只出现一次,如果允许有重复抽样,需要添加参数 replace = TRUE ,如下所示: sample函数通常会从某些向量中随机挑一些参数,如下所示: 也可以挑日期,如下所示: 上述分布函数前面加上r,p、q、d就可以表示相应的目的:

输入为一个vector,我们以a <- seq(1, 250, 1)做为示例数据

利用qqnorm函数直接绘制出了如下正态检验qq图

还可以进一步使用qqline命令在qq图上加上标准直线

注:qqline的默认算法为向量a上四分位数和下四分位数对应两个点的连线

Step 1: 首先我们算出vector中每一个数对应的百分位数

  在向量a中,数字1对应的累积比例(即小于等于数字1的频率)为1/length(a) = 0.04,数字250对应的累积比例为250/length(a) = 100%

  

Step 2: 根据累积比例数计算出正态分布对应的百分位数值

  直接绘制点图即为qqplot图

  

Step 3: 可以查看一下q值发现,最后的q值为Inf

  这是因为百分位100%对应的正态分布数值为无穷大,所以最后得出的图与R自带的qqnorm的稍微有一点点区别,这是因为在内置的qqnorm函数中对累积百分数进行了调整,为了避免inf的出现,使用 t <- (rank(a) -0.5)/length(a) 调整后得出的结果与qqnorm的结果图就完全一致了。

Step 4: 绘制标准直线

  如果是依据标准正态分布做的qq图,则标准直线截距为mean(a),斜率为sd(a)

[图片上传失败...(image-50be7a-1512789490785)]

  如果是依据(mean(a), var(a))正态分布做的qq图,则标准直线为y=x

[图片上传失败...(image-4e2370-1512789490785)]

pp plot横轴为实际累积概率,即上文qq plot中的变量t

纵轴为期望累积的概率,标准直线为 y=x

[图片上传失败...(image-682bd0-1512789490785)]

结果大致呈一条直线则说明大致服从正态分布

快速计算累积百分数的方法:

[图片上传失败...(image-de8e63-1512789490785)]

参考:

https://wenku.baidu.com/view/c661ebb365ce050876321319.html

http://data.library.virginia.edu/understanding-q-q-plots/

http://www.cnblogs.com/xianghang123/archive/2012/08/08/2628623.html

https://d.cosx.org/d/18521-18521

ks.test()实现了KS检验,可以检验任意样本是不是来自给定的连续分布。你这里的用法就是:ks.test(data,pt,df=df) #data是样本的数据,df是要检验的t分布的自由度我们可以用很多方法分析一个单变量数据集的分布。最简单的办法就是直接看数字。利用函数summary 和fivenum 会得到两个稍稍有点差异的汇总信息。此外,stem(\茎叶"图)也会反映整个数据集的数字信息。>attach(faithful)>summary(eruptions)Min. 1st Qu. Median Mean 3rd Qu. Max.1.600 2.163 4.000 3.488 4.454 5.100>fivenum(eruptions)[1] 1.6000 2.1585 4.0000 4.4585 5.1000>stem(eruptions)The decimal point is 1 digit(s) to the left of the |16 | 07035555558818 | 00002223333333557777777788882233577788820 | 0000222337880003577822 | 000233557802357824 | 0022826 | 2328 | 08030 | 732 | 233734 | 25007736 | 000082357738 | 233333558222557740 | 000000335778888800223355557777842 | 0333555577880023333355557777844 | 0222233555778000000002333335777888846 | 000023335770000002357848 | 0000002233580033350 | 0370茎叶图和柱状图相似,R 用函数hist 绘制柱状图。>hist(eruptions)>## 让箱距缩小,绘制密度图>hist(eruptions, seq(1.6, 5.2, 0.2), prob=TRUE)>lines(density(eruptions, bw=0.1))>rug(eruptions) # 显示实际的数据点更为精致的密度图是用函数density 绘制的。在这个例子中,我们加了一条由density 产生的曲线。你可以用试错法(trial-and-error)选择带宽bw(bandwidth)因为默认的带宽值让密度曲线过于平滑(这样做常常会让你得到非常有\意思"的密度分布)。(现在已经有一些自动的带宽挑选方法2,在这个例子中bw = "SJ"给出的结果不错。)我们可以用函数ecdf 绘制一个数据集的经验累积分布(empirical cumulativedistribution)函数。>plot(ecdf(eruptions), do.points=FALSE, verticals=TRUE)显然,这个分布和其他标准分布差异很大。那么右边的情况怎么样呢,就是火山爆发3分钟后的状况?我们可以拟合一个正态分布,并且重叠前面得到的经验累积密度分布。>long <- eruptions[eruptions >3]>plot(ecdf(long), do.points=FALSE, verticals=TRUE)>x <- seq(3, 5.4, 0.01)>lines(x, pnorm(x, mean=mean(long), sd=sqrt(var(long))), lty=3)分位比较图(Quantile-quantile (Q-Q) plot)便于我们更细致地研究二者的吻合程度。par(pty="s") # 设置一个方形的图形区域qqnorm(long)qqline(long)上述命令得到的QQ图表明二者还是比较吻合的,但右侧尾部偏离期望的正态分布。我们可以用t 分布获得一些模拟数据以重复上面的过程x <- rt(250, df = 5)qqnorm(x)qqline(x)这里得到的QQ图常常会出现偏离正态期望的长尾区域(如果是随机样本)。我们可以用下面的命令针对特定的分布绘制Q-Q图qqplot(qt(ppoints(250), df = 5), x, xlab = "Q-Q plot for t dsn")qqline(x)最后,我们可能需要一个比较正规的正态性检验方法。R提供了Shapiro-Wilk 检验>shapiro.test(long)Shapiro-Wilk normality testdata: longW = 0.9793, p-value = 0.01052和Kolmogorov-Smirnov 检验>ks.test(long, "pnorm", mean = mean(long), sd = sqrt(var(long)))One-sample Kolmogorov-Smirnov testdata: longD = 0.0661, p-value = 0.4284alternative hypothesis: two.sided(注意一般的统计分布理论(distribution theory)在这里可能无效,因为我们用同样的样本对正态分布的参数进行估计的。)转载于: http://www.biostatistic.net/thread-2413-1-1.html