web-dev-qa-db-ja.com

Pythonでリストの分散を計算するにはどうすればよいですか?

このようなリストがある場合:

results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
          0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]

このリストの分散をPythonで計算します。これは平均からの差の二乗の平均です。

これについてどうすればいいですか?リスト内の要素にアクセスして計算を行うと、平方差を取得するのが混乱します。

14
minks

Numpyの組み込み関数 var を使用できます。

import numpy as np

results = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
          0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]

print(np.var(results))

これにより、28.822364260579157

-何らかの理由でnumpyを使用できない場合、および/または組み込み関数を使用したくない場合は、たとえば「手動」で計算することもできます。 リスト内包表記

# calculate mean
m = sum(results) / len(results)

# calculate variance using a list comprehension
var_res = sum((xi - m) ** 2 for xi in results) / len(results)

同じ結果が得られます。

標準偏差に興味がある場合は、 numpy.std を使用できます:

print(np.std(results))
5.36864640860051

@ Serge Ballestaは非常にうまく説明しました 分散nn-1。 numpyでは、オプションddof;を使用してこのパラメーターを簡単に設定できます。デフォルトは0、したがってn-1単純にできる場合:

np.var(results, ddof=1)

「手で」解決策は @ Serge Ballestaの答え で与えられます。

どちらのアプローチでも32.024849178421285

stdにもパラメーターを設定できます。

np.std(results, ddof=1)
5.659050201086865
39
Cleb

さて、分散を定義するには2つの方法があります。フルセットがある場合に使用する分散nと分散n-1サンプルがあるときに使用します。

2の違いは、値m = sum(xi) / nが実際の平均なのか、それとも平均値の近似値なのかということです。

例1:クラスの生徒の平均身長とその分散を知りたい:ok、値m = sum(xi) / nは実際の平均であり、Clebによって与えられた式はok(variancen)。

例2:バス停でバスが通過する平均時間とその変動を知りたいとします。 1か月の時間を記録し、30個の値を取得します。ここで、値m = sum(xi) / nは実際の平均の近似にすぎず、その近似はより多くの値でより正確になります。その場合、実際の分散の最適な近似は分散ですn-1

varRes = sum([(xi - m)**2 for xi in results]) / (len(results) -1)

OK、Pythonとは関係ありませんが、統計分析に影響があり、質問には statistics および variance というタグが付けられています

注:通常、numpyなどの統計ライブラリは、varまたはvarianceと呼ばれるものに分散nを使用し、標準偏差を与える関数の分散n-1

7
Serge Ballesta

Python 3.4から、標準ライブラリには variance 関数(サンプルの分散またはが付属しています statistics モジュールの一部としての分散n-1):

from statistics import variance
# data = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439, 0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
variance(data)
# 32.024849178421285

p人口分散(またはvariance n)は pvariance 関数を使用して取得できます:

from statistics import pvariance
# data = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439, 0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
pvariance(data)
# 28.822364260579157

リストの平均がすでにわかっている場合、varianceおよびpvariance関数は2番目の引数(それぞれxbarおよびmu)を順番に取ることに注意してください(分散計算の一部である)サンプルの平均を再計算するための予備。

2
Xavier Guihot

実際、Numpyは最もエレガントで高速な方法です。

実際の質問は、リストの個々の要素にアクセスしてそのような計算を自分で行う方法についてだったと思うので、以下の例:

results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
      0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]

import numpy as np
print 'numpy variance: ', np.var(results)


# without numpy by hand  

# there are two ways of calculating the variance 
#   - 1. direct as central 2nd order moment (https://en.wikipedia.org/wiki/Moment_(mathematics))divided by the length of the vector
#   - 2. "mean of square minus square of mean" (see https://en.wikipedia.org/wiki/Variance)

# calculate mean
n= len(results)
sum=0
for i in range(n):
    sum = sum+ results[i]


mean=sum/n
print 'mean: ', mean

#  calculate the central moment
sum2=0
for i in range(n):
    sum2=sum2+ (results[i]-mean)**2

myvar1=sum2/n
print "my variance1: ", myvar1

# calculate the mean of square minus square of mean
sum3=0
for i in range(n):
    sum3=sum3+ results[i]**2

myvar2 = sum3/n - mean**2
print "my variance2: ", myvar2

あなたにあげる:

numpy variance:  28.8223642606
mean:  -3.731599805
my variance1:  28.8223642606
my variance2:  28.8223642606
1
roadrunner66

正解はNumPyのようなパッケージの1つを使用することですが、自分でロールバックしたい場合や、段階的に実行したい場合は、より正確なアルゴリズムがあります。このリンクを参照してください https://www.johndcook.com/blog/standard_deviation/

Perlの実装をPythonに移植しました。コメントで問題を指摘してください。

Mklast = 0
Mk = 0
Sk = 0
k  = 0 

for xi in results:
  k = k +1
  Mk = Mklast + (xi - Mklast) / k
  Sk = Sk + (xi - Mklast) * ( xi - Mk)
  Mklast = Mk

var = Sk / (k -1)
print var

答えは

>>> print var
32.0248491784
0
Mark Lakata
import numpy as np
def get_variance(xs):
    mean = np.mean(xs)
    summed = 0
    for x in xs:
        summed += (x - mean)**2
    return summed / (len(xs) - 1)
print(get_variance([1,2,3,4,5]))

アウト2.5

a = [1,2,3,4,5]
variance = np.var(a, ddof=1)
print(variance)
0
sim