by『前処理大全(第8章:数値型)』
内容:
- 8-7 数値型の補完(欠損値処理)
8-7 数値型の補完
欠損値種類:
- MCAR (Missing Completely At Random):
偶然に起きている完全にランダムな欠損。例えば、室温を測る温度センサーから送られてくるデータが一定の確率で破損する場合。 - MAR (Missing At Random):
欠損した項目データとは関係なく、他の項目データに依存した欠損。例えば、室温を測るセンサーから送られてくるデータが、湿度が高いほど破損する確率が高くなる場合。 - MNAR (Missing Not At Random):
欠損した項目データに依存した欠損。例えば、室温を測る温度センサーから送られてくるデータが40度を超えると破損する場合など。
※欠損値種類の詳細は、missing data analysis参照
欠損値保管方法:
- 定数による補完:
指定した定数のデータが極端に増えるので、データの分散が新の値よりずっと小さくなるなどの弊害がある。欠損値が多い場合は非推奨。 - 集計値による補完:
平均/中央/最小/最大値などで補完。指定した定数のデータが極端に増えるので、欠損値が多い場合は非推奨。 - 欠損していないデータに基づく予測値による補完:
機械学習モデルにより欠損値を予測して埋める。例えば、身長と体重の関係を分析し、体重から欠損している身長を予測し、補完する。 - 時系列の関係から補完:
欠損しているデータの前後のデータから欠損値を予測して補完する。例えば、10:01の温度データが欠けているときに、10:00の温度データと10:02の温度データの平均値を利用し、補完する。時間に対して連続している値が対象なら、MCAR, MARにおいて有効。 - 多重代入法:
補完したデータセットを複数作成し、そのそれぞれのデータセットに対して解析を行い、この複数の結果を統合することで、バイアスの少ない結果を得る。MCAR, MARにおいて有効。 - 最尤法:
潜在変数を導入し、EMアルゴリズムを用いて(補完した結果のデータが多変量正規分布に従うとした)尤度を最大化することで、欠損値を推定する。MCAR, MARにおいて有効。
EMアルゴリズムは、ここの学習ノートで復習
MCAR, MARにおいては、多重代入法または最尤法の利用が一般的。
例)欠損レコードの削除
製造レコードにおいて、thicknessが欠損しているレコードを削除する。
- SQL
SELECT
*
FROM
work.production_missn_tb
-- thicknessがnullのレコードを除外
WHERE
thickness is not NULL;- Python
# replace関数により、文字列'None'をnanに変換
# (Noneを指定する際には、文字列として指定する必要がある)
production_miss_num.replace('None', np.nan, inplace=True)
# dropna()で、thicknessにnanを含むレコードを削除
production_miss_num.dropna(subset=['thickness'], inplace=True)
例)定数補完
欠損しているthicknessを1の値で補完する。
- SQL
SELECT
type,
length,
-- thicknessの欠損値を1で補完
COALESCE(thickness, 1) AS thickness,
fault_flg
FROM
work.production_missn_tb;- Python
# replace()で、文字列'None'をnanに変換
production_miss_num.replace('None', np.nan, inplace=True)
# fillna()で、thicknessの欠損値を1で補完
production_miss_num['thickness'].fillna(1, inplace=True)
例)平均値補完
thicknessが欠損している製造レコードにおいて、欠損しているthicknessを欠損していないthicknessの平均値で補完する。
- SQL
SELECT
type,
length,
COALESCE(thickness,
(SELECT
AVG(thickness)
FROM
work.production_missn_tb)
) AS thickness,
fault_flg
FROM
work.production_missn_tb;- Python
# replace()で、文字列'None'をnanに変換
production_miss_num.replace('None', np.nan, inplace=True)
# thicknessを数値型に変換(Noneが混ざっているため数値型になっていない)
production_miss_num['thickness'] = \
production_miss_num['thickness'].astype('float64')
# thicknessの平均値を計算
thickness_mean = production_miss_num['thickness'].mean()
# thicknessの欠損値をthicknessの平均値で補完
production_miss_num['thickness'].fillna(thickness_mean, inplace=True)
例)PMMによる多重代入
thicknessに欠損が存在する製造レコードにおいて、欠損しているthicknessの値を多重代入法で補完する。
補:PMM (Predictive Mean Matching)のアルゴリズム
- 欠損データを除いたデータから欠損データを予測する回帰モデルを構築
- 構築した回帰モデルの係数と誤差分散の分布を計算
- 係数と誤差分散の分布から新たな係数と誤差分散の値を生成
- 3で生成した係数と誤差分散の値に従った回帰モデルから予測値を計算
- 欠損していない観測データの中から予測値に最も近いデータを補完値として採用
- データを補完して、新たに構築した回帰モデルの係数と誤差分散の分布を計算し、3に戻る
3〜6を補完する値の分布が安定するまで繰り返し、安定してから指定したデータセットの数分の補完値が得られたら終了。
- Python
from fancyimpute import MICE
# replace()により、文字列'None'をnanに変換
production_miss_num.replace('None', np.nan, inplace=True)
# mice関数を利用するためにデータ型を変換(mice関数内でモデル構築をするため)
production_miss_num['thickness'] = \
producition_miss_num['thickness'].astype('float64')
production_miss_num['type'] = \
production_miss_num['type'].astype('category')
production_miss_num['fault_flg'] = \
production_miss_num['fault_flg'].astype('category')
# ダミー変数化
production_dummy_flg = pg.get_dummies(
production_miss_num[['type', 'fault_flg']], drop_first=True)
# mice関数にPMMを指定して、多重代入法を実施
# n_imputationsは、取得するデータセットの数
# n_burn_inは、 値を取得する前に試行する回数
mice = MICE(n_imputations=10, n_burn_in=50, impute_type='pmm')
# 処理内部でTensorFlowを利用
production_mice = mice.multiple_imputations(
# 数値の列とダミー変数を連結
pd.concat([production_miss_num[['lenght', 'thickness']], production_dummy_flg], axis=1)
)
# 下記に補完する値が格納されている
production_mice[0]
MICEクラスは、multiple_imputations関数により多重代入法を実現する。m引数で多重代入法により補完する値のパターン数(取得するデータセットの数)を設定できる。maxit引数は、値を取得する前のモデル係数の更新回数を指定できる。method引数は、多重代入法の手法を指定でき、pmm以外にcolを指定できる。colを指定すると、事後予測分布のサンプリングした値の平均値を補完地として利用する。
MICE, KNNによる欠損値補完の詳細は、『MICE, KNNよる欠損値処理』ページ参照
0コメント