• Posts tagged "R"
  • (Page 20)

Blog Archives

常用连续型分布介绍及R语言实现

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-density/

r-density

前言

随机变量在我们的生活中处处可见,如每日天气,股价涨跌,彩票中奖等,这些事情都是事前不可预言其结果的,就算在相同的条件下重复进行试验,其结果未必相同。数学家们总结了这种规律,用概率分布来描述随机变量取值。

就算股价不能预测,但如果我们知道它的概率分布,那么有90%的可能我们可以猜出答案。

目录

  1. 正态分布
  2. 指数分步
  3. γ(伽玛)分布
  4. weibull分布
  5. F分布
  6. T分布
  7. β(贝塔)分布
  8. χ²(卡方)分布
  9. 均匀分布

1. 正态分布

正态分布(Normal distribution)又名高斯分布(Gaussian distribution),是一个在数学、物理及工程等领域都非常重要的概率分布,在统计学的许多方面有着重大的影响力。

若随机变量X服从一个数学期望为μ、方差为σ^2的正态分布,记为N(μ,σ^2)。其概率密度函数为正态分布的期望值μ决定了其位置,其标准差σ决定了分布的幅度。因其曲线呈钟形,因此人们又经常称之为钟形曲线。我们通常所说的标准正态分布是μ = 0,σ = 1的正态分布。

1). 概率密度函数

norm-distribution


set.seed(1)
x <- seq(-5,5,length.out=100)
y <- dnorm(x,0,1)
  
plot(x,y,col="red",xlim=c(-5,5),ylim=c(0,1),type='l',
     xaxs="i", yaxs="i",ylab='density',xlab='',
     main="The Normal Density Distribution")

lines(x,dnorm(x,0,0.5),col="green")
lines(x,dnorm(x,0,2),col="blue")
lines(x,dnorm(x,-2,1),col="orange")

legend("topright",legend=paste("m=",c(0,0,0,-2)," sd=", c(1,0.5,2,1)), lwd=1, col=c("red", "green","blue","orange"))

norm

2). 累积分布函数

norm-distribution-cum


set.seed(1)
x <- seq(-5,5,length.out=100)
y <- pnorm(x,0,1)

plot(x,y,col="red",xlim=c(-5,5),ylim=c(0,1),type='l',
     xaxs="i", yaxs="i",ylab='density',xlab='',
     main="The Normal Cumulative Distribution")

lines(x,pnorm(x,0,0.5),col="green")
lines(x,pnorm(x,0,2),col="blue")
lines(x,pnorm(x,-2,1),col="orange")

legend("bottomright",legend=paste("m=",c(0,0,0,-2)," sd=", c(1,0.5,2,1)), lwd=1,col=c("red", "green","blue","orange"))

norm2

3). 分布检验

Shapiro-Wilk正态分布检验: 用来检验是否数据符合正态分布,类似于线性回归的方法一样,是检验其于回归曲线的残差。该方法推荐在样本量很小的时候使用,样本在3到5000之间。

该检验原假设为H0:数据集符合正态分布,统计量W为:

