欠損値を補完する一般的な方法は平均値補完(mean imputation) です。ある列に欠損値(NaN)が存在する場合に、その列の値の平均値を欠損値(NaN)と置き換えるというものです。
このように補完する時はscikit-learnのSimpleImputerクラスを利用すると簡単に補完できます。
欠損値(NaN)が含まれている以下の3つの列の欠損値を補完します。
身長(cm)
体重(kg)
視力
まず身長(cm)に平均値を補完し、その後体重(kg)には中央値、視力には最頻値を補完します。
中央値とはデータの集合の中で真ん中に位置する値のことをさします。最頻値とはデータの集合の中で一番頻繁に現れる値を指します。
※ 非数(NaN)として、numpy.nan を使っています。
import pandas as pd
df = pd.read_csv('./input/data1.csv')
# 全データの表示
df
import numpy as np
from sklearn.impute import SimpleImputer
# 欠損値(NaN) に対して 平均値(mean) を割り当てるSimpleImputerオブジェクトを生成
imp = SimpleImputer(missing_values=np.nan, strategy="mean")
# データセットの学習
imp.fit(df[["身長(cm)"]])
# strategy="mean"に基づいて欠損値(NaN)を平均値に置き換える
values = imp.transform(df[["身長(cm)"]])
# DataFrameに変換したデータを代入する
df[["身長(cm)"]] = values
df
# 欠損値(NaN) に対して 中央値(median) を割り当てるImputerオブジェクトを生成
imp = SimpleImputer(missing_values=np.nan, strategy="median")
# データセットの学習 + strategy="median"に基づいて欠損値(NaN)を中央値に置き換える
values = imp.fit_transform(df[["体重(kg)"]])
# DataFrameに変換したデータを代入する
df[["体重(kg)"]] = values
df
# 欠損値(NaN) に対して 最頻値(most_frequent) を割り当てるImputerオブジェクトを生成
imp = SimpleImputer(missing_values=np.nan, strategy="most_frequent")
# データセットの学習 + strategy="most_frequent"に基づいて欠損値(NaN)を最頻値に置き換える
values = imp.fit_transform(df[["視力"]])
# DataFrameに変換したデータを代入する
df[["視力"]] = values
df
欠損値がある列をそれぞれ以下のように補完できましたね。
- 身長(cm)・・・平均値で補完
- 体重(kg)・・・中央値で補完
- 視力・・・最頻値で補完
これでデータを不必要に失わずに済み、解析に適したデータを用意する手段を学べました
SimpleImputer
解説
SimpleImputerは指定した欠損値(missing_value引数)をstrategy引数に応じて補完するクラスです。
fitメソッドで補完するための元となるトレーニングデータセットを学習し、transformメソッドでstrategry引数に応じた補完処理を実行します。
from sklearn.impute import SimpleImputer
# 欠損値(NaN)に対して平均値(mean)を補完するSimpleImputerオブジェクト
imp = SimpleImputer(missing_values=np.nan, strategy="mean")
# トレーニングデータセットの学習
imp.fit(df[["身長(cm)"]])
# 欠損値(NaN)に平均値を補完する
values = imp.transform(df[["身長(cm)"]])
print(values)
# 欠損値のあった箇所に平均値165が補完されている
# => array([
# [ 176.], [ 170.], [ 165.], [ 148.], [ 164.],
# [ 170.], [ 165.], [ 178.], [ 163.], [ 151.]
# ])
strategy
引数によって補完方法を変更できます。以下の3つが指定できます。
mean
… 平均値の補完median
… 中央値の補完most_frequent
… 最頻値の補完
体重
と視力
のところで写経したように、fit
とtransform
を一度に実行するfit_transform
メソッドなどもあります。
SimpleImputer
クラスにaxis=1
という引数を指定すれば行
方向にも補完処理ができます。
# 各行に欠損値があるDataFrameの生成
df = pd.DataFrame({
"A": [1, None, 3],
"B": [4, 5, None],
"C": [None, 8, 9]
})
# 各行のデータの「平均値」を補完するSimpleImputerオブジェクト
imp = SimpleImputer(missing_values=np.nan, strategy="mean", axis=1)
# トレーニングデータの学習と補完処理
values = imp.fit_transform(df)
# 各行の欠損値に平均値がセットされている
print(values)
# => [
# [ 1. 4. 2.5]
# [ 6.5 5. 8. ]
# [ 3. 6. 9. ]
# ]
コメント