Edited at

pythonでのデータ分析 欠損値の取扱い

More than 1 year has passed since last update.

備忘録です

機械学習による予測をするためには欠損値を取り扱う必要がある。


■欠損値を調べる


単純な調べ方

isnull() と sum() を組み合わせて調べる。


train_df.isnull().sum()

------------------
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
person 0
deck 687
family 0
dtype: int64


欠損値の割合・値のバリエーションを調べる

それぞれのカラム毎にどのくらいのnullが存在し、また値のバリエーションを調べてみる。

def null調べ(df):

for i in df.columns:
print("■■■ " + i )
print("NULL数:" + str(df[i].isnull().sum() )+
"    NULL率:" + str((df[i].isnull().sum()/len(df)).round(3)) +
" データの種類数:" + str(df[i].value_counts().count()))

null調べ(train_df)
----------------------
■■■ PassengerId
NULL:0    NULL:0.0 データの種類数:891
■■■ Survived
NULL:0    NULL:0.0 データの種類数:2
■■■ Pclass
NULL:0    NULL:0.0 データの種類数:3
■■■ Name
NULL:0    NULL:0.0 データの種類数:891
■■■ Sex
NULL:0    NULL:0.0 データの種類数:2
■■■ Age
NULL:177    NULL:0.199 データの種類数:88
■■■ SibSp
NULL:0    NULL:0.0 データの種類数:7
■■■ Parch
NULL:0    NULL:0.0 データの種類数:7
■■■ Ticket
NULL:0    NULL:0.0 データの種類数:681
■■■ Fare
NULL:0    NULL:0.0 データの種類数:248
■■■ Cabin
NULL:687    NULL:0.771 データの種類数:147
■■■ Embarked
NULL:2    NULL:0.002 データの種類数:3

これらで、null率が高いものを調べる


■欠損値の扱い

欠損値がどのような理由で生まれているかによって、アプローチが異なる

欠損に意味がないパターン

 MCAR(Missing completely) : ランダムな欠損

欠損が意味があるパターン

 MAR(Missing at random) :   データの他の特徴量に依存して欠損

 MNAR(Missing not at random) : 欠損となった値自体に依存して欠損

くわしくは機械学習のための欠損値処理まとめが参考になる


1 欠損値を単純に処理する(削除する、一意の値を入れる)

データ量が十分に確保できる場合は単純に削除でよい

data.dropna()   #nullが含まれる行を削除する

train_df.fillna(0) #nullに0をいれる


2 欠損値に値を補完する

データ量が少ない場合は単純に削除すると、データ量が減ってしまい、データがムダになる・妥当性にムラがでる。

そこで、削除するのではなく、なにかしらデータを補完する必要がでてくる。

それぞれデータを眺めたあと、どのような形で補完するかを決定するのがよい。


単純に平均値/最頻値を入れる

単純に平均値/最頻値をいれてしまう方法

train_df["Age"] = train_df["Age"].fillna(train_df["Age"].mean())

plt.hist(train_df_original["Age"].dropna(), alpha=0.2,color="r") #もともとのグラフを赤で描画
plt.hist(train_df["Age"],alpha=0.2,color="b") #平均値をいれたグラフを青で描画

image.png


平均からばらつきを考慮して補完する

平均値から標準偏差でばらつきを考慮して補完する

#平均・標準偏差・null数を取得する

Age_average = train_df["Age"].mean() #平均値
Age_std = train_df["Age"].std() #標準偏差
Age_nullcount = train_df["Age"].isnull().sum() #null値の数=補完する数

# 正規分布に従うとし、標準偏差の範囲内でランダムに数字を作る
rand = np.random.randint(Age_average - Age_std, Age_average + Age_std , size = Age_nullcount)

#Ageの欠損値
train_df["Age"][np.isnan(train_df["Age"])] = rand

#グラフ描画
plt.hist(train_df_original["Age"].dropna(), alpha=0.2,color="r")
plt.hist(train_df["Age"],alpha=0.2,color="b")

image.png


k近傍法

(のちに勉強する)


3 欠損値という値として扱う

参考:

Python pandas 欠損値/外れ値/離散化の処理

機械学習のための欠損値処理まとめ

欠損値を含むデータをどう解析するか?

外れ値や欠損値のあるデータの解析

kaggle kernel "A Journey through Titanic"