shapiro-wilk-test

  • 统计量W 最大值是1,越接近1,表示样本与正态分布匹配
  • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
  • R语言程序

    
    > set.seed(1)
    > S<-rnorm(1000)
    > shapiro.test(S)
    	Shapiro-Wilk normality test
    data:  S
    W = 0.9988, p-value = 0.7256
    

    结论: W接近1,p-value>0.05,不能拒绝原假设,所以数据集S符合正态分布!

    Kolmogorov-Smirnov连续分布检验:检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合正态分布,H1:样本所来自的总体分布不符合正态分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近正态分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rnorm(1000)
    > ks.test(S, "pnorm")
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0211, p-value = 0.7673
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合正态分布!

    2. 指数分布

    指数分布(Exponential distribution)用来表示独立随机事件发生的时间间隔,比如旅客进机场的时间间隔、中文维基百科新条目出现的时间间隔等等。

    许多电子产品的寿命分布一般服从指数分布。有的系统的寿命分布也可用指数分布来近似。它在可靠性研究中是最常用的一种分布形式。指数分布是伽玛分布和weibull分布的特殊情况,产品的失效是偶然失效时,其寿命服从指数分布。

    指数分布可以看作当weibull分布中的形状系数等于1的特殊分布,指数分布的失效率是与时间t无关的常数,所以分布函数简单。

    1). 概率密度函数

    Exponential-distribution

    其中λ > 0是分布的一个参数,常被称为率参数(rate parameter)。即每单位时间发生该事件的次数。指数分布的区间是[0,∞)。 如果一个随机变量X 呈指数分布,则可以写作:X ~ Exponential(λ)。

    
    set.seed(1)
    x<-seq(-1,2,length.out=100)
    y<-dexp(x,0.5)
    
    plot(x,y,col="red",xlim=c(0,2),ylim=c(0,5),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Exponential Density Distribution")
    lines(x,dexp(x,1),col="green")
    lines(x,dexp(x,2),col="blue")
    lines(x,dexp(x,5),col="orange")
    
    legend("topright",legend=paste("rate=",c(.5, 1, 2,5)), lwd=1,col=c("red", "green","blue","orange"))
    

    exp

    2). 累积分布函数

    Exponential-distribution-cum

    
    set.seed(1)
    x<-seq(-1,2,length.out=100)
    y<-pexp(x,0.5)
    
    plot(x,y,col="red",xlim=c(0,2),ylim=c(0,1),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Exponential Cumulative Distribution Function")
    lines(x,pexp(x,1),col="green")
    lines(x,pexp(x,2),col="blue")
    lines(x,pexp(x,5),col="orange")
    
    legend("bottomright",legend=paste("rate=",c(.5, 1, 2,5)), lwd=1, col=c("red", "green","blue","orange"))
    

    exp2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验:检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合指数分布,H1:样本所来自的总体分布不符合指数分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近指数分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rexp(1000)
    > ks.test(S, "pexp")
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0387, p-value = 0.1001
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合指数分布!

    3. γ(伽玛)分布

    伽玛分布(Gamma)是著名的皮尔逊概率分布函数簇中的重要一员,称为皮尔逊Ⅲ型分布。它的曲线有一个峰,但左右不对称。

    伽玛分布中的参数α,称为形状参数,β称为尺度参数。

    gamma0

    伽玛函数为:

    gamma-fo

    伽玛函数是阶乘在实数上的泛化。

    1). 概率密度函数

    gamma

    
    set.seed(1)
    x<-seq(0,10,length.out=100)
    y<-dgamma(x,1,2)
    
    plot(x,y,col="red",xlim=c(0,10),ylim=c(0,2),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Gamma Density Distribution")
    
    lines(x,dgamma(x,2,2),col="green")
    lines(x,dgamma(x,3,2),col="blue")
    lines(x,dgamma(x,5,1),col="orange")
    lines(x,dgamma(x,9,1),col="black")
    
    legend("topright",legend=paste("shape=",c(1,2,3,5,9)," rate=", c(2,2,2,1,1)), lwd=1, col=c("red", "green","blue","orange","black"))
    

    gamma

    2). 累积分布函数

    gamma2

    
    set.seed(1)
    x<-seq(0,10,length.out=100)
    y<-pgamma(x,1,2)
    
    plot(x,y,col="red",xlim=c(0,10),ylim=c(0,1),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Gamma Cumulative Distribution Function")
    
    lines(x,pgamma(x,2,2),col="green")
    lines(x,pgamma(x,3,2),col="blue")
    lines(x,pgamma(x,5,1),col="orange")
    lines(x,pgamma(x,9,1),col="black")
    
    legend("bottomright",legend=paste("shape=",c(1,2,3,5,9)," rate=", c(2,2,2,1,1)), lwd=1, col=c("red", "green","blue","orange","black"))
    

    gamma2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合伽玛分布,H1:样本所来自的总体分布不符合伽玛分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近伽玛分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rgamma(1000,1)
    > ks.test(S, "pgamma", 1)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0363, p-value = 0.1438
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合shape=1伽玛分布!

    检验失败:

    
    > ks.test(S, "pgamma", 2)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.3801, p-value < 2.2e-16
    alternative hypothesis: two-sided
    

    结论:D值不够小, p-value<0.05,拒绝原假设,所以数据集S符合shape=2伽玛分布!

    4. weibull分布

    weibull(韦伯)分布,又称韦氏分布或威布尔分布,是可靠性分析和寿命检验的理论基础。Weibull分布能被应用于很多形式,分布由形状、尺度(范围)和位置三个参数决定。其中形状参数是最重要的参数,决定分布密度曲线的基本形状,尺度参数起放大或缩小曲线的作用,但不影响分布的形状。

    Weibull分布通常用在故障分析领域( field of failure analysis)中;尤其是它可以模拟(mimic) 故障率(failture rate)持续( over time)变化的分布。故障率为:

    • 一直为常量(constant over time), 那么 α = 1, 暗示在随机事件中发生
    • 一直减少(decreases over time),那么α < 1, 暗示"早期失效(infant mortality)"
    • 一直增加(increases over time),那么α > 1, 暗示"耗尽(wear out)" - 随着时间的推进,失败的可能性变大

    1). 概率密度函数

    weibull

    
    set.seed(1)
    x<- seq(0, 2.5, length.out=1000)
    y<- dweibull(x, 0.5)
    
    plot(x, y, type="l", col="blue",xlim=c(0, 2.5),ylim=c(0, 6),
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Weibull Density Distribution")
    
    lines(x, dweibull(x, 1), type="l", col="red")
    lines(x, dweibull(x, 1.5), type="l", col="magenta")
    lines(x, dweibull(x, 5), type="l", col="green")
    lines(x, dweibull(x, 15), type="l", col="purple")
    legend("topright", legend=paste("shape =", c(.5, 1, 1.5, 5, 15)), lwd=1,col=c("blue", "red", "magenta", "green","purple"))
    

    weibull

    2). 累积分布函数

    weibull2

    
    set.seed(1)
    x<- seq(0, 2.5, length.out=1000)
    y<- pweibull(x, 0.5)
    
    plot(x, y, type="l", col="blue",xlim=c(0, 2.5),ylim=c(0, 1.2),
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Weibull Cumulative Distribution Function")
    
    lines(x, pweibull(x, 1), type="l", col="red")
    lines(x, pweibull(x, 1.5), type="l", col="magenta")
    lines(x, pweibull(x, 5), type="l", col="green")
    lines(x, pweibull(x, 15), type="l", col="purple")
    legend("bottomright", legend=paste("shape =", c(.5, 1, 1.5, 5, 15)), lwd=1, col=c("blue", "red", "magenta", "green","purple"))
    

    weibull2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合weibull分布,H1:样本所来自的总体分布不符合weibull分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近weibull分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rweibull(1000,1)
    > ks.test(S, "pweibull",1)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0244, p-value = 0.5928
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合shape=1的weibull分布!

    5. F分布

    F-分布(F-distribution)是一种连续概率分布,被广泛应用于似然比率检验,特别是ANOVA中。F分布定义为:设X、Y为两个独立的随机变量,X服从自由度为k1的卡方分布,Y服从自由度为k2的卡方分布,这2 个独立的卡方分布被各自的自由度除以后的比率这一统计量的分布。即: 上式F服从第一自由度为k1,第二自由度为k2的F分布。

    F分布的性质

    • 它是一种非对称分布
    • 它有两个自由度,即n1 -1和n2-1,相应的分布记为F( n1 –1, n2-1), n1 –1通常称为分子自由度, n2-1通常称为分母自由度
    • F分布是一个以自由度n1 –1和n2-1为参数的分布族,不同的自由度决定了F 分布的形状
    • F分布的倒数性质:Fα,df1,df2=1/F1-α,df1,df2[1]

    1). 概率密度函数

    f

    B是Beta函数(beta function)

    
    set.seed(1)
    x<-seq(0,5,length.out=1000)
    y<-df(x,1,1,0)
    
    plot(x,y,col="red",xlim=c(0,5),ylim=c(0,1),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The F Density Distribution")
    
    lines(x,df(x,1,1,2),col="green")
    lines(x,df(x,2,2,2),col="blue")
    lines(x,df(x,2,4,4),col="orange")
    
    legend("topright",legend=paste("df1=",c(1,1,2,2),"df2=",c(1,1,2,4)," ncp=", c(0,2,2,4)), lwd=1, col=c("red", "green","blue","orange"))
    

    f

    2). 累积分布函数

    f2

    I是不完全Beta函数

    
    set.seed(1)
    x<-seq(0,5,length.out=1000)
    y<-df(x,1,1,0)
    
    plot(x,y,col="red",xlim=c(0,5),ylim=c(0,1),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The F Cumulative Distribution Function")
    
    lines(x,pf(x,1,1,2),col="green")
    lines(x,pf(x,2,2,2),col="blue")
    lines(x,pf(x,2,4,4),col="orange")
    
    legend("topright",legend=paste("df1=",c(1,1,2,2),"df2=",c(1,1,2,4)," ncp=", c(0,2,2,4)), lwd=1, col=c("red", "green","blue","orange"))
    

    f2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合F分布,H1:样本所来自的总体分布不符合F分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近F分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rf(1000,1,1,2)
    > ks.test(S, "pf", 1,1,2)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0113, p-value = 0.9996
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合df1=1, df2=1, ncp=2的F分布!

    6. T分布

    学生t-分布(Student's t-distribution),可简称为t分布。应用在估计呈正态分布的母群体之平均数。它是对两个样本均值差异进行显著性测试的学生t检定的基础。学生t检定改进了Z检定(Z-test),因为Z检定以母体标准差已知为前提。虽然在样本数量大(超过30个)时,可以应用Z检定来求得近似值,但Z检定用在小样本会产生很大的误差,因此必须改用学生t检定以求准确。

    在母体标准差未知的情况下,不论样本数量大或小皆可应用学生t检定。在待比较的数据有三组以上时,因为误差无法压低,此时可以用变异数分析(ANOVA)代替学生t检定。

    1). 概率密度函数

    t

    v 等于n − 1。 T的分布称为t-分布。参数\nu 一般被称为自由度。
    γ 是伽玛函数。

    
    set.seed(1)
    x<-seq(-5,5,length.out=1000)
    y<-dt(x,1,0)
    
    plot(x,y,col="red",xlim=c(-5,5),ylim=c(0,0.5),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The T Density Distribution")
    
    lines(x,dt(x,5,0),col="green")
    lines(x,dt(x,5,2),col="blue")
    lines(x,dt(x,50,4),col="orange")
    
    legend("topleft",legend=paste("df=",c(1,5,5,50)," ncp=", c(0,0,2,4)), lwd=1, col=c("red", "green","blue","orange"))
    

    t

    2). 累积分布函数

    t2

    v 等于n − 1。 T的分布称为t-分布。参数\nu 一般被称为自由度。
    γ 是伽玛函数。

    
    set.seed(1)
    x<-seq(-5,5,length.out=1000)
    y<-pt(x,1,0)
    
    plot(x,y,col="red",xlim=c(-5,5),ylim=c(0,0.5),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The T Cumulative Distribution Function")
    
    lines(x,pt(x,5,0),col="green")
    lines(x,pt(x,5,2),col="blue")
    lines(x,pt(x,50,4),col="orange")
    
    legend("topleft",legend=paste("df=",c(1,5,5,50)," ncp=", c(0,0,2,4)), lwd=1, col=c("red", "green","blue","orange"))
    

    t2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合T分布,H1:样本所来自的总体分布不符合T分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近T分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rt(1000, 1,2)
    > ks.test(S, "pt", 1, 2)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0253, p-value = 0.5461
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合df1=1, ncp=2的T分布!

    7. β(贝塔Beta)分布

    贝塔分布(Beta Distribution)是指一组定义在(0,1)区间的连续概率分布,Beta分布有α和β两个参数α,β>0,其中α为成功次数加1,β为失败次数加1。

    Beta分布的一个重要应该是作为伯努利分布和二项式分布的共轭先验分布出现,在机器学习和数理统计学中有重要应用。贝塔分布中的参数可以理解为伪计数,伯努利分布的似然函数可以表示为,表示一次事件发生的概率,它为贝塔有相同的形式,因此可以用贝塔分布作为其先验分布。

    1). 概率密度函数

    beta

    随机变量X服从参数为a, β,服从Beta分布
    γ 是伽玛函数

    
    set.seed(1)
    x<-seq(-5,5,length.out=10000)
    y<-dbeta(x,0.5,0.5)
      
    plot(x,y,col="red",xlim=c(0,1),ylim=c(0,6),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Beta Density Distribution")
    
    lines(x,dbeta(x,5,1),col="green")
    lines(x,dbeta(x,1,3),col="blue")
    lines(x,dbeta(x,2,2),col="orange")
    lines(x,dbeta(x,2,5),col="black")
    
    legend("top",legend=paste("a=",c(.5,5,1,2,2)," b=", c(.5,1,3,2,5)), lwd=1,col=c("red", "green","blue","orange","black"))
    

    beta

    2). 累积分布函数

    beta2

    I是正则不完全Beta函数

    
    set.seed(1)
    x<-seq(-5,5,length.out=10000)
    y<-pbeta(x,0.5,0.5)
    
    plot(x,y,col="red",xlim=c(0,1),ylim=c(0,1),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Beta Cumulative Distribution Function")
    
    lines(x,pbeta(x,5,1),col="green")
    lines(x,pbeta(x,1,3),col="blue")
    lines(x,pbeta(x,2,2),col="orange")
    lines(x,pbeta(x,2,5),col="black")
    
    legend("topleft",legend=paste("a=",c(.5,5,1,2,2)," b=", c(.5,1,3,2,5)), lwd=1,col=c("red", "green","blue","orange","black"))
    

    beta2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合Beta分布,H1:样本所来自的总体分布不符合Beta分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近Beta分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rbeta(1000,1,2)
    > ks.test(S, "pbeta",1,2)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0202, p-value = 0.807
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合shape1=1, shape2=2的Beta分布!

    8. χ²(卡方)分布

    若n个相互独立的随机变量ξ₁、ξ₂、……、ξn ,均服从标准正态分布(也称独立同分布于标准正态分布),则这n个服从标准正态分布的随机变量的平方和构成一新的随机变量,其分布规律称为χ²分布(chi-square distribution)。其中参数n称为自由度,自由度不同就是另一个χ²分布,正如正态分布中均值或方差不同就是另一个正态分布一样。

    1). 概率密度函数

    chi-square

    γ 是伽玛函数

    
    set.seed(1)
    x<-seq(0,10,length.out=1000)
    y<-dchisq(x,1)
    
    plot(x,y,col="red",xlim=c(0,5),ylim=c(0,2),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Chisq Density Distribution")
    
    lines(x,dchisq(x,2),col="green")
    lines(x,dchisq(x,3),col="blue")
    lines(x,dchisq(x,10),col="orange")
    
    legend("topright",legend=paste("df=",c(1,2,3,10)), lwd=1, col=c("red", "green","blue","orange"))
    

    x2

    2). 累积分布函数

    chi-square2

    γ 是伽玛函数

    
    set.seed(1)
    x<-seq(0,10,length.out=1000)
    y<-pchisq(x,1)
    
    plot(x,y,col="red",xlim=c(0,10),ylim=c(0,1),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Chisq Cumulative Distribution Function")
    
    lines(x,pchisq(x,2),col="green")
    lines(x,pchisq(x,3),col="blue")
    lines(x,pchisq(x,10),col="orange")
    
    legend("topleft",legend=paste("df=",c(1,2,3,10)), lwd=1, col=c("red", "green","blue","orange"))
    

    x22

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合卡方分布,H1:样本所来自的总体分布不符合卡方分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近卡方分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-rchisq(1000,1)
    > ks.test(S, "pchisq",1)
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0254, p-value = 0.5385
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合df=1的卡方分布!

    9. 均匀分布

    均匀分布(Uniform distribution)是均匀的,不偏差的一种简单的概率分布,分为:离散型均匀分布与连续型均匀分布。

    1). 概率密度函数

    uniform

    
    set.seed(1)
    x<-seq(0,10,length.out=1000)
    y<-dunif(x,0,1)
    
    plot(x,y,col="red",xlim=c(0,10),ylim=c(0,1.2),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Uniform Density Distribution")
    lines(x,dnorm(x,0,0.5),col="green")
    lines(x,dnorm(x,0,2),col="blue")
    lines(x,dnorm(x,-2,1),col="orange")
    lines(x,dnorm(x,4,2),col="purple")
    
    legend("topright",legend=paste("m=",c(0,0,0,-2,4)," sd=", c(1,0.5,2,1,2)), lwd=1, col=c("red", "green","blue","orange","purple"))
    

    unif

    2). 累积分布函数

    uniform2

    
    set.seed(1)
    x<-seq(0,10,length.out=1000)
    y<-punif(x,0,1)
    
    plot(x,y,col="red",xlim=c(0,10),ylim=c(0,1.2),type='l',
         xaxs="i", yaxs="i",ylab='density',xlab='',
         main="The Uniform Cumulative Distribution Function")
    
    lines(x,punif(x,0,0.5),col="green")
    lines(x,punif(x,0,2),col="blue")
    lines(x,punif(x,-2,1),col="orange")
    
    legend("bottomright",legend=paste("m=",c(0,0,0,-2)," sd=", c(1,0.5,2,1)), lwd=1, col=c("red", "green","blue","orange","purple"))
    

    unif2

    3). 分布检验

    Kolmogorov-Smirnov连续分布检验: 检验单一样本是不是服从某一预先假设的特定分布的方法。以样本数据的累计频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。

    该检验原假设为H0:数据集符合均匀分布,H1:样本所来自的总体分布不符合均匀分布。令F0(x)表示预先假设的理论分布,Fn(x)表示随机样本的累计概率(频率)函数.

    统计量D为: D=max|F0(x) - Fn(x)|

    • D值越小,越接近0,表示样本数据越接近均匀分布
    • p值,如果p-value小于显著性水平α(0.05),则拒绝H0
    
    > set.seed(1)
    > S<-runif(1000)
    > ks.test(S, "punif")
    	One-sample Kolmogorov-Smirnov test
    data:  S
    D = 0.0244, p-value = 0.5928
    alternative hypothesis: two-sided
    

    结论: D值很小, p-value>0.05,不能拒绝原假设,所以数据集S符合均匀分布!

    在我们掌握了,这几种常用的连续型分布后,我们就可以基于这些分布来建模了,很多的算法模型就能解释通了!!

    参考资料

    转载请注明出处:
    http://blog.fens.me/r-density/

    打赏作者

