1. デシル分析

複雑な分析では説明時に処理内容を理解してもらえなくて拒否反応を受けることがあります。

簡単で誰でも理解しやすい分析が必要です。

デシル分析は簡単なのでだれでも理解でき使い勝手が良い分析です。

この記事ではデシル分析をpandasのqcutで実装します。

2. データ準備

sklearnのBostonデータを使用します。pandas.DataFrameに変換しておきます。

create_dataframe.py
import pandas as pd
from sklearn.datasets import load_boston

data = load_boston()
boston = pd.DataFrame(
    data.data,
    columns=data.feature_names
)

3. qcutでビニング処理

犯罪率:CRIMをqcutで離散化します。

q=オプションで分割数を指定します。今回はデシル分析なので10分割です。

qcut_example.py
pd.qcut(
    boston.CRIM,
    q=10,
)

4. bostonデータフレームにビニング処理結果の変数を追加

assignを使用してビニング処理結果の変数をデータフレームに追加します。

add_variable.py
boston = (
    boston
    .assign(
        CRIM_decile=lambda x: (
            pd.qcut(
                x.CRIM,
                q=10
            )
        )
    )
)

5. ビニング結果を使用してgroupby分析

ビニング処理結果を使用して分析します。

犯罪率のビニング結果とCHAS:(川沿いかどうか)の関係を確認します。

ビニング結果別のデータ数(count)、CHAS数(sum)、そしてCHAS率(mean)を確認しています。

groupby_analysis.py
CHAS_CRIM = (
    boston
    .groupby('CRIM_decile')
    .agg(
        N=('CHAS', 'count'),
        CHAS_sum=('CHAS', 'sum'),
        CHAS_mean=('CHAS', 'mean'),
    )
)
CHAS_CRIM
output
                    N  CHAS_sum  CHAS_mean
CRIM_decile
(0.00532, 0.0382]  51       1.0   0.019608
(0.0382, 0.0642]   51       4.0   0.078431
(0.0642, 0.0992]   50       1.0   0.020000
(0.0992, 0.15]     51       4.0   0.078431
(0.15, 0.257]      50       3.0   0.060000
(0.257, 0.55]      51       6.0   0.117647
(0.55, 1.728]      50       5.0   0.100000
(1.728, 5.581]     51       7.0   0.137255
(5.581, 10.753]    50       4.0   0.080000
(10.753, 88.976]   51       0.0   0.000000

犯罪率と川沿い率にきれいな直線関係とは言えませんが何かしらの関係性はあるかもしれないことがわかります。

6. まとめ

qcutでデシル分析を実装しました。

紹介したすべてのコードをまとめておきます。

groupby_analysis.py
import pandas as pd
from sklearn.datasets import load_boston

data = load_boston()
boston = pd.DataFrame(
    data.data,
    columns=data.feature_names
)

pd.qcut(
    boston.CRIM,
    q=10,
)

boston = (
    boston
    .assign(
        CRIM_decile=lambda x: (
            pd.qcut(
                x.CRIM,
                q=10
            )
        )
    )
)

CHAS_CRIM = (
    boston
    .groupby('CRIM_decile')
    .agg(
        N=('CHAS', 'count'),
        CHAS_sum=('CHAS', 'sum'),
        CHAS_mean=('CHAS', 'mean'),
    )
)
CHAS_CRIM