1. 地味に悩む度数分布の作成

データを与えられてまずはじめに確認したいのが度数分布

データの概要を把握するために度数分布は有用。

でも、いざ度数分布を作ろうと思ったときに地味に悩みどころがあります

悩みどころやニーズ
  • 多変数について全部一括で度数分布を作成したい

  • 全変数の度数分布を作成してどのようなフォーマットで出力するか?

  • 様々な尺度の変数が混在(数値型orカテゴリ型or etc)

  • 要素数(cardinality:カーディナリティ)が多い変数だと出力が膨大になる

新しいデータに遭遇するたびに毎回悩みがちで無駄な時間なので、このへんでしっかりと度数分布の作成方法を整理します。

2. 度数分布の出力フォーマット

検討して導き出した度数分布の出力フォーマットのサンプルが下記。

Table 1. 出力フォーマット
Variable Value Count Proportion

CRIM

(-0.08360000000000001, 8.903]

439.0

0.8675889328063241

CRIM

(8.903, 17.8]

44.0

0.08695652173913043

CRIM

(17.8, 26.697]

14.0

0.02766798418972332

CRIM

(35.594, 44.491]

3.0

0.005928853754940711

CRIM

(44.491, 53.388]

2.0

0.003952569169960474

CRIM

(80.079, 88.976]

1.0

0.001976284584980237

CRIM

(71.182, 80.079]

1.0

0.001976284584980237

CRIM

(62.285, 71.182]

1.0

0.001976284584980237

CRIM

(26.697, 35.594]

1.0

0.001976284584980237

プログラム上の扱い易さを考慮して度数分布はpandas.DataFrame型で出力します。

DataFrameならcsvファイルにエクスポートすることも簡単です。

1列目に変数名、2列目に値、3列目に件数、4列目に構成比。

このフォーマットで多変数の度数分布を一括で扱うことが可能です。

またDataFrame型なのでgroupbyとheadを使用することで要素数が多い場合に出力が膨大になってしまう問題も解決することが可能です。

3. 度数分布を作成するために使用するメソッド:value_counts

value_countsは使用することが多いので馴染み深いメソッドです。

でも、普段はあまり意識していなかったけど便利なオプションがあるのでこれらを整理して利用していきます。

特に多変数の度数分布を出力する場合に重要なオプションは下記の3つです。

重要なオプション
  1. bins=10

  2. dropna=False

  3. normalize=True

これらのオプションを使いこなすことで効率的の度数分布を作成できます。

3.1. sort=True

sort=Trueを指定することでカテゴリの件数順に出力します。

データ概要を把握するときには件数の多いカテゴリ、あるいは件数の少ないカテゴリから確認したいのでsort=Trueを指定します。

当然ながら不要な場合はsort=False。

3.2. ascending=False

ascending=Falseを指定することでカテゴリ数の降順で出力します。

はじめは件数の多いカテゴリから確認したいことが多いので、ascending=False。

また、レアケースのカテゴリを確認したい場合はascending=True。

3.3. bins=10

このオプションは私も有効活用できていませんでしたが便利です。

数値型の変数の場合にbins数に分割して離散化してくれます。

このオプションを使用することで数値型の変数が混在していても問題なく度数分布を作成できます。

3.4. dropna=False

欠損値も含めて集計します。データの確認では欠損値も重要なのでFalse。

デフォルトではTrueとなっているのでFalseを明示的に指定する必要があります。

3.5. normalize=True

構成比を出力します。件数だけでなく構成比の確認も大事。

件数と構成比の両方を確認したいのでTrueを指定した場合とFalseをした場合の2パターンでvalue_countsを実行します。

最終的には上記2パターンの出力結果をマージして1つの度数分布表に仕上げます。

4. applyとlambda : 全変数に対してvalue_counts

全変数に対してvalue_countsするために、applyとlambdaを使用します。

使用例
count = X.apply(
    lambda x: x.value_counts(
        sort=True,
        ascending=False,
        bins=10,
        dropna=False,
    )
)

5. applyの結果を1つにまとめる:.T.stack().reset_index()

applyの結果は各変数の度数分布が別々なので1つのデータにまとめます

使用するのは .T.stack().reset_index()

使用例
count = X.apply(
    lambda x: x.value_counts(
        sort=True,
        ascending=False,
        bins=10,
        dropna=False,
    )
).T.stack().reset_index()

6. 度数分布を作成する関数を定義

全変数に対して度数分布を作成する関数を定義します。

frequency_table.py
def frequency_table(
    X,
    sort=True,
    ascending=False,
    bins=10,
    dropna=False,
):
    count = X.apply(
        lambda x: x.value_counts(
            sort=sort,
            ascending=ascending,
            bins=bins,
            dropna=dropna,
        )
    ).T.stack().reset_index()
    count.columns = ['Variable', 'Value', 'Count']
    count['Proportion'] = X.apply(
        lambda x: x.value_counts(
            sort=sort,
            ascending=ascending,
            bins=bins,
            dropna=dropna,
            normalize=True,
        )
    ).T.stack().to_numpy()
    return count

7. 使用例:jupyter notebook

使用例としてjupyter notebookを作成しました。

8. まとめ

使用頻度が高いのにどのように実装すべきか悩みがちな度数分布の作成方法をまとめました。

今回は以上です。