用R解析Mahout用户推荐协同过滤算法(UserCF)

RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析。Hadoop主要用来存储海量数据,R语言完成MapReduce 算法,用来替代Java的MapReduce实现。有了RHadoop可以让广大的R语言爱好者,有更强大的工具处理大数据1G, 10G, 100G, TB, PB。 由于大数据所带来的单机性能问题,可能会一去不复返了。

RHadoop实践是一套系列文章,主要包括”Hadoop环境搭建”,”RHadoop安装与使用”,R实现MapReduce的协同过滤算法”,”HBase和rhbase的安装与使用”。对于单独的R语言爱好者,Java爱好者,或者Hadoop爱好者来说,同时具备三种语言知识并不容 易。此文虽为入门文章,但R,Java,Hadoop基础知识还是需要大家提前掌握。

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-mahout-usercf/

r-mahout

前言
用R全面解析Mahout的基于用户推荐协同过滤算法(UserCF),改进的采用欧氏距离,并用R语言实现,与Mahout的结果进行对比。

Mahout是Hahoop家族用于机器学习的一个框架,包括三个主要部分,推荐,聚类,分类!
我在这里做的是推荐部分。推荐系统在现在的互联网应用中很常见,比如,亚马逊会推荐你买书,豆瓣会给你一个书评,影评。

