我正在尝试在Scala中构建一个功耗分析工具。特别是,我正在尝试创建一个函数,它确实返回所需的样本大小给定一些限制(统计功效,效果大小,两个样本大小之间的比率,显着性水平和我们想要运行的假设检验的类型)
我写了以下代码:
import org.apache.commons.math3.analysis.UnivariateFunction
import org.apache.commons.math3.analysis.solvers.BrentSolver
import org.apache.commons.math3.distribution.NormalDistribution
import scala.math._
object normal_sample_size extends App {
val theta1 = 0.0025
val theta2 = theta1 * 1.05
val split = 0.50
val power = 0.80
val significance = 0.05
val alternative = "two sided"
val result = requiredSizeCalculationNormal(effectSizeCalculation(theta1, theta2), split, power, significance, alternative)
println(result)
def effectSizeCalculation(mu1: Double, mu2: Double): Double = {
2 * math.asin(math.sqrt(mu1)) - 2 * math.asin(math.sqrt(mu2))
}
def requiredSizeCalculationNormal(effect_size: Double, split_ratio: Double, power: Double, significance: Double, alternative: String): Unit = {
if (alternative == "two sided") {
val z_score = new NormalDistribution().inverseCumulativeProbability(significance / 2.0)
val func = new UnivariateFunction {def value(n: Double) = (1 - new NormalDistribution().cumulativeProbability(z_score.abs - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))) +
new NormalDistribution().cumulativeProbability(z_score - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))}
val solver = new BrentSolver()
try {solver.solve(500, func, 0.001, 1000000)} catch {case _:Throwable => None}
} else if (alternative == "less") {
//val z_score = new NormalDistribution().inverseCumulativeProbability(significance)
//new NormalDistribution().cumulativeProbability(z_score - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))
} else if (alternative == "greater") {
//val z_score = new NormalDistribution().inverseCumulativeProbability(significance).abs
//1 - new NormalDistribution().cumulativeProbability(z_score - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))
} else {
println("Error message: Specify the right alternative. Possible values are 'two sided', 'less', 'greater'")
}
}
}
requiredSizeCalculationNormal()
识别哪种类型的假设检验正在处理(“双面”,“更大”或“更少”),然后计算所需的样本量。最后一点是我在努力的地方!使用Brent的方法(来自math3库)我想找到解决函数的n的值。
通过代码,只关注我的函数的“双面”部分(我将在第二阶段完成“更大”和“更少”),我试图创建一个名为{{1的函数}}。然后使用命令func
我试图使用最多500次迭代并在区间(0.001,1000000)内解决它。不幸的是,该命令既不返回结果也不返回错误消息。
编辑:我已从try {solver.solve(500, func, 0.001, 1000000)} catch {case _:Throwable => None}
上面引用的代码中删除了(无论如何都是多余的)。这段代码实际上是捕获所有异常并且不对它们执行任何操作。
我看到运行代码的例外是:
//catch {case _:Throwable => None}
所以问题似乎是函数在指定的时间间隔内没有改变符号。