statistics —数理統計関数
バージョン3.4の新機能。
ソースコード: :source: `Lib / statistics.py`
このモジュールは、数値(実数値)データの数学的統計を計算するための関数を提供します。
このモジュールは、 NumPy 、 SciPy などのサードパーティライブラリ、またはMinitab、SAS、Matlabなどのプロの統計家を対象とした独自のフル機能の統計パッケージと競合することを意図したものではありません。 。 グラフ電卓や関数電卓のレベルを対象としています。
特に明記されていない限り、これらの関数は int 、 float 、 Decimal 、および Fraction をサポートします。 他のタイプ(数値タワー内かどうかに関係なく)での動作は現在サポートされていません。 タイプが混在するコレクションも未定義であり、実装に依存します。 入力データが混合タイプで構成されている場合は、 map()を使用して、一貫した結果を保証できる場合があります(例:map(float, input_data)
)。
中央の場所の平均と測定
これらの関数は、母集団またはサンプルから平均値または標準値を計算します。
mean()
|
データの算術平均(「平均」)。 |
fmean()
|
高速浮動小数点算術平均。 |
geometric_mean()
|
データの幾何平均。 |
harmonic_mean()
|
データの調和平均。 |
median()
|
データの中央値(中央値)。 |
median_low()
|
データの中央値が低い。 |
median_high()
|
データの中央値が高い。 |
median_grouped()
|
グループ化されたデータの中央値、つまり50パーセンタイル。 |
mode()
|
離散データまたは名目データのシングルモード(最も一般的な値)。 |
multimode()
|
離散データまたは名目データのモード(最も一般的な値)のリスト。 |
quantiles()
|
データを等しい確率で間隔に分割します。 |
広がりの尺度
これらの関数は、母集団またはサンプルが標準値または平均値からどれだけ逸脱する傾向があるかの尺度を計算します。
pstdev()
|
データの母標準偏差。 |
pvariance()
|
データの母分散。 |
stdev()
|
データのサンプル標準偏差。 |
variance()
|
データのサンプル分散。 |
機能詳細
注:関数は、それらに与えられたデータをソートする必要はありません。 ただし、読みやすくするために、ほとんどの例ではソートされたシーケンスを示しています。
- statistics.mean(data)
data のサンプル算術平均を返します。これは、シーケンスまたは反復可能です。
算術平均は、データの合計をデータポイントの数で割ったものです。 これは一般に「平均」と呼ばれますが、多くの異なる数学的平均の1つにすぎません。 これは、データの中央の場所の尺度です。
data が空の場合、 StatisticsError が発生します。
使用例:
>>> mean([1, 2, 3, 4, 4]) 2.8 >>> mean([-1.0, 2.5, 3.25, 5.75]) 2.625 >>> from fractions import Fraction as F >>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)]) Fraction(13, 21) >>> from decimal import Decimal as D >>> mean([D("0.5"), D("0.75"), D("0.625"), D("0.375")]) Decimal('0.5625')
- statistics.fmean(data)
data を浮動小数点数に変換し、算術平均を計算します。
これは mean()関数よりも高速に実行され、常に float を返します。 data は、シーケンスまたは反復可能です。 入力データセットが空の場合、 StatisticsError が発生します。
>>> fmean([3.5, 4.0, 5.25]) 4.25
バージョン3.8の新機能。
- statistics.geometric_mean(data)
data を浮動小数点数に変換し、幾何平均を計算します。
幾何平均は、値の積を使用してデータの中心傾向または典型的な値を示します(それらの合計を使用する算術平均とは対照的です)。
入力データセットが空の場合、ゼロが含まれている場合、または負の値が含まれている場合は、 StatisticsError を発生させます。 data は、シーケンスまたは反復可能です。
正確な結果を達成するために特別な努力はなされていません。 (ただし、これは将来変更される可能性があります。)
>>> round(geometric_mean([54, 24, 36]), 1) 36.0
バージョン3.8の新機能。
- statistics.harmonic_mean(data)
data の調和平均、実数値のシーケンスまたは反復可能値を返します。
調和平均は、サブコントラリー平均と呼ばれることもあり、データの逆数の算術 mean()の逆数です。 たとえば、 a 、 b 、 c の3つの値の調和平均は、
3/(1/a + 1/b + 1/c)
と同等になります。 値の1つがゼロの場合、結果はゼロになります。調和平均は平均の一種であり、データの中心的な位置の尺度です。 速度などの速度や比率を平均化する場合に適していることがよくあります。
車が時速40kmで10km走行し、次に時速60kmでさらに10km走行するとします。 平均速度はどれくらいですか?
>>> harmonic_mean([40, 60]) 48.0
投資家が、株価収益率(P / E(価格/収益))が2.5、3、および10で、3つの会社のそれぞれで等しい価値の株式を購入するとします。 投資家のポートフォリオの平均株価収益率はどれくらいですか?
>>> harmonic_mean([2.5, 3, 10]) # For an equal investment portfolio. 3.6
StatisticsError は、 data が空の場合、またはいずれかの要素がゼロ未満の場合に発生します。
現在のアルゴリズムは、入力でゼロに遭遇すると早期終了します。 これは、後続の入力の有効性がテストされないことを意味します。 (この動作は将来変更される可能性があります。)
バージョン3.6の新機能。
- statistics.median(data)
一般的な「中間2の平均」メソッドを使用して、数値データの中央値(中央値)を返します。 data が空の場合、 StatisticsError が発生します。 data は、シーケンスまたは反復可能にすることができます。
中央値は中央値のロバストな尺度であり、外れ値の存在による影響が少なくなります。 データポイントの数が奇数の場合、中央のデータポイントが返されます。
>>> median([1, 3, 5]) 3
データポイントの数が偶数の場合、中央値は2つの中間値の平均を取ることによって補間されます。
>>> median([1, 3, 5, 7]) 4.0
これは、データが離散的であり、中央値が実際のデータポイントではない可能性がある場合に適しています。
データが順序(順序操作をサポート)であるが数値ではない(加算をサポートしない)場合は、代わりに median_low()または median_high()の使用を検討してください。
- statistics.median_low(data)
数値データの中央値の低い値を返します。 data が空の場合、 StatisticsError が発生します。 data は、シーケンスまたは反復可能にすることができます。
低い中央値は常にデータセットのメンバーです。 データポイントの数が奇数の場合、中央の値が返されます。 偶数の場合、2つの中間値のうち小さい方が返されます。
>>> median_low([1, 3, 5]) 3 >>> median_low([1, 3, 5, 7]) 3
データが離散的であり、中央値を内挿ではなく実際のデータポイントにする場合は、低い中央値を使用します。
- statistics.median_high(data)
データの中央値の高い値を返します。 data が空の場合、 StatisticsError が発生します。 data は、シーケンスまたは反復可能にすることができます。
高い中央値は常にデータセットのメンバーです。 データポイントの数が奇数の場合、中央の値が返されます。 偶数の場合、2つの中間値の大きい方が返されます。
>>> median_high([1, 3, 5]) 3 >>> median_high([1, 3, 5, 7]) 5
データが離散的であり、中央値を内挿ではなく実際のデータポイントにする場合は、高い中央値を使用します。
- statistics.median_grouped(data, interval=1)
補間を使用して、50パーセンタイルとして計算されたグループ化された連続データの中央値を返します。 data が空の場合、 StatisticsError が発生します。 data は、シーケンスまたは反復可能にすることができます。
>>> median_grouped([52, 52, 53, 54]) 52.5
次の例では、データが丸められているため、各値はデータクラスの中点を表します。 1はクラス0.5〜1.5の中点、2は1.5〜2.5の中点、3は2.5〜3.5の中点などです。 与えられたデータでは、中間値はクラス3.5〜4.5のどこかにあり、補間を使用してそれを推定します。
>>> median_grouped([1, 2, 2, 3, 4, 4, 4, 4, 4, 5]) 3.7
オプションの引数 interval はクラス間隔を表し、デフォルトは1です。 クラス間隔を変更すると、当然、補間が変更されます。
>>> median_grouped([1, 3, 3, 5, 7], interval=1) 3.25 >>> median_grouped([1, 3, 3, 5, 7], interval=2) 3.5
この関数は、データポイントが少なくとも間隔離れているかどうかをチェックしません。
- statistics.mode(data)
離散または名目上のデータから最も一般的な単一のデータポイントを返します。 モード(存在する場合)は最も一般的な値であり、中央の場所の尺度として機能します。
同じ周波数のモードが複数ある場合は、 data で最初に検出されたモードを返します。 代わりに、それらの最小または最大が必要な場合は、
min(multimode(data))
またはmax(multimode(data))
を使用してください。 入力 data が空の場合、 StatisticsError が発生します。mode
は離散データを想定し、単一の値を返します。 これは、学校で一般的に教えられているモードの標準的な扱いです。>>> mode([1, 1, 2, 3, 3, 3, 3, 4]) 3
このモードは、このパッケージで名目(非数値)データにも適用される唯一の統計であるという点で独特です。
>>> mode(["red", "blue", "blue", "red", "green", "red", "red"]) 'red'
バージョン3.8で変更:最初に検出されたモードを返すことにより、マルチモーダルデータセットを処理するようになりました。 以前は、複数のモードが見つかったときに StatisticsError が発生していました。
- statistics.multimode(data)
data で最初に検出された順序で最も頻繁に発生する値のリストを返します。 複数のモードがある場合は複数の結果を返し、 data が空の場合は空のリストを返します。
>>> multimode('aabbbbccddddeeffffgg') ['b', 'd', 'f'] >>> multimode('') []
バージョン3.8の新機能。
- statistics.pstdev(data, mu=None)
母標準偏差(母分散の平方根)を返します。 引数およびその他の詳細については、 pvariance()を参照してください。
>>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) 0.986893273527251
- statistics.pvariance(data, mu=None)
data の母分散、空でないシーケンス、または実数値の反復可能値を返します。 分散、または平均に関する2次モーメントは、データの変動性(広がりまたは分散)の尺度です。 大きな分散は、データが分散していることを示します。 小さな分散は、平均の周りに密集していることを示します。
オプションの2番目の引数 mu が指定されている場合、それは通常、データの平均です。 また、平均ではない点の周りの2次モーメントを計算するために使用することもできます。 欠落している場合、または
None
(デフォルト)の場合、算術平均が自動的に計算されます。この関数を使用して、母集団全体からの分散を計算します。 サンプルから分散を推定するには、通常、 Variance()関数の方が適しています。
data が空の場合、 StatisticsError を発生させます。
例:
>>> data = [0.0, 0.25, 0.25, 1.25, 1.5, 1.75, 2.75, 3.25] >>> pvariance(data) 1.25
データの平均をすでに計算している場合は、オプションの2番目の引数 mu としてデータを渡して、再計算を回避できます。
>>> mu = mean(data) >>> pvariance(data, mu) 1.25
小数と分数がサポートされています:
>>> from decimal import Decimal as D >>> pvariance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")]) Decimal('24.815') >>> from fractions import Fraction as F >>> pvariance([F(1, 4), F(5, 4), F(1, 2)]) Fraction(13, 72)
ノート
母集団全体で呼び出されると、これにより母分散σ²が得られます。 代わりにサンプルで呼び出された場合、これはバイアスされたサンプル分散s²であり、N自由度の分散としても知られています。
どういうわけか真の母平均μがわかっている場合は、この関数を使用してサンプルの分散を計算し、既知の母平均を2番目の引数として指定できます。 データポイントが母集団のランダムサンプルである場合、結果は母分散の偏りのない推定値になります。
- statistics.stdev(data, xbar=None)
サンプルの標準偏差(サンプルの分散の平方根)を返します。 引数およびその他の詳細については、 Variance()を参照してください。
>>> stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) 1.0810874155219827
- statistics.variance(data, xbar=None)
data のサンプル分散を返します。これは、少なくとも2つの実数値の反復可能です。 分散、または平均に関する2次モーメントは、データの変動性(広がりまたは分散)の尺度です。 大きな分散は、データが分散していることを示します。 小さな分散は、平均の周りに密集していることを示します。
オプションの2番目の引数 xbar が指定されている場合、それは data の平均である必要があります。 欠落している場合、または
None
(デフォルト)の場合、平均は自動的に計算されます。データが母集団からのサンプルである場合は、この関数を使用します。 母集団全体から分散を計算するには、 pvariance()を参照してください。
data の値が2未満の場合、 StatisticsError を発生させます。
例:
>>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5] >>> variance(data) 1.3720238095238095
データの平均をすでに計算している場合は、オプションの2番目の引数 xbar としてデータを渡して、再計算を回避できます。
>>> m = mean(data) >>> variance(data, m) 1.3720238095238095
この関数は、実際の平均を xbar として渡したことを確認しようとはしません。 xbar に任意の値を使用すると、無効または不可能な結果が生じる可能性があります。
10進値と小数値がサポートされています。
>>> from decimal import Decimal as D >>> variance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")]) Decimal('31.01875') >>> from fractions import Fraction as F >>> variance([F(1, 6), F(1, 2), F(5, 3)]) Fraction(67, 108)
ノート
これは、ベッセルの補正を使用したサンプル分散s²であり、N-1自由度の分散としても知られています。 データポイントが代表的なものである場合(例: 独立して同じように分布している場合)、結果は真の母分散の偏りのない推定値になるはずです。
実際の母平均μがどういうわけかわかっている場合は、それを pvariance()関数に mu パラメーターとして渡して、サンプルの分散を取得する必要があります。
- statistics.quantiles(data, *, n=4, method='exclusive')
データを n の連続区間に等しい確率で分割します。 間隔を区切る
n - 1
カットポイントのリストを返します。四分位数の場合は n を4に設定します(デフォルト)。 十分位数の場合は、 n を10に設定します。 パーセンタイルの n を100に設定すると、データを100の等しいサイズのグループに分割する99のカットポイントが得られます。 n が1以上の場合、 StatisticsError を発生させます。
data は、サンプルデータを含む任意のイテラブルにすることができます。 意味のある結果を得るには、 data のデータポイントの数を n より大きくする必要があります。 少なくとも2つのデータポイントがない場合、 StatisticsError を発生させます。
カットポイントは、最も近い2つのデータポイントから線形補間されます。 たとえば、カットポイントが2つのサンプル値
100
と112
の間の距離の3分の1にある場合、カットポイントは104
と評価されます。分位数を計算するためのメソッドは、データが母集団から可能な最小値と最大値を含むか除外するかによって異なります。
デフォルトのメソッドは「排他的」であり、サンプルに見られるよりも極端な値を持つ可能性のある母集団からサンプリングされたデータに使用されます。 m でソートされたデータポイントの i番目を下回る母集団の部分は、
i / (m + 1)
として計算されます。 9つのサンプル値が与えられると、メソッドはそれらをソートし、次のパーセンタイルを割り当てます:10%、20%、30%、40%、50%、60%、70%、80%、90%。method を「包括的」に設定することは、母集団データを記述するため、または母集団からの最も極端な値を含むことがわかっているサンプルに使用されます。 data の最小値は0パーセンタイルとして扱われ、最大値は100パーセンタイルとして扱われます。 m でソートされたデータポイントの i番目を下回る母集団の部分は、
(i - 1) / (m - 1)
として計算されます。 11個のサンプル値が与えられると、メソッドはそれらをソートし、次のパーセンタイルを割り当てます:0%、10%、20%、30%、40%、50%、60%、70%、80%、90%、100%。# Decile cut points for empirically sampled data >>> data = [105, 129, 87, 86, 111, 111, 89, 81, 108, 92, 110, ... 100, 75, 105, 103, 109, 76, 119, 99, 91, 103, 129, ... 106, 101, 84, 111, 74, 87, 86, 103, 103, 106, 86, ... 111, 75, 87, 102, 121, 111, 88, 89, 101, 106, 95, ... 103, 107, 101, 81, 109, 104] >>> [round(q, 1) for q in quantiles(data, n=10)] [81.0, 86.2, 89.0, 99.4, 102.5, 103.6, 106.0, 109.8, 111.0]
バージョン3.8の新機能。
NormalDist オブジェクト
NormalDist は、確率変数の正規分布を作成および操作するためのツールです。 これは、データ測定値の平均と標準偏差を単一のエンティティとして扱うクラスです。
正規分布は中心極限定理から生じ、統計に幅広い用途があります。
- class statistics.NormalDist(mu=0.0, sigma=1.0)
新しい NormalDist オブジェクトを返します。ここで、 mu は算術平均を表し、シグマは標準偏差を表します。
sigma が負の場合、 StatisticsError が発生します。
- mean
正規分布の算術平均の読み取り専用プロパティ。
- median
正規分布の中央値の読み取り専用プロパティ。
- mode
正規分布のモードの読み取り専用プロパティ。
- stdev
正規分布の標準偏差の読み取り専用プロパティ。
- variance
正規分布の分散の読み取り専用プロパティ。 標準偏差の2乗に等しい。
- classmethod from_samples(data)
fmean()および stdev()[を使用してデータから推定された mu および sigma パラメーターを使用して正規分布インスタンスを作成します。 X155X]。
data は、任意の iterable にすることができ、タイプ float に変換できる値で構成する必要があります。 data に少なくとも2つの要素が含まれていない場合、中心値を推定するのに少なくとも1ポイント、分散を推定するのに少なくとも2ポイントかかるため、 StatisticsError が発生します。
- samples(n, *, seed=None)
指定された平均と標準偏差に対して n ランダムサンプルを生成します。 float 値の list を返します。
seed が指定されている場合、基になる乱数ジェネレーターの新しいインスタンスを作成します。 これは、マルチスレッドのコンテキストでも再現可能な結果を作成するのに役立ちます。
- pdf(x)
確率密度関数(pdf)を使用して、確率変数 X が指定された値 x に近づく相対尤度を計算します。 数学的には、 dx がゼロに近づくときの比率
P(x <= X < x+dx) / dx
の限界です。相対尤度は、狭い範囲でサンプルが発生する確率を範囲の幅で割ったものとして計算されます(したがって、「密度」という言葉が使用されます)。 尤度は他のポイントに関連しているため、その値は 1.0 より大きくなる可能性があります。
- cdf(x)
累積分布関数(cdf)を使用して、確率変数 X が x 以下になる確率を計算します。 数学的には、
P(X <= x)
と書かれています。
- inv_cdf(p)
分位関数またはパーセントポイント関数とも呼ばれる逆累積分布関数を計算します。 数学的には、
x : P(X <= x) = p
と書かれています。確率変数 X の値 x を見つけて、変数がその値以下になる確率が指定された確率 p と等しくなるようにします。
- overlap(other)
2つの正規確率分布間の一致を測定します。 0.0から1.0までの値を返し、 2つの確率密度関数の重複領域を指定します。
- quantiles(n=4)
正規分布を n の連続区間に等しい確率で分割します。 間隔を区切る(n-1)個のカットポイントのリストを返します。
四分位数の場合は n を4に設定します(デフォルト)。 十分位数の場合は、 n を10に設定します。 パーセンタイルの n を100に設定すると、正規分布を100の等しいサイズのグループに分割する99のカットポイントが得られます。
NormalDist のインスタンスは、定数による加算、減算、乗算、除算をサポートしています。 これらの操作は、変換とスケーリングに使用されます。 例えば:
>>> temperature_february = NormalDist(5, 2.5) # Celsius >>> temperature_february * (9/5) + 32 # Fahrenheit NormalDist(mu=41.0, sigma=4.5)
NormalDist のインスタンスによる定数の除算は、結果が正規分布されないためサポートされていません。
正規分布は独立変数の相加効果から生じるため、 NormalDist のインスタンスとして表される2つの独立した正規分布確率変数を加算および減算することができます。 例えば:
>>> birth_weights = NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]) >>> drug_effects = NormalDist(0.4, 0.15) >>> combined = birth_weights + drug_effects >>> round(combined.mean, 1) 3.1 >>> round(combined.stdev, 1) 0.5
バージョン3.8の新機能。
NormalDist 例とレシピ
NormalDist は、古典的な確率の問題を簡単に解決します。
たとえば、 SAT試験の履歴データが、スコアが通常平均1060、標準偏差195で分布していることを示している場合、テストスコアが1100〜1200の学生の割合を、四捨五入後に決定します。最も近い整数:
>>> sat = NormalDist(1060, 195)
>>> fraction = sat.cdf(1200 + 0.5) - sat.cdf(1100 - 0.5)
>>> round(fraction * 100.0, 1)
18.4
>>> list(map(round, sat.quantiles()))
[928, 1060, 1192]
>>> list(map(round, sat.quantiles(n=10)))
[810, 896, 958, 1011, 1060, 1109, 1162, 1224, 1310]
解析的に解くのが容易ではないモデルの分布を推定するために、 NormalDist はモンテカルロシミュレーションの入力サンプルを生成できます。
>>> def model(x, y, z):
... return (3*x + 7*x*y - 5*y) / (11 * z)
...
>>> n = 100_000
>>> X = NormalDist(10, 2.5).samples(n, seed=3652260728)
>>> Y = NormalDist(15, 1.75).samples(n, seed=4582495471)
>>> Z = NormalDist(50, 1.25).samples(n, seed=6582483453)
>>> quantiles(map(model, X, Y, Z))
[1.4591308524824727, 1.8035946855390597, 2.175091447274739]
正規分布は、サンプルサイズが大きく、試行が成功する確率が50%に近い場合に、二項分布を近似するために使用できます。
たとえば、オープンソース会議には750人の参加者と500人収容の2つの部屋があります。 PythonとRubyについての話があります。 以前の会議では、参加者の65 % o fがPythonの講演を聞くことを好みました。 人口の好みが変わっていないと仮定すると、Pythonルームが容量制限内にとどまる確率はどれくらいですか?
>>> n = 750 # Sample size
>>> p = 0.65 # Preference for Python
>>> q = 1.0 - p # Preference for Ruby
>>> k = 500 # Room capacity
>>> # Approximation using the cumulative normal distribution
>>> from math import sqrt
>>> round(NormalDist(mu=n*p, sigma=sqrt(n*p*q)).cdf(k + 0.5), 4)
0.8402
>>> # Solution using the cumulative binomial distribution
>>> from math import comb, fsum
>>> round(fsum(comb(n, r) * p**r * q**(n-r) for r in range(k+1)), 4)
0.8402
>>> # Approximation using a simulation
>>> from random import seed, choices
>>> seed(8675309)
>>> def trial():
... return choices(('Python', 'Ruby'), (p, q), k=n).count('Python')
>>> mean(trial() <= k for i in range(10_000))
0.8398
正規分布は通常、機械学習の問題で発生します。
ウィキペディアには、単純ベイズ分類器の良い例があります。 課題は、身長、体重、足のサイズなどの正規分布の特徴の測定値から人の性別を予測することです。
8人の測定値を含むトレーニングデータセットが提供されます。 測定値は正規分布であると想定されているため、 NormalDist でデータを要約します。
>>> height_male = NormalDist.from_samples([6, 5.92, 5.58, 5.92])
>>> height_female = NormalDist.from_samples([5, 5.5, 5.42, 5.75])
>>> weight_male = NormalDist.from_samples([180, 190, 170, 165])
>>> weight_female = NormalDist.from_samples([100, 150, 130, 150])
>>> foot_size_male = NormalDist.from_samples([12, 11, 12, 10])
>>> foot_size_female = NormalDist.from_samples([6, 8, 7, 9])
次に、特徴の測定値はわかっているが性別は不明な新しい人物に遭遇します。
>>> ht = 6.0 # height
>>> wt = 130 # weight
>>> fs = 8 # foot size
男性または女性である50%事前確率から始めて、性別が与えられた場合の特徴測定の尤度の積の事前時間として事後確率を計算します。
>>> prior_male = 0.5
>>> prior_female = 0.5
>>> posterior_male = (prior_male * height_male.pdf(ht) *
... weight_male.pdf(wt) * foot_size_male.pdf(fs))
>>> posterior_female = (prior_female * height_female.pdf(ht) *
... weight_female.pdf(wt) * foot_size_female.pdf(fs))
最終的な予測は、最大の後方に行きます。 これは、最大事後確率またはMAPとして知られています。
>>> 'male' if posterior_male > posterior_female else 'female'
'female'