由于时间仓促,欢迎大家一起讨论。

目录

  1. Mahout的模型介绍
  2. R语言模型实现
  3. 算法实现的原理–矩阵变换
  4. 算法总结
  5. 参考资料

1. Mahout的模型介绍

mahout-recommendation-process

Mahout版本

 
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.5</version>
</dependency>

Mahout程序写法


public class UserBaseCFMain {

    final static int NEIGHBORHOOD_NUM = 2;
    final static int RECOMMENDER_NUM = 3;

    public static void main(String[] args) throws IOException, TasteException {
        String file = "metadata/data/testCF.csv";
        DataModel model = new FileDataModel(new File(file));
        UserSimilarity user = new EuclideanDistanceSimilarity(model);
        NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, user, model);
        Recommender r = new GenericUserBasedRecommender(model, neighbor, user);
        LongPrimitiveIterator iter = model.getUserIDs();

        while (iter.hasNext()) {
            long uid = iter.nextLong();
            List list = r.recommend(uid, RECOMMENDER_NUM);
            System.out.printf("uid:%s", uid);
            for (RecommendedItem ritem : list) {
                System.out.printf("(%s,%f)", ritem.getItemID(), ritem.getValue());
            }
            System.out.println();
        }
    }
} 

推荐结果:


uid:1(104,4.250000)(106,4.000000)
uid:2(105,3.956999)
uid:3(103,3.185407)(102,2.802432)
uid:4(102,3.000000)
uid:5 

