Python でデータ整理と度数分布表からヒストグラムの作成

統計

データ分析をするうえで重要なのが、データがどのような状態なのかを確認することです。

確認方法として一般的なのが、データの種類の確認、度数分布表とヒストグラムですね。

この記事はこんな人におすすめ。

  • データの種類について確認したい。
  • 度数分布表の作り方を知りたい。
  • ヒストグラムの作り方を知りたい。

プログラミング無料体験はこちら↓↓↓


データって何?情報との違いは?

データってなんとなく数字の塊だと思っていたのですが、実際はそれだけでないんですね。

データとは、行動を決定または、結論付けるための「事実」または「資料」です。

そしてデータは、数字の羅列や文章、そしてその両方など様々な形態があり、一目見ただけでは意思決定の役に立たないものも数多くあります。

データと似ているものには情報があります。

情報は加工されたデータで、そこから意思決定に必要な情報を抽出できる「事実」または「資料」になります。

つまりデータと情報の違いは、事実や資料から意思決定ができるかどうかにあります。

巷でよく言われる「データを活用して意思決定に反映」の意味は「データを加工し情報を抜き出して意思決定に反映させる」という意味なんです。

そして、データを加工し情報を抜き出すために使われる技術が「統計」と言われるものになります。

ちなみに、「データ(data)」は英語では複数形であり、その単数形は「datum」。

ラテン語起源の言葉ですね。

データを整理する前に

統計的にデータを整理する前にまず、いくつかの統計用語を知っておく必要があります。

統計を使ってデータや情報についての話をする際の、共通の言語になるので普段使わない言葉ですが、覚えておいてください。

母集団

母集団とは、自分が知りたい情報を持っていると推測される集団です。

簡単な例でいうと「男」「女」などです。

そしてこの母集団「男」の例で、どの年齢層に分類されるのか、どんな職業に分類されるのかを調べたい場合がありますよね。

その場合「年齢層」や「職業」を変量といい、それがどのように分布しているか、例えば20代が100人で30代が200人など、を母集団分布といいます。

この各変量の母集団分布は、母集団一人一人を調査すればできますが、母集団が100人ぐらいならともかく、1億人のような大量の数ではとても調査することができません。

そこで、行われるのが母集団から無作為に標本を一定数抽出し、その標本から母集団の特色を推測する、つまり「統計的推測を行う」ことが必要になります。

度数分布表

この統計的推測を行うために必要なのが、度数分布表ですが「質的変数」と「量的変数」の違いを分かって作らないと、情報として成り立たなくなってしまいます。

質的変量と量的変量の違い

質的変量とは何かというと、数字で表すことができないもの、例えば「好きな食べ物」「名前」「血液型」など。

好きな食べ物に対する答えは「ラーメン」や「寿司」など、数字では表すことができない答えになります。

反対に、量的変量は答えが数字で表すことができるもの。

例えば「身長や体重」「金額」「速度」「面積」など数字で表すことができるもの全てが、量的変量になりますね。

ではPythonを使って、実装してみましょう。

質的変量の度数分布表

例題で学ぶ統計入門で使われている、血液型の例を使って度数分布表を作成してみましょう。

標本数は50人で血液型が変量です。

当然血液型は数値ではありませんので、質的変量になりますね。

python に直接書き込んでもよかったんですが、CSVファイルで作成したものをPythonに読み込んでいます。

# DataFrameを扱うライブラリをインポート
import pandas as pd 

# CSVファイルの読み込み
qualitative_data = pd.read_csv("qualitative_variables.csv", encoding='shift-jis') 

# 読み込んだCSVファイルの表示
display(qualitative_data)

出力したDataFrameがこちら。

このデータをもとにヒストグラムを作ってみましょう。

まず、ヒストグラムを作りやすいように、DataFrameを少し加工します。

#index_col=0を加えることで、血液型をインデックスにする。
qualitative_data = pd.read_csv("qualitative_variables.csv", encoding='shift-jis', index_col=0) 

#計の行を削除
qualitative_data2 = qualitative_data.drop("計") 

display(qualitative_data)

この処理を行うことで、以下のように血液型をインデックスにすることができます。

これで、ヒストグラムを描いてみましょう。

import matplotlib.pyplot as plt # グラフ描写ライブラリのインポート
from matplotlib import rcParams # 辞書オブジェクトrcParamsをインポート
plt.rcParams["font.family"] = "MS Gothic" # rcParamsで日本語フォントMS Gothicを設定

plt.figure(figsize=(10, 5)) # ヒストグラムを出力、およびグラフのサイズを定義
x=qualitative_data2.index # x軸をqualitative_data2のインデックスで定義
y=qualitative_data2['度数'].values # y 軸をqualitative_data2['度数'].value で定義

plt.xlabel('血液型', fontsize=18) 
plt.ylabel('度数', fontsize=18)
plt.title('血液型の割合', fontsize=18)
plt.bar(x,y)
plt.grid()
plt.show()

できました。

