我使用 scipy skewnorm 创建一个带有loc和scale的偏斜分布。
我根据Adelchi Azzalini的页面(Here is link)调整传递给scipy.stats.skewnorm的loc和scale,使用该页面底部的部分"平均值&# 34;和" delta"。
我使用的代码是:
-
但是,当我运行它时,我没有得到我期望的意思,而stdev就是我所期望的:
import math
import scipy.stats
skew = -2
mean = 0.05
stdev = 0.05
delta = skew / math.sqrt(1. + math.pow(skew, 2.))
adjMean = mean - stdev * math.sqrt(2. / math.pi) * delta
adjStdev = math.sqrt(math.pow(stdev, 2.) / (1. - 2. * math.pow(delta, 2.) / math.pi))
print 'target mean={:.4f} actual mean={:.4f}'.format(mean, float(scipy.stats.skewnorm.stats(skew, loc=adjMean, scale=adjStdev, moments='mvsk')[0]))
print 'target stdev={:.4f} actual stdev={:.4f}'.format(stdev, math.sqrt(float(scipy.stats.skewnorm.stats(skew, loc=adjMean, scale=adjStdev, moments='mvsk')[1])))
我觉得我错过了关于skewnorm或scipy.stats.skewnorm ...
我已经在数字上整合了分布,而且平均值匹配"实际均值"上方。
答案 0 :(得分:1)
你有一个代数错误。
adjMean = mean - stdev * math.sqrt(2. / math.pi) * delta
但在右侧,stdev
应为adjStdev
。
以下是您的代码的修改版本:
import math
import scipy.stats
skew = 2.0
mean = 1.5
stdev = 3.0
delta = skew / math.sqrt(1. + math.pow(skew, 2.))
adjStdev = math.sqrt(math.pow(stdev, 2.) / (1. - 2. * math.pow(delta, 2.) / math.pi))
adjMean = mean - adjStdev * math.sqrt(2. / math.pi) * delta
print('target mean={:.4f} actual mean={:.4f}'.format(mean, float(scipy.stats.skewnorm.stats(skew, loc=adjMean, scale=adjStdev, moments='mvsk')[0])))
print('target stdev={:.4f} actual stdev={:.4f}'.format(stdev, math.sqrt(float(scipy.stats.skewnorm.stats(skew, loc=adjMean, scale=adjStdev, moments='mvsk')[1]))))
这是输出:
target mean=1.5000 actual mean=1.5000
target stdev=3.0000 actual stdev=3.0000