2. R语言模型实现

  • 1). 建立数据模型
  • 2). 欧氏距离相似度算法
  • 3). 最紧邻算法
  • 4). 推荐算法
  • 5). 运行程序

由于时间仓促,R的代码中,有不少for循环影响性能,请暂时跳过!

1). 建立数据模型


FileDataModel<-function(file){
data<-read.csv(file,header=FALSE)
names(data)<-c("uid","iid","pref")

user <- unique(data$uid)
item <- unique(sort(data$iid))
uidx <- match(data$uid, user)
iidx <- match(data$iid, item)
M <- matrix(0, length(user), length(item))
i <- cbind(uidx, iidx, pref=data$pref)
for(n in 1:nrow(i)){
M[i[n,][1],i[n,][2]]<-i[n,][3]
}
dimnames(M)[[2]]<-item
M
}

2). 欧氏距离相似度算法


EuclideanDistanceSimilarity<-function(M){
row<-nrow(M)
s<-matrix(0, row, row)
for(z1 in 1:row){
for(z2 in 1:row){
if(z1<z2){< span="">
num<-intersect(which(M[z1,]!=0),which(M[z2,]!=0)) #可计算的列

sum<-0
for(z3 in num){
sum<-sum+(M[z1,][z3]-M[z2,][z3])^2
}

s[z2,z1]<-length(num)/(1+sqrt(sum))

if(s[z2,z1]>1) s[z2,z1]<-1 #标准化
if(s[z2,z1]< -1) s[z2,z1]<- -1 #标准化

#print(paste(z1,z2));print(num);print(sum)
}
}
}
#补全三角矩阵
ts<-t(s)
w<-which(upper.tri(ts))
s[w]<-ts[w]
s
}

