[参考] 統計学における「変数」とは:
例えば、数学のテストの点数や辛いものの好き嫌いを考えましょう。これらは人それぞれで違う値をとります。 それを統計学では『変数』と呼んでいます。数学テストの点数」という変数は、人によって例えば80点, 60点, 75点などの値をとります。これらの値は大小比較ができますので、量的変数といいます。
それに対し、『辛いものの好き嫌い』も人それぞれで違う値をとりますが、『好き』『嫌い』『どちらでもない』の3種類に値が分けられるでしょう。このように「種類(カテゴリ)」による分類を値とする変数は質的変数と言います。 </blockquote> ここでは数値要約に焦点をあてます。数値要約とは、データの持つ特徴を一つの数値にまとめる、ということで、後で取り上げる平均や中央値がその代表的なものです。
ここで、変数の種類に二通りあることに注意してください。
- 質的変数: データを分類したもの(例: 男/女、好き/嫌い)を値とする。またその値(分類)をカテゴリという。
- 量的変数: データが数で表され、データの種類ではなく、その値の大小(数量)に意味がある。
量的変数ではその値の範囲の分類 (例えば、値が100未満、100以上200未満、200以上、のように分類する)や、質的変数では、その値であるカテゴリをとりあげましょう。 それぞれの分類(カテゴリ)に含まれるデータの個数を調べることはよく行われています。 それぞれの分類に含まれるデータの個数を度数といい、すべての分類について度数を求めたものを度数分布といいます。
質的データや、量的データでも値が離散型のデータにおいて、そのデータの値とそれが現れる度数(頻度)をまとめたものを度数分布といい、それを表で表したものを度数分布表といいます。例えば、80名の学生の物理学の成績をS, A, B, C, Dの5ランクに分けたとき、それぞれのランクの人数の分布は度数分布といえます。
成績のランク | S | A | B | C | D |
---|---|---|---|---|---|
度数 | 3 | 5 | 28 | 34 | 10 |
これはもともと次のような分布の成績でした:
Buturi = ["D", "B", "C", "B", "D", "B", "D", "C", "C", "C", "S", "C", "A", "B", "B", "C", "B", "C",
"S", "B", "A", "A", "C", "B", "B", "C", "B", "B", "C", "B", "C", "A", "B", "C", "D", "C", "B", "C",
"D", "C", "D", "D", "C", "C", "B", "B", "C", "C", "B", "C", "B", "D", "C", "B", "C", "C", "B", "A",
"B", "B", "B", "B", "B", "C", "C", "C", "B", "D", "C", "C", "B", "C", "C", "C", "C", "S", "C", "C",
"D", "B"]
このデータから度数分布表を作るには以下のようにします。まずButuriデータにはどのような値があるかをset関数を用いて調べます。
Grades = set(Buturi)
print(Grades)
dosu = { key: Buturi.count(key) for key in Grades} # 辞書として度数分布表を作る
print(dosu)
これをまとめてtableという関数を作っても良いかもしれません。
def table(lst):
return {key:lst.count(key) for key in set(lst)}
def table(lst):
return {key:lst.count(key) for key in set(lst)}
print(table(Buturi))
参考:ヒストグラムを書く
%matplotlib inline
import matplotlib.pyplot as plt
ind=range(len(dosu.keys()))
plt.bar(ind,dosu.values()) # 棒グラフを書く
plt.xticks(ind, dosu.keys()) # x座標にラベルを貼る
help(plt.bar)
実は、元をたどるとButuriは、次のような素点(100点満点で成績をつけたもの)から得られたものでした:
Seiseki =[59, 74, 64, 73, 59, 71, 57, 60, 68, 65, 99, 61, 86, 75, 78, 66, 73, 61, 91,
77, 87, 81, 64, 71, 71, 63, 72, 76, 66, 72, 67, 84, 73, 68, 57, 66, 74, 60, 52, 69, 54,
59, 65, 65, 71, 79, 64, 67, 73, 68, 70, 59, 64, 71, 61, 62, 74, 83, 77, 74, 75, 75, 75,
65, 65, 69, 73, 58, 69, 64, 75, 67, 68, 61, 62, 90, 69, 60, 57, 73]
先にあげた度数分布は、90点以上をS、80点以上90点未満をA, 70点以上80点未満をB、60点以上70点未満をC、60点未満をDとして分類し、それぞれの分類に該当する人数を表にしたものでした。ちなみに、S,A,B,C,Dは名義尺度の質的データです。
度数分布から、横軸にデータの分類を、縦軸にその度数を表すグラフを書いたものをヒストグラム(histogram)と言います。 Pythonでは matplotlibモジュールのhistという関数で表示させることができます。 これを実行して表示されるのが以下のグラフです。成績データを10個に分類し、それぞれの分類にはいる人数を縦軸に表示しています。何通りに分類されるかはコンピュータ任せですが、この場合は4.7点刻みで分類されています。
%matplotlib inline
import matplotlib.pyplot as plt
plt.hist(Seiseki)
histにはどこで分類するかをbinsオプションで指定することができます。次は50点(最小値)、60点、70点、80点、90点、100点(最大値)という分類範囲を指定したものです。この結果表示されるのが次のグラフです。
plt.hist(Seiseki,bins=(50,60,70,80,90,100))
help(plt.hist)
# 課題1-2.
Math = [17,13,14,7,12,10,6,8,15,4,14,9,6,10,12,5,12,8,8,12,15,18]
代表値とは、データを代表する値のことで、 後述しますが、データの分布の型が「正規分布である」というように分かっている場合はそのパラメタ(正規分布の場合は平均と分散)、そうでない場合はデータの分布の中心的な値が代表値となります。要約統計量ということもあります。
代表値としては、次の三つの値がよく使われます:
解答欄
random.randint(min,max)
により、min以上max以下の整数乱数が1個生成されます。
[ヒント] numpyモジュールには平均値を求める関数はありますが、中央値や最頻値を求める関数は用意されていません。Python3で使えるstatisticsモジュールにはあるかも...
# 課題1-4
help(random.randint)
# 参考: 一様分布に従う [0,1) の実数の乱数
help(random.random)
import numpy as np
data = np.array(data)
print("mean = %8.2f" % (data.mean()))
data.sort()
print(data)
散布度とは、変数の値の散らばりのことです。 どんなデータでも、平均だけではその特徴はわかりません。 平均のまわりにどのようにデータが散らばっているかも、データも性質を考える上でとても重要な情報です。
$n$はデータの個数, $x_1,\ldots,x_n$はデータ、$\mu$はその平均とします。 散布度を表すのによく使われる標本分散 (sample variance)の定義は以下のとおり: $$ 標本分散 = \frac{ (x_1 - \mu)^2 + (x_2 - \mu)^2 + \cdots + (x_n - \mu)^2 }{n} = \frac{1}{n}\sum_{i=1}^n (x_i-\mu)^2 $$ これに対し、不偏分散(unbiased variance) の定義は以下のとおりです: $$ 不偏分散 = \frac{ (x_1 - \mu)^2 + (x_2 - \mu)^2 + \cdots + (x_n - \mu)^2 }{n-1} = \frac{1}{n-1}\sum_{i=1}^n (x_i-\mu)^2 $$ 不偏分散の定義では、分母は(標本分散では$n$に対して) $n-1$ です。
標本分散と不偏分散の違いについて説明します。
標本分散は、手元にあるデータの「散らばり」を表す値です。
それに対し、不偏分散は、「手元にあるデータは何らかの大きなデータの集まり
(これを母集団といいます)から抽出したもの」と考え、
母集団のデータの散らばりを推定した値です。
そして、Pythonでは標本分散を計算するため、numpyモジュールに関数var
が用意されています。(不偏分散を求めるには ddof=1
というオプションが必要です )
参考: 母集団と標本(長い説明)
統計におけるとても重要な用語の一つが母集団です。まずはこれが何を意味しているか、例を使って説明します。母集団のおおまかな意味は「推測対象の要素の集まり」ということです。先ほどの「あなたが作った機械の製品」の例では、「その機械が将来にわたって作る製品の不良品の割合」が推測したいものでした。これは「作り出される製品すべて」と「その中の不良品すべて」が分かれば計算できます。そこで推測対象として「機械が作り出す製品(の良さ)」を考えましょう。そしてこの「製品(の良さ)」が母集団となります。もちろんこの中にはまだ存在していないものも含まれています。そこでこの場合、母集団の要素の個数は無限個とみなせます。このときの母集団を無限母集団といいます。このように、母集団の要素数が多かったり、実際には存在していないものだったりすることがあるので、母集団をそのまま扱うことは一般に難しいのです。この母集団に対して、標本(サンプル)という用語があります。先の機械の例で言えば、その機械で作られ、実際に手元にある製品100個(の良さの割合)が「標本」に相当します。このように、標本とは母集団の一部です。そして、統計学は、この標本(サンプル)の性質を調べることによって、母集団の性質を予測したり、比較したりする手段を与えてくれます。
別な例として選挙を例にします。大きな選挙があるたびに、新聞やテレビなどのメディアでは選挙結果の予測を行います。この予測はどのような方法で行われているのでしょうか。
この場合、母集団の要素は、選挙人それぞれによる投票結果といえます。人口200万人の名古屋市くらいの都市なら、選挙人(要するに投票権がある人)の総数は100万人以上いるでしょう。その人達一人ひとりに、どの政党に投票するかを聞いて回るのはとても大変ですし、お金もかかります。 そこで、メディアではランダムに電話をかけどの政党に投票するかを聞くという方法(Random Digit Sampling)をとっています。そうやって標本を集めます。およそ1千分の1から1万分の1くらいの人数、200万人ならば1,000人くらいを調査の対象としているようです。この場合は、機械の例と異なり、有限で実在する人たちの投票が母集団でした。投票そのものはまだ行われていないので母集団の要素は実在しませんが、そこにいる人達の考えがそのまま投票に反映されるとすれば、母集団は無限でも存在しない要素を含まないともみなせます。そこで、この母集団は有限母集団といえるでしょう。それでも、母集団をすべて調べるのではなく、標本の性質を調べることによって母集団の振る舞いを予測することが行われています。
このような扱いは残念ながら、統計学の教科書で一致していません。後で取り上げるz値や偏差値の計算には、標準偏差を標本分散の平方根とする方が扱いやすいからかもしれません。
ですから、他の統計学の本を読む場合には、分散と標準偏差の定義にまず気をつけてください。
各データの値から平均を引いたものを平均からの偏差といい、平均偏差とは、「平均からの偏差」の絶対値の平均で、平均からどの程度ずれているかを表す数値です。
また範囲(レンジ)とは、データの最大値と最小値の差のことで、データの値の変化の大きさを表します。
なお、平均偏差と紛らわしいのですが、標準偏差(standard deviation) は分散の正の平方根の値で、とても大事な指標です。Pythonのnumpyモジュールでは std という関数が用意されており、これは標本分散の平方根を返します(不偏分散の平方根としての標準偏差を求めるにはddof=1
というオプションをつける必要があります)。
[課題1-5のヒント] Pythonのnumpyモジュールには標本分散とその平方根(標準偏差)を計算するための関数があります。そして、 不偏分散とその平方根を求めるにはオプションを指定するか、標本分散とサンプルサイズを用いて計算する必要があります。
# 課題1-5
[課題1-6のヒント] 「データの要素の2乗の和」はPythonでは簡単に求められます。変数dataにnumpy.ndarray型のデータが入っているとすると、data**2で「データの要素の2乗」を要素とするベクトルが得られます。そして関数 sum によりその和を求めることができます。
# 課題1-6
data**2
z得点とは、平均が0、標準偏差が1になるよう変換した標準得点のことです。ただしここでは後述する偏差値と同様に、標準偏差は標本分散の平方根とします。 $$ z得点 = \frac{データの値 - 平均}{標準偏差}$$ また、平均が50、標準偏差が10になるよう変換した標準得点のことを偏差値といいます。偏差値とz得点の間には以下の関係が成り立ちます: $$偏差値 = z得点 * 10 + 50$$
from __future__ import division
import numpy as np
PsycTest = np.array( [13, 14, 7, 12, 10, 6, 8, 15, 4, 14, 9, 6, 10, 12, 5, 12, 8, 8, 12, 15] )
[課題1-7のヒント] 変数dataのデータをz得点に変換するためのアルゴリズムを書きます。
from __future__ import division
import numpy as np
PsycTest = np.array( [13, 14, 7, 12, 10, 6, 8, 15, 4, 14, 9, 6, 10, 12, 5, 12, 8, 8, 12, 15] )
# 課題1-7
注: 以下では numpyをnp, numpy.random を random, matplotlib.pyplotをpltと略記する
目的 | 関数名とモジュール | 使い方 |
---|---|---|
度数分布(「辞書」)の作成 | 自作 table (リスト) |
table(['A','B','A','C','B','C','C','B','C','D','A']) |
棒グラフの描画 | plt.bar(x座標リスト,y座標データ) | plt.bar(range(5),[20,3,5,8,1]) |
ヒストグラムの描画 | plt.hist(データ) | plt.hist([59, 74, 64, 73, 59, 71, 80]) |
合計(総和) | sum(リスト) もしくは np.sum(配列) | sum([1,2,3]), np.sum(np.array([1,2,3])) |
データの個数 | len(リスト) | len(['A','B','A','C','B','C','C','B','C','D','A']) |
平均を求める | np.mean(配列) | np.mean(np.array([[1,2,3],[3,2,5]])) |
標本分散を求める | np.var(配列) | np.var([59, 74, 64, 73, 59, 71, 80]) |
不偏分散を求める | np.var(配列, ddof=1) | np.var([59, 74, 64, 73, 59, 71, 80], ddof=1) |
標準偏差を求める | np.std(配列) もしくは np.std(配列, ddof=1) | np.std([59, 74, 64, 73, 59, 71, 80], ddof=1) |
絶対値を求める | abs(数) もしくは np.abs(数) | abs(-1.23) |
平方根を求める | 数**0.5 もしくは np.sqrt(数) | np.sqrt(2.0) |
最大値を求める | max(リスト) もしくは np.max(配列) | np.max([2,6,9,3,8]) |
最小値を求める | min(リスト) もしくは np.min(配列) | np.min([2,6,9,3,8]) |
一様乱数を生成(整数) | random.randint(m,n) : [m,n)の整数 | random.randint(1,7) : さいころの出目 |
一様乱数を生成([0,1)の実数) | random.random(個数) | random.random(10) : 10個の乱数生成 |
import numpy as np Auniv = np.array([60,100,50,40,50,230,120,240,200,30]) Buniv = np.array([50,60,40,50,100,80,30,20,100,120])
# 問題1-1(1)
# 問題1-1(2)
# 問題1-1(3)
20, 55, 30, 82, 75, 66, 40, 60, 50, 29, 81, 60, 88, 91, 86, 91, 99, 73, 42以下の質問に答えなさい。
# 問題1-2 (1)
# 問題1-2 (2)
# 問題1-2 (3)
# 問題1-2 (4)
# 問題1-2 (5)
問題1-2 (6)の解答欄
# 問題1-2 (7)