量的変量の度数分布表

同じように、量的変量の度数分布表を見てみます。

こちらはサンプル数50人の身長をもとに作っています。

# CSVファイルの読み込み 
quantitative_data = pd.read_csv("quantitative_variables.csv", encoding='shift-jis') 

# 読み込んだCSVファイルの表示
display(quantitative_data)

これでDataFrameを出力すると以下になります。

このデータでも、ヒストグラムを書いてみましょう。

まずはDataFrameの整理。

#index_col=0を加えることで、階級をインデックスにする。
quantitative_data = pd.read_csv("quantitative_variables.csv", encoding='shift-jis', index_col=0) 

# 階級値を削除
quantitative_data2 = quantitative_data.drop("階級値", axis = 1) 

display(quantitative_data2)

この処理を行うことで、以下のように階級をインデックスにします。

このDataFrameをもとに、ヒストグラムを作成すると、

import matplotlib.pyplot as plt # グラフ描写ライブラリのインポート
from matplotlib import rcParams # 辞書オブジェクトrcParamsをインポート

plt.rcParams["font.family"] = "MS Gothic" # rcParamsで日本語フォントMS Gothicを設定
plt.figure(figsize=(10, 5)) # ヒストグラムを出力、およびグラフのサイズを定義

x=quantitative_data2.index
y=quantitative_data2['度数'].values
plt.xlabel('階級', fontsize=18)
plt.ylabel('度数', fontsize=18)
plt.title('身長の分布', fontsize=18)
plt.bar(x,y)
plt.grid()
plt.show()

では次にエクセルデータの読み込みから、度数分布表作成とヒストグラムの描画を行ってみます。

必要なモジュールとデータセットの読み込み

度数分布表を書くためにまず必要なのが、データと必要なモジュールの読み込みです。

データは「例題で学ぶ統計入門」の救急車の出動回数を使ってみました。

度数分布表を書くために必要なモジュールは以下の二つ。

  • pandas: 数表および時系列データ解析用
  • numpy: 数値計算

これらモジュールをインポート後、データファイルを読み込みます。

import pandas as pd 
import numpy as np 

# データファイル(CSVファイル)の読みこみ
ambulance = pd.read_excel('ambulance.xlsx')
ambulance.head()

先頭の5行だけを抽出しています。

年月日をインデックスに設定

次に後々便利なので、読み込んだデータの列をset_index()関数を使って、「年月日」の列をインデックスにします。

ambulance = ambulance.set_index('年月日')
ambulance.head()

要約統計量を取得

とりあえずデータの内容がどうなっているのか知りたいので、describe()関数を使って、基本統計量を表示します。

ambulance.describe()

ここから見えることは、

  • count: 40 サンプルサイズ40日間
  • mean: 2.05 期間中の平均出動数
  • std: 1.299 標準偏差
  • min: 0 最小値
  • max: 5 最大値

と、基本的なデータの情報を知ることができます。

度数分布表を作る

ではさっそく、度数分布表を作っていきましょう。

スタージェスの公式から階級の数を求める

度数分布表を作る際に、一つの列にサンプルが何個入るかを決める階級の数を決める必要があります。

なんとなく勘で決めるのも、分析っぽくないので階級の数を決めるスタージェスの公式を使って決めます。

スタージェスの公式:

この公式をデータに当てはめる前に、DataFrameの数値をndarrayオブジェクトに変換します。

dispach = np.array(ambulance['出動回数'])

次に度数分布表の作成まで一気にやってしまいます。

コードはこちらのページを参考にしました。

def frequency_distribution(data, class_width=None):
    data = np.asarray(data)
    if class_width is None:
        class_size = 1 + int(np.log2(data.size).round())
        class_width = round((data.max()- data.min())/class_size)
        
    bins = np.arange(0, data.max()+class_width+1, class_width)
    hist = np.histogram(data,bins)[0]
    cumsum = hist.cumsum()
    
    return pd.DataFrame({'階級値': (bins[1:] + bins[:-1])/2,
                        '度数': hist, 
                        '累積度数': cumsum,
                        '相対度数': hist/cumsum[-1],
                        '累積相対度数': cumsum/cumsum[-1]},
                        index=pd.Index([f'{bins[i]}以上{bins[i+1]}未満'
                                       for i in range(hist.size)],
                                       name='階級'))

frequency_distribution(dispach)

度数分布表の完成です。

では度数分布表をヒストグラムで描いてみましょう。

必要なモジュールは描画モジュールmatplotlib です。

from matplotlib import pyplot as plt # 描画モジュールのインポート
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.hist(dispach, bins = 6, histtype = 'barstacked', ec = 'black')
plt.show()

実行すると、以下のヒストグラムが完成しました。

プログラミング無料体験はこちら↓↓↓


関連記事↓↓↓

https://paython-iot.com/2021/05/29/variance-standard-deviation/
https://paython-iot.com/2021/05/26/python-mean/

コメント

タイトルとURLをコピーしました