3). 最紧邻算法

NearestNUserNeighborhood<-function(S,n){ row<-nrow(S) neighbor<-matrix(0, row, n) for(z1 in 1:row){ for(z2 in 1:n){ m<-which.max(S[,z1]) #       print(paste(z1,z2,m,'\n')) neighbor[z1,][z2]<-m S[,z1][m]=0 } } neighbor }

4). 推荐算法


UserBasedRecommender<-function(uid,n,M,S,N){
row<-ncol(N)
col<-ncol(M)
r<-matrix(0, row, col)
N1<-N[uid,]
for(z1 in 1:length(N1)){
num<-intersect(which(M[uid,]==0),which(M[N1[z1],]!=0)) #可计算的列
#     print(num)

for(z2 in num){
#       print(paste("for:",z1,N1[z1],z2,M[N1[z1],z2],S[uid,N1[z1]]))
r[z1,z2]=M[N1[z1],z2]*S[uid,N1[z1]]
}
}

sum<-colSums(r)
s2<-matrix(0, 2, col)
for(z1 in 1:length(N1)){
num<-intersect(which(colSums(r)!=0),which(M[N1[z1],]!=0))
for(z2 in num){
s2[1,][z2]<-s2[1,][z2]+S[uid,N1[z1]]
s2[2,][z2]<-s2[2,][z2]+1
}
}

s2[,which(s2[2,]==1)]=10000
s2<-s2[-2,]

r2<-matrix(0, n, 2)
rr<-sum/s2
item <-dimnames(M)[[2]]
for(z1 in 1:n){
w<-which.max(rr)
if(rr[w]>0.5){
r2[z1,1]<-item[which.max(rr)]
r2[z1,2]<-as.double(rr[w])
rr[w]=0
}
}
r2
}

5). 运行程序


FILE<-"testCF.csv"
NEIGHBORHOOD_NUM<-2
RECOMMENDER_NUM<-3

M<-FileDataModel(FILE)
S<-EuclideanDistanceSimilarity(M)
N<-NearestNUserNeighborhood(S,NEIGHBORHOOD_NUM)

R1<-UserBasedRecommender(1,RECOMMENDER_NUM,M,S,N);R1
##      [,1]  [,2]  
## [1,] "104" "4.25"
## [2,] "106" "4"   
## [3,] "0"   "0" 

R2<-UserBasedRecommender(2,RECOMMENDER_NUM,M,S,N);R2
##      [,1]  [,2]
## [1,] "105" "3.95699903407931"
## [2,] "0"   "0"
## [3,] "0"   "0"

R3<-UserBasedRecommender(3,RECOMMENDER_NUM,M,S,N);R3
##      [,1]  [,2]
## [1,] "103" "3.18540697329411"
## [2,] "102" "2.80243217111765"
## [3,] "0"   "0"

R4<-UserBasedRecommender(4,RECOMMENDER_NUM,M,S,N);R4
##      [,1]  [,2]
## [1,] "102" "3" 
## [2,] "0"   "0" 
## [3,] "0"   "0"

R5<-UserBasedRecommender(5,RECOMMENDER_NUM,M,S,N);R5
##      [,1] [,2]
## [1,]    0    0
## [2,]    0    0
## [3,]    0    0

3. 算法实现的原理–矩阵变换

所谓协同过滤算法,其实就是矩阵变换的结果!!请大家下面留意矩阵操作!
1). 原始数据

 1,101,5.0
  1,102,3.0
  1,103,2.5
  2,101,2.0
  2,102,2.5
  2,103,5.0
  2,104,2.0
  3,101,2.5
  3,104,4.0
  3,105,4.5
  3,107,5.0
  4,101,5.0
  4,103,3.0
  4,104,4.5
  4,106,4.0
  5,101,4.0
  5,102,3.0
  5,103,2.0
  5,104,4.0
  5,105,3.5
  5,106,4.0 

