Pythonで平均、stdを与えられた正規分布で確率を計算する方法は?この質問のOPのような定義に従って、自分の関数をいつでも明示的にコーディングできます。 Pythonの分布における確率変数の確率の計算
ライブラリ関数呼び出しがあるかどうか疑問に思うだけで、これが可能になります。私の想像では、これは次のようになります:
nd = NormalDistribution(mu=100, std=12)
p = nd.prob(98)
Perlにも同様の質問があります: Perlの正規分布が与えられた時点で確率を計算するにはどうすればよいですか? 。しかし、私はPythonでそれを見ませんでした。
Numpy
にはrandom.normal
関数がありますが、これはサンプリングのようなもので、正確には必要ではありません。
scipy.stats に1つあります:
>>> import scipy.stats
>>> scipy.stats.norm(0, 1)
<scipy.stats.distributions.rv_frozen object at 0x928352c>
>>> scipy.stats.norm(0, 1).pdf(0)
0.3989422804014327
>>> scipy.stats.norm(0, 1).cdf(0)
0.5
>>> scipy.stats.norm(100, 12)
<scipy.stats.distributions.rv_frozen object at 0x928352c>
>>> scipy.stats.norm(100, 12).pdf(98)
0.032786643008494994
>>> scipy.stats.norm(100, 12).cdf(98)
0.43381616738909634
>>> scipy.stats.norm(100, 12).cdf(100)
0.5
[注意すべきことの1つは、単なるヒントですが、パラメーターの受け渡しが少し広いということです。コードの設定方法により、誤ってscipy.stats.norm(mean=100, std=12)
またはscipy.stats.norm(100, 12)
の代わりにscipy.stats.norm(loc=100, scale=12)
を記述した場合、それは受け入れられますが、それらの余分なキーワード引数は静かに破棄され、デフォルト(0,1)。]
Scipy.statsは素晴らしいモジュールです。別のアプローチを提供するために、次を使用して直接計算できます。
import math
def normpdf(x, mean, sd):
var = float(sd)**2
denom = (2*math.pi*var)**.5
num = math.exp(-(float(x)-float(mean))**2/(2*var))
return num/denom
これは、次の式を使用します。 http://en.wikipedia.org/wiki/Normal_distribution#Probability_density_function
テストする:
>>> normpdf(7,5,5)
0.07365402806066466
>>> norm(5,5).pdf(7)
0.073654028060664664
詳細 です。最初に、凍結分布を扱います(この場合、凍結分布とは、そのパラメーターが特定の値に設定されることを意味します)。凍結された配布を作成するには:
import scipy.stats
scipy.stats.norm(loc=100, scale=12)
#where loc is the mean and scale is the std dev
#if you wish to pull out a random number from your distribution
scipy.stats.norm.rvs(loc=100, scale=12)
#To find the probability that the variable has a value LESS than or equal
#let's say 113, you'd use CDF cumulative Density Function
scipy.stats.norm.cdf(113,100,12)
Output: 0.86066975255037792
#or 86.07% probability
#To find the probability that the variable has a value GREATER than or
#equal to let's say 125, you'd use SF Survival Function
scipy.stats.norm.sf(125,100,12)
Output: 0.018610425189886332
#or 1.86%
#To find the variate for which the probability is given, let's say the
#value which needed to provide a 98% probability, you'd use the
#PPF Percent Point Function
scipy.stats.norm.ppf(.98,100,12)
Output: 124.64498692758187
Python 3.8
から、標準ライブラリは NormalDist
モジュールの一部として statistics
オブジェクトを提供します。
確率密度関数( pdf
-ランダムサンプルXが特定のmean(mu
)および標準偏差(sigma
):
from statistics import NormalDist
NormalDist(mu=100, sigma=12).pdf(98)
# 0.032786643008494994
また、NormalDist
オブジェクトは累積分布関数(cdf
-ランダムサンプルXはx以下です):
NormalDist(mu=100, sigma=12).cdf(98)
# 0.43381616738909634
回答に記載されているウィキペディアから引用された式は、通常の確率を計算するために使用することはできません。確率を計算するには、その式を使用して数値積分近似関数を作成する必要があります。
その式は、確率密度関数の値を計算します。正規分布は連続的であるため、確率を得るには積分を計算する必要があります。ウィキペディアのサイトでは、CDFについて言及していますが、CDFには正規配布用の閉じた形式はありません。
私はあなたのために数学をするためにこのプログラムを書きました。要約統計に入力するだけです。配列を提供する必要はありません:
これを比率ではなく平均で行うには、それに応じてzの式を変更します
website に記載されているように、数学ライブラリに組み込まれているエラー関数を使用できます。
X mean = 1の2つの値の間の面積を見つけたい場合。標準偏差= 2; [0.5,2]の間のxの確率
import scipy.stats
scipy.stats.norm(1, 2).cdf(2) - scipy.stats.norm(1,2).cdf(0.5)