【Scala统计学系列】 Student‘s t-distribution t分布定义用法示例源码

Scala Student’s t-distribution t分布由来定义用法示例源码

由来

概率论和统计学中,学生t-分布(Student’s t-distribution)经常应用在对呈正态分布的总体的均值进行估计。它是对两个样本均值差异进行显著性测试的学生t测定的基础。t检定改进了Z检定(en:Z-test),不论样本数量大或小皆可应用。在样本数量大(超过30)时 [5],可以应用Z检定,但Z检定用在小的样本会产生很大的误差,因此样本很小的情况下得改用学生t检定。在数据有三组以上时,因为误差无法压低,此时可以用变异数分析代替学生t检定。

当母群体的标准差是未知的但却又需要估计时,可以使用学生t-分布。

学生t-分布可简称为t分布。其推导由威廉·戈塞于1908年首先发表,当时他还在都柏林的健力士酿酒厂工作。因为不能以他本人的名义发表,所以论文使用了学生(Student)这一笔名。之后t检验以及相关理论经由罗纳德·费雪的工作发扬光大,而正是他将此分布称为学生分布。

定义

由于在实际工作中,往往σ是未知的,常用s作为σ的估计值,为了与u变换区别,称为t变换,统计量t 值的分布称为t分布。 [1]

假设X服从标准正态分布N(0,1),Y服从 χ 2 ( n )  ⁣ \chi ^{2}(n)\! χ2(n)分布,那么 Z = X ( Y / n ) Z=\frac{X}{\sqrt(Y/n)} Z=( Y/n)X

的分布称为自由度为n的t分布,记为 Z Z Z ~ t(n)。

分布密度函数 在这里插入图片描述

其中,Gam(x)为伽马函数。

分布密度函数

img

正态分布以及不同自由度的t分布的概率密度函数

img

代码示例

package org.example.scala

object TStudentTest extends App{
  // 导入统计库
  import org.apache.commons.math3.distribution.TDistribution

  // 定义样本数据
  val sample = Array(1.0, 2.0, 3.0, 4.0, 5.0)

  // 创建学生t分布对象
  val tDist = new TDistribution(sample.length - 1)

  // 计算平均值和标准差
  val mean = sample.sum / sample.length // 计算样本的平均值
  val variance = sample.map(x => math.pow(x - mean, 2)).sum / (sample.length - 1) // 计算样本的方差
  val stdDev = math.sqrt(variance) // 计算样本的标准差

  // 计算置信区间
  val confidenceLevel = 0.95 // 置信水平
  val criticalValue = tDist.inverseCumulativeProbability(1 - (1 - confidenceLevel) / 2) // 根据自由度和置信水平计算临界值
  val marginOfError = criticalValue * stdDev / math.sqrt(sample.length) // 计算误差范围
  val lowerBound = mean - marginOfError // 置信区间下界
  val upperBound = mean + marginOfError // 置信区间上界

  // 计算t分布的CDF值
  val tcdfValue = tDist.cumulativeProbability(1.5)

  // 使用CDF值计算t分布的ICDF值
  val invtcdfValue= tDist.inverseCumulativeProbability(tcdfValue)


  // 打印结果
  println(s"样本平均值: $mean")
  println(s"样本标准差: $stdDev")
  println(s"置信水平: $confidenceLevel")
  println(s"临界值: $criticalValue")
  println(s"误差范围: $marginOfError")
  println(s"置信区间: [$lowerBound, $upperBound]")
  println("t分布的CDF值: " + tcdfValue)
  println("t分布的ICDF值: " + invtcdfValue)
//  样本平均值: 3.0
//  样本标准差: 1.5811388300841898
//  置信水平: 0.95
//  临界值: 2.7764451050184613
//  误差范围: 1.9632431613507502
//  置信区间: [1.0367568386492498, 4.96324316135075]
//  t分布的CDF值: 0.8960000000000001
//  t分布的ICDF值: 1.500000000000648
}

中文源码

/**
  * 学生t分布类
  *
  * @param degreesOfFreedom 自由度
  * @param randBasis 随机种子
  */
case class StudentsT(degreesOfFreedom: Double)(implicit randBasis: RandBasis = Rand) extends ContinuousDistr[Double] with Moments[Double, Double] with HasCdf {
  require(degreesOfFreedom > 0, "degreesOfFreedom must be positive, but got " + degreesOfFreedom)

  /**
    * 将对象转为字符串
    *
    * @return 对象的字符串表示
    */
  override def toString: String = ScalaRunTime._toString(this)

  private val innerInstance = new TDistribution(randBasis.generator, degreesOfFreedom, TDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY)

  /**
    * 从学生t分布中随机生成一个数值
    *
    * @return 随机生成的数值
    */
  def draw(): Double = {
    // TODO: for small DoF this seems a little wrong..., StudentsT is even worse though.
    // numpy version
    val N = randBasis.gaussian.draw()
    val G = new Gamma(degreesOfFreedom/2, 1.0).draw()
    val X = sqrt(degreesOfFreedom/2)*N/sqrt(G)
    X
  }

  /**
    * 计算指定区间上的概率密度函数值
    *
    * @param x 区间下界
    * @param y 区间上界
    * @return 指定区间上的概率密度函数值
    */
  override def probability(x: Double, y: Double): Double = {
    val t = new org.apache.commons.math3.distribution.TDistribution(degreesOfFreedom)
    t.probability(x, y)
  }

  /**
    * 计算指定值的累积分布函数值
    *
    * @param x 指定值
    * @return 指定值的累积分布函数值
    */
  def cdf(x: Double):Double = {
    val t = new org.apache.commons.math3.distribution.TDistribution(degreesOfFreedom)
    t.cumulativeProbability(x)
  }

  /**
    * 计算未归一化的概率密度函数值的对数
    *
    * @param x 指定值
    * @return 未归一化的概率密度函数值的对数
    */
  def unnormalizedLogPdf(x: Double): Double = -(degreesOfFreedom  + 1)/2 * math.log(1 + (x * x)/degreesOfFreedom)

  /**
    * 对数归一化常数
    */
  lazy val logNormalizer: Double = 0.5 * math.log(math.Pi * degreesOfFreedom) + lgamma(degreesOfFreedom / 2) - lgamma((degreesOfFreedom + 1)/2)

  /**
    * 计算均值
    *
    * @return 均值
    */
  def mean: Double = innerInstance.getNumericalMean

  /**
    * 计算方差
    *
    * @return 方差
    */
  def variance: Double = innerInstance.getNumericalVariance

  /**
    * 计算熵
    *
    * @return 熵
    */
  def entropy: Double = (
    (degreesOfFreedom + 1)/2 * (digamma((degreesOfFreedom + 1)/2) -  digamma(degreesOfFreedom))
      - .5 * log(degreesOfFreedom)
      + lbeta(degreesOfFreedom/2, 0.5)
  )

  /**
    * 计算众数
    *
    * @return 众数
    */
  def mode: Double = mean
}

/**
  * 学生t分布对象
  */
object StudentsT extends ContinuousDistributionUFuncProvider[Double,StudentsT]

om/2, 0.5)
)

/**
* 计算众数
*
* @return 众数
*/
def mode: Double = mean
}

/**

  • 学生t分布对象
    */
    object StudentsT extends ContinuousDistributionUFuncProvider[Double,StudentsT]

# [参考](https://baike.baidu.com/item/t%E5%88%86%E5%B8%83/299142)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值