2). 矩阵转换

 101 102 103 104 105 106 107
[1,] 5.0 3.0 2.5 0.0 0.0   0   0
[2,] 2.0 2.5 5.0 2.0 0.0   0   0
[3,] 2.5 0.0 0.0 4.0 4.5   0   5
[4,] 5.0 0.0 3.0 4.5 0.0   4   0
[5,] 4.0 3.0 2.0 4.0 3.5   4   0 

3). 欧氏相似矩阵转换

 [,1]      [,2]      [,3]      [,4]      [,5]
[1,] 0.0000000 0.6076560 0.2857143 1.0000000 1.0000000
[2,] 0.6076560 0.0000000 0.6532633 0.5568464 0.7761999
[3,] 0.2857143 0.6532633 0.0000000 0.5634581 1.0000000
[4,] 1.0000000 0.5568464 0.5634581 0.0000000 1.0000000
[5,] 1.0000000 0.7761999 1.0000000 1.0000000 0.0000000 

4). 最近邻矩阵

 top1 top2
[1,]    4    5
[2,]    5    3
[3,]    5    2
[4,]    1    5
[5,]    1    3 

5). 以R1为例的推荐矩阵

 101  102  103  104  105  106  107
   4    0    0    0  4.5  0.0    4    0
   5    0    0    0  4.0  3.5    4    0 

6). 以R1为例的推荐结果

 推荐物品  物品得分
[1,] "104"    "4.25"
[2,] "106"    "4" 

4. 算法总结

我这里只是用R语言现实了Mahout的基于“用户的”,“欧氏距离”,“最近邻”的协同过滤算法。实现过程中发现,Mahout做各种算法时,都有自己的优化。

比如,算欧氏距离时,并不是标准的

similar = 1/(1+sqrt( (a-b)2 + (a-c)2 ))

而是改进的算法

similar = n/(1+sqrt( (a-b)2 + (a-c)2 )) 
  1. n为b,c的个数
  2. similar>1 => similar=1
  3. similar<-1 => similar=-1

从而更能优化结果。

5. 参考资料:

  1. Mahout In Action
  2. Mahout Source Code
  3. R help

转载请注明出处:
http://blog.fens.me/r-mahout-usercf/

打赏作者

为什么要开发@晒粉丝应用!

logo

从业互联网,软件行业已经多年,疲于做各种的项目、系统。原本走软件架构方向,基于SOA的各种系统集成解决方案。后来又投入互联网在高并发,大数据的背景下,做了云计算,SaaS等。一路跟着时代发展的脚步在前进。

现在的SNS,电子商务,微薄,博客等等的各种网络应用,都已经大众化,积累了大量的用户数据。这些数据怎么处理,便成为下一阶段要考虑的问题。@晒粉丝的应用,其实对于我来说是建立一个数据挖掘算法的运行平台。我会分析数据,但我没有能力采集数据,也没有能力存储数据。微博的开放平台,正好为我提供了一个采集数据和存储数据的平台,我可以专心做算法,解决数据的事情。

大家都知道算法有很多种,有数学,概率,统计的基础理论算法,也有计算世界里的排序算法,数据结构算法,ACM的各种算法,还是一些智能的算法,贝叶斯,神经网络,聚类等。这么多的算法,怎么用来处理微博的数据?其实我也并没有太多的经验,但我愿意努力去尝试。我希望从微博粉丝这个小点开始,发掘微博内在的关系。

晒粉丝的平台,也主要是以我个人的知识去构建的,按照以下的过程执行。

 

  1.  通过每个访问者的微博行为,进行数据采集。
  2.  设计算法模型,对每种数据集进行数据分析。
  3.  通过各种开源算法库去完成计算。
  4.  进行可视化的输出,返回用户能看得懂的数据。

 

这个应用开始只有简简单单地几个功能,粉丝云,粉丝微博年龄,认证比例。。。主要是为了搭建平台前期铺垫。之后会尽我的知识所学,发现微博的各种秘密!!

如果你使用了这个应用,谢谢你的支持。

如果你能提出你的宝贵意见,我会更加高兴!

现在只是刚开始,一切